Skip to content

Commit

Permalink
implants
Browse files Browse the repository at this point in the history
  • Loading branch information
Fragoler committed Sep 23, 2024
1 parent 9571b3c commit 8c92a22
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 0 deletions.
108 changes: 108 additions & 0 deletions Content.Server/_Exodus/Implants/InjectImplantSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Content.Server.Administration.Logs;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Database;
using Content.Shared.Implants.Components;
using Content.Shared.FixedPoint;
using Robust.Shared.Audio.Systems;
using Content.Shared.Chemistry;
using Content.Shared.IdentityManagement;
using Content.Server.Explosion.EntitySystems;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Popups;


namespace Content.Server.Exodus.Implants
{

public sealed partial class InjectImplantSystem : EntitySystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly ReactiveSystem _reactiveSystem = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<InjectOnTriggerComponent, TriggerEvent>(OnInjectOnTrigger);
}

public bool InjectSolution(EntityUid user, Entity<InjectOnTriggerComponent> implantEnt, string solutionName, float transferAmount)
{
var (implant, injectComp) = implantEnt;

// Try get initial solution
if (!_solutionContainer.TryGetSolution(implant, solutionName, out var initialSoln, out var initialSolution))
{
Log.Error($"Couldnt find solution named {solutionName} in entity {user}");
return false;
}

// Try get insert solution
if (!_solutionContainer.TryGetInjectableSolution(user, out var targetSoln, out var targetSolution))
{
_popup.PopupEntity(Loc.GetString("inject-trigger-cant-inject-message", ("target", Identity.Entity(user, _entMan))), user, user);
return false;
}

var realtransferAmount = FixedPoint2.Min(initialSolution.Volume, targetSolution.AvailableVolume, transferAmount);
if (realtransferAmount <= 0)
{
_popup.PopupEntity(Loc.GetString("inject-trigger-empty-capsule-message"), user, user);
return false;
}

// Move units from init solution to target solution
var removedSolution = _solutionContainer.SplitSolution(initialSoln.Value, realtransferAmount);
if (!targetSolution.CanAddSolution(removedSolution))
{
_popup.PopupEntity(Loc.GetString("inject-trigger-cant-inject-message", ("target", Identity.Entity(user, _entMan))), user, user);
return false;
}

_audio.PlayPvs(injectComp.InjectSound, user);

_reactiveSystem.DoEntityReaction(user, removedSolution, ReactionMethod.Injection);
_solutionContainer.TryAddSolution(targetSoln.Value, removedSolution);

_popup.PopupEntity(Loc.GetString("inject-trigger-feel-prick-message"), user, user);
_adminLogger.Add(LogType.ForceFeed, $"{_entMan.ToPrettyString(user):user} used inject implant with a solution {SolutionContainerSystem.ToPrettyString(removedSolution):removedSolution}");

return true;
}

private void OnInjectOnTrigger(EntityUid uid, InjectOnTriggerComponent component, TriggerEvent args)
{
// Get user uid
if (!TryComp<SubdermalImplantComponent>(uid, out var implantComp) ||
implantComp.ImplantedEntity == null)
return;
var user = implantComp.ImplantedEntity.Value;


// Geting inject solutions form many avaible solutions
if (component.InjectSolutions.Count == 0)
{
_popup.PopupEntity(Loc.GetString("inject-trigger-empty-message"), user, user);
return;
}

foreach (var solData in component.InjectSolutions)
{
if (solData.UsedCount >= solData.Charges)
continue;

InjectSolution(user, (uid, component), solData.Name, solData.TransferAmount);
solData.UsedCount += 1;
break;
}

args.Handled = true;
}

}
}
24 changes: 24 additions & 0 deletions Content.Server/_Exodus/Implants/InjectOnTriggerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Robust.Shared.Audio;

namespace Content.Server.Exodus.Implants;

[RegisterComponent]
public sealed partial class InjectOnTriggerComponent : Component
{
[DataField("solutions")]
public List<InjectSolutionData> InjectSolutions = [];

[DataField]
public SoundSpecifier InjectSound = new SoundPathSpecifier("/Audio/Items/hypospray.ogg");
}

[Serializable]
[DataRecord]
public sealed partial class InjectSolutionData()
{
public string Name = "";
public int Charges = 1;
public float TransferAmount = 10.0f;
public int UsedCount = 0;

}
12 changes: 12 additions & 0 deletions Resources/Locale/ru-RU/exodus/inject-implants/implants.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ent-ChemicalsImplanter = { ent-BaseImplantOnlyImplanter }
.desc = { ent-BaseImplantOnlyImplanter.desc }
.suffix = Химический
ent-StimulantsImplanter = { ent-BaseImplantOnlyImplanterSyndi }
.desc = { ent-BaseImplantOnlyImplanterSyndi.desc }
.suffix = Химический
ent-ChemicalImplant = Химический имплант
.desc = Вводит в кровь вещества из заранее установленных в имплант капсул
ent-StimulantsImplant = Имплант стимулятора
.desc = Вводит в кровь стимулятор из заранее установленных в имплант капсул
ent-ActionChemicalCapsule = Ввести реактивы в кровь
.desc = Вводит в кровь вещества из заранее установленных в имплант капсул
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
inject-trigger-empty-message = В импланте нет полных капсул!
inject-trigger-cant-inject-message = Нельзя сделать инъекцию в { $target }!
inject-trigger-empty-capsule-message = Капсула в импланте пустая!
inject-trigger-feel-prick-message = Вы чувствуете как жидкость растекается в вашей крови!
3 changes: 3 additions & 0 deletions Resources/Locale/ru-RU/exodus/store/uplink-catalog.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
uplink-stimulants-implant-name = { ent-StimulantsImplant }
uplink-stimulants-implant-desc = Продвинутый имплант Cybersun, содержащий три капсулы первокласного стимулирующего вещества, моментально вводимые в кровь по желанию носителя.
15 changes: 15 additions & 0 deletions Resources/Prototypes/_Exodus/Actions/implants.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- type: entity
id: ActionChemicalCapsule
name: Inject chemicats into bloodstream
description: Bring chemicats from small capsules in implant and injure it to bloodstream
noSpawn: true
components:
- type: InstantAction
checkCanInteract: false
itemIconStyle: BigAction
priority: -20
useDelay: 5
icon:
sprite: Objects/Specific/Chemistry/syringe.rsi
state: syringe_base0
event: !type:ActivateImplantEvent
19 changes: 19 additions & 0 deletions Resources/Prototypes/_Exodus/Catalog/uplink_catalog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- type: listing
id: UplinkChemicalImplant
name: uplink-stimulants-implant-name
description: uplink-stimulants-implant-desc
productEntity: StimulantsImplanter
icon: { sprite: /Textures/Objects/Specific/Chemistry/syringe.rsi, state: syringe_base0 }
cost:
Telecrystal: 8
categories:
- UplinkImplants
conditions:
- !type:StoreWhitelistCondition
whitelist:
tags:
- NukeOpsUplink
- !type:BuyerWhitelistCondition
blacklist:
components:
- SurplusBundle
15 changes: 15 additions & 0 deletions Resources/Prototypes/_Exodus/Entities/Objects/Misc/implants.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- type: entity
id: ChemicalsImplanter
parent: BaseImplantOnlyImplanter
suffix: Chemical
components:
- type: Implanter
implant: ChemicalImplant

- type: entity
id: StimulantsImplanter
parent: BaseImplantOnlyImplanterSyndi
suffix: Stimulants
components:
- type: Implanter
implant: StimulantsImplant
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
- type: entity
parent: BaseSubdermalImplant
id: ChemicalImplant
name: Chemical implant
description: Inject chemicats to blood stream from small capsules in itself
noSpawn: true
components:
- type: SubdermalImplant
implantAction: ActionChemicalCapsule
- type: SolutionContainerManager
- type: TriggerImplantAction
- type: InjectOnTrigger
- type: Tag
tags:
- SubdermalImplant
- HideContextMenu

- type: entity
parent: ChemicalImplant
id: StimulantsImplant
name: Stimulants implant
description: Inject stimulants to blood stream from small capsules in itself
noSpawn: true
components:
- type: SolutionContainerManager
solutions:
container1:
reagents:
- ReagentId: Stimulants
Quantity: 16
maxVol: 16
canMix: True
container2:
reagents:
- ReagentId: Stimulants
Quantity: 16
maxVol: 16
canMix: True
container3:
reagents:
- ReagentId: Stimulants
Quantity: 16
maxVol: 16
canMix: True
- type: InjectOnTrigger
solutions:
- name: container1
transferAmount: 16
- name: container2
transferAmount: 16
- name: container3
transferAmount: 16

0 comments on commit 8c92a22

Please sign in to comment.