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 +{ + /// <summary> + /// The name of the volume to refill. + /// </summary> + /// <remarks> + /// Should match the <see cref="SolutionContainerComponent"/> name or otherwise. + /// </remarks> + [DataField("solution"), ViewVariables(VVAccess.ReadWrite)] + public string Solution { get; } = "filler"; + + /// <summary> + /// The amount of reagent that this silicon filler will fill with at most. + /// </summary> + [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<BloodstreamFillerComponent, AfterInteractEvent>(OnUseInWorld); + SubscribeLocalEvent<BloodstreamFillerComponent, UseInHandEvent>(OnUseInHand); + + SubscribeLocalEvent<BloodstreamFillerComponent, DoAfterEvent>(OnDoAfter); + } + + private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args) + { + if (!args.CanReach || args.Target == null) + return; + + if (!EntityManager.TryGetComponent<BloodstreamComponent>(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<BloodstreamComponent>(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<BloodstreamComponent>(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<BloodstreamComponent>(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<ReagentTankComponent>(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{^r<?wJ*ya4emiM?y zi2dBeb-P&m%!)lf&y8uuX*{yc#pR4o-!vF0Ed00MT-ADkK)`v{9s^Af<1CP&YrTNi vBSXb!?MgcqQDK9v&+g_o8VNR7LXiKWP#FP^gth;G{$}uW^>bP0l+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`S<B7%ZUQ8K{(8Z z3cuK6_h>h>yqoU<eZJu3HSYNh&x(KK9WUqUH%MZdb?%|HZ*_R$6W<M0eD@Py-Ov6K ooN&x(`Mu~r5-t$;s>>&^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<<gz?a+6)#=eBvqIO@^Glbz+<a+Py&`{xFe6U1SSaB3 z=D#=N>{nPXkgt38pjBdOLtM$-)fHPFf306Teb3*%P0Y8-ek_g+SpRj?A^SOnocne+ z)(WNB&rLixi>bQXa_JAhV+zk)7zm@7*aIbH4w4fB{@;(DBpbjn;~Z<x1}*Ca0tU0W zB@!dc9Hb^VC?~$0_sToqBBS^BJ-<X|s4*F+gVA%&>p6-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<x^D{r diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/2-inhand-right.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/2-inhand-right.png index c55b8d6fd657be61855017749620e8cdac9d6df8..afd31cbeb483b80eb36c20390bee82f4257ad198 100644 GIT binary patch delta 278 zcmX@Wbc|_&W&ICN7srr_Id5+{@*PqTalLr^i0sb)syo!Cw5j!GYO?JUyl*Y+zO3Ny z*5)GTIm`;@7zLg)bQCijv1E88!%)cAV8QMH6kez5pf#U+@{Z+G<WBFpbJ{eX)x&2+ zj@{|k>)lqcRZLy7^-2H9*SWtwW-)$}IJ@oR-rToWH7&RcEUoH=Z!UXSV4u$TFZJ{6 zesza7oK_%gc6k1MxwZ9&yelj<k5jWwm{u{b$&V|4&T(i;Hc!7n64SIzKTl|KSg$tt z<iFvU+&<?QZ%uz`3T(V^q55>cBh=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&<x=5u-W`+Rde2;}#DEipF#W38 zX21Gta}K*r_4BK@GWK1nm|q&OQ0T(34_BY<zjm5O<9vhJ?ESmAf2Hqzch$d4rYX5& zv(T#f=Mu~AGNrfQH2R}(UE!Gv17UP0*1^(x0guOu|L=8A@@cS~aOQ0ey~)_xkfry4 z<MbxxOARbioZi{1_#Kb(MMQmmx7}eT$ALKzWM20|TUd9E)dHZ;89ZJ6T-G@yGywon CFLt>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!<Tms(;GzlXRGdJmSyt##<cIFkX`Bm zXNNNV2jYveQkPXbE^>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<F7srr_Id5+{@--QVusu}#=yvZv$GnwZM_9zC%(~<{_y6r3O5b`# z#h$jsFeyxDIHAf=#Myw#ye_mLXFm7mjJVH{4MqB`$Biz($-lkpy1><=;mmK^=C3`l ziSPcW$5)xATtB**ci;A$!{Oxz0~;={HJ(_?)pxkEkLl0p5AyaC52%K}*i(0`oPA%( z`-W@9Ke%~*_T6JR`~1URx7K}+<Svx(-Os$Sn=AYt%j)MJWZVAjU027|6Y=80|1h~` eh_mL{9T1*+N#}6})3b97K;Y@>=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`<fO1U;M=(W7qzENp*|d`v&LdA9~wjcR%+o_%5^W;DzI>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)<lL0~W{3X+}&CFVi+H&UJo0z#6KLs3K zpk=*4z+g7_4yVX62dN1T$_uwFtK!fqbI3fq{65oV7lvmLRKxh~o5`c7e_<bh0l?tt L>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(<y45aat* zzqVYnzui)>^=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!<aDC|fsPE2yp<QY^8+~O?Xges~`+c_ek9!9D z4~IF-3g;LFo-=e5GaRvGcqGG6$k$-O4ia9c>QHm+grHM`@bjw2ALH^$&u(S-{^5<v z+V4^2ON16mJV^ermut>z-^1JgR4ipET%P;ibw`{2yQY|iSM}F!ddyO`_SZYGpQrxy zJw_uWV{zDaj?vBTPBH)g)on~)?i}{t@Wk4!-{G_EpB14C(`}e%y?e;6`+NPNGwlf< w<?0SxdTjbzcSF)b@AK2*o1rd$!n}uJf3kVw5wmu79tI%rboFyt=akR{09OHfPyhe` delta 249 zcmX@ibdYI+W&LMQ7srr_Id5-z^Bq!<aDC|fsPE2yp<QY^8+~O?Xges~`+YX_pYj%F zxsGCnBbE%0WEcwh8Z6iy<}fRqV-$GK021EH(s5qG(upJIQB1zgz0+&g?G$?;H*fBe zuW_&YLX<?9Yk2mDHx}>B{4vdby@<lQEpPX8T>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$s<iGfvg!lV)IG@bq+X45^s&_ToWK1_KTj$JU5G`QPgg zP7}&e<m}k++g@Ua>RCphIw1JWICJM&pF6S941x<=cigStxj<lT!*qxo0|UF&b54n? SpE|yR1Uy~+T-G@yGywolVkk8L delta 102 zcmV-s0Ga=n0fPaMBwtENL_t(|obAv%3cxT71W_xe^jXJ;TX!K{R2TwbUZZC9L1Rdg zB&i8VlANAf-QaV1Rki!xT;1SW>#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$s<iGfvg!lV)IGi1BoB45^s&_ToX#0|p!pfy}W-S?|=d ziC>7lG(#{cQ}a*##}~r-KP`Ytf#AXahMlV{!`3q^C3$U5ZrJ_)=}gU4RVB6D32BQ3 mOqT|}X1)6~_kb`XM78;^<HBo#nh&soxSs5;elF{r5}E+(Q8M2E delta 102 zcmV-s0Ga=)0fPaMBwtENL_t(|obAv%3cxT71W_xe^jXJ;TX!K{R2TwbUZZC9L1Rdg zB&i8VlANAf-QaV1Rki!xT;1SW>#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<iGfvg!lV)IGNb_`Y45^s&_WVI!21O2+K(m`+84drk z7cjnPVv4a{!`g6h#+m&EbB=qrGXqrvLBnsxwdU_G-{v#e>~{20L;an*oil^)FK1k3 yWxu{>Ipg9E1wqZ;<&4^G-VIY3!8!_LJ}|QX5ff~6cS$q=iFmsDxvX<aXaWE+fi@oi delta 102 zcmV-s0Ga=^0fPaMBwtENL_t(|obAxD4ZtuA13`_+S${dYGN3FVAqKB;`IM_7A|m3C z0NeIz{926z24+Uwcz*#)ni<e9moyu%`u@OpypLFmM?^g904~FAlk(<HX8-^I07*qo IM6N<$f{|D%)&Kwi diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe4.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe4.png index d8b7e8a701b086365b192639d62dc4ce25b167f9..d6c2e08ff197a4172f1c484b0f6f3d9141e1b89f 100644 GIT binary patch delta 167 zcmbQqc$jg5N<C+RM`SSr1K$x4W}K?cC(XdXQ0nR87*a9k?UjwZ2NZZ*0^Lt(#Wnm* zPhi~K%B~O~v2<&%km6m_DgSpqTsEH_s2&8KGyl3#vwq`wMx{%dI}HvzT5Fp0?84VX zhqa}#^E%rZ#KJ?hmM(deci{IY*+TOKH}$0OJG=%g3b}WF$_s+@JCyOO`YN^BDBfNO O;(EIJxvX<aXaWE|v_3=t delta 124 zcmV-?0E7R-0hs}iBz0g(L_t(|obA-X4Zt7_13;_0We3li441yBP@Y9iq{{b!pB)4M zA|fJ(+&xL=SoqRjVh=wlalH*UGeiUcAR?aq=j!Anv+W+#aCh$y-`Ca`Fm~+A*yOdu e=*J@>@=G^IccH;N_qR*{0000<MNUMnLSTYgp*Pb2 diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base0.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base0.png index 9cf92274d4b7ad8e567d67704611d6289cfab32f..55e8e6081d30b269ca376a88720dbc63c26122f3 100644 GIT binary patch delta 237 zcmV<J022Sp0*C^TBYyx1a7bBm000ie000ie0hKEb8vp<Rx=BPqRCt{2)IkcuFc3!J z1bUi+P(k!aJwtZ|PvI(O$T5^c3x!^%`h$U4xR@~$12VH|HsyUKX&P5~3}65Q{5POG zT=r$X`zioVycmERF9MLnRRIX&DT%89Quugk-8^mL_p<<qBW8?2T>AA{0K~`Z(8m~W zE@Qp|(0B;JOAlTaKr=1|XvbNA6nV!VnsF8&#j$?H&zf--fFkg#X~tOqdc$eQSpd2P nB@pZ___Y2RpyU|900wvhTS16;M&o~w00000NkvXXu0mjf<7!?Z delta 305 zcmV-10nYx20?PuBBYy!BNkl<Zc%1E(KMKMy7{#B(V@S~x)S*&vaFmW&3T`evfw+si z)YZWoxHt;k3RM)B;sKQ6Is6=KOVEndnpCh4LXsuF_x(u%l=^p7L<2O#q<9@{SHgKu z;c0sSP~_Q3S2gbeKbvA^+2r~g(hM^h(hTtMS7&^^2Q<T^PJdg+a4^nPlH4`pqwMz> zy!9T(@SM3Ha%Z5S)&Kw#X9RD(N2jeP#)Q<J7qe`_EsGV+Fv*$D9-zWZ+{5GfT>~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 zcmV<N01p4l0*nHXBYyx1a7bBm000ie000ie0hKEb8vp<RzDYzuRCt{2)X@opKn#Fk z3r<rgSdexkXYj4y6h7SyH-;i82wmrDz(9~bBwkKIav<u1{9imY&rV(jFn|HB4JaP( zFwNcV6aXil48V;i0Z8Ji00_fb5?29W_*vewarla#j{<C7cWRJM9|eFoOuZbzIVTQB z0U-Wq>dJfH;{BfKcL8V|CXb1W0orjE03&O>*Nn3O7>Da6{?d%I02Be=xn`UNpno{+ rI150xAO(WG1^=!O1EgFAFn|Gmu9=2%o}rGS00000NkvXXu0mjfrxsp4 delta 305 zcmV-10nYx60?PuBBYy!BNkl<Zc%1E&zY2m-7{yQGV}#ff*iZ-!jpFDcw6*vI(H`xg zYeR3)(ipf2Dn(25073K~UqfE8QnKt`0zDvCLGJH-e}P7ISBp15(@kRU$K94YuMnR1 z4FHljJNc5UUhuamwrq#|FeXhm(?^(rEd1RaKkoreH)%NNVShTAmnuo+nq{LLk1Pby z0q4uLbU#$iKu2i<02b~HL3F@y&`XVRse4wI?GWxkNSbbv>n&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<U00;ll0+RxeBYyx1a7bBm000ie000ie0hKEb8vp<R#Ysd#RCt{2)=>(BFbsg< z3Z6y~CJa2%&agMZQ~1;~^cVxd!C=>^=AjV!U=xxeND9L#jQ`U(v2_<O0~o*n_Xa%r zF@Ara<`MuUUJXEvR{?P1ssISXmJ?S2r10?U+_wJNzZU_r%W)mKXD<S9XRQjz;}Q%T z05O>N@rmC1MtUV!0EkWV`xQc1(!O*IML>$+xW<{20VxjOwc{iJM!^4EGfoEJF=)n% yfc)`V191w#^T)@W;v(IIuHw4)E13ZdKv_GmcY<=JLlVXS0000<MNUMnLSTX)NorUC delta 312 zcmV-80muH60@4DIBYy!INkl<Zc${Nk7zHC8Fw)ureRGfhF!sfhJ7{hnPRp_J85kHC znCRym?0|(*0|spn2ZW~l-+lD>e|>WgIHsEekS!-<2G!GmzPZPLJ1Y~0lA=bUqJ-i& zL-u8SL;%B~V`mudKYBuRdZ0K26y;<X7#J8Bdiv@a4jntgV1H+20(Tfq;vE?Tgr@vw zfOvvQ-`wMWU;hjYOKIi^bjx8hsSY433Iak?{%=@4hZ$<Y--{=AFq2~rSpb{Qk=P7S zN6{wl2ZW~l@9Uod4{oUCEHqDS=#IeUbDCO;&c~MGX$A~T-7qYoYq0M=di*~&M^FP0 zRUKbGb&)|qK{1Yjfx+#+f`S~whShWESMAa@s7EaywR{weNB{s96OGa;4pdeE0000< KMNUMnLSTZhy@aFy diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base3.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base3.png index 35e22c64542f76398d4c4148f9e54714b041cfa3..9a560e6d30da52962ae2b6a27ed564bb9a556a4a 100644 GIT binary patch delta 238 zcmV<K01^Mn0*L~UBYyx1a7bBm000ie000ie0hKEb8vp<RyGcYrRCt{2)Ikb^Fc5{| z2t7?fP!M{aoGj-N1O=hjNqvie1e6)_5}`~sW+VR>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!ANkl<Zc${Nk7zHC8Fw)ureRGfhF!sfhJ7{hnPRp_J85kHC znCRym?0|(*0|spn2ZW~l-+lD>e|>WgIHsEekS!-<2G!GmzPZPLJ1Y~0lA=bUqJ-i& zL-u8SL;%B~V`mudKYBuRdZ0K26y;<X7#J8Bdiv@a4jntgV1H+20(Tfq;vE?Tgr@vw zfP^BWzPZQ$zWx~)mJ)IV*&z@Rn(`mXxBo7l+`+VP#RihiA-f#duzC(70|Uc<nC0Y} zLvbR6g~Y-Y8{i3#?u8T06Wf3TXlkbkAS&@Zc<_i;_7ewoA3grxz|@T<p+HnNynN~+ zgMxw_0|SHGe<=k8Ian5?4;auCK5F^MvwRecNB{s@vwBhYHW6_E0000<MNUMnLSTYc CAc3X; diff --git a/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base4.png b/Resources/Textures/Objects/Specific/Chemistry/syringe.rsi/syringe_base4.png index 834ae95f9f67cc4e4216a6bbb38dab01db3a127d..cce9207cc181ce87a92566829116062536d038f3 100644 GIT binary patch delta 226 zcmV<803H9F0{#JzB!3BTNLh0L01m_e01m_fl`9S#00026Nkl<Zc%1Fk;Rb*(6o%nN zR})c0m%HnUD5Be0Ee@HLbK19!Y-GRkKHJJ_m3b6E0TjT$0bM(qb(^Xz08Ts_fE$kj zki?+?8@96~4gpZO9~!mHyZHSefV163y80l1^sJ!(Hy(l!16z=BF#sKB0Von9&H_-} z{$}T6wAK|W&H@nPoGt`1&Ia6~&^QZlU$O67hzjt<lI+0Oiv<RttyT%f;}N7-{VO2V cD1hvM0~hUoDGtb=761SM07*qoM6N<$f+9&=?EnA( delta 256 zcmV+b0ssE~0h|JmB!A;cL_t(|oMT`Z1tT3W(%J%jbC3Tp_QjJsXl@@)%dznp7#J9s z=;s{lfQ3>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<MNUMn GLSTZxEOOQW From 7c849b297bf795c3889316235408f78eefcb0a8f Mon Sep 17 00:00:00 2001 From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com> 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 +{ + /// <summary> + /// The duration of the fill DoAfter, in seconds. + /// </summary> + [DataField("fillTime"), ViewVariables(VVAccess.ReadWrite)] + public float FillTime = 1.0f; + + /// <summary> + /// The multiplier for the DoAfter time when attempting to fill yourself. + /// </summary> + [DataField("selfFillMutli"), ViewVariables(VVAccess.ReadWrite)] + public float SelfFillMutli = 3.5f; + + /// <summary> + /// The name of the volume to refill. + /// </summary> + /// <remarks> + /// Should match the <see cref="SolutionContainerComponent"/> name or otherwise. + /// </remarks> + [DataField("solution"), ViewVariables(VVAccess.ReadWrite)] + public string Solution { get; } = "filler"; + + /// <summary> + /// The amount of reagent that this bloodstream filler will fill with at most. + /// </summary> + [DataField("amount"), ViewVariables(VVAccess.ReadWrite)] + public float Amount = 100.0f; + + /// <summary> + /// The regent allowed to be used by this filler. + /// </summary> + /// <remarks> + /// If null, any reagent will be allowed. + /// </remarks> + [DataField("reagent"), ViewVariables(VVAccess.ReadWrite)] + public string? Reagent = null; + + /// <summary> + /// Will this filler only fill Silicons? + /// </summary> + /// <remarks> + /// Somewhat niche use case, but Bloodstreams are very inflexible. + /// </remarks> + [DataField("siliconOnly"), ViewVariables(VVAccess.ReadWrite)] + public bool SiliconOnly = true; + + /// <summary> + /// Can this bloodfiller be used to overfill someone? + /// </summary> + /// <remarks> + /// If true, the bloodfiller will be able to fill someone already at max blood, causing damage and spilling blood. + /// </remarks> + [DataField("overfill"), ViewVariables(VVAccess.ReadWrite)] + public bool Overfill = true; + + /// <summary> + /// The multiplier for the DoAfter time when attempting to overfill someone. + /// </summary> + [DataField("overfillMutli"), ViewVariables(VVAccess.ReadWrite)] + public float OverfillMutli = 5.5f; + + /// <summary> + /// The amount of damage dealt when overfilling someone. + /// </summary> + /// <remarks> + /// This must be specified in YAML. + /// </remarks> + [DataField("overfillDamage"), ViewVariables(VVAccess.ReadWrite)] + public DamageSpecifier OverfillDamage = default!; + + #region Player Feedback + /// <summary> + /// The sound played when the filler is used. + /// </summary> + [DataField("useSound")] + public SoundSpecifier UseSound = new SoundPathSpecifier("/Audio/Effects/bang.ogg"); + + /// <summary> + /// The sound played when the filler refills. + /// </summary> + [DataField("refillSound")] + public SoundSpecifier RefillSound = new SoundPathSpecifier("/Audio/Effects/buckle.ogg"); + + /// <summary> + /// The sound played when overfilling someone. + /// </summary> + [DataField("overfillSound")] + public SoundSpecifier OverfillSound = new SoundPathSpecifier("/Audio/Effects/demon_dies.ogg"); + + /// <summary> + /// The popup text when the filler is used. + /// </summary> + [DataField("usePopup")] + public string UsePopup = "bloodfiller-use-user"; + + /// <summary> + /// The popup text when the filler is used on you. + /// </summary> + [DataField("usedOnPopup")] + public string UsedOnPopup = "bloodfiller-use-target"; + + /// <summary> + /// The popup text when the bloodfiller is empty. + /// </summary> + [DataField("emptyPopup")] + public string EmptyPopup = "bloodfiller-use-empty"; + + /// <summary> + /// The popup text when the bloodfiller can't be used on the target. + /// </summary> + /// <remarks> + /// Due to <see cref="SiliconOnly"/> or otherwise. + /// </remarks> + [DataField("targetInvalidPopup")] + public string TargetInvalidPopup = "bloodfiller-use-invalid-target"; + + /// <summary> + /// The popup text when the bloodfiller doesn't have the target's blood. + /// </summary> + [DataField("targetBloodInvalidPopup")] + public string TargetBloodInvalidPopup = "bloodfiller-use-invalid-blood"; + + /// <summary> + /// The popup text when the filler is already full. + /// </summary> + [DataField("refillFullPopup")] + public string RefillFullPopup = "bloodfiller-refill-filler-full"; + + /// <summary> + /// The popup text when the tank is empty. + /// </summary> + [DataField("refillTankEmptyPopup")] + public string RefillTankEmptyPopup = "bloodfiller-refill-tank-empty"; + + /// <summary> + /// The popup text when trying to refill the bloodfiller from a tank with the wrong reagent. + /// </summary> + [DataField("refillReagentInvalidPopup")] + public string RefillReagentInvalidPopup = "bloodfiller-refill-reagent-invalid"; + + /// <summary> + /// The popup text when either a tank or filler contains a dirty mixture. + /// </summary> + [DataField("dirtyPopup")] + public string DirtyPopup = "bloodfiller-reagent-dirty"; + + /// <summary> + /// The popup text when trying to overfill someone. + /// </summary> + [DataField("targetOverfillPopup")] + public string TargetOverfillPopup = "bloodfiller-user-overfill"; + + /// <summary> + /// The popup text when getting overfilled. + /// </summary> + [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<BloodstreamFillerComponent, AfterInteractEvent>(OnUseInWorld); + SubscribeLocalEvent<BloodstreamFillerComponent, UseInHandEvent>(OnUseInHand); + + SubscribeLocalEvent<BloodstreamComponent, BloodstreamFillerDoAfterEvent>(OnDoAfter); + } + + private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args) + { + if (!args.CanReach || args.Target == null) + return; + + if (!EntityManager.TryGetComponent<BloodstreamComponent>(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<BloodstreamComponent>(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<SiliconComponent>(target)) // To be turned on once Silicons are merged :) + // { + // // Do failure stuff + // return; + // } + + var bloodComp = EntityManager.GetComponent<BloodstreamComponent>(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<BloodstreamFillerComponent>(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<BloodstreamComponent>(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<DamageableComponent>(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<ReagentTankComponent>(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 -{ - /// <summary> - /// The name of the volume to refill. - /// </summary> - /// <remarks> - /// Should match the <see cref="SolutionContainerComponent"/> name or otherwise. - /// </remarks> - [DataField("solution"), ViewVariables(VVAccess.ReadWrite)] - public string Solution { get; } = "filler"; - - /// <summary> - /// The amount of reagent that this silicon filler will fill with at most. - /// </summary> - [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<BloodstreamFillerComponent, AfterInteractEvent>(OnUseInWorld); - SubscribeLocalEvent<BloodstreamFillerComponent, UseInHandEvent>(OnUseInHand); - - SubscribeLocalEvent<BloodstreamFillerComponent, DoAfterEvent>(OnDoAfter); - } - - private void OnUseInWorld(EntityUid uid, BloodstreamFillerComponent component, AfterInteractEvent args) - { - if (!args.CanReach || args.Target == null) - return; - - if (!EntityManager.TryGetComponent<BloodstreamComponent>(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<BloodstreamComponent>(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<BloodstreamComponent>(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<BloodstreamComponent>(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<ReagentTankComponent>(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*<sc3iW6Af2RNd002ovPDHLkV1ft<YU}_2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankslime.png b/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/bloodtankslime.png new file mode 100644 index 0000000000000000000000000000000000000000..28da368552bd15d3bfcff104763937fba72db41c GIT binary patch literal 3980 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/meta.json new file mode 100644 index 0000000000..3dafefc256 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Storage/tanks.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Modified by Pspritechologist from tgstation at commit https://github.com/tgstation/tgstation/commit/8442af39ee82b813194f71db82edd2923d97818d", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "bloodtankblood" + }, + { + "name": "bloodtankslime" + } + ] +} From f2ed9fc18e0123cc6b630587ba29ab13cd8256cb Mon Sep 17 00:00:00 2001 From: Pspritechologist <81725545+Pspritechologist@users.noreply.github.com> 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<SiliconComponent>(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<BloodstreamFillerComponent>(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<BloodstreamComponent>(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; /// <summary> - /// The name of the volume to refill. + /// The name of the volume to refill. /// </summary> /// <remarks> - /// Should match the <see cref="SolutionContainerComponent"/> name or otherwise. + /// Should match the <see cref="SolutionContainerComponent"/> name or otherwise. /// </remarks> [DataField("solution"), ViewVariables(VVAccess.ReadWrite)] public string Solution { get; } = "filler"; @@ -64,8 +64,8 @@ public sealed class BloodstreamFillerComponent : Component /// <summary> /// The multiplier for the DoAfter time when attempting to overfill someone. /// </summary> - [DataField("overfillMutli"), ViewVariables(VVAccess.ReadWrite)] - public float OverfillMutli = 5.5f; + [DataField("overfillMulti"), ViewVariables(VVAccess.ReadWrite)] + public float OverfillMulti = 5.5f; /// <summary> /// The amount of damage dealt when overfilling someone. @@ -163,5 +163,5 @@ public sealed class BloodstreamFillerComponent : Component /// </summary> [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<BloodstreamFillerComponent>(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<DamageableComponent>(target, out var damageableComp)) + if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution) || + !TryComp<DamageableComponent>(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<ReagentTankComponent>(target, out _)) - return; - - if (!_solution.TryGetDrainableSolution(target, out var targetSolution)) - return; - - if (!_solution.TryGetSolution(filler, fillComp.Solution!, out var fillerSolution)) + if (!EntityManager.TryGetComponent<ReagentTankComponent>(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 /// <remarks> /// If null, any reagent will be allowed. /// </remarks> - [DataField("reagent"), ViewVariables(VVAccess.ReadWrite)] - public string? Reagent = null; + [DataField("reagents"), ViewVariables(VVAccess.ReadWrite)] + public List<string> Reagents = new(); /// <summary> /// 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