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< wB{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!VnsF8&#j$?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