From 3d7908411e6edac161d3c4ea675601b61db035d7 Mon Sep 17 00:00:00 2001
From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com>
Date: Thu, 20 Apr 2023 00:55:41 -0400
Subject: [PATCH 1/7] Started work on what used to be a "SiliconFiller", but
now is a tool to inject blood into people. Lots of work to be done.
---
.../Components/SiliconFillerComponent.cs | 20 +++
.../Silicon/Systems/SiliconFillerSystem.cs | 146 ++++++++++++++++++
.../Chemistry/syringe.rsi/1-inhand-left.png | Bin 316 -> 314 bytes
.../Chemistry/syringe.rsi/1-inhand-right.png | Bin 320 -> 316 bytes
.../Chemistry/syringe.rsi/2-inhand-left.png | Bin 316 -> 317 bytes
.../Chemistry/syringe.rsi/2-inhand-right.png | Bin 320 -> 326 bytes
.../Chemistry/syringe.rsi/3-inhand-left.png | Bin 322 -> 316 bytes
.../Chemistry/syringe.rsi/3-inhand-right.png | Bin 315 -> 318 bytes
.../Chemistry/syringe.rsi/4-inhand-left.png | Bin 321 -> 323 bytes
.../Chemistry/syringe.rsi/4-inhand-right.png | Bin 321 -> 323 bytes
.../Chemistry/syringe.rsi/syringe1.png | Bin 131 -> 151 bytes
.../Chemistry/syringe.rsi/syringe2.png | Bin 131 -> 170 bytes
.../Chemistry/syringe.rsi/syringe3.png | Bin 131 -> 180 bytes
.../Chemistry/syringe.rsi/syringe4.png | Bin 153 -> 195 bytes
.../Chemistry/syringe.rsi/syringe_base0.png | Bin 331 -> 264 bytes
.../Chemistry/syringe.rsi/syringe_base1.png | Bin 331 -> 268 bytes
.../Chemistry/syringe.rsi/syringe_base2.png | Bin 338 -> 275 bytes
.../Chemistry/syringe.rsi/syringe_base3.png | Bin 330 -> 265 bytes
.../Chemistry/syringe.rsi/syringe_base4.png | Bin 284 -> 254 bytes
19 files changed, 166 insertions(+)
create mode 100644 Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
create mode 100644 Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
diff --git a/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs b/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
new file mode 100644
index 0000000000..4b6415dbf4
--- /dev/null
+++ b/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
@@ -0,0 +1,20 @@
+namespace Content.Server.SimpleStation14.Silicon.Components;
+
+[RegisterComponent]
+public sealed class BloodstreamFillerComponent : Component
+{
+ ///
+ /// The name of the volume to refill.
+ ///
+ ///
+ /// Should match the name or otherwise.
+ ///
+ [DataField("solution"), ViewVariables(VVAccess.ReadWrite)]
+ public string Solution { get; } = "filler";
+
+ ///
+ /// The amount of reagent that this silicon filler will fill with at most.
+ ///
+ [DataField("amount"), ViewVariables(VVAccess.ReadWrite)]
+ public float Amount = 100.0f;
+}
diff --git a/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs b/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
new file mode 100644
index 0000000000..5287a1f7b5
--- /dev/null
+++ b/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
@@ -0,0 +1,146 @@
+using Content.Server.Body.Components;
+using Content.Server.DoAfter;
+using Content.Server.SimpleStation14.Silicon.Components;
+using Content.Shared.DoAfter;
+using Content.Shared.Interaction;
+using Content.Shared.Interaction.Events;
+using Content.Shared.SimpleStation14.Silicon.Components;
+
+using Content.Server.Body.Systems;
+using Content.Server.Chemistry.Components;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.FixedPoint;
+
+namespace Content.Server.SimpleStation14.Silicon.Systems;
+
+public sealed class BloodstreamFillerSystem : EntitySystem
+{
+ [Dependency] private readonly DoAfterSystem _doAfter = default!;
+ [Dependency] private readonly BloodstreamSystem _bloodSystem = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnUseInWorld);
+ SubscribeLocalEvent(OnUseInHand);
+
+ SubscribeLocalEvent(OnDoAfter);
+ }
+
+ private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args)
+ {
+ if (!args.CanReach || args.Target == null)
+ return;
+
+ if (!EntityManager.TryGetComponent(args.Target, out var bloodComp))
+ {
+ TryRefill(uid, args.Target.Value, component);
+ return;
+ }
+
+ TryFill(args.User, args.Target.Value, args.Used, component);
+ }
+
+ private void OnUseInHand(EntityUid uid, BloodstreamFillerComponent component, UseInHandEvent args)
+ {
+ if (!EntityManager.TryGetComponent(args.User, out var bloodComp))
+ return;
+
+ TryFill(args.User, args.User, uid, component);
+ }
+
+ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp)
+ {
+ var bloodComp = EntityManager.GetComponent(target);
+
+ if (!_solutionSystem.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution) ||
+ fillerSolution.Contents.Count != 1 || // Extra dorty
+ fillerSolution.Contents[0].ReagentId != bloodComp.BloodReagent)
+ return;
+
+ var delay = 2.5f;
+ if (user == target)
+ delay *= 3.5f;
+
+ _doAfter.DoAfter(new DoAfterEventArgs(user, delay, target: target, used: filler)
+ {
+ RaiseOnTarget = true,
+ RaiseOnUser = false,
+ BreakOnUserMove = true,
+ BreakOnDamage = true,
+ BreakOnStun = true,
+ BreakOnTargetMove = true,
+ MovementThreshold = 0.2f
+ });
+ }
+
+ private void OnDoAfter(EntityUid uid, BloodstreamFillerComponent component, DoAfterEvent args)
+ {
+ if (args.Cancelled)
+ {
+ return;
+ }
+
+ if (args.Handled || args.Args.Target == null)
+ return;
+
+ Fill(args.Args.Target.Value, args.Args.Used!.Value, component);
+
+ args.Handled = true;
+ }
+
+ private void Fill(EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp)
+ {
+ if (!_solutionSystem.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
+ return;
+
+ var bloodComp = EntityManager.GetComponent(target);
+
+ var tansfAmount = FixedPoint2.Min(bloodComp.BloodSolution.AvailableVolume, Math.Min((float) fillerSolution.Volume, fillComp.Amount));
+
+ if (tansfAmount > 0)
+ {
+ var drained = _solutionSystem.SplitSolution(filler, fillerSolution, tansfAmount);
+
+ _bloodSystem.TryModifyBloodLevel(target, drained.Volume, bloodComp);
+ // _audioSystem.PlayPvs(welder.WelderRefill, welderUid);
+ // _popupSystem.PopupCursor(Loc.GetString("welder-component-after-interact-refueled-message"), user);
+ }
+ }
+
+ private void TryRefill(EntityUid filler, EntityUid target, BloodstreamFillerComponent fillComp)
+ {
+ if (!EntityManager.TryGetComponent(target, out var tankComp))
+ return;
+
+ // Check that the tank has one, and only one reagent.
+ if (!_solutionSystem.TryGetDrainableSolution(target, out var targetSolution)||
+ targetSolution.Contents.Count > 1) // Dorty
+ return;
+
+ // Check that the filler has one, and only one reagent, and that it's the same as the tank.
+ if (!_solutionSystem.TryGetSolution(filler, (string) fillComp.Solution!, out var fillerSolution) ||
+ fillerSolution.Contents.Count > 1 || // Extra dorty
+ (fillerSolution.Contents.Count > 0 && fillerSolution.Contents[0].ReagentId != targetSolution.Contents[0].ReagentId))
+ return;
+
+ var tansfAmount = FixedPoint2.Min(fillerSolution.AvailableVolume, targetSolution.Volume);
+ if (tansfAmount > 0)
+ {
+ var drained = _solutionSystem.Drain(target, targetSolution, tansfAmount);
+ _solutionSystem.TryAddSolution(filler, fillerSolution, drained);
+ // _audioSystem.PlayPvs(welder.WelderRefill, welderUid);
+ // _popupSystem.PopupCursor(Loc.GetString("welder-component-after-interact-refueled-message"), user);
+ }
+ else if (fillerSolution.AvailableVolume <= 0)
+ {
+ // _popupSystem.PopupCursor(Loc.GetString("welder-component-already-full"), user);
+ }
+ else
+ {
+ // _popupSystem.PopupCursor(Loc.GetString("welder-component-no-fuel-in-tank", ("owner", target)), user);
+ }
+ }
+}
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/1-inhand-left.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/1-inhand-left.png
index 0f1f04747227f06e5c0c56f604645d6041d860c8..fc2247ba5e3be21e70713012999c0281fc6e0ac0 100644
GIT binary patch
literal 314
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1FeX
zi(^Q|oVT+K`I-#`SlBh?A3wD@+bOz8B$Ma4tK;s=0Y9He^X*QMpCQbM6D=0H@a_4h
z^sRLP{towRQXlggYBBD8d2HLkUGvs|iq)_DE&G&3=l8SoevZ{^rbP0l+XkKw^3`!
delta 268
zcmdnRw1;VeW&Jx(7srr_Id5+{ave6{VZCVh#cl6@!6G%&xE80)o?0gb{?)Hu=VG(t
zqf(vXIYxo!3?0P`M=Tj0$uJc1HCV7a%wbjl3SSp`AS-xV;`4J23Gv@H-zr5n`$aM3
z+)w8%5`2^%w{zY812vB{=3QU(S+>CD%l_R8yQ}pgKML8D9j>2yR44M!mRBM>cF$1l
zo?pYGgxeCh-SgxWYReaBAL#0zty<1*#T0Undxui!0%eD9aR)?GH}BT>C~?u4d-Jc*
mn;VQvjpx^KErB_B2mj{HvZXaSTiO_az|+-_)n%PiLK6V+mTw3E
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/1-inhand-right.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/1-inhand-right.png
index c55b8d6fd657be61855017749620e8cdac9d6df8..c999a4c65ae3481d1445992542057403e42b6c81 100644
GIT binary patch
delta 268
zcmX@Ww1;VeW&Jx(7srr_Id5+{@--`nxL(Y@)Vs52dYfui61xKLg(u(l8oxXtl2>2a
zpnt@Y;gJkOAzy<9yTcr2g>#Go&lx(389>5OOiMl&EA~AzwP*D>GVOYNZvg*>+zsml
zUSB`|sp@j>U)QY+FKY|8^xoHf{%mz{0M`c#t45j20XO_L>ksVD`Sh>yqoU>&^pEQ#dlo#5Y%K!wPu70d8>zopr054v0S^xk5
delta 272
zcmdnPbbx7sW&I~l7srr_Id5+|@--`nxL$O>BwPC5JHdC$wFwphEexGs_8Grev39=n
zQAYiPmJJVN918dpEZ7C+Fms$^WO>feRLlSp&SF|p?$xEpqWj1?zw7so?Z)?6J#M?l
zq`$RquiXB#`|x!;rfkt0&wWkfby#<-{a#S{?UB_wrZxM1)Gw|vpR?|{)`9&xcG>%w
z4RDx`B3xB>r-<)=NGxO2xrgjCihA$4FZd->H{qe6+Z)Ev=O5-S`}_Tb?}iG#`-!g}
roBq-@NWQSLx;wrZ>eLU6c8z*+Wr`Q;au^sGI2k-${an^LB{Ts5S;}@k
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/2-inhand-left.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/2-inhand-left.png
index 0f1f04747227f06e5c0c56f604645d6041d860c8..54307dc06908161ac503300e2a19eced6a9c693f 100644
GIT binary patch
literal 317
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1HE{
zi(^Q|oVT+a`3@NfFslpMKl<{nPXkgt38pjBdOLtM$-)fHPFf306Teb3*%P0Y8-ek_g+SpRj?A^SOnocne+
z)(WNB&rLixi>bQXa_JAhV+zk)7zm@7*aIbH4w4fB{@;(DBpbjn;~Zp6-pUB=S{fL>?tboFyt=akR{
E0N%!T1ONa4
delta 268
zcmdnXw1;VeW&Jx(7srr_Id5+{ave6{VZCVh#cl6@!6G%&xE80)o?0gb{?)Hu=VG(t
zqf(vXIYxo!3?0P`M=Tj0$uJc1HCV7a%wbjl3SSp`AS-xV;`4J23Gv@H-zr5n`$aM3
z+)w8%5`2^%w{zY812vB{=3QU(S+>CD%l_R8yQ}pgKML8D9j>2yR44M!mRBM>cF$1l
zo?pYGgxeCh-SgxWYReaBAL#0zty<1*#T0Undxui!0%eD9aR)?GH}BT>C~?u4d-Jc*
mn;VQvjpx^KErB_B2mj{HvZXaSTiO_az|+-_)n%PiLK6V)lqcRZLy7^-2H9*SWtwW-)$}IJ@oR-rToWH7&RcEUoH=Z!UXSV4u$TFZJ{6
zesza7oK_%gc6k1MxwZ9&yeljcBh=xa80WpIR&q7s-?Z420SG)@{an^LB{Ts5ukd+L
delta 272
zcmX@cbbx7sW&I~l7srr_Id5+|@--`nxL$O>BwPC5JHdC$wFwphEexGs_8Grev39=n
zQAYiPmJJVN918dpEZ7C+Fms$^WO>feRLlSp&SF|p?$xEpqWj1?zw7so?Z)?6J#M?l
zq`$RquiXB#`|x!;rfkt0&wWkfby#<-{a#S{?UB_wrZxM1)Gw|vpR?|{)`9&xcG>%w
z4RDx`B3xB>r-<)=NGxO2xrgjCihA$4FZd->H{qe6+Z)Ev=O5-S`}_Tb?}iG#`-!g}
roBq-@NWQSLx;wrZ>eLU6c8z*+Wr`Q;au^sGI2k-${an^LB{Ts5WNLOu
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/3-inhand-left.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/3-inhand-left.png
index 3bbc9fe6839a6bb11a5086fae0cb79bd543437f2..5fe7f1f943db2452f4f1973914461a1d503169d9 100644
GIT binary patch
literal 316
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1G3n
zi(^Q|oVT+K`3@@xu&`^|pZY(4g84*+Ko_s%-w`6&A
literal 322
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1FYV
zi(^Q|oVT+axegofupGZ2|MkEBi`iEsgfzBXST>0#vE0v+^ZkMd_SbC|VhuQvF4H@~
zj}pmseN9ChuO_b!4}9G##%TPf?uCN-Lk@rO*!>4?9A2*ZW=Vg^J;vh;|G#a@`Tplf
zmv=#%g>;(dkCUr33(U?;`XJozcw{33VYG8s!CtJp0aj!(wKy?6_L4C2)f)nV#L#a#^>xHW}!D22WQ%mvv4F
FO#oNkfnfju
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/3-inhand-right.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/3-inhand-right.png
index 71ecded6f6b4872f9268f8097ba3ffc3c1e8a308..cba15421ff0a47b0fe25f406029c8510cd9ec0ba 100644
GIT binary patch
delta 236
zcmdnZw2x_mW&H<=;mmK^=C3`l
ziSPcW$5)xATtB**ci;A$!{Oxz0~;={HJ(_?)pxkEkLl0p5AyaC52%K}*i(0`oPA%(
z`-W@9Ke%~*_T6JR`~1URx7K}+=d#Wzp$Py{-*W)~
delta 239
zcmdnTw3}&yW&K-E7srr_Id5-9^EDZWusu{PbbnXRxn^Zn%Mo#nCAm!J{_pL6?z6+@
zOJfX^!gPicstiS(4XDg=6^F`chirU>%|FiDe&&ARYUArnYfcxd#=mlY1)1RqF>C
zC%b1(d%F4?Q^@PsJ66Bn$wf21+xKVvdAZr#zjIiBOn(}_{5?bO#0%mR?{J4@{QNkx
z_{Zuju7YPW`zlSFrS>SwM
g_a~1M#C5+I^py%VMHB_kMlt|_r>mdKI;Vst01r)X=l}o!
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/4-inhand-left.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/4-inhand-left.png
index 2d4447acb7207a094a364cb231fc7a5350d2f7af..2a0575895cd17f8d8042c0e68592333371885634 100644
GIT binary patch
literal 323
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1Gj#
zi(^Q|oVT+axegl$Fdx4l|MkEBi`jQ1f;gT`x}xno;n@^#vG)n<`LA&oD>2|iDopqG
ze)rFQyjgV0>uB3;Riaz{JXm_3eRnN?rt)W&d+RHXEf@d1dBp$!G>=BQ!)@{Z@AY1+
z%B@d1Dj?%~XR1MUiQeW{Vmof1ne>c(C!3)gTe~DWM4fpRsXc
literal 321
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAQ1G*-
zi(^Q|oVT+axegofupGZ2|MkEBi`iEsggCxTx)SGnV{WjX;3b7<_SdbJf(^=NXpx$-rBA;!HwY+ok%916723UOcX^^yBz`@j0e3-&PIn)hdaY{05*
z_M0CGy>Y!W)u5_GZ*vyc9o;m~k8^t*&vY^nMwPo79^Pe~+929LJGhKpgsF@5%q`gf
z4hx~6vV&XhGQMnLk>U(aUZwBo%I?$q^NXf|4@-g{7@ZUU-()B(bKw65p!XR(UHx3v
IIVCg!06Cm`J^%m!
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/4-inhand-right.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/4-inhand-right.png
index fa55e86eb97cf04d88a24bb2698eef0dec06b57c..92d9a14b1f979f13f15f0b6698cce7829d4683c0 100644
GIT binary patch
delta 275
zcmX@ebeL&^W&KxA7srr_Id5-y^Bq!QHm+grHM`@bjw2ALH^$&u(S-{^5z-^1JgR4ipET%P;ibw`{2yQY|iSM}F!ddyO`_SZYGpQrxy
zJw_uWV{zDaj?vBTPBH)g)on~)?i}{t@Wk4!-{G_EpB14C(`}e%y?e;6`+NPNGwlf<
w0SxdTjbzcSF)b@AK2*o1rd$!n}uJf3kVw5wmu79tI%rboFyt=akR{09OHfPyhe`
delta 249
zcmX@ibdYI+W&LMQ7srr_Id5-z^Bq!B{4vdby@o%1b^>?6T>&d;&*GHlCs}_?f0%#Q
z+M#XYMd>)Gv6cr;v{%1-SbsI3VP5qQ&S`&+y%5aU*FHa`szvgA!?Nlhj;HrkKXcwt
u!Ec}N^5d+(Vi6lJEKNVX-Vy4~PmFQwKaDq4-)B!|00K`}KbLh*2~7aVL39uR
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe1.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe1.png
index 74cfa72ab4831e7514d2eeb8180dae0d69d6f858..82af39342e6ed658647dfe4105d8af9c5c9dc425 100644
GIT binary patch
delta 122
zcmZo>oX$8wrI@q8BeIx*f$sRCphIw1JWICJM&pF6S941x<=cigStxj#o4@PqY95GUxo}07?3#4FkLz9fEf#bN~PV07*qo
IM6N<$g0p}tX#fBK
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe2.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe2.png
index 74cfa72ab4831e7514d2eeb8180dae0d69d6f858..1e952a5d308646fd936612ed734917a2218dec37 100644
GIT binary patch
delta 142
zcmZo>T*Wv+rJl3EBeIx*f$s7lG(#{cQ}a*##}~r-KP`Ytf#AXahMlV{!`3q^C3$U5ZrJ_)=}gU4RVB6D32BQ3
mOqT|}X1)6~_kb`XM78;^#o4@PqY95GUxo}07?3#4FkLz9fEf#bN~PV07*qo
IM6N<$g1Ztcd;kCd
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe3.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe3.png
index 9aa237b1364439229cd4fc3efad57fa474e9e433..64e3e409d5cfe86ae7a386950ceac701ea38357c 100644
GIT binary patch
delta 152
zcmZo>+`>3PrJl3EBeIx*f$s~{20L;an*oil^)FK1k3
yWxu{>Ipg9E1wqZ;<&4^G-VIY3!8!_LJ}|QX5ff~6cS$q=iFmsDxvX@=G^IccH;N_qR*{0000AA{0K~`Z(8m~W
zE@Qp|(0B;JOAlTaKr=1|XvbNA6nV!VnsF8j$?H&zf--fFkg#X~tOqdc$eQSpd2P
nB@pZ___Y2RpyU|900wvhTS16;M&o~w00000NkvXXu0mjf<7!?Z
delta 305
zcmV-10nYx20?PuBBYy!BNkl
zy!9T(@SM3Ha%Z5S)&Kw#X9RD(N2jeP#)Q~GL
zfLS&z7jq>7T!QUN-h-AFIk!e+O3dBQ0v9F@t`q`yrn98cq{0E9+3FIrY$^l}0It8G
z*hJc0&!bG=@hV{#pk7yTI)wlvf4fpsUBXLvslU_}fg6@HnMdU)00000NkvXXu0mjf
D!5@p`
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base1.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base1.png
index 2d455682f40660b7f1c31e2b33ec407c2f74203f..6cae5f27fde4fedc503ab09cd8fc747995c5491d 100644
GIT binary patch
delta 241
zcmVdJfH;{BfKcL8V|CXb1W0orjE03&O>*Nn3O7>Da6{?d%I02Be=xn`UNpno{+
rI150xAO(WG1^=!O1EgFAFn|Gmu9=2%o}rGS00000NkvXXu0mjfrxsp4
delta 305
zcmV-10nYx60?PuBBYy!BNkln&fP+)O;f+4-q~ul9gt
zJG5D^S`3iXTg+0+i<}u@|8SfA0=UGz*%;jQmT9dMxGW6LPT`RQK(}u^?D)KK<0?Ol
zDQn`F@KR%V+A1HRstN#uR8;{RK_L>F>IUAx8`V-bJv5U%WxRcf00000NkvXXu0mjf
D&2Wtb
diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base2.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base2.png
index b898840c308b1475ade399d2d90ac0873d02b1f4..a81f1c6ff2b804579ebbeba8392f81531a9fd0a7 100644
GIT binary patch
delta 248
zcmV(BFbsg<
z3Z6y~CJa2%&agMZQ~1;~^cVxd!C=>^=AjV!U=xxeND9L#jQ`U(v2_N@rmC1MtUV!0EkWV`xQc1(!O*IML>$+xW<{20VxjOwc{iJM!^4EGfoEJF=)n%
yfc)`V191w#^T)@W;v(IIuHw4)E13ZdKv_GmcY<=JLlVXS0000e|>WgIHsEekS!-<2G!GmzPZPLJ1Y~0lA=bUqJ-i&
zL-u8SL;%B~V`mudKYBuRdZ0K26y;Gx%~3F9R6B0RIgb`cK^UxqAd4
ziB|(i<5d8fI2C{}o|-rXkiz5icI)z0zh4B%K6lifz6hYbYiBATkC$N70A^ebKn%ln
z1SxS5AVt#i07UP7#Kbq5ffUCc;SfT{8bA@?jKHaxaWNpj21i`t8Nj{<;u3K6Z*TSm
o&cj!8-ChCvv}!<$WdH;G09nq1RC%#!{{R3007*qoM6N<$g7W}hlmGw#
delta 304
zcmV-00nh%40?GoABYy!ANkle|>WgIHsEekS!-<2G!GmzPZPLJ1Y~0lA=bUqJ-i&
zL-u8SL;%B~V`mudKYBuRdZ0K26y;625k@rgr@x8ef0Q$eRB^urkewhEhl6K)zg5!xyOGyD-(v2qDG>kgyJ|u
z_GNrT0K=hUXBh53dO~!1pjx8Yef0SMsT1Zh*jbq{EL^bxE_qJZgxS|W10&uEr30#_
zfuh0;l6^bi1rbf+XFv<5;RymlQ>b5zLIF{U@WF#ew6dQ#u>0uo{|2URGzkTws^iP2
zE;1-6$T2W5xcyg9kYm`edJg?kHchJ0QOidy9|fZT2><}8?_osFS+RQn0000
Date: Sun, 23 Apr 2023 07:40:26 -0400
Subject: [PATCH 2/7] Removed Silicon remnants
---
.../SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs b/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
index 5287a1f7b5..74579cabb9 100644
--- a/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
+++ b/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
@@ -4,7 +4,6 @@
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
-using Content.Shared.SimpleStation14.Silicon.Components;
using Content.Server.Body.Systems;
using Content.Server.Chemistry.Components;
From 01c60dc311e469cbd3122b6a19f9761c9ce6c15c Mon Sep 17 00:00:00 2001
From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com>
Date: Wed, 14 Jun 2023 07:21:39 -0400
Subject: [PATCH 3/7] Big ol update to just about everything
---
.../Components/BloodstreamFillerComponent.cs | 167 +++++++++++
.../Systems/BloodstreamFillerSystem.cs | 263 ++++++++++++++++++
.../Components/SiliconFillerComponent.cs | 20 --
.../Silicon/Systems/SiliconFillerSystem.cs | 145 ----------
.../Silicon/BloodstreamFillerEvents.cs | 24 ++
.../Content/BloodFiller/bloodFiller.ftl | 13 +
.../Objects/Specific/Medical/hypospray.yml | 46 +++
.../Structures/Storage/Tanks/tanks.yml | 55 ++++
.../Storage/tanks.rsi/bloodtankblood.png | Bin 0 -> 3863 bytes
.../Storage/tanks.rsi/bloodtankslime.png | Bin 0 -> 3980 bytes
.../Structures/Storage/tanks.rsi/meta.json | 17 ++
11 files changed, 585 insertions(+), 165 deletions(-)
create mode 100644 Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
create mode 100644 Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
delete mode 100644 Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
delete mode 100644 Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
create mode 100644 Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
create mode 100644 Resources/Locale/en-US/SimpleStation14/Content/BloodFiller/bloodFiller.ftl
create mode 100644 Resources/Prototypes/SimpleStation14/Entities/Structures/Storage/Tanks/tanks.yml
create mode 100644 Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankblood.png
create mode 100644 Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankslime.png
create mode 100644 Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/meta.json
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
new file mode 100644
index 0000000000..97d8b02849
--- /dev/null
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
@@ -0,0 +1,167 @@
+using Content.Shared.Damage;
+using Content.Shared.Damage.Prototypes;
+using Robust.Shared.Audio;
+
+namespace Content.Server.SimpleStation14.BloodstreamFiller.Components;
+
+[RegisterComponent]
+public sealed class BloodstreamFillerComponent : Component
+{
+ ///
+ /// The duration of the fill DoAfter, in seconds.
+ ///
+ [DataField("fillTime"), ViewVariables(VVAccess.ReadWrite)]
+ public float FillTime = 1.0f;
+
+ ///
+ /// The multiplier for the DoAfter time when attempting to fill yourself.
+ ///
+ [DataField("selfFillMutli"), ViewVariables(VVAccess.ReadWrite)]
+ public float SelfFillMutli = 3.5f;
+
+ ///
+ /// The name of the volume to refill.
+ ///
+ ///
+ /// Should match the name or otherwise.
+ ///
+ [DataField("solution"), ViewVariables(VVAccess.ReadWrite)]
+ public string Solution { get; } = "filler";
+
+ ///
+ /// The amount of reagent that this bloodstream filler will fill with at most.
+ ///
+ [DataField("amount"), ViewVariables(VVAccess.ReadWrite)]
+ public float Amount = 100.0f;
+
+ ///
+ /// The regent allowed to be used by this filler.
+ ///
+ ///
+ /// If null, any reagent will be allowed.
+ ///
+ [DataField("reagent"), ViewVariables(VVAccess.ReadWrite)]
+ public string? Reagent = null;
+
+ ///
+ /// Will this filler only fill Silicons?
+ ///
+ ///
+ /// Somewhat niche use case, but Bloodstreams are very inflexible.
+ ///
+ [DataField("siliconOnly"), ViewVariables(VVAccess.ReadWrite)]
+ public bool SiliconOnly = true;
+
+ ///
+ /// Can this bloodfiller be used to overfill someone?
+ ///
+ ///
+ /// If true, the bloodfiller will be able to fill someone already at max blood, causing damage and spilling blood.
+ ///
+ [DataField("overfill"), ViewVariables(VVAccess.ReadWrite)]
+ public bool Overfill = true;
+
+ ///
+ /// The multiplier for the DoAfter time when attempting to overfill someone.
+ ///
+ [DataField("overfillMutli"), ViewVariables(VVAccess.ReadWrite)]
+ public float OverfillMutli = 5.5f;
+
+ ///
+ /// The amount of damage dealt when overfilling someone.
+ ///
+ ///
+ /// This must be specified in YAML.
+ ///
+ [DataField("overfillDamage"), ViewVariables(VVAccess.ReadWrite)]
+ public DamageSpecifier OverfillDamage = default!;
+
+ #region Player Feedback
+ ///
+ /// The sound played when the filler is used.
+ ///
+ [DataField("useSound")]
+ public SoundSpecifier UseSound = new SoundPathSpecifier("/Audio/Effects/bang.ogg");
+
+ ///
+ /// The sound played when the filler refills.
+ ///
+ [DataField("refillSound")]
+ public SoundSpecifier RefillSound = new SoundPathSpecifier("/Audio/Effects/buckle.ogg");
+
+ ///
+ /// The sound played when overfilling someone.
+ ///
+ [DataField("overfillSound")]
+ public SoundSpecifier OverfillSound = new SoundPathSpecifier("/Audio/Effects/demon_dies.ogg");
+
+ ///
+ /// The popup text when the filler is used.
+ ///
+ [DataField("usePopup")]
+ public string UsePopup = "bloodfiller-use-user";
+
+ ///
+ /// The popup text when the filler is used on you.
+ ///
+ [DataField("usedOnPopup")]
+ public string UsedOnPopup = "bloodfiller-use-target";
+
+ ///
+ /// The popup text when the bloodfiller is empty.
+ ///
+ [DataField("emptyPopup")]
+ public string EmptyPopup = "bloodfiller-use-empty";
+
+ ///
+ /// The popup text when the bloodfiller can't be used on the target.
+ ///
+ ///
+ /// Due to or otherwise.
+ ///
+ [DataField("targetInvalidPopup")]
+ public string TargetInvalidPopup = "bloodfiller-use-invalid-target";
+
+ ///
+ /// The popup text when the bloodfiller doesn't have the target's blood.
+ ///
+ [DataField("targetBloodInvalidPopup")]
+ public string TargetBloodInvalidPopup = "bloodfiller-use-invalid-blood";
+
+ ///
+ /// The popup text when the filler is already full.
+ ///
+ [DataField("refillFullPopup")]
+ public string RefillFullPopup = "bloodfiller-refill-filler-full";
+
+ ///
+ /// The popup text when the tank is empty.
+ ///
+ [DataField("refillTankEmptyPopup")]
+ public string RefillTankEmptyPopup = "bloodfiller-refill-tank-empty";
+
+ ///
+ /// The popup text when trying to refill the bloodfiller from a tank with the wrong reagent.
+ ///
+ [DataField("refillReagentInvalidPopup")]
+ public string RefillReagentInvalidPopup = "bloodfiller-refill-reagent-invalid";
+
+ ///
+ /// The popup text when either a tank or filler contains a dirty mixture.
+ ///
+ [DataField("dirtyPopup")]
+ public string DirtyPopup = "bloodfiller-reagent-dirty";
+
+ ///
+ /// The popup text when trying to overfill someone.
+ ///
+ [DataField("targetOverfillPopup")]
+ public string TargetOverfillPopup = "bloodfiller-user-overfill";
+
+ ///
+ /// The popup text when getting overfilled.
+ ///
+ [DataField("overfilledPopup")]
+ public string OverfilledPopup = "bloodfiller-target-overfill";
+ #endregion
+}
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
new file mode 100644
index 0000000000..920a35d070
--- /dev/null
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
@@ -0,0 +1,263 @@
+using Content.Server.Body.Components;
+using Content.Server.SimpleStation14.BloodstreamFiller.Components;
+using Content.Shared.DoAfter;
+using Content.Shared.Interaction;
+using Content.Shared.Interaction.Events;
+using Content.Server.Body.Systems;
+using Content.Server.Chemistry.Components;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Shared.FixedPoint;
+using Content.Shared.SimpleStation14.BloodstreamFiller;
+using Robust.Shared.Utility;
+using Content.Server.Popups;
+using Robust.Server.GameObjects;
+using Content.Shared.Popups;
+using Content.Shared.Damage;
+using Content.Server.Fluids.EntitySystems;
+
+namespace Content.Server.SimpleStation14.BloodstreamFiller.Systems;
+
+public sealed class BloodstreamFillerSystem : EntitySystem
+{
+ [Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
+ [Dependency] private readonly AudioSystem _audio = default!;
+ [Dependency] private readonly BloodstreamSystem _bloodstream = default!;
+ [Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly PuddleSystem _puddle = default!;
+ [Dependency] private readonly SolutionContainerSystem _solution = default!;
+ [Dependency] private readonly PopupSystem _popup = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnUseInWorld);
+ SubscribeLocalEvent(OnUseInHand);
+
+ SubscribeLocalEvent(OnDoAfter);
+ }
+
+ private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args)
+ {
+ if (!args.CanReach || args.Target == null)
+ return;
+
+ if (!EntityManager.TryGetComponent(args.Target, out var bloodComp))
+ {
+ TryRefill(args.User, uid, args.Target.Value, component);
+ return;
+ }
+
+ TryFill(args.User, args.Target.Value, args.Used, component);
+ }
+
+ private void OnUseInHand(EntityUid uid, BloodstreamFillerComponent component, UseInHandEvent args)
+ {
+ if (!EntityManager.TryGetComponent(args.User, out var bloodComp))
+ return;
+
+ TryFill(args.User, args.User, uid, component);
+ }
+
+ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp)
+ {
+ // if (fillComp.SiliconOnly && !HasComp(target)) // To be turned on once Silicons are merged :)
+ // {
+ // // Do failure stuff
+ // return;
+ // }
+
+ var bloodComp = EntityManager.GetComponent(target);
+
+ if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution)) // No solution
+ return;
+
+ if (fillComp.Reagent != null && fillComp.Reagent != bloodComp.BloodReagent) // Wrong reagent as specified by the component
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.TargetInvalidPopup, ("filler", filler)), user);
+ return;
+ }
+
+ if (fillerSolution.Contents.Count == 0) // Empty
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.EmptyPopup, ("filler", filler)), user);
+ return;
+ }
+
+ if (fillerSolution.Contents.Count > 1) // Extra dorty
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.DirtyPopup, ("volume", filler)), user);
+ return;
+ }
+
+ if (fillerSolution.Contents[0].ReagentId != bloodComp.BloodReagent) // Wrong reagent contained
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.TargetBloodInvalidPopup, ("filler", filler), ("target", target)), user);
+ return;
+ }
+
+ var overfill = false;
+
+ var delay = fillComp.FillTime;
+ if (user == target)
+ delay *= fillComp.SelfFillMutli;
+
+ // If the bloodstream is already full, and the filler can overfill, and target is not the user, then overfill.
+ if (fillComp.Overfill && bloodComp.BloodSolution.AvailableVolume == 0 && user != target)
+ {
+ overfill = true;
+ delay *= fillComp.OverfillMutli;
+ }
+
+ _doAfter.TryStartDoAfter(new DoAfterArgs(user, delay, new BloodstreamFillerDoAfterEvent(overfill), target, target, filler)
+ {
+ BreakOnDamage = true,
+ BreakOnTargetMove = true,
+ BreakOnUserMove = true,
+ MovementThreshold = 0.2f,
+ CancelDuplicate = true
+ });
+
+ if (!overfill)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.UsePopup, ("target", target)), user);
+ _popup.PopupEntity(Loc.GetString(fillComp.UsedOnPopup), target, target, PopupType.Medium);
+ }
+ else
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.TargetOverfillPopup, ("target", target)), user, PopupType.MediumCaution);
+ _popup.PopupEntity(Loc.GetString(fillComp.OverfilledPopup), target, target, PopupType.LargeCaution);
+ }
+ }
+
+ private void OnDoAfter(EntityUid uid, BloodstreamComponent component, BloodstreamFillerDoAfterEvent args)
+ {
+ if (args.Cancelled)
+ {
+ return;
+ }
+
+ if (args.Handled || args.Args.Target == null)
+ return;
+
+ if (!TryComp(args.Args.Used, out var fillComp))
+ {
+ DebugTools.Assert("Filler component not found");
+ Logger.ErrorS("silicon", $"Filler component not found on entity {ToPrettyString(args.Args.Used.Value)}");
+
+ return;
+ }
+ if (!EntityManager.TryGetComponent(args.Args.Target, out var bloodComp))
+ {
+ DebugTools.Assert("Bloodstream component not found");
+ Logger.ErrorS("silicon", $"Bloodstream component not found on entity {ToPrettyString(args.Args.Target.Value)}");
+
+ return;
+ }
+
+ if (!args.Overfill)
+ Fill(args.Args.Target.Value, args.Args.Used!.Value, fillComp, bloodComp);
+ else
+ Overfill(args.Args.User, args.Args.Target.Value, args.Args.Used!.Value, fillComp, bloodComp);
+
+ args.Handled = true;
+ }
+
+ private void Fill(EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp, BloodstreamComponent bloodComp)
+ {
+ if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
+ return;
+
+ var tansfAmount = FixedPoint2.Min(bloodComp.BloodSolution.AvailableVolume, Math.Min((float) fillerSolution.Volume, fillComp.Amount));
+
+ if (tansfAmount > 0)
+ {
+ var drained = _solution.SplitSolution(filler, fillerSolution, tansfAmount);
+
+ _bloodstream.TryModifyBloodLevel(target, drained.Volume, bloodComp);
+
+ _audio.PlayPvs(fillComp.RefillSound, filler);
+ }
+ }
+
+ private void Overfill(EntityUid user, EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp, BloodstreamComponent bloodComp)
+ {
+ if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
+ return;
+
+ if (!TryComp(target, out var damageableComp))
+ return;
+
+ _damageable.TryChangeDamage(target, fillComp.OverfillDamage, origin: user, damageable: damageableComp);
+
+ _puddle.TrySplashSpillAt(target, Transform(target).Coordinates, fillerSolution, out _, user: user);
+
+ Fill(target, filler, fillComp, bloodComp);
+ }
+
+ private void TryRefill(EntityUid user, EntityUid filler, EntityUid target, BloodstreamFillerComponent fillComp)
+ {
+ if (!EntityManager.TryGetComponent(target, out _))
+ return;
+
+ if (!_solution.TryGetDrainableSolution(target, out var targetSolution))
+ return;
+
+ if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
+ return;
+
+ // Check that the tank is not empty.
+ if (targetSolution.Contents.Count == 0)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.RefillTankEmptyPopup, ("tank", target)), user);
+ return;
+ }
+
+ // Check that the tank has one, and only one reagent.
+ if (targetSolution.Contents.Count > 1)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.DirtyPopup, ("volume", target)), user);
+ return;
+ }
+
+ // Check that the tank's solution matches the filler's listed reagent.
+ // This is seperate from checking the actual solution to prevent any funny business.
+ if (fillComp.Reagent != null && targetSolution.Contents[0].ReagentId != fillComp.Reagent)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.RefillReagentInvalidPopup, ("tank", target)), user);
+ return;
+ }
+
+ // Check that if the filler isn't empty, that it only has one reagent.
+ if (fillerSolution.Contents.Count > 1)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.DirtyPopup, ("volume", filler)), user);
+ return;
+ }
+
+ // Check that if the filler isn't empty, that it's reagent matches the tank's reagent.
+ if (fillerSolution.Contents.Count == 1 && fillerSolution.Contents[0].ReagentId != targetSolution.Contents[0].ReagentId)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.RefillReagentInvalidPopup, ("filler", filler)), user);
+ return;
+ }
+
+ var tansfAmount = FixedPoint2.Min(fillerSolution.AvailableVolume, targetSolution.Volume);
+
+ if (tansfAmount > 0)
+ {
+ var drained = _solution.Drain(target, targetSolution, tansfAmount);
+ _solution.TryAddSolution(filler, fillerSolution, drained);
+
+ _audio.PlayPvs(fillComp.UseSound, filler);
+ }
+ else if (fillerSolution.AvailableVolume <= 0)
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.RefillFullPopup, ("filler", filler)), user);
+ }
+ else
+ {
+ _popup.PopupCursor(Loc.GetString(fillComp.RefillTankEmptyPopup, ("tank", target)), user);
+ }
+ }
+}
diff --git a/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs b/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
deleted file mode 100644
index 4b6415dbf4..0000000000
--- a/Content.Server/SimpleStation14/Silicon/Components/SiliconFillerComponent.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Content.Server.SimpleStation14.Silicon.Components;
-
-[RegisterComponent]
-public sealed class BloodstreamFillerComponent : Component
-{
- ///
- /// The name of the volume to refill.
- ///
- ///
- /// Should match the name or otherwise.
- ///
- [DataField("solution"), ViewVariables(VVAccess.ReadWrite)]
- public string Solution { get; } = "filler";
-
- ///
- /// The amount of reagent that this silicon filler will fill with at most.
- ///
- [DataField("amount"), ViewVariables(VVAccess.ReadWrite)]
- public float Amount = 100.0f;
-}
diff --git a/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs b/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
deleted file mode 100644
index 74579cabb9..0000000000
--- a/Content.Server/SimpleStation14/Silicon/Systems/SiliconFillerSystem.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using Content.Server.Body.Components;
-using Content.Server.DoAfter;
-using Content.Server.SimpleStation14.Silicon.Components;
-using Content.Shared.DoAfter;
-using Content.Shared.Interaction;
-using Content.Shared.Interaction.Events;
-
-using Content.Server.Body.Systems;
-using Content.Server.Chemistry.Components;
-using Content.Server.Chemistry.EntitySystems;
-using Content.Shared.FixedPoint;
-
-namespace Content.Server.SimpleStation14.Silicon.Systems;
-
-public sealed class BloodstreamFillerSystem : EntitySystem
-{
- [Dependency] private readonly DoAfterSystem _doAfter = default!;
- [Dependency] private readonly BloodstreamSystem _bloodSystem = default!;
- [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!;
-
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent(OnUseInWorld);
- SubscribeLocalEvent(OnUseInHand);
-
- SubscribeLocalEvent(OnDoAfter);
- }
-
- private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args)
- {
- if (!args.CanReach || args.Target == null)
- return;
-
- if (!EntityManager.TryGetComponent(args.Target, out var bloodComp))
- {
- TryRefill(uid, args.Target.Value, component);
- return;
- }
-
- TryFill(args.User, args.Target.Value, args.Used, component);
- }
-
- private void OnUseInHand(EntityUid uid, BloodstreamFillerComponent component, UseInHandEvent args)
- {
- if (!EntityManager.TryGetComponent(args.User, out var bloodComp))
- return;
-
- TryFill(args.User, args.User, uid, component);
- }
-
- private void TryFill(EntityUid user, EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp)
- {
- var bloodComp = EntityManager.GetComponent(target);
-
- if (!_solutionSystem.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution) ||
- fillerSolution.Contents.Count != 1 || // Extra dorty
- fillerSolution.Contents[0].ReagentId != bloodComp.BloodReagent)
- return;
-
- var delay = 2.5f;
- if (user == target)
- delay *= 3.5f;
-
- _doAfter.DoAfter(new DoAfterEventArgs(user, delay, target: target, used: filler)
- {
- RaiseOnTarget = true,
- RaiseOnUser = false,
- BreakOnUserMove = true,
- BreakOnDamage = true,
- BreakOnStun = true,
- BreakOnTargetMove = true,
- MovementThreshold = 0.2f
- });
- }
-
- private void OnDoAfter(EntityUid uid, BloodstreamFillerComponent component, DoAfterEvent args)
- {
- if (args.Cancelled)
- {
- return;
- }
-
- if (args.Handled || args.Args.Target == null)
- return;
-
- Fill(args.Args.Target.Value, args.Args.Used!.Value, component);
-
- args.Handled = true;
- }
-
- private void Fill(EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp)
- {
- if (!_solutionSystem.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
- return;
-
- var bloodComp = EntityManager.GetComponent(target);
-
- var tansfAmount = FixedPoint2.Min(bloodComp.BloodSolution.AvailableVolume, Math.Min((float) fillerSolution.Volume, fillComp.Amount));
-
- if (tansfAmount > 0)
- {
- var drained = _solutionSystem.SplitSolution(filler, fillerSolution, tansfAmount);
-
- _bloodSystem.TryModifyBloodLevel(target, drained.Volume, bloodComp);
- // _audioSystem.PlayPvs(welder.WelderRefill, welderUid);
- // _popupSystem.PopupCursor(Loc.GetString("welder-component-after-interact-refueled-message"), user);
- }
- }
-
- private void TryRefill(EntityUid filler, EntityUid target, BloodstreamFillerComponent fillComp)
- {
- if (!EntityManager.TryGetComponent(target, out var tankComp))
- return;
-
- // Check that the tank has one, and only one reagent.
- if (!_solutionSystem.TryGetDrainableSolution(target, out var targetSolution)||
- targetSolution.Contents.Count > 1) // Dorty
- return;
-
- // Check that the filler has one, and only one reagent, and that it's the same as the tank.
- if (!_solutionSystem.TryGetSolution(filler, (string) fillComp.Solution!, out var fillerSolution) ||
- fillerSolution.Contents.Count > 1 || // Extra dorty
- (fillerSolution.Contents.Count > 0 && fillerSolution.Contents[0].ReagentId != targetSolution.Contents[0].ReagentId))
- return;
-
- var tansfAmount = FixedPoint2.Min(fillerSolution.AvailableVolume, targetSolution.Volume);
- if (tansfAmount > 0)
- {
- var drained = _solutionSystem.Drain(target, targetSolution, tansfAmount);
- _solutionSystem.TryAddSolution(filler, fillerSolution, drained);
- // _audioSystem.PlayPvs(welder.WelderRefill, welderUid);
- // _popupSystem.PopupCursor(Loc.GetString("welder-component-after-interact-refueled-message"), user);
- }
- else if (fillerSolution.AvailableVolume <= 0)
- {
- // _popupSystem.PopupCursor(Loc.GetString("welder-component-already-full"), user);
- }
- else
- {
- // _popupSystem.PopupCursor(Loc.GetString("welder-component-no-fuel-in-tank", ("owner", target)), user);
- }
- }
-}
diff --git a/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs b/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
new file mode 100644
index 0000000000..9dce1045c7
--- /dev/null
+++ b/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
@@ -0,0 +1,24 @@
+using Content.Shared.DoAfter;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.SimpleStation14.BloodstreamFiller;
+
+[Serializable, NetSerializable]
+public sealed class BloodstreamFillerDoAfterEvent : DoAfterEvent
+{
+ [DataField("overfill")]
+ public readonly bool Overfill = false;
+
+ private BloodstreamFillerDoAfterEvent()
+ {
+ }
+ public BloodstreamFillerDoAfterEvent(bool overfill)
+ {
+ Overfill = overfill;
+ }
+
+ public override DoAfterEvent Clone()
+ {
+ return this;
+ }
+}
diff --git a/Resources/Locale/en-US/SimpleStation14/Content/BloodFiller/bloodFiller.ftl b/Resources/Locale/en-US/SimpleStation14/Content/BloodFiller/bloodFiller.ftl
new file mode 100644
index 0000000000..df003261bc
--- /dev/null
+++ b/Resources/Locale/en-US/SimpleStation14/Content/BloodFiller/bloodFiller.ftl
@@ -0,0 +1,13 @@
+bloodfiller-use-user = You begin filling { THE($target) }.
+bloodfiller-use-target = You feel your bloodstream beginning to pressurize...
+bloodfiller-use-empty = { CAPITALIZE(THE($filler)) } is empty.
+bloodfiller-use-invalid-target = { CAPITALIZE(THE($filler)) } can't be used here.
+bloodfiller-use-invalid-blood = { CAPITALIZE(THE($filler)) } does not contain the blood required by { THE($target) }.
+
+bloodfiller-refill-filler-full = { CAPITALIZE(THE($filler)) } is already full.
+bloodfiller-refill-tank-empty = { CAPITALIZE(THE($tank)) } is empty.
+bloodfiller-refill-reagent-invalid = { CAPITALIZE(THE($tank)) } does not contain the correct reagent.
+bloodfiller-reagent-dirty = { CAPITALIZE(THE($volume)) } contains a dirty mixture.
+
+bloodfiller-user-overfill = You begin overpressurizing { THE($target) }...
+bloodfiller-target-overfill = You feel like your veins are bursting at the seams...
diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
index 37cc523db6..ba40e66a87 100644
--- a/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
+++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
@@ -49,3 +49,49 @@
- reagents:
- ReagentId: CellularDivider
Quantity: 100
+
+- type: entity
+ abstract: true
+ parent: BaseItem
+ id: BloodFillerBase
+ components:
+ - type: Sprite
+ sprite: Objects/Specific/Medical/hypospray.rsi
+ state: hypo
+ - type: Item
+ sprite: Objects/Specific/Medical/hypospray.rsi
+ - type: BloodstreamFiller
+ solution: filler
+ overfillDamage:
+ groups:
+ Brute: 18
+ - type: UseDelay
+ delay: 2
+ - type: SolutionContainerManager
+ solutions:
+ filler:
+ maxVol: 250
+ # - type: RefillableSolution
+ # solution: filler
+ - type: ExaminableSolution
+ solution: filler
+
+- type: entity
+ parent: BloodFillerBase
+ id: BloodFillerBlood
+ name: bloodfiller
+ description: A pump to inject blood into your body.
+ components:
+ - type: BloodstreamFiller
+ reagent: Blood
+ amount: 100
+
+- type: entity
+ parent: BloodFillerBase
+ id: BloodFillerSilicon
+ name: IPC coolant injector
+ description: A pump to inject coolant into an IPC.
+ components:
+ - type: BloodstreamFiller
+ reagent: Water
+ amount: 200
diff --git a/Resources/Prototypes/SimpleStation14/Entities/Structures/Storage/Tanks/tanks.yml b/Resources/Prototypes/SimpleStation14/Entities/Structures/Storage/Tanks/tanks.yml
new file mode 100644
index 0000000000..7a808cf49a
--- /dev/null
+++ b/Resources/Prototypes/SimpleStation14/Entities/Structures/Storage/Tanks/tanks.yml
@@ -0,0 +1,55 @@
+- type: entity
+ abstract: true
+ id: BloodTankBase
+ parent: StorageTank
+ suffix: Empty
+ components:
+ - type: DynamicPrice
+ price: 2000
+ - type: Sprite
+ sprite: SimpleStation14/Structures/Storage/tanks.rsi
+ state: bloodtankblood
+ - type: ExaminableSolution
+ solution: tank
+
+- type: entity
+ id: BloodTankBlood
+ parent: BloodTankBase
+ suffix: Empty
+ components:
+ - type: Sprite
+ state: bloodtankblood
+
+- type: entity
+ parent: BloodTankBlood
+ id: BloodTankBloodFull
+ suffix: Full
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Blood
+ Quantity: 1500
+
+- type: entity
+ id: BloodTankSlime
+ parent: BloodTankBase
+ suffix: Empty
+ components:
+ - type: DynamicPrice
+ price: 2500
+ - type: Sprite
+ state: bloodtankslime
+
+- type: entity
+ parent: BloodTankSlime
+ id: BloodTankSlimeFull
+ suffix: Full
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Slime
+ Quantity: 1500
diff --git a/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankblood.png b/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankblood.png
new file mode 100644
index 0000000000000000000000000000000000000000..0745546669a81fc4a611a2e8fe3b0203d4aec997
GIT binary patch
literal 3863
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
Ze*
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
mDIQvPXGgpCZ(Oz4qWce#O#zT+Y4Ifh0000
Date: Wed, 14 Jun 2023 07:24:37 -0400
Subject: [PATCH 4/7] Simple Silicon stuff
---
.../BloodstreamFiller/Systems/BloodstreamFillerSystem.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
index 920a35d070..a42a94112d 100644
--- a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
@@ -63,7 +63,7 @@ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, Bloodst
{
// if (fillComp.SiliconOnly && !HasComp(target)) // To be turned on once Silicons are merged :)
// {
- // // Do failure stuff
+ // _popup.PopupCursor(Loc.GetString(fillComp.TargetInvalidPopup, ("filler", filler)), user);
// return;
// }
@@ -143,14 +143,14 @@ private void OnDoAfter(EntityUid uid, BloodstreamComponent component, Bloodstrea
if (!TryComp(args.Args.Used, out var fillComp))
{
DebugTools.Assert("Filler component not found");
- Logger.ErrorS("silicon", $"Filler component not found on entity {ToPrettyString(args.Args.Used.Value)}");
+ Logger.ErrorS("bloodfiller", $"Filler component not found on entity {ToPrettyString(args.Args.Used.Value)}");
return;
}
if (!EntityManager.TryGetComponent(args.Args.Target, out var bloodComp))
{
DebugTools.Assert("Bloodstream component not found");
- Logger.ErrorS("silicon", $"Bloodstream component not found on entity {ToPrettyString(args.Args.Target.Value)}");
+ Logger.ErrorS("bloodfiller", $"Bloodstream component not found on entity {ToPrettyString(args.Args.Target.Value)}");
return;
}
From e070cc1e75da9619328acfb92c6a8009b274cec0 Mon Sep 17 00:00:00 2001
From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com>
Date: Sun, 18 Jun 2023 19:19:15 -0400
Subject: [PATCH 5/7] Review suggestions
---
.../Components/BloodstreamFillerComponent.cs | 10 +++----
.../Systems/BloodstreamFillerSystem.cs | 28 ++++++-------------
.../Silicon/BloodstreamFillerEvents.cs | 1 +
3 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
index 97d8b02849..0745594816 100644
--- a/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
@@ -20,10 +20,10 @@ public sealed class BloodstreamFillerComponent : Component
public float SelfFillMutli = 3.5f;
///
- /// The name of the volume to refill.
+ /// The name of the volume to refill.
///
///
- /// Should match the name or otherwise.
+ /// Should match the name or otherwise.
///
[DataField("solution"), ViewVariables(VVAccess.ReadWrite)]
public string Solution { get; } = "filler";
@@ -64,8 +64,8 @@ public sealed class BloodstreamFillerComponent : Component
///
/// The multiplier for the DoAfter time when attempting to overfill someone.
///
- [DataField("overfillMutli"), ViewVariables(VVAccess.ReadWrite)]
- public float OverfillMutli = 5.5f;
+ [DataField("overfillMulti"), ViewVariables(VVAccess.ReadWrite)]
+ public float OverfillMulti = 5.5f;
///
/// The amount of damage dealt when overfilling someone.
@@ -163,5 +163,5 @@ public sealed class BloodstreamFillerComponent : Component
///
[DataField("overfilledPopup")]
public string OverfilledPopup = "bloodfiller-target-overfill";
- #endregion
+ #endregion Player Feedback
}
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
index a42a94112d..cc9bd18852 100644
--- a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
@@ -106,7 +106,7 @@ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, Bloodst
if (fillComp.Overfill && bloodComp.BloodSolution.AvailableVolume == 0 && user != target)
{
overfill = true;
- delay *= fillComp.OverfillMutli;
+ delay *= fillComp.OverfillMulti;
}
_doAfter.TryStartDoAfter(new DoAfterArgs(user, delay, new BloodstreamFillerDoAfterEvent(overfill), target, target, filler)
@@ -132,12 +132,10 @@ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, Bloodst
private void OnDoAfter(EntityUid uid, BloodstreamComponent component, BloodstreamFillerDoAfterEvent args)
{
- if (args.Cancelled)
- {
+ if (args.Handled || args.Cancelled)
return;
- }
- if (args.Handled || args.Args.Target == null)
+ if (args.Args.Target == null)
return;
if (!TryComp(args.Args.Used, out var fillComp))
@@ -182,10 +180,8 @@ private void Fill(EntityUid target, EntityUid filler, BloodstreamFillerComponent
private void Overfill(EntityUid user, EntityUid target, EntityUid filler, BloodstreamFillerComponent fillComp, BloodstreamComponent bloodComp)
{
- if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
- return;
-
- if (!TryComp(target, out var damageableComp))
+ if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution) ||
+ !TryComp(target, out var damageableComp))
return;
_damageable.TryChangeDamage(target, fillComp.OverfillDamage, origin: user, damageable: damageableComp);
@@ -197,13 +193,9 @@ private void Overfill(EntityUid user, EntityUid target, EntityUid filler, Bloods
private void TryRefill(EntityUid user, EntityUid filler, EntityUid target, BloodstreamFillerComponent fillComp)
{
- if (!EntityManager.TryGetComponent(target, out _))
- return;
-
- if (!_solution.TryGetDrainableSolution(target, out var targetSolution))
- return;
-
- if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
+ if (!EntityManager.TryGetComponent(target, out _) ||
+ !_solution.TryGetDrainableSolution(target, out var targetSolution) ||
+ !_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution))
return;
// Check that the tank is not empty.
@@ -252,12 +244,8 @@ private void TryRefill(EntityUid user, EntityUid filler, EntityUid target, Blood
_audio.PlayPvs(fillComp.UseSound, filler);
}
else if (fillerSolution.AvailableVolume <= 0)
- {
_popup.PopupCursor(Loc.GetString(fillComp.RefillFullPopup, ("filler", filler)), user);
- }
else
- {
_popup.PopupCursor(Loc.GetString(fillComp.RefillTankEmptyPopup, ("tank", target)), user);
- }
}
}
diff --git a/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs b/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
index 9dce1045c7..8ed999bdaf 100644
--- a/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
+++ b/Content.Shared/SimpleStation14/Silicon/BloodstreamFillerEvents.cs
@@ -11,6 +11,7 @@ public sealed class BloodstreamFillerDoAfterEvent : DoAfterEvent
private BloodstreamFillerDoAfterEvent()
{
+
}
public BloodstreamFillerDoAfterEvent(bool overfill)
{
From d6f27be5fe8faab2bfa30035fbdadfaf034c0471 Mon Sep 17 00:00:00 2001
From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com>
Date: Mon, 19 Jun 2023 07:36:03 -0400
Subject: [PATCH 6/7] Allowed reagents is now a list
---
.../Components/BloodstreamFillerComponent.cs | 4 +--
.../Systems/BloodstreamFillerSystem.cs | 4 +--
.../Objects/Specific/Medical/hypospray.yml | 26 +++++++++++++++----
3 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
index 0745594816..d435331d32 100644
--- a/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Components/BloodstreamFillerComponent.cs
@@ -40,8 +40,8 @@ public sealed class BloodstreamFillerComponent : Component
///
/// If null, any reagent will be allowed.
///
- [DataField("reagent"), ViewVariables(VVAccess.ReadWrite)]
- public string? Reagent = null;
+ [DataField("reagents"), ViewVariables(VVAccess.ReadWrite)]
+ public List Reagents = new();
///
/// Will this filler only fill Silicons?
diff --git a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
index cc9bd18852..5045f65e9c 100644
--- a/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
+++ b/Content.Server/SimpleStation14/BloodstreamFiller/Systems/BloodstreamFillerSystem.cs
@@ -72,7 +72,7 @@ private void TryFill(EntityUid user, EntityUid target, EntityUid filler, Bloodst
if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution)) // No solution
return;
- if (fillComp.Reagent != null && fillComp.Reagent != bloodComp.BloodReagent) // Wrong reagent as specified by the component
+ if (fillComp.Reagents.Count > 0 && !fillComp.Reagents.Contains(bloodComp.BloodReagent)) // Wrong reagent as specified by the component
{
_popup.PopupCursor(Loc.GetString(fillComp.TargetInvalidPopup, ("filler", filler)), user);
return;
@@ -214,7 +214,7 @@ private void TryRefill(EntityUid user, EntityUid filler, EntityUid target, Blood
// Check that the tank's solution matches the filler's listed reagent.
// This is seperate from checking the actual solution to prevent any funny business.
- if (fillComp.Reagent != null && targetSolution.Contents[0].ReagentId != fillComp.Reagent)
+ if (fillComp.Reagents.Count > 0 && !fillComp.Reagents.Contains(targetSolution.Contents[0].ReagentId))
{
_popup.PopupCursor(Loc.GetString(fillComp.RefillReagentInvalidPopup, ("tank", target)), user);
return;
diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
index ba40e66a87..2fe77c73a9 100644
--- a/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
+++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Specific/Medical/hypospray.yml
@@ -80,11 +80,21 @@
parent: BloodFillerBase
id: BloodFillerBlood
name: bloodfiller
- description: A pump to inject blood into your body.
+ description: A pump to inject blood into your body. Also accepts Slime.
components:
+ - type: UseDelay
+ delay: 6
- type: BloodstreamFiller
- reagent: Blood
- amount: 100
+ amount: 60
+ fillTime: 1.3
+ reagents:
+ - Blood
+ - Slime
+ - Water
+ - type: SolutionContainerManager
+ solutions:
+ filler:
+ maxVol: 120
- type: entity
parent: BloodFillerBase
@@ -93,5 +103,11 @@
description: A pump to inject coolant into an IPC.
components:
- type: BloodstreamFiller
- reagent: Water
- amount: 200
+ reagents: [ Water ]
+ amount: 150
+ fillTime: 0.85
+ siliconOnly: true
+ - type: SolutionContainerManager
+ solutions:
+ filler:
+ maxVol: 250
From f1b3725eba8b3becb30f99eec6d4760c1049f163 Mon Sep 17 00:00:00 2001
From: Cabbage <130223709+SomeCabbage@users.noreply.github.com>
Date: Fri, 30 Jun 2023 02:25:45 -0400
Subject: [PATCH 7/7] blood filler cargo orders (#173)
# Description
Adds the slime tank and blood tank orders to cargo for 2.5k each
---
.../Catalog/Cargo/cargo_medical.yml | 23 +++++++++++++++++++
.../Catalog/Fills/Crates/medical.yml | 21 +++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 Resources/Prototypes/SimpleStation14/Catalog/Cargo/cargo_medical.yml
create mode 100644 Resources/Prototypes/SimpleStation14/Catalog/Fills/Crates/medical.yml
diff --git a/Resources/Prototypes/SimpleStation14/Catalog/Cargo/cargo_medical.yml b/Resources/Prototypes/SimpleStation14/Catalog/Cargo/cargo_medical.yml
new file mode 100644
index 0000000000..b2bec36ff7
--- /dev/null
+++ b/Resources/Prototypes/SimpleStation14/Catalog/Cargo/cargo_medical.yml
@@ -0,0 +1,23 @@
+- type: cargoProduct
+ id: MedicalBloodTank
+ name: Blood tank crate
+ description: "Contains a tank of blood."
+ icon:
+ sprite: SimpleStation14/Structures/Storage/tanks.rsi
+ state: bloodtankblood
+ product: CrateMedicalBloodTank
+ cost: 2500
+ category: Medical
+ group: market
+
+- type: cargoProduct
+ id: MedicalSlimeTank
+ name: slime tank crate
+ description: "Contains a tank of slime."
+ icon:
+ sprite: SimpleStation14/Structures/Storage/tanks.rsi
+ state: bloodtankblood
+ product: CrateMedicalSlimeTank
+ cost: 2500
+ category: Medical
+ group: market
diff --git a/Resources/Prototypes/SimpleStation14/Catalog/Fills/Crates/medical.yml b/Resources/Prototypes/SimpleStation14/Catalog/Fills/Crates/medical.yml
new file mode 100644
index 0000000000..d77447d901
--- /dev/null
+++ b/Resources/Prototypes/SimpleStation14/Catalog/Fills/Crates/medical.yml
@@ -0,0 +1,21 @@
+- type: entity
+ id: CrateMedicalBloodTank
+ name: blood tank crate
+ description: "Contains a tank of blood."
+ parent: CrateMedicalSecure
+ components:
+ - type: StorageFill
+ contents:
+ - id: BloodTankBloodFull
+ amount: 1
+
+- type: entity
+ id: CrateMedicalSlimeTank
+ name: slime tank crate
+ description: "Contains a tank of slime."
+ parent: CrateMedicalSecure
+ components:
+ - type: StorageFill
+ contents:
+ - id: BloodTankSlimeFull
+ amount: 1