From a40f0be6fdb9f3987f11240cacae6784100cd30a Mon Sep 17 00:00:00 2001 From: pathetic meowmeow Date: Sun, 16 Mar 2025 17:18:53 -0400 Subject: [PATCH] Set up surgical augments infrastructure & add tool panel augments (#3059) * Set up _Shitmed groundwork for organ slot manipulation * Groundwork for surgical augments * Add tool panel augments * sprite gaming * code review gaming * i think the textures got swapped * localization gaming * surgery localization gaming * crafting gaming * fix tests * fix tests actually * now we deal with ouroboros * she feed on my back til i * relocation * nuke felinid * augment fixes * event-based battery search * descriptionned --------- Co-authored-by: Lyndomen <49795619+Lyndomen@users.noreply.github.com> --- .../_DV/Augments/AugmentToolPanelMenu.xaml | 10 + .../_DV/Augments/AugmentToolPanelMenu.xaml.cs | 72 ++++++ .../AugmentToolPanelMenuBoundUserInterface.cs | 39 +++ .../Power/EntitySystems/ChargerSystem.cs | 44 +++- Content.Server/PowerCell/PowerCellSystem.cs | 8 + .../_DV/Augments/AugmentPowerCellSystem.cs | 128 ++++++++++ .../_DV/Augments/AugmentToolPanelSystem.cs | 93 +++++++ .../_EE/Power/Systems/BatteryDrinkerSystem.cs | 22 +- .../_DV/Augments/AugmentActionComponent.cs | 9 + .../_DV/Augments/AugmentActionSystem.cs | 38 +++ .../Augments/AugmentActivatableUIComponent.cs | 27 ++ .../Augments/AugmentActivatableUISystem.cs | 39 +++ .../_DV/Augments/AugmentArmComponent.cs | 9 + .../_DV/Augments/AugmentChargerComponent.cs | 16 ++ .../_DV/Augments/AugmentComponent.cs | 19 ++ .../_DV/Augments/AugmentPowerCellSlot.cs | 24 ++ Content.Shared/_DV/Augments/AugmentSystem.cs | 42 +++ .../_DV/Augments/AugmentToolPanelComponent.cs | 38 +++ .../Augments/SharedAugmentToolPanelSystem.cs | 19 ++ .../SurgeryBodyConditionComponent.cs | 18 ++ .../SurgeryOrganSlotConditionComponent.cs | 13 + .../Surgery/SharedSurgerySystem.Steps.cs | 17 ++ .../_Shitmed/Surgery/SharedSurgerySystem.cs | 13 + .../Steps/SurgeryAddOrganSlotStepComponent.cs | 6 + .../Locale/en-US/_DV/augments/augments.ftl | 3 + .../Locale/en-US/_DV/augments/surgeries.ftl | 3 + .../en-US/_DV/research/technologies.ftl | 2 + .../en-US/_Shitmed/surgery/surgery-popup.ftl | 2 + .../Circuitboards/Machine/production.yml | 4 + .../Entities/Structures/Machines/lathe.yml | 2 + .../Entities/Structures/Power/chargers.yml | 3 + Resources/Prototypes/_DV/Augments/arm.yml | 241 ++++++++++++++++++ Resources/Prototypes/_DV/Augments/base.yml | 6 + Resources/Prototypes/_DV/Augments/power.yml | 137 ++++++++++ .../_DV/Entities/Surgery/surgeries.yml | 179 +++++++++++++ .../_DV/Entities/Surgery/surgery_steps.yml | 17 ++ .../Recipes/Construction/Graphs/augments.yml | 131 ++++++++++ .../_DV/Recipes/Construction/augments.yml | 90 +++++++ .../_DV/Recipes/Lathes/Packs/robotics.yml | 17 +- .../_DV/Recipes/Lathes/robotics.yml | 35 +++ .../_DV/Research/civilianservices.yml | 31 +++ Resources/Prototypes/_DV/tags.yml | 27 ++ .../Entities/Surgery/surgery_steps.yml | 24 ++ .../_DV/Objects/Augments/arm.rsi/base.png | Bin 0 -> 326 bytes .../Objects/Augments/arm.rsi/base_cables.png | Bin 0 -> 384 bytes .../_DV/Objects/Augments/arm.rsi/botany.png | Bin 0 -> 808 bytes .../Objects/Augments/arm.rsi/engineering.png | Bin 0 -> 352 bytes .../_DV/Objects/Augments/arm.rsi/meta.json | 29 +++ .../Objects/Augments/arm.rsi/paperwork.png | Bin 0 -> 799 bytes .../_DV/Objects/Augments/arm.rsi/surgical.png | Bin 0 -> 352 bytes .../_DV/Objects/Augments/power.rsi/apc.png | Bin 0 -> 191 bytes .../_DV/Objects/Augments/power.rsi/cell.png | Bin 0 -> 275 bytes .../Augments/power.rsi/incomplete_cell.png | Bin 0 -> 220 bytes .../power.rsi/incomplete_cell_cables.png | Bin 0 -> 275 bytes .../Augments/power.rsi/incomplete_charger.png | Bin 0 -> 223 bytes .../power.rsi/incomplete_charger_cables.png | Bin 0 -> 239 bytes .../_DV/Objects/Augments/power.rsi/meta.json | 32 +++ .../Objects/Augments/power.rsi/station.png | Bin 0 -> 190 bytes 58 files changed, 1757 insertions(+), 21 deletions(-) create mode 100644 Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml create mode 100644 Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml.cs create mode 100644 Content.Client/_DV/Augments/AugmentToolPanelMenuBoundUserInterface.cs create mode 100644 Content.Server/_DV/Augments/AugmentPowerCellSystem.cs create mode 100644 Content.Server/_DV/Augments/AugmentToolPanelSystem.cs create mode 100644 Content.Shared/_DV/Augments/AugmentActionComponent.cs create mode 100644 Content.Shared/_DV/Augments/AugmentActionSystem.cs create mode 100644 Content.Shared/_DV/Augments/AugmentActivatableUIComponent.cs create mode 100644 Content.Shared/_DV/Augments/AugmentActivatableUISystem.cs create mode 100644 Content.Shared/_DV/Augments/AugmentArmComponent.cs create mode 100644 Content.Shared/_DV/Augments/AugmentChargerComponent.cs create mode 100644 Content.Shared/_DV/Augments/AugmentComponent.cs create mode 100644 Content.Shared/_DV/Augments/AugmentPowerCellSlot.cs create mode 100644 Content.Shared/_DV/Augments/AugmentSystem.cs create mode 100644 Content.Shared/_DV/Augments/AugmentToolPanelComponent.cs create mode 100644 Content.Shared/_DV/Augments/SharedAugmentToolPanelSystem.cs create mode 100644 Content.Shared/_Shitmed/Surgery/Conditions/SurgeryBodyConditionComponent.cs create mode 100644 Content.Shared/_Shitmed/Surgery/Conditions/SurgeryOrganSlotConditionComponent.cs create mode 100644 Content.Shared/_Shitmed/Surgery/Steps/SurgeryAddOrganSlotStepComponent.cs create mode 100644 Resources/Locale/en-US/_DV/augments/augments.ftl create mode 100644 Resources/Locale/en-US/_DV/augments/surgeries.ftl create mode 100644 Resources/Prototypes/_DV/Augments/arm.yml create mode 100644 Resources/Prototypes/_DV/Augments/base.yml create mode 100644 Resources/Prototypes/_DV/Augments/power.yml create mode 100644 Resources/Prototypes/_DV/Entities/Surgery/surgeries.yml create mode 100644 Resources/Prototypes/_DV/Entities/Surgery/surgery_steps.yml create mode 100644 Resources/Prototypes/_DV/Recipes/Construction/Graphs/augments.yml create mode 100644 Resources/Prototypes/_DV/Recipes/Construction/augments.yml create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/base.png create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/base_cables.png create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/botany.png create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/engineering.png create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/meta.json create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/paperwork.png create mode 100644 Resources/Textures/_DV/Objects/Augments/arm.rsi/surgical.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/apc.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/cell.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_cell.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_cell_cables.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_charger.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_charger_cables.png create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/meta.json create mode 100644 Resources/Textures/_DV/Objects/Augments/power.rsi/station.png diff --git a/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml b/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml new file mode 100644 index 0000000000..eeff0b0863 --- /dev/null +++ b/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml @@ -0,0 +1,10 @@ + + + + diff --git a/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml.cs b/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml.cs new file mode 100644 index 0000000000..7a8ad72bff --- /dev/null +++ b/Content.Client/_DV/Augments/AugmentToolPanelMenu.xaml.cs @@ -0,0 +1,72 @@ +using Content.Client.UserInterface.Controls; +using JetBrains.Annotations; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Client.UserInterface; +using Content.Shared.Storage; +using System.Numerics; +using Robust.Shared.GameObjects; + +namespace Content.Client._DV.Augments; + +[GenerateTypedNameReferences] +public sealed partial class AugmentToolPanelMenu : RadialMenu +{ + [Dependency] private readonly EntityManager _entManager = default!; + + public event Action? SendAugmentToolPanelSystemMessageAction; + + private EntityUid _owner; + + public AugmentToolPanelMenu() + { + IoCManager.InjectDependencies(this); + RobustXamlLoader.Load(this); + } + + public void SetEntity(EntityUid uid) + { + _owner = uid; + Refresh(); + } + + public void Refresh() + { + if (!_entManager.TryGetComponent(_owner, out var storage)) + return; + + foreach (var (entity, _) in storage.StoredItems) + { + var button = new RadialMenuTextureButtonWithSector() + { + SetSize = new Vector2(64f, 64f), + }; + + button.AddChild(new SpriteView(entity, _entManager) + { + Scale = new Vector2(3f, 3f), + }); + Main.AddChild(button); + + button.OnButtonUp += _ => + { + SendAugmentToolPanelSystemMessageAction?.Invoke(entity); + Close(); + }; + } + + var nilButton = new RadialMenuTextureButtonWithSector() + { + SetSize = new Vector2(64f, 64f), + }; + + Main.AddChild(nilButton); + + nilButton.OnButtonUp += _ => + { + SendAugmentToolPanelSystemMessageAction?.Invoke(null); + Close(); + }; + } +} diff --git a/Content.Client/_DV/Augments/AugmentToolPanelMenuBoundUserInterface.cs b/Content.Client/_DV/Augments/AugmentToolPanelMenuBoundUserInterface.cs new file mode 100644 index 0000000000..4d5af73e10 --- /dev/null +++ b/Content.Client/_DV/Augments/AugmentToolPanelMenuBoundUserInterface.cs @@ -0,0 +1,39 @@ +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.UserInterface; +using Robust.Shared.Prototypes; +using Content.Shared._DV.Augments; + +namespace Content.Client._DV.Augments; + +public sealed class AugmentToolPanelMenuBoundUserInterface : BoundUserInterface +{ + [Dependency] private readonly IClyde _displayManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IEntityManager _entMan = default!; + + private AugmentToolPanelMenu? _menu; + + public AugmentToolPanelMenuBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + IoCManager.InjectDependencies(this); + } + + protected override void Open() + { + base.Open(); + + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendAugmentToolPanelSystemMessageAction += SendAugmentToolPanelSystemMessage; + + // Open the menu, centered on the mouse + var vpSize = _displayManager.ScreenSize; + _menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / vpSize); + } + + public void SendAugmentToolPanelSystemMessage(EntityUid? desiredTool) + { + SendMessage(new AugmentToolPanelSystemMessage(_entMan.GetNetEntity(desiredTool))); + } +} diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index 09b598d262..fbd4e723ba 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -11,6 +11,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Storage.Components; using Robust.Server.Containers; using Content.Shared.Whitelist; +using Content.Server._DV.Augments; // DeltaV - bodies can have an augment power cell namespace Content.Server.Power.EntitySystems; @@ -22,6 +23,7 @@ internal sealed class ChargerSystem : EntitySystem [Dependency] private readonly BatterySystem _battery = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + [Dependency] private readonly AugmentPowerCellSystem _augments = default!; // DeltaV - bodies can have an augment power cell public override void Initialize() { @@ -250,15 +252,45 @@ internal sealed class ChargerSystem : EntitySystem UpdateStatus(uid, component); } - private bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? batteryUid, [NotNullWhen(true)] out BatteryComponent? component) + // Begin DeltaV - event-based search for battery + public bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? batteryUid, [NotNullWhen(true)] out BatteryComponent? component) { // try get a battery directly on the inserted entity - if (!TryComp(uid, out component)) + if (TryComp(uid, out component)) { - // or by checking for a power cell slot on the inserted entity - return _powerCell.TryGetBatteryFromSlot(uid, out batteryUid, out component); + batteryUid = uid; + return true; } - batteryUid = uid; - return true; + + var evt = new SearchForBatteryEvent(); + RaiseLocalEvent(uid, ref evt); + if (evt.Handled) + { + batteryUid = evt.Uid; + component = evt.Component; + return evt.Handled; + } + + batteryUid = null; + component = null; + return false; } + // End DeltaV - event-based search for battery } + +// Begin DeltaV - event-based search for battery + +/// +/// Event raised to search for batteries within an entity +/// +[ByRefEvent] +public struct SearchForBatteryEvent +{ + public EntityUid? Uid; + + public BatteryComponent? Component; + + public bool Handled; +} + +// End DeltaV - event-based search for battery diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index dfbb02e73d..0a1443b761 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -42,8 +42,16 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem SubscribeLocalEvent(OnCellSlotExamined); // funny SubscribeLocalEvent(OnSlotMicrowaved); + SubscribeLocalEvent(OnSearchForBattery); // DeltaV - event-based search for battery } + // Begin DeltaV - event-based search for battery + private void OnSearchForBattery(Entity ent, ref SearchForBatteryEvent args) + { + args.Handled = TryGetBatteryFromSlot(ent, out args.Uid, out args.Component); + } + // End DeltaV - event-based search for battery + private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args) { if (!_itemSlotsSystem.TryGetSlot(uid, component.CellSlotId, out var slot)) diff --git a/Content.Server/_DV/Augments/AugmentPowerCellSystem.cs b/Content.Server/_DV/Augments/AugmentPowerCellSystem.cs new file mode 100644 index 0000000000..347661f6d8 --- /dev/null +++ b/Content.Server/_DV/Augments/AugmentPowerCellSystem.cs @@ -0,0 +1,128 @@ +using Content.Server.Power.Components; // ough BatteryComponent why are you in server +using Content.Server.Power.EntitySystems; +using Content.Server.PowerCell; +using Content.Shared._DV.Augments; +using Content.Shared.Alert; +using Content.Shared.Body.Organ; +using Content.Shared.Body.Systems; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; +using Content.Shared.PowerCell.Components; + +namespace Content.Server._DV.Augments; + +public sealed class AugmentPowerCellSystem : EntitySystem +{ + [Dependency] private readonly AlertsSystem _alerts = default!; + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSearchForBattery); + } + + private void OnSearchForBattery(Entity ent, ref SearchForBatteryEvent args) + { + // or by checking for an augment power cell + if (TryGetAugmentPowerCell(ent) is (_, var insertedBattery) && insertedBattery is {} battery) + { + args.Uid = battery.Owner; + args.Component = battery.Comp; + args.Handled = true; + return; + } + } + + public (Entity Organ, Entity? Battery)? TryGetAugmentPowerCell(EntityUid body) + { + foreach (var organ in _body.GetBodyOrganEntityComps(body)) + { + if (!TryComp(organ, out var powerCellSlot)) + continue; + + var entity = new Entity(organ.Owner, organ.Comp1, organ.Comp2, powerCellSlot); + + if (_powerCell.TryGetBatteryFromSlot(organ, out var batteryUid, out var batteryComp)) + { + return (entity, new(batteryUid.Value, batteryComp)); + } + return (entity, null); + } + return null; + } + + public (Entity Organ, Entity? Battery)? TryGetAugmentPowerCellFromAugment(EntityUid augment) + { + if (!TryComp(augment, out var organ) || organ.Body is not {} uid) + return null; + + return TryGetAugmentPowerCell(uid); + } + + public bool TryDrawPower(EntityUid augment, float amount) + { + if (!TryComp(augment, out var organ) || organ.Body is not {} body) + return false; + + if (TryGetAugmentPowerCellFromAugment(augment) is not (_, var battery)) + { + _popup.PopupEntity(Loc.GetString("augments-no-power-cell-slot"), body, body); + return false; + } + + if (battery is not {} insertedBattery) + { + _popup.PopupEntity(Loc.GetString("power-cell-no-battery"), body, body); + return false; + } + + if (!_battery.TryUseCharge(insertedBattery.Owner, amount)) + { + _popup.PopupEntity(Loc.GetString("power-cell-insufficient"), body, body); + return false; + } + + return true; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var owner, out _)) + { + if (_mobState.IsDead(owner)) + continue; + + var powerCell = TryGetAugmentPowerCell(owner); + if (powerCell is not {} power) + continue; + var augment = power.Organ; + + if (power.Battery is not {} insertedBattery) + { + if (_alerts.IsShowingAlert(owner, augment.Comp1.BatteryAlert)) + { + _alerts.ClearAlert(owner, augment.Comp1.BatteryAlert); + _alerts.ShowAlert(owner, augment.Comp1.NoBatteryAlert); + } + continue; + } + + if (_alerts.IsShowingAlert(owner, augment.Comp1.NoBatteryAlert)) + { + _alerts.ClearAlert(owner, augment.Comp1.NoBatteryAlert); + } + + var chargePercent = (short) MathF.Round(insertedBattery.Comp.CurrentCharge / insertedBattery.Comp.MaxCharge * 10f); + _alerts.ShowAlert(owner, augment.Comp1.BatteryAlert, chargePercent); + } + } +} diff --git a/Content.Server/_DV/Augments/AugmentToolPanelSystem.cs b/Content.Server/_DV/Augments/AugmentToolPanelSystem.cs new file mode 100644 index 0000000000..8aeb0f6cd6 --- /dev/null +++ b/Content.Server/_DV/Augments/AugmentToolPanelSystem.cs @@ -0,0 +1,93 @@ +using System.Linq; +using Content.Server.Power.EntitySystems; +using Content.Shared._DV.Augments; +using Content.Shared.Body.Organ; +using Content.Shared.Body.Part; +using Content.Shared.Body.Systems; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Popups; +using Content.Shared.Storage.EntitySystems; +using Robust.Shared.Containers; + +namespace Content.Server._DV.Augments; + +public sealed class AugmentToolPanelSystem : EntitySystem +{ + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly SharedStorageSystem _storage = default!; + [Dependency] private readonly AugmentPowerCellSystem _augmentPowerCell = default!; + + public override void Initialize() + { + base.Initialize(); + + Subs.BuiEvents(AugmentToolPanelUiKey.Key, subs => + { + subs.Event(OnSwitchTool); + }); + } + + private void OnSwitchTool(Entity augment, ref AugmentToolPanelSystemMessage args) + { + if (!TryComp(augment, out var organ) || organ.Body is not {} body) + return; + + if (!TryComp(body, out var hands)) + return; + + if (!_container.TryGetContainingContainer(augment.Owner, out var container)) + return; + + if (!_augmentPowerCell.TryDrawPower(augment, augment.Comp.PowerDrawOnSwitch)) + return; + + foreach (var part in _body.GetBodyPartChildren(container.Owner)) + { + if (part.Component.PartType != BodyPartType.Hand) + continue; + + var handLocation = part.Component.Symmetry switch { + BodyPartSymmetry.None => HandLocation.Middle, + BodyPartSymmetry.Left => HandLocation.Left, + BodyPartSymmetry.Right => HandLocation.Right, + _ => throw new InvalidOperationException(), + }; + + var desiredHand = hands.Hands.Values.FirstOrDefault(hand => hand.Location == handLocation); + if (desiredHand == null) + continue; + + // if we have a tool that's currently out + if (HasComp(desiredHand.HeldEntity)) + { + // deposit it back into the storage + RemComp(desiredHand.HeldEntity!.Value); + + if (!_storage.PlayerInsertEntityInWorld(augment.Owner, body, desiredHand.HeldEntity!.Value)) + { + EnsureComp(desiredHand.HeldEntity!.Value); + return; + } + } + else if (desiredHand.HeldEntity is not null) + { + _popup.PopupCursor(Loc.GetString("augment-tool-panel-hand-full"), body); + return; + } + + if (GetEntity(args.DesiredTool) is not {} desiredTool) + return; + + if (!_hands.TryPickup(body, desiredTool, desiredHand)) + { + _popup.PopupCursor(Loc.GetString("augment-tool-panel-cannot-pick-up"), body); + return; + } + EnsureComp(desiredTool); + } + } +} diff --git a/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs b/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs index 6e2307181e..5e2601c40c 100644 --- a/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs +++ b/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs @@ -28,6 +28,7 @@ public sealed class BatteryDrinkerSystem : EntitySystem [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly PowerCellSystem _powerCell = default!; [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly ChargerSystem _chargers = default!; // DeltaV - people with augment power cells can drink batteries public override void Initialize() { @@ -45,7 +46,8 @@ public sealed class BatteryDrinkerSystem : EntitySystem if (!TryComp(args.User, out var drinkerComp) || !TestDrinkableBattery(uid, drinkerComp) || - !_silicon.TryGetSiliconBattery(args.User, out var drinkerBattery)) + // DeltaV - people with augment power cells can drink batteries + !_chargers.SearchForBattery(args.User, out _, out _)) return; AlternativeVerb verb = new() @@ -97,21 +99,13 @@ public sealed class BatteryDrinkerSystem : EntitySystem var drinker = uid; var sourceBattery = Comp(source); - _silicon.TryGetSiliconBattery(drinker, out var drinkerBatteryComponent); - - if (!TryComp(uid, out PowerCellSlotComponent? batterySlot)) + // DeltaV - people with augment power cells can drink batteries + if (!_chargers.SearchForBattery(drinker, out var drinkerBattery, out var drinkerBatteryComponent)) return; - var container = _container.GetContainer(uid, batterySlot.CellSlotId); - var drinkerBattery = container.ContainedEntities.First(); - + // DeltaV - people with augment power cells can drink batteries TryComp(source, out var sourceComp); - DebugTools.AssertNotNull(drinkerBattery); - - if (drinkerBattery == null) - return; - var amountToDrink = drinkerComp.DrinkMultiplier * 1000; amountToDrink = MathF.Min(amountToDrink, sourceBattery.CurrentCharge); @@ -127,10 +121,10 @@ public sealed class BatteryDrinkerSystem : EntitySystem } if (_battery.TryUseCharge(source, amountToDrink)) - _battery.SetCharge(drinkerBattery, drinkerBatteryComponent.CurrentCharge + amountToDrink, drinkerBatteryComponent); + _battery.SetCharge(drinkerBattery.Value, drinkerBatteryComponent.CurrentCharge + amountToDrink, drinkerBatteryComponent); // DeltaV - people with augment power cells can drink batteries else { - _battery.SetCharge(drinkerBattery, sourceBattery.CurrentCharge + drinkerBatteryComponent.CurrentCharge, drinkerBatteryComponent); + _battery.SetCharge(drinkerBattery.Value, sourceBattery.CurrentCharge + drinkerBatteryComponent.CurrentCharge, drinkerBatteryComponent); // DeltaV - people with augment power cells can drink batteries _battery.SetCharge(source, 0); } diff --git a/Content.Shared/_DV/Augments/AugmentActionComponent.cs b/Content.Shared/_DV/Augments/AugmentActionComponent.cs new file mode 100644 index 0000000000..181823eea8 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentActionComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._DV.Augments; + +/// +/// Component that allows an augment to have actions +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentActionComponent : Component; diff --git a/Content.Shared/_DV/Augments/AugmentActionSystem.cs b/Content.Shared/_DV/Augments/AugmentActionSystem.cs new file mode 100644 index 0000000000..c157d18215 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentActionSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared._Shitmed.Body.Organ; +using Content.Shared.Actions; +using Content.Shared.Body.Organ; + +namespace Content.Shared._DV.Augments; + +public sealed class AugmentActionSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly ActionContainerSystem _actionContainer = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnOrganEnableChanged); + } + + private void OnOrganEnableChanged(Entity augment, ref OrganEnableChangedEvent args) + { + if (!TryComp(augment, out var organ) || organ.Body is not {} body) + return; + + var actionsComponent = EnsureComp(body); + + if (args.Enabled) + { + var ev = new GetItemActionsEvent(_actionContainer, body, augment); + RaiseLocalEvent(augment, ev); + + _actions.GrantActions(body, ev.Actions, augment, actionsComponent); + } + else + { + _actions.RemoveProvidedActions(body, augment, actionsComponent); + } + } +} diff --git a/Content.Shared/_DV/Augments/AugmentActivatableUIComponent.cs b/Content.Shared/_DV/Augments/AugmentActivatableUIComponent.cs new file mode 100644 index 0000000000..40b64496e3 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentActivatableUIComponent.cs @@ -0,0 +1,27 @@ +using Content.Shared.Actions; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations; + +namespace Content.Shared._DV.Augments; + +/// +/// Component that allows an augment to have a user interface +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class AugmentActivatableUIComponent : Component +{ + [DataField(required: true, customTypeSerializer: typeof(EnumSerializer))] + public Enum? Key; + + [DataField] + public EntProtoId OpenAction = "ActionOpenAugmentInterface"; + + [DataField, AutoNetworkedField] + public EntityUid? OpenActionEntity; +} + +/// +/// Event that should be dispatched by the to open the UI +/// +public sealed partial class AugmentUIOpenEvent : InstantActionEvent; diff --git a/Content.Shared/_DV/Augments/AugmentActivatableUISystem.cs b/Content.Shared/_DV/Augments/AugmentActivatableUISystem.cs new file mode 100644 index 0000000000..46f2e41e93 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentActivatableUISystem.cs @@ -0,0 +1,39 @@ +using Content.Shared._Shitmed.Body.Organ; +using Content.Shared.Actions; +using Content.Shared.Body.Organ; +using Robust.Shared.GameObjects; + +namespace Content.Shared._DV.Augments; + +public sealed class AugmentActivatableUISystem : EntitySystem +{ + [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnOpen); + SubscribeLocalEvent(OnGetActions); + } + + private void OnOpen(Entity augment, ref AugmentUIOpenEvent args) + { + if (!TryComp(augment, out var organ) || organ.Body is not {} body) + return; + + if (augment.Comp.Key == null || !_uiSystem.HasUi(augment, augment.Comp.Key)) + return; + + _uiSystem.OpenUi(augment.Owner, augment.Comp.Key, body); + args.Handled = true; + } + + private void OnGetActions(Entity ent, ref GetItemActionsEvent args) + { + if (!TryComp(ent, out var organ) || organ.Body is not {} body) + return; + + args.AddAction(ref ent.Comp.OpenActionEntity, ent.Comp.OpenAction); + } +} diff --git a/Content.Shared/_DV/Augments/AugmentArmComponent.cs b/Content.Shared/_DV/Augments/AugmentArmComponent.cs new file mode 100644 index 0000000000..3268176a38 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentArmComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._DV.Augments; + +/// +/// Marker component to indicate that an entity serves as an AugmentArm organ +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentArmComponent : Component; diff --git a/Content.Shared/_DV/Augments/AugmentChargerComponent.cs b/Content.Shared/_DV/Augments/AugmentChargerComponent.cs new file mode 100644 index 0000000000..5e2ecef486 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentChargerComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._DV.Augments; + +/// +/// Marker component to indicate that an entity serves as an AugmentCharger organ +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentChargerComponent : Component; + +/// +/// Marker component to indicate that an entity will recharge its augment power cell from borg charging stations +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentStationRechargeComponent : Component; + diff --git a/Content.Shared/_DV/Augments/AugmentComponent.cs b/Content.Shared/_DV/Augments/AugmentComponent.cs new file mode 100644 index 0000000000..a8fd1364ca --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._DV.Augments; + +/// +/// Component that indicates an entity is an augment +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentComponent : Component; + +/// +/// Component that tracks which augments are installed on this body +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class InstalledAugmentsComponent : Component +{ + [DataField] + public HashSet InstalledAugments = new(); +} diff --git a/Content.Shared/_DV/Augments/AugmentPowerCellSlot.cs b/Content.Shared/_DV/Augments/AugmentPowerCellSlot.cs new file mode 100644 index 0000000000..3a4a1cdd15 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentPowerCellSlot.cs @@ -0,0 +1,24 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Content.Shared.Alert; + +namespace Content.Shared._DV.Augments; + +/// +/// Component for entitie that serve as AugmentPowerCellSlot organs +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentPowerCellSlotComponent : Component +{ + [DataField] + public ProtoId BatteryAlert = "BorgBattery"; + + [DataField] + public ProtoId NoBatteryAlert = "BorgBatteryNone"; +} + +/// +/// Marker component to indicate that an entity currently has an AugmentPowerCellSlot organ +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class HasAugmentPowerCellSlotComponent : Component; diff --git a/Content.Shared/_DV/Augments/AugmentSystem.cs b/Content.Shared/_DV/Augments/AugmentSystem.cs new file mode 100644 index 0000000000..f54cd84555 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentSystem.cs @@ -0,0 +1,42 @@ +using Content.Shared.Body.Events; +using Content.Shared.Body.Organ; +using Content.Shared.Interaction; + +namespace Content.Shared._DV.Augments; + +public sealed class AugmentSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnOrganOrganAddedToBody); + SubscribeLocalEvent(OnOrganOrganRemovedFromBody); + SubscribeLocalEvent(OnAccessibleOverride); + } + + private void OnOrganOrganAddedToBody(Entity augment, ref OrganAddedToBodyEvent args) + { + var installed = EnsureComp(args.Body); + installed.InstalledAugments.Add(GetNetEntity(augment)); + } + + private void OnOrganOrganRemovedFromBody(Entity augment, ref OrganRemovedFromBodyEvent args) + { + if (!TryComp(args.OldBody, out var installed)) + return; + + installed.InstalledAugments.Remove(GetNetEntity(augment)); + if (installed.InstalledAugments.Count == 0) + RemComp(args.OldBody); + } + + private void OnAccessibleOverride(Entity augment, ref AccessibleOverrideEvent args) + { + if (!TryComp(args.Target, out var organ)) + return; + + args.Handled = true; + args.Accessible = organ.Body == args.User; + } +} diff --git a/Content.Shared/_DV/Augments/AugmentToolPanelComponent.cs b/Content.Shared/_DV/Augments/AugmentToolPanelComponent.cs new file mode 100644 index 0000000000..51b9ae2b58 --- /dev/null +++ b/Content.Shared/_DV/Augments/AugmentToolPanelComponent.cs @@ -0,0 +1,38 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Robust.Shared.Prototypes; + +namespace Content.Shared._DV.Augments; + +/// +/// Marker component to indicate that an entity will allow access to its storage via a radial menu once implanted +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentToolPanelComponent : Component +{ + [DataField] + public float PowerDrawOnSwitch = 10f; +} + +/// +/// Marker component to indicate that an entity is the active tool of an augment tool panel +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AugmentToolPanelActiveItemComponent : Component; + +[Serializable, NetSerializable] +public sealed class AugmentToolPanelSystemMessage : BoundUserInterfaceMessage +{ + public NetEntity? DesiredTool; + + public AugmentToolPanelSystemMessage(NetEntity? desiredTool) + { + DesiredTool = desiredTool; + } +} + +[Serializable, NetSerializable] +public enum AugmentToolPanelUiKey : byte +{ + Key +} diff --git a/Content.Shared/_DV/Augments/SharedAugmentToolPanelSystem.cs b/Content.Shared/_DV/Augments/SharedAugmentToolPanelSystem.cs new file mode 100644 index 0000000000..b0b5aaa0ea --- /dev/null +++ b/Content.Shared/_DV/Augments/SharedAugmentToolPanelSystem.cs @@ -0,0 +1,19 @@ +using Content.Shared.Hands; +using Robust.Shared.Containers; + +namespace Content.Shared._DV.Augments; + +public sealed class SharedAugmentToolPanelSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDropAttempt); + } + + private void OnDropAttempt(Entity ent, ref ContainerGettingRemovedAttemptEvent args) + { + args.Cancel(); + } +} diff --git a/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryBodyConditionComponent.cs b/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryBodyConditionComponent.cs new file mode 100644 index 0000000000..8dd3d2a4d6 --- /dev/null +++ b/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryBodyConditionComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Content.Shared.Body.Prototypes; + +namespace Content.Shared._Shitmed.Medical.Surgery.Conditions; + +/// +/// Requires that this surgery is (not) done on one of the provided body prototypes +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryBodyConditionComponent : Component +{ + [DataField(required: true)] + public HashSet> Accepted = default!; + + [DataField] + public bool Inverse; +} diff --git a/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryOrganSlotConditionComponent.cs b/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryOrganSlotConditionComponent.cs new file mode 100644 index 0000000000..67ebe0546f --- /dev/null +++ b/Content.Shared/_Shitmed/Surgery/Conditions/SurgeryOrganSlotConditionComponent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Shitmed.Medical.Surgery.Conditions; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryOrganSlotConditionComponent : Component +{ + [DataField(required: true)] + public string OrganSlot = default!; + + [DataField] + public bool Inverse; +} diff --git a/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.Steps.cs b/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.Steps.cs index dd0d28600f..868ea862d3 100644 --- a/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.Steps.cs +++ b/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.Steps.cs @@ -55,6 +55,7 @@ public abstract partial class SharedSurgerySystem SubSurgery(OnAffixOrganStep, OnAffixOrganCheck); SubSurgery(OnAddMarkingStep, OnAddMarkingCheck); SubSurgery(OnRemoveMarkingStep, OnRemoveMarkingCheck); + SubSurgery(OnAddOrganSlotStep, OnAddOrganSlotCheck); Subs.BuiEvents(SurgeryUIKey.Key, subs => { subs.Event(OnSurgeryTargetStepChosen); @@ -449,6 +450,22 @@ public abstract partial class SharedSurgerySystem } } + private void OnAddOrganSlotStep(Entity ent, ref SurgeryStepEvent args) + { + if (!TryComp(args.Surgery, out SurgeryOrganSlotConditionComponent? condition)) + return; + + _body.TryCreateOrganSlot(args.Part, condition.OrganSlot, out _); + } + + private void OnAddOrganSlotCheck(Entity ent, ref SurgeryStepCompleteCheckEvent args) + { + if (!TryComp(args.Surgery, out SurgeryOrganSlotConditionComponent? condition)) + return; + + args.Cancelled = !_body.CanInsertOrgan(args.Part, condition.OrganSlot); + } + private void OnAffixPartStep(Entity ent, ref SurgeryStepEvent args) { if (!TryComp(args.Surgery, out SurgeryPartRemovedConditionComponent? removedComp)) diff --git a/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.cs b/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.cs index 58638bd4df..94117932ad 100644 --- a/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.cs +++ b/Content.Shared/_Shitmed/Surgery/SharedSurgerySystem.cs @@ -79,6 +79,8 @@ public abstract partial class SharedSurgerySystem : EntitySystem SubscribeLocalEvent(OnOrganConditionValid); SubscribeLocalEvent(OnWoundedValid); SubscribeLocalEvent(OnPartRemovedConditionValid); + SubscribeLocalEvent(OnBodyConditionValid); + SubscribeLocalEvent(OnOrganSlotConditionValid); SubscribeLocalEvent(OnPartPresentConditionValid); SubscribeLocalEvent(OnMarkingPresentValid); SubscribeLocalEvent(OnBodyComponentConditionValid); @@ -278,6 +280,17 @@ public abstract partial class SharedSurgerySystem : EntitySystem } } + private void OnBodyConditionValid(Entity ent, ref SurgeryValidEvent args) + { + if (TryComp(args.Body, out var body) && body.Prototype is {} bodyId) + args.Cancelled = ent.Comp.Accepted.Contains(bodyId) ^ !ent.Comp.Inverse; + } + + private void OnOrganSlotConditionValid(Entity ent, ref SurgeryValidEvent args) + { + args.Cancelled = _body.CanInsertOrgan(args.Part, ent.Comp.OrganSlot) ^ !ent.Comp.Inverse; + } + private void OnPartRemovedConditionValid(Entity ent, ref SurgeryValidEvent args) { if (!_body.CanAttachToSlot(args.Part, ent.Comp.Connection)) diff --git a/Content.Shared/_Shitmed/Surgery/Steps/SurgeryAddOrganSlotStepComponent.cs b/Content.Shared/_Shitmed/Surgery/Steps/SurgeryAddOrganSlotStepComponent.cs new file mode 100644 index 0000000000..b77c886a1a --- /dev/null +++ b/Content.Shared/_Shitmed/Surgery/Steps/SurgeryAddOrganSlotStepComponent.cs @@ -0,0 +1,6 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Shitmed.Medical.Surgery.Steps; + +[RegisterComponent, NetworkedComponent] +public sealed partial class SurgeryAddOrganSlotStepComponent : Component; diff --git a/Resources/Locale/en-US/_DV/augments/augments.ftl b/Resources/Locale/en-US/_DV/augments/augments.ftl new file mode 100644 index 0000000000..c7888db493 --- /dev/null +++ b/Resources/Locale/en-US/_DV/augments/augments.ftl @@ -0,0 +1,3 @@ +augments-no-power-cell-slot = You don't have a power cell slot installed +augment-tool-panel-hand-full = There's something in your hand +augment-tool-panel-cannot-pick-up = Your hand isn't capable of holding that diff --git a/Resources/Locale/en-US/_DV/augments/surgeries.ftl b/Resources/Locale/en-US/_DV/augments/surgeries.ftl new file mode 100644 index 0000000000..aa048db176 --- /dev/null +++ b/Resources/Locale/en-US/_DV/augments/surgeries.ftl @@ -0,0 +1,3 @@ +surgery-popup-step-SurgeryStepInsertAugmentPowerCellSlot = {$user} is inserting a power cell slot into {$target}'s {$part}. +surgery-popup-step-SurgeryStepInsertAugmentPowerCellCharger = {$user} is inserting a power cell recharger into {$target}'s {$part}. +surgery-popup-step-SurgeryStepInsertAugmentArm = {$user} is inserting an augment into {$target}'s {$part}. diff --git a/Resources/Locale/en-US/_DV/research/technologies.ftl b/Resources/Locale/en-US/_DV/research/technologies.ftl index 4c94820670..42e87c7f5f 100644 --- a/Resources/Locale/en-US/_DV/research/technologies.ftl +++ b/Resources/Locale/en-US/_DV/research/technologies.ftl @@ -7,6 +7,8 @@ research-technology-cloning = Cloning # Civilian research-technology-syringe-gun = Syringe Gun +research-technology-basic-augmentation = Basic Augmentation +research-technology-implanted-tools = Implanted Tools # Arsenal research-technology-exotic-ammunition = Exotic Ammunition diff --git a/Resources/Locale/en-US/_Shitmed/surgery/surgery-popup.ftl b/Resources/Locale/en-US/_Shitmed/surgery/surgery-popup.ftl index 5d5c062f09..b8374074c5 100644 --- a/Resources/Locale/en-US/_Shitmed/surgery/surgery-popup.ftl +++ b/Resources/Locale/en-US/_Shitmed/surgery/surgery-popup.ftl @@ -35,6 +35,8 @@ surgery-popup-step-SurgeryStepRemoveItem = {$user} is removing something from {$ surgery-popup-step-SurgeryStepRemoveOrgan = {$user} is removing an organ from {$target}'s {$part}! surgery-popup-step-SurgeryStepInsertOrgan = {$user} is inserting an organ into {$target}'s {$part}! +surgery-popup-step-SurgeryStepOpenOrganSlot = {$user} is opening a cavity in {$target}'s {$part}! + surgery-popup-procedure-SurgeryRemoveBrain-step-SurgeryStepRemoveOrgan = {$user} is removing the brain from {$target}'s {$part}! surgery-popup-procedure-SurgeryRemoveHeart-step-SurgeryStepRemoveOrgan = {$user} is removing the heart from {$target}'s {$part}! surgery-popup-procedure-SurgeryRemoveLiver-step-SurgeryStepRemoveOrgan = {$user} is removing the liver from {$target}'s {$part}! diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index d72e9b7eb7..43dd19a24e 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -701,6 +701,8 @@ Plastic: 30 - type: StaticPrice price: 15 + - type: Tag # DeltaV - augment construction + tags: [ AugmentAPCBoard ] - type: entity id: PowerCageRechargerCircuitboard @@ -744,6 +746,8 @@ Plastic: 30 - type: StaticPrice price: 15 + - type: Tag # DeltaV - augment construction + tags: [ AugmentStationBoard ] - type: entity id: WeaponCapacitorRechargerCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 45359ec4eb..26b8ca83b8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -325,6 +325,8 @@ - MechParts - MechEquipment - Cybernetics # Shitmed change + - PowerAugments # DeltaV - augments + - ToolAugments # DeltaV - augments - type: EmagLatheRecipes # DeltaV emagStaticPacks: - RoboticsEmagStatic diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index b6f67ba7bf..9bacbd3c30 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -248,6 +248,7 @@ components: - BorgChassis - Silicon # EE IPCs + - AugmentStationRecharge # DeltaV augment power cells - type: Construction containers: - machine_parts @@ -291,6 +292,8 @@ whitelist: components: - BorgChassis + - Silicon # EE IPCs + - AugmentStationRecharge # DeltaV augment power cells - type: ContainerContainer containers: entity_storage: !type:Container diff --git a/Resources/Prototypes/_DV/Augments/arm.yml b/Resources/Prototypes/_DV/Augments/arm.yml new file mode 100644 index 0000000000..31dbe15bea --- /dev/null +++ b/Resources/Prototypes/_DV/Augments/arm.yml @@ -0,0 +1,241 @@ +- type: entity + parent: BaseAugment + id: AugmentBaseArm + name: base arm augment + abstract: true + components: + - type: Organ + slotId: armImplant + - type: AugmentArm + +- type: entity + parent: ActionOpenAugmentInterface + id: ActionOpenToolsPanel + name: Open tools panel + description: Access the tools implanted within you + components: + - type: InstantAction + icon: { sprite: Clothing/Belt/utility.rsi, state: icon } + +- type: entity + parent: AugmentBaseArm + id: AugmentBaseToolPanel + name: base tool panel augment + abstract: true + components: + - type: Sprite + sprite: _DV/Objects/Augments/arm.rsi + state: base + - type: Storage + maxItemSize: Normal + defaultStorageOrientation: Vertical + grid: + - 0,0,9,1 + - type: Item + size: Ginormous + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] + - type: AugmentToolPanel + - type: UserInterface + interfaces: + enum.StorageUiKey.Key: + type: StorageBoundUserInterface + enum.AugmentToolPanelUiKey.Key: + type: AugmentToolPanelMenuBoundUserInterface + interactionRange: 0 + - type: AugmentActivatableUI + key: enum.AugmentToolPanelUiKey.Key + openAction: ActionOpenToolsPanel + - type: AugmentAction + - type: Construction + graph: CreateToolsPanel + +- type: entity + parent: BaseElectronics + id: AugmentBaseElectronics + abstract: true + components: + - type: PhysicalComposition + materialComposition: + Glass: 100 + Steel: 100 + chemicalComposition: + Silicon: 20 + - type: Sprite + sprite: Objects/Misc/module.rsi + state: mainboard + +- type: entity + parent: AugmentBaseElectronics + id: AugmentUtilityPanelElectronics + name: utility tools panel electronics + description: An electronics board that programs a tool panel to hold a specific type of item. This one holds utility tools. + components: + - type: Item + storedRotation: 0 + - type: Tag + tags: [ AugmentToolBelt ] + +- type: entity + parent: AugmentBaseElectronics + id: AugmentBotanyPanelElectronics + name: botany tools panel electronics + description: An electronics board that programs a tool panel to hold a specific type of item. This one holds botanical tools. + components: + - type: Item + storedRotation: 0 + - type: Tag + tags: [ AugmentBotanyToolBelt ] + +- type: entity + parent: AugmentBaseElectronics + id: AugmentSurgeryPanelElectronics + name: surgery tools panel electronics + description: An electronics board that programs a tool panel to hold a specific type of item. This one holds surgical tools. + components: + - type: Item + storedRotation: 0 + - type: Tag + tags: [ AugmentSurgeryToolBelt ] + +- type: entity + parent: AugmentBaseElectronics + id: AugmentPaperworkPanelElectronics + name: paperwork tools panel electronics + description: An electronics board that programs a tool panel to hold a specific type of item. This one holds paperwork tools. + components: + - type: Item + storedRotation: 0 + - type: Tag + tags: [ AugmentPaperworkToolBelt ] + +- type: entity + parent: BaseItem + id: BaseIncompleteAugmentToolPanel + abstract: true + components: + - type: Sprite + sprite: _DV/Objects/Augments/arm.rsi + - type: Item + size: Ginormous + - type: Construction + graph: CreateToolsPanel + +- type: entity + parent: BaseIncompleteAugmentToolPanel + id: AugmentToolPanelCasing + name: tools panel augment casing + description: Can be implanted into a body to provide access to specific tools. This one is incomplete. + components: + - type: Sprite + state: base + - type: Construction + node: casing + - type: Tag + tags: [ AugmentToolPanelCasing ] + +- type: entity + parent: BaseIncompleteAugmentToolPanel + id: AugmentToolPanelCasingCables + name: tools panel augment casing with cables + description: Can be implanted into a body to provide access to specific tools. This one is incomplete. + components: + - type: Sprite + state: base_cables + - type: Construction + node: cables + +- type: entity + parent: AugmentBaseToolPanel + id: AugmentToolsPanel + name: tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold tools. + components: + - type: Sprite + state: engineering + - type: Storage + whitelist: + tags: + - Wirecutter + - Crowbar + - Screwdriver + - Wrench + - GeigerCounter + - Powerdrill + - JawsOfLife + - HolofanProjector + - Multitool + - AppraisalTool + components: + - StationMap + - SprayPainter + - NetworkConfigurator + - RCD + - RCDAmmo + - Welder + - PowerCell + - Geiger + - TrayScanner + - GasAnalyzer + - type: Construction + node: "utility tools panel" + +- type: entity + parent: AugmentBaseToolPanel + id: AugmentBotanyPanel + name: botanical tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold botanical tools. + components: + - type: Sprite + state: botany + - type: Storage + whitelist: + tags: + - PlantSampleTaker + - BotanyShovel + - BotanyHoe + - BotanyHatchet + - Dropper + components: + - HandLabeler + - type: Construction + node: "botany tools panel" + +- type: entity + parent: AugmentBaseToolPanel + id: AugmentPaperworkPanel + name: paperwork tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold paperwork tools. + components: + - type: Sprite + state: paperwork + - type: Storage + whitelist: + tags: + - Folder + - HandLabeler + components: + - Stamp + - TapeRecorder + - type: Construction + node: "paperwork tools panel" + +- type: entity + parent: AugmentBaseToolPanel + id: AugmentSurgicalPanel + name: surgical tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold surgical tools. + components: + - type: Sprite + state: surgical + - type: Storage + whitelist: + requireAll: true + tags: + - SurgeryTool + components: + - SurgeryTool + - type: Construction + node: "surgery tools panel" diff --git a/Resources/Prototypes/_DV/Augments/base.yml b/Resources/Prototypes/_DV/Augments/base.yml new file mode 100644 index 0000000000..019ce8272b --- /dev/null +++ b/Resources/Prototypes/_DV/Augments/base.yml @@ -0,0 +1,6 @@ +- type: entity + parent: BaseItem + id: BaseAugment + abstract: true + components: + - type: Augment diff --git a/Resources/Prototypes/_DV/Augments/power.yml b/Resources/Prototypes/_DV/Augments/power.yml new file mode 100644 index 0000000000..411a04bc95 --- /dev/null +++ b/Resources/Prototypes/_DV/Augments/power.yml @@ -0,0 +1,137 @@ +- type: entity + id: ActionOpenAugmentInterface + abstract: true + # name: Open augment UI + # description: This is a developer placeholder and should not be seen + components: + - type: InstantAction + icon: { sprite: Clothing/Mask/gas.rsi, state: icon } + iconOn: Interface/Default/blocked.png + event: !type:AugmentUIOpenEvent + +- type: entity + parent: BaseItem + id: AugmentPowerCellSlotCasing + name: augment power cell slot casing + description: Can be implanted into a body to provide power to other implants. This one is incomplete. + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_cell + - type: Construction + graph: CreatePowerCellAugment + node: casing + defaultTarget: augment + - type: Tag + tags: [ AugmentCellCasing ] + +- type: entity + parent: BaseItem + id: AugmentPowerCellSlotCasingCables + name: augment power cell slot casing with cables + description: Can be implanted into a body to provide power to other implants. This one is incomplete. + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_cell_cables + - type: Construction + graph: CreatePowerCellAugment + node: cables + +- type: entity + parent: BaseAugment + id: AugmentPowerCellSlot + name: augment power cell slot + description: Can be implanted into a body to provide power to other implants. + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: cell + - type: Organ + slotId: powerCell + onAdd: + - type: HasAugmentPowerCellSlot + - type: AugmentPowerCellSlot + - type: Construction + graph: CreatePowerCellAugment + node: augment + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot { } + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + +- type: entity + parent: BaseAugment + id: AugmentBaseCharger + name: base charger augment + abstract: true + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: cell + - type: Organ + slotId: charger + - type: AugmentCharger + +- type: entity + parent: BaseItem + id: AugmentRechargerCasing + name: augment recharger casing + description: Can be implanted into a body to recharge an internal power cell. This one is incomplete. + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_charger + - type: Construction + graph: CreatePowerCellChargerAugment + node: casing + - type: Tag + tags: [ AugmentChargerCasing ] + +- type: entity + parent: BaseItem + id: AugmentRechargerCasingCables + name: augment recharger casing with cables + description: Can be implanted into a body to recharge an internal power cell. This one is incomplete. + components: + - type: Sprite + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_charger_cables + - type: Construction + graph: CreatePowerCellChargerAugment + node: cables + +- type: entity + parent: AugmentBaseCharger + id: AugmentRechargerAPC + name: augment apc recharger + description: Allows the implantee to recharge their power cell via APCs. + components: + - type: Sprite + state: apc + - type: Organ + onAdd: + - type: BatteryDrinker + - type: Construction + graph: CreatePowerCellChargerAugment + node: apc + +- type: entity + parent: AugmentBaseCharger + id: AugmentRechargerStation + name: augment station recharger + description: Allows the implantee to recharge their power cell via cyborg recharging stations. + components: + - type: Sprite + state: station + - type: Organ + onAdd: + - type: AugmentStationRecharge + - type: Construction + graph: CreatePowerCellChargerAugment + node: station diff --git a/Resources/Prototypes/_DV/Entities/Surgery/surgeries.yml b/Resources/Prototypes/_DV/Entities/Surgery/surgeries.yml new file mode 100644 index 0000000000..ed27995327 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Surgery/surgeries.yml @@ -0,0 +1,179 @@ +- type: entity + parent: SurgeryBase + id: SurgeryInsertPowerCellSlot + name: Insert Power Cell Slot + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepInsertAugmentPowerCellSlot + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganCondition + organ: + - type: AugmentPowerCellSlot + inverse: true + reattaching: true + - type: SurgeryOrganSlotCondition + organSlot: powerCell + +- type: entity + parent: SurgeryBase + id: SurgeryOpenPowerCellSlot + name: Open Cavity For Power Cell Slot + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepOpenOrganSlot + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganSlotCondition + organSlot: powerCell + inverse: true + - type: SurgeryBodyCondition + accepted: [ IPC ] + inverse: true + +- type: entity + parent: SurgeryBase + id: SurgeryRemovePowerCellSlot + name: Remove Power Cell Slot + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepClampInternalBleeders + - SurgeryStepRemoveOrgan + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganCondition + organ: + - type: AugmentPowerCellSlot + +- type: entity + parent: SurgeryBase + id: SurgeryInsertPowerCellCharger + name: Insert Internal Power Cell Charger + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepInsertAugmentPowerCellCharger + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganCondition + organ: + - type: AugmentCharger + inverse: true + reattaching: true + - type: SurgeryOrganSlotCondition + organSlot: charger + +- type: entity + parent: SurgeryBase + id: SurgeryOpenPowerCellCharger + name: Open Cavity For Power Cell Charger + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepOpenOrganSlot + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganSlotCondition + organSlot: charger + inverse: true + - type: SurgeryBodyCondition + accepted: [ IPC ] + inverse: true + +- type: entity + parent: SurgeryBase + id: SurgeryRemovePowerCellCharger + name: Remove Internal Power Cell Charger + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenRibcage + steps: + - SurgeryStepSawBones + - SurgeryStepClampInternalBleeders + - SurgeryStepRemoveOrgan + - type: SurgeryPartCondition + part: Torso + - type: SurgeryOrganCondition + organ: + - type: AugmentCharger + +- type: entity + parent: SurgeryBase + id: SurgeryOpenArmAugment + name: Open Cavity For Arm Augments + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenIncision + steps: + - SurgeryStepSawBones + - SurgeryStepOpenOrganSlot + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Arm + - type: SurgeryOrganSlotCondition + organSlot: armImplant + inverse: true + +- type: entity + parent: SurgeryBase + id: SurgeryInsertArmAugment + name: Insert Arm Augment + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenIncision + steps: + - SurgeryStepSawBones + - SurgeryStepInsertAugmentArm + - SurgeryStepSealOrganWound + - type: SurgeryPartCondition + part: Arm + - type: SurgeryOrganCondition + organ: + - type: AugmentArm + inverse: true + reattaching: true + - type: SurgeryOrganSlotCondition + organSlot: armImplant + +- type: entity + parent: SurgeryBase + id: SurgeryRemoveArmAugment + name: Remove Arm Augment + categories: [ HideSpawnMenu ] + components: + - type: Surgery + requirement: SurgeryOpenIncision + steps: + - SurgeryStepSawBones + - SurgeryStepClampInternalBleeders + - SurgeryStepRemoveOrgan + - type: SurgeryPartCondition + part: Arm + - type: SurgeryOrganCondition + organ: + - type: AugmentArm diff --git a/Resources/Prototypes/_DV/Entities/Surgery/surgery_steps.yml b/Resources/Prototypes/_DV/Entities/Surgery/surgery_steps.yml new file mode 100644 index 0000000000..a0f5504e32 --- /dev/null +++ b/Resources/Prototypes/_DV/Entities/Surgery/surgery_steps.yml @@ -0,0 +1,17 @@ +- type: entity + parent: SurgeryStepInsertOrgan + id: SurgeryStepInsertAugmentPowerCellSlot + name: Add power cell slot + categories: [ HideSpawnMenu ] + +- type: entity + parent: SurgeryStepInsertOrgan + id: SurgeryStepInsertAugmentPowerCellCharger + name: Add power cell charger + categories: [ HideSpawnMenu ] + +- type: entity + parent: SurgeryStepInsertOrgan + id: SurgeryStepInsertAugmentArm + name: Add arm augment + categories: [ HideSpawnMenu ] diff --git a/Resources/Prototypes/_DV/Recipes/Construction/Graphs/augments.yml b/Resources/Prototypes/_DV/Recipes/Construction/Graphs/augments.yml new file mode 100644 index 0000000000..e93563d641 --- /dev/null +++ b/Resources/Prototypes/_DV/Recipes/Construction/Graphs/augments.yml @@ -0,0 +1,131 @@ +- type: constructionGraph + id: CreatePowerCellAugment + start: start + graph: + - node: start + edges: + - to: casing + steps: + - tag: AugmentCellCasing + name: casing + icon: + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_cell + - node: casing + entity: AugmentPowerCellSlotCasing + edges: + - to: cables + steps: + - material: Cable + amount: 1 + - node: cables + entity: AugmentPowerCellSlotCasingCables + edges: + - to: augment + steps: + - material: Plastic + amount: 1 + - node: augment + entity: AugmentPowerCellSlot + +- type: constructionGraph + id: CreatePowerCellChargerAugment + start: start + graph: + - node: start + edges: + - to: casing + steps: + - tag: AugmentChargerCasing + name: casing + icon: + sprite: _DV/Objects/Augments/power.rsi + state: incomplete_charger + - node: casing + entity: AugmentRechargerCasing + edges: + - to: cables + steps: + - material: Cable + amount: 1 + - node: cables + entity: AugmentRechargerCasingCables + edges: + - to: apc + steps: + - tag: AugmentAPCBoard + name: "cell recharger machine board" + icon: + sprite: Objects/Misc/module.rsi + state: charger_APC + - to: station + steps: + - tag: AugmentStationBoard + name: "cyborg recharging station machine board" + icon: + sprite: Objects/Misc/module.rsi + state: charger_APC + - node: apc + entity: AugmentRechargerAPC + - node: station + entity: AugmentRechargerStation + +- type: constructionGraph + id: CreateToolsPanel + start: start + graph: + - node: start + edges: + - to: casing + steps: + - tag: AugmentToolPanelCasing + name: casing + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: base + - node: casing + entity: AugmentToolPanelCasing + edges: + - to: cables + steps: + - material: Cable + amount: 1 + - node: cables + entity: AugmentToolPanelCasingCables + edges: + - to: "botany tools panel" + steps: + - tag: AugmentBotanyToolBelt + name: botany tools panel electronics + icon: + sprite: Objects/Misc/module.rsi + state: mainboard + - to: "paperwork tools panel" + steps: + - tag: AugmentPaperworkToolBelt + name: paperwork tools panel electronics + icon: + sprite: Objects/Misc/module.rsi + state: mainboard + - to: "utility tools panel" + steps: + - tag: AugmentToolBelt + name: utility tools panel electronics + icon: + sprite: Objects/Misc/module.rsi + state: mainboard + - to: "surgery tools panel" + steps: + - tag: AugmentSurgeryToolBelt + name: surgery tools panel electronics + icon: + sprite: Objects/Misc/module.rsi + state: mainboard + - node: "botany tools panel" + entity: AugmentBotanyPanel + - node: "paperwork tools panel" + entity: AugmentPaperworkPanel + - node: "surgery tools panel" + entity: AugmentSurgicalPanel + - node: "utility tools panel" + entity: AugmentToolsPanel diff --git a/Resources/Prototypes/_DV/Recipes/Construction/augments.yml b/Resources/Prototypes/_DV/Recipes/Construction/augments.yml new file mode 100644 index 0000000000..76afbb8d82 --- /dev/null +++ b/Resources/Prototypes/_DV/Recipes/Construction/augments.yml @@ -0,0 +1,90 @@ +- type: construction + name: augment power cell slot + description: Can be implanted into a body to provide power to other implants. + id: AugmentPowerCellSlot + graph: CreatePowerCellAugment + startNode: start + targetNode: augment + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/power.rsi + state: cell + +- type: construction + name: augment apc recharger + description: Allows the implantee to recharge their power cell via APCs. + id: AugmentRechargerAPC + graph: CreatePowerCellChargerAugment + startNode: start + targetNode: apc + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/power.rsi + state: apc + +- type: construction + name: augment station recharger + description: Allows the implantee to recharge their power cell via cyborg recharging stations. + id: AugmentRechargerStation + graph: CreatePowerCellChargerAugment + startNode: start + targetNode: station + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/power.rsi + state: station + +- type: construction + name: tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold tools. + id: AugmentToolsPanel + graph: CreateToolsPanel + startNode: start + targetNode: "utility tools panel" + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: engineering + +- type: construction + name: botanical tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold botanical tools. + id: AugmentBotanyPanel + graph: CreateToolsPanel + startNode: start + targetNode: "botany tools panel" + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: botany + +- type: construction + name: paperwork tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold paperwork tools. + id: AugmentPaperworkPanel + graph: CreateToolsPanel + startNode: start + targetNode: "paperwork tools panel" + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: paperwork + +- type: construction + name: surgical tools panel augment + description: A panel that can be augmented into a patient's arm to provide them access to its contents. This one can hold surgical tools. + id: AugmentSurgicalPanel + graph: CreateToolsPanel + startNode: start + targetNode: "surgery tools panel" + category: construction-category-utilities + canBuildInImpassable: false + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: surgical diff --git a/Resources/Prototypes/_DV/Recipes/Lathes/Packs/robotics.yml b/Resources/Prototypes/_DV/Recipes/Lathes/Packs/robotics.yml index 7f74ea9424..72b8986ebd 100644 --- a/Resources/Prototypes/_DV/Recipes/Lathes/Packs/robotics.yml +++ b/Resources/Prototypes/_DV/Recipes/Lathes/Packs/robotics.yml @@ -38,4 +38,19 @@ recipes: - BorgModuleSecurityChase - BorgModuleSecurityEscalate - - BorgModuleSecurityBastion \ No newline at end of file + - BorgModuleSecurityBastion + +- type: latheRecipePack + id: PowerAugments + recipes: + - AugmentPowerCellSlotCasing + - AugmentRechargerCasing + +- type: latheRecipePack + id: ToolAugments + recipes: + - AugmentToolPanelCasing + - AugmentUtilityPanelElectronics + - AugmentBotanyPanelElectronics + - AugmentSurgeryPanelElectronics + - AugmentPaperworkPanelElectronics diff --git a/Resources/Prototypes/_DV/Recipes/Lathes/robotics.yml b/Resources/Prototypes/_DV/Recipes/Lathes/robotics.yml index a85e741d17..5372d3fd6e 100644 --- a/Resources/Prototypes/_DV/Recipes/Lathes/robotics.yml +++ b/Resources/Prototypes/_DV/Recipes/Lathes/robotics.yml @@ -169,3 +169,38 @@ parent: IdChipSyndie id: IdChipRoboNeuroticist result: IdChipRoboNeuroticist + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentPowerCellSlotCasing + result: AugmentPowerCellSlotCasing + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentRechargerCasing + result: AugmentRechargerCasing + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentToolPanelCasing + result: AugmentToolPanelCasing + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentUtilityPanelElectronics + result: AugmentUtilityPanelElectronics + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentBotanyPanelElectronics + result: AugmentBotanyPanelElectronics + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentSurgeryPanelElectronics + result: AugmentSurgeryPanelElectronics + +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: AugmentPaperworkPanelElectronics + result: AugmentPaperworkPanelElectronics diff --git a/Resources/Prototypes/_DV/Research/civilianservices.yml b/Resources/Prototypes/_DV/Research/civilianservices.yml index 73be7fb5a9..d982aecc44 100644 --- a/Resources/Prototypes/_DV/Research/civilianservices.yml +++ b/Resources/Prototypes/_DV/Research/civilianservices.yml @@ -10,3 +10,34 @@ recipeUnlocks: - LauncherSyringe - MiniSyringe + +- type: technology + id: BasicAugmentation + name: research-technology-basic-augmentation + icon: + sprite: _DV/Objects/Augments/power.rsi + state: cell + discipline: CivilianServices + tier: 2 + cost: 5000 + recipeUnlocks: + - AugmentPowerCellSlotCasing + - AugmentRechargerCasing + +- type: technology + id: ImplantedTools + name: research-technology-implanted-tools + icon: + sprite: _DV/Objects/Augments/arm.rsi + state: base + discipline: CivilianServices + tier: 2 + cost: 10000 + technologyPrerequisites: [ BasicAugmentation ] + recipeUnlocks: + - AugmentToolPanelCasing + - AugmentUtilityPanelElectronics + - AugmentBotanyPanelElectronics + - AugmentSurgeryPanelElectronics + - AugmentPaperworkPanelElectronics + diff --git a/Resources/Prototypes/_DV/tags.yml b/Resources/Prototypes/_DV/tags.yml index 5a51ca0819..7da6e7d46a 100644 --- a/Resources/Prototypes/_DV/tags.yml +++ b/Resources/Prototypes/_DV/tags.yml @@ -1,5 +1,32 @@ ## This is for Nyano and Delta V tags +- type: Tag + id: AugmentAPCBoard + +- type: Tag + id: AugmentBotanyToolBelt + +- type: Tag + id: AugmentCellCasing + +- type: Tag + id: AugmentChargerCasing + +- type: Tag + id: AugmentPaperworkToolBelt + +- type: Tag + id: AugmentStationBoard + +- type: Tag + id: AugmentSurgeryToolBelt + +- type: Tag + id: AugmentToolBelt + +- type: Tag + id: AugmentToolPanelCasing + - type: Tag id: Bayonet #Craftable Musket diff --git a/Resources/Prototypes/_Shitmed/Entities/Surgery/surgery_steps.yml b/Resources/Prototypes/_Shitmed/Entities/Surgery/surgery_steps.yml index 6358efab1a..9814a0ecf1 100644 --- a/Resources/Prototypes/_Shitmed/Entities/Surgery/surgery_steps.yml +++ b/Resources/Prototypes/_Shitmed/Entities/Surgery/surgery_steps.yml @@ -519,6 +519,30 @@ toolDirtiness: 7.5 gloveDirtiness: 7.5 +- type: entity + parent: SurgeryStepBase + id: SurgeryStepOpenOrganSlot + name: Carve out a cavity + categories: [ HideSpawnMenu ] + components: + - type: SurgeryStep + tool: + - type: Scalpel + duration: 6 + - type: Sprite + sprite: _Shitmed/Objects/Specific/Medical/Surgery/manipulation.rsi + state: insertion + - type: SurgeryAddOrganSlotStep + - type: SurgeryStepEmoteEffect + - type: SurgeryDamageChangeEffect # DeltaV + sleepModifier: 0.5 + damage: + types: + Blunt: 5 + - type: SurgeryStepDirtiness # DeltaV - surgery cross contamination + toolDirtiness: 7.5 + gloveDirtiness: 7.5 + - type: entity parent: SurgeryStepInsertOrgan id: SurgeryStepInsertLungs diff --git a/Resources/Textures/_DV/Objects/Augments/arm.rsi/base.png b/Resources/Textures/_DV/Objects/Augments/arm.rsi/base.png new file mode 100644 index 0000000000000000000000000000000000000000..ee221aa200de96326685a25ebf02958b1f39b117 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|TmyVUT!FN) zrQ<@c6H73bdP!c`t_lMCr$0D?JEyz>MPm0nq1oKxVTO= zIo-dtCGF|yoFZ4P9W4gp%3L)-gTzaM{DK+&V+9+!i|+%K^mw{BhFJ98z39l-V!*+A zVN$%)M$egn@9V=7)3o1AeOs?85>=f#F?{CYa=n(Gga8{3|3%i*u#9X zmhY9}!wbLnOf2{_aq{<%&IgS=rm;tS+qlJ%XXn1%-6AbF`ZtS}$xVBw*)rqjvem^u z%{o@g=^ePE{ZQOp^N-5huH2RdHFN6&kMpnL{?g67bpzkx(?EAIc)I$ztaD0e0sv)Q BjobhL literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/arm.rsi/base_cables.png b/Resources/Textures/_DV/Objects/Augments/arm.rsi/base_cables.png new file mode 100644 index 0000000000000000000000000000000000000000..fbda9c7f1184a21c360500700250a7b19c3259ed GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|TmyVUT!FN) zrQ<@c6H73bdP!c`t_lMCr$0D?JEyz>MPm0nq1oKxVTO= zIo-dtCGF|yoFZ4P9W4gp%3L)-gTzaM{DK+&V+9+!i|+%K9P@N>46*3FJMo}UvjUF` zCnFQrlF-}#|6gG%TsGJ6Ml}E3?lW(c)5Mei1u5*>pu3=0?$Cwh62VUVWlxr8&PsMV zp(R*WKabTw%dw$DLAW91RwchvLGIxhN6eqvFrC=mv+wS8MwK-^F13oHD{3Cw9k{Wk zrJ*XmMdHsvmd?QGrP(dd-nTr>O?{bpVe8h$8B1SwKRsyZKwnhNw0gQu&X J%Q~loCIFM?r-uLl literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/arm.rsi/botany.png b/Resources/Textures/_DV/Objects/Augments/arm.rsi/botany.png new file mode 100644 index 0000000000000000000000000000000000000000..b45feed798c9e623d04b00fc91ae489256f321fd GIT binary patch literal 808 zcmV+@1K0eCP)Px%;z>k7R9J=WmQP4jQ5431&$OT!GxXhIl41%npJR!PGh!u9^vA$e(4tMa5u!~l zN`x?4L>bg7LTVF;D_d1qppnrlXi?)}Su+y|6_Lu!7zy(>{<|%vd5qaO^Rz!ie()Ce zzRUT(ckVgod$5XC{O?d!8lbAuCDYfh-+r_dGk>|ndWBz}%KLz-3OqI202u!~1t5KM zf?JV5PC}NI0lmU6kHv@B(VYNbv@f}@g}rQY7BlkZ9oOf#;t%Ut<6F)^iahUVf~F=1 z0An75;h;f;0EE2&w269jkl94!Ss`!Hye4_;jql_W1_0F_+k&$%pI%bhL_K6I!?0XbvIA}212kJ8y(dZ--v4jH2jP*z(V@>3o0jID_w_5|i zQ?t!{cI_TNI72D!~-;r|-I2JIwz; zo(nA1fZMGx`1m=hDwxS%Ls6+fRRx2OpD+6I6t>?v^XmkpF#h!ms-u{$)mH&s*K*wI*Llgg0bvBtIG>_&u1M*mI|gt^U7P1fZ`N(d0VaF+-8H`&N{jWrs>y% z6ig@Ea$U)Bs-goqjbqEBI5k*$q``y92xZmD)-0ID9K(>iDXqv2eGMJ*Q}`Ngw?;f3 z17PEok3iBN#%^YhZ`lic4IOg*-bQo11qg+bB4*nI=18s`Y~o?%3z;nwmIS1#TEFa9 zS~Rb0R&4Z0gO{;{vZFm9t35W>UTq>c^qx)5DH;#g0xT&a=PU3vbjVaYrO4AOy!0ee zedaR%4}wGQiN|9Z2b3k8KIC5DXqg<&DeSVU(k1u%z0xV{(kbjqI^nXhl*Rs5;#@`i mF|=r2*?+P6?+aPQKaFqj)+X>`Yokm60000A_;KR!T5ZFPK9SYKl(G!_;Y#)1HXK>+XMN9MQ^H9mVkdBG_!B0WVk(z8LMekEgP zPlbeL<;!exMJl+2FtB>QkN^Mx0d!JMQvg8b*k%9#0Le*2K~y-6-I7ZV!ypVqF$N6b z*CuK2f7F@~sg*G4u8YowNb_RsF-rZVfOTPOKw~VpsZZXAfEM)356cpLKu99t4nIZ) zlt>UDB5(yDt~T~T2&Q%D1N$nEC4g+3(YF6(00~P)qTY}QlzOYZfYM1A0?K`5Vse9W zJVsf!y%Cas5W4PL<(wv2Ywf63PWob9iPHdH$i&S#GvQ-2VvU@6dZ&CeXeA<@=>&cg yc&72GN9*$V;-%5(_c8i0v){yp-195)d%Xaw=mlF51(q=Y0000Px%*-1n}R9J=Wm0w6xaU8`zi&mG!gf^!#*LpD6ro(?*E&MYI(h47hq=z0xFsL`J z6hamTl1jaV4?;Z%K2}mOwGj_0Q&m<0DS)zz?7!t?P!o29L7B^$DNY5%T~AO5c6y9glY%OI)vS31fa0M zq+I#g>GCnnX{@0cfBlN@sHTF09dqmCKMrM;SBJ%X(=zu1BT*?Pz7hHPuXy<#UWOfOy$WU;j&7iqQoe! z)wo1OiBY($k}&I7w~SQb@^Ra;A!{|9S%)IRtYd4)SHpT0`&)_CiuhyjS{&lp^}N3? dWE=l9egbr*B63@tQb7O!002ovPDHLkV1mh_Z`c3; literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/arm.rsi/surgical.png b/Resources/Textures/_DV/Objects/Augments/arm.rsi/surgical.png new file mode 100644 index 0000000000000000000000000000000000000000..c66e9e1019a3d8587c8324c447912b91896ba950 GIT binary patch literal 352 zcmV-m0iXVfP)+9>n!O3GNG%YJORED}XQ+%G<^mDcAH9mVkdBG_!B0WVk(z8LMekEgP zPlbeL<;!exMJl+2FsM=hCIA2c0d!JMQvg8b*k%9#0Le*2K~y-6-I7ZV!ypVqF$N6b z*CuK2f7F@~sg*G4u8YowNb_RsF-rZVfOTPOKw~VpsZZXAfEM)356cpLKu99t4nIZ) zlt>UDB5(yDt~T~T2&Q%D1N$nEC4g+3(YF6(00~P)qTY}QlzOYZfYM1A0?K`5Vse9W zJVsf!y%Cas5W4PL<(wv2Ywf63PWob9iPHdH$i&S#GvQ-2VvU@6dZ&CeXeA<@=>&cg yc&72GN9*$V;-%5(_c8i0v){yp-195)d%Xaw=mlF51(q=Y0000BOM zWbkzLb6Mw<&;$S%RYJ@F literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/power.rsi/cell.png b/Resources/Textures/_DV/Objects/Augments/power.rsi/cell.png new file mode 100644 index 0000000000000000000000000000000000000000..9be6d7980c814abd2c2d82ae4b590a0e48631265 GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}XFXjULn2z= zPO%nhG7xd)@9Qz@qLn2z= zPO;`|HV|+z7gAMNuw}>Td3Vb@HF%TmI*YO=d0Z1badyuoxypI=MuH3s4QFhE4xQPP zvH4om)mvGNX>nD_E7q)Bc2H%Bt zx+X+dnboasnEiA^iS<0EO%6MrFYEORF8epVL7bESP4rChznLlj*@2E~5Z(9K^u^@U RHV1(m22WQ%mvv4FO#mu$R7wB< literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_cell_cables.png b/Resources/Textures/_DV/Objects/Augments/power.rsi/incomplete_cell_cables.png new file mode 100644 index 0000000000000000000000000000000000000000..01f1e9ffab975239bb71514593e97541053f394b GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}XFXjULn2z= zPT4DX$bhGH{(B8!y@h8sy0Trcn0JzUgFD*^u^6uh1y#Wb+`^xeohQ1*zqEO2dvYH` zlLE(~Q!9iF1$V~0HQRF<8vik61sAp+O?~Yt1r-RZ(WK?FyeHPisE3;JK=pHjRNn zz(wF0_mbP0l+XkKt@LG? literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Objects/Augments/power.rsi/meta.json b/Resources/Textures/_DV/Objects/Augments/power.rsi/meta.json new file mode 100644 index 0000000000..ae48e82710 --- /dev/null +++ b/Resources/Textures/_DV/Objects/Augments/power.rsi/meta.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "taken from /tg/ station at commit https://github.com/tgstation/tgstation/commit/02756c2bc2cf3000080d030955e994242bab39b5", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "apc" + }, + { + "name": "cell" + }, + { + "name": "station" + }, + { + "name": "incomplete_charger" + }, + { + "name": "incomplete_charger_cables" + }, + { + "name": "incomplete_cell" + }, + { + "name": "incomplete_cell_cables" + } + ] +} diff --git a/Resources/Textures/_DV/Objects/Augments/power.rsi/station.png b/Resources/Textures/_DV/Objects/Augments/power.rsi/station.png new file mode 100644 index 0000000000000000000000000000000000000000..0e6986e7919138fe0624b2942fe36c306d9b2eba GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|Bm#UwT!D0d zLw0hojjImVwF3+HE@@&go;j0&;f=pqBv6i{B*-tA;XediJr!aE6m#%&aSXBOecQj0 zmqCH&@Fa(a|N9%+gE-lyRjo}mb@<5H6&Em>|4ozk2KkpEN}$Z?=D5Kt=!n literal 0 HcmV?d00001