From 3957bbb97d7cd59ce32d9aff736ab52954b0c095 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Sat, 19 Apr 2025 01:34:59 +0200 Subject: [PATCH 01/16] Updated air scrubber and air vent sprites. (#34223) * vents * slower animation * formatting fix * scrubber --- .../Atmospherics/scrubber.rsi/meta.json | 163 ++++++++++++++---- .../Atmospherics/scrubber.rsi/scrub_off.png | Bin 1002 -> 1213 bytes .../Atmospherics/scrubber.rsi/scrub_on.png | Bin 20683 -> 6218 bytes .../Atmospherics/scrubber.rsi/scrub_purge.png | Bin 7441 -> 6204 bytes .../Atmospherics/scrubber.rsi/scrub_wide.png | Bin 10949 -> 6620 bytes .../Piping/Atmospherics/vent.rsi/meta.json | 136 +++++++++++---- .../Piping/Atmospherics/vent.rsi/vent_in.png | Bin 1595 -> 4224 bytes .../Atmospherics/vent.rsi/vent_lockout.png | Bin 1302 -> 1195 bytes .../Piping/Atmospherics/vent.rsi/vent_off.png | Bin 1117 -> 1221 bytes .../Piping/Atmospherics/vent.rsi/vent_out.png | Bin 2926 -> 4296 bytes .../Atmospherics/vent.rsi/vent_passive.png | Bin 2958 -> 853 bytes .../Atmospherics/vent.rsi/vent_welded.png | Bin 1958 -> 1845 bytes 12 files changed, 232 insertions(+), 67 deletions(-) diff --git a/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/meta.json index 191aa398a9..88eeace3d8 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/meta.json @@ -1,34 +1,133 @@ { - "version":1, - "size":{ - "x":32, - "y":32 - }, - "license":"CC-BY-SA-3.0", - "copyright":"Taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da", - "states":[ - { - "name":"scrub_off", - "directions": 4 - }, - { - "name":"scrub_welded", - "directions": 4 - }, - { - "name":"scrub_on", - "directions": 4, - "delays": [[0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08], [0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08], [0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08], [0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08]] - }, - { - "name": "scrub_purge", - "directions": 4, - "delays": [[0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04]] - }, - { - "name": "scrub_wide", - "directions": 4, - "delays": [[0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04], [0.2, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04]] - } - ] + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/32742/commits/44820f5b6e2c864a35bfad448e0a9437f01ad2e2", + "states": [ + { + "name": "scrub_off", + "directions": 4 + }, + { + "name": "scrub_welded", + "directions": 4 + }, + { + "name": "scrub_on", + "directions": 4, + "delays": [ + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ] + ] + }, + { + "name": "scrub_purge", + "directions": 4, + "delays": [ + [ + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06 + ], + [ + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06 + ], + [ + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06 + ], + [ + 0.06, + 0.06, + 0.06, + 0.06, + 0.06, + 0.06 + ] + ] + }, + { + "name": "scrub_wide", + "directions": 4, + "delays": [ + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ], + [ + 0.10, + 0.10, + 0.10, + 0.10, + 0.10, + 0.10 + ] + ] + } + ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_off.png b/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_off.png index efc173d893669b4ff418f61ae32ccd3d92ffd3fd..8f7e5e6782be6beba8daa6b5cb702bafd38ea77e 100644 GIT binary patch delta 1194 zcmV;b1XcU$2fYc9BYyx1a7bBm000ie000ie0hKEb8vpwoL(^}BF;d;89fgyZAm zAphm%WfFh1064$1vr`|p8L+Xj!P{aC5pe$S@UT9T_#rYwqFUVdeK2N`#oO z93+BuK9xT<5<3NG&OFL~+S_wK?(XW}*yQu|^wftU=a~u4$%q^gY}gOw?-L<-37{z9 z#S0Pu$!bxOGJZv)9U~XwaeuaCJU*q&eV=w~vGlPi)15mha6=t(EiAdw* zKoP)9Hh=l$ScqT3^&uDm2yk(JzH*LmBkV-3@Z%b_C=me&(8VuNbXhj}tq)xYCP7HF z*Z|y$m=R@RKmx*05|oT6br;Cxk4b=_SAc45@52crL@tugM@Qa3j&%#d2o^4l^?5dM zB!{1cQVco;s1^@?F#-w13~Iy7CLn+jES|J3$A6IAm0SpYY2%mTQHV-~hmSg$FJ&78-KHC(uJ)4fY|!{*!=lZV*8JxB3G@{Ru_-0~p|c><=i`CC2rhQ-7b2 zZBPh-D9{Qpm7o5G=3=RdV1Ixbq*LqjkeBEW$n8%Mf06zGb&ST==e2w-)gPdKgB1Q4 z=Rs6|fHRR`OViE%0EJyFc?_%w&2I57{_5^gu0OzvVAln}*5^w*FIW+@ye`$B5WOK1 zQ=d<5PDsI6{Rv51Vq?_jQ!vI((<8ho>L!j^05@^W0=S9eH`U;qlz%spd;kCd07*qo IM6N<$f`qm|p#T5? delta 981 zcmV;`11kKz3F-%sBYy+2Nkll*O7=|C$od|F^psYA>5N~k^Gx1;;@L+rK zV59~AMS;!%@|!vqC^QL$mN%uI{Ww2X@ zSSSC<9gt<&Y=3{>-aH5bs;XjgTQHtzc6TCsty0QP5}2(b2^=Id(~zi$500F-4(nx+;$o@j=n3!0|k?DP=;41OVUnxw*cw6YIwhc{m(h*urGY zPp#9SEB?|N08rPpEjYu`1$R^R2!3;Yh41?o4iAN?uIp9{@0$N)0E7@WqVt?yXwAPF#n(^ch`!D&vPoC$k z7T+a*VG0ZegRP<{@H~&Is?b{7v7_S?n{#(lWq%73fYzF-s_;CIq9|HF5_iR4x&y*6 zv=0??MNx$B`}W@$jxPB4VUM%ZL$ucHyh-fC%e+f#t1kFUi{M}|*sALqV+?7UvhyaP zA4`-{wlMAPL@1@`$I`-$F)L|^y5K+A41K@Jqi$@jpL^k>Zmieqt-KptH~-m_ocH5N zl7B4h$BUw1-R}cd&ENPpLQYOjPEJlvPEJlvP8+F>?*?1>1JX2QI{j+L;&_`p&pY!6 ztdj5i0ndRue}MA`IDf!q`U9ktw&1impO;c{d3o7p{r}tuj818NK-v|5X%SRPz3O~^UX0qR3%>IQEE{zG z0Ot>I{s60gpU*Gq$Gh?etdhU+Z-ktjoSdATHdx;Pxa0vevn7qZ00000NkvXXu0mjf Du-Wmf diff --git a/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_on.png b/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_on.png index 9bc5d8c0bf341e5ecd829e77a0e1b8f689be12cb..bdef533ae36dd9ff691ee057dd48a3444f6c1093 100644 GIT binary patch literal 6218 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 M;E@AGR%asr3%w$v8vpZb`)Furm^9Qc>C({b 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 NE?>J;a?#?!{{!f+=`#QT diff --git a/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_purge.png b/Resources/Textures/Structures/Piping/Atmospherics/scrubber.rsi/scrub_purge.png index 75ba6d6de046aae288fa21c5aa213a07c35a64a6..6bbc79c31b2b608934a9acc0380951052ecde90b 100644 GIT binary patch literal 6204 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 Ul2s)9cYuJIiRGz$qido60X#*jkN^Mx literal 7441 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 WbuYi0g#WG)usm*atlZo+{Qm$+I5~^} literal 10949 zcmai)1yq#by6@>B9l9Ho78Ile1`s3#M5IJQB_t$NYQ`BPMM`O;RZ1k35G95I0civ& z5r#%O1{h|TxF7rMefB=*-nH&p6YG0t))#L)&;S2>-gqkuBNj$}MhXfF787FwYv8;6 z>`hMxd|LnU1yNAQCYl)N*@Wh8=lj^)SE68|gIp%RBua;Age^|Q!R?;x}vP~G*tima>GhY z?YO8vUNz^Zh(x&_lOL+^Q|N|-U>nKWI>eo|xwjzF(M*NW%5GMhIdq74@){>{gonhF z-jX|Vls!jLuB=s6RZ6*ouZ$(9AqfWJ0qTOa)4n5KD(4+uY@bBc6qG>8JIpnf-=!Xs zu5u~yR|j(Hoh}+dp;yIU)2k<6ljhV{7mRhf7-w2S)u{xWk(Zwz zXjy&A7Q6_CljUbm=^#9)GaU1Bw`IBX zi&=NRiPPIQzJmu->C#io2dIBWOGc=OSVqD~(EG{(-M5tj6TD_R&{zc8M3`_}ZT1uk z4q;o)N5CkD+%*R3-0G{~+ugXRn*0(d!b%(|MHgZo7t04Z_FLIKt$FVQ@()Znn(>gK zvECkOy8g+(vIn_)FBMK)t6vKNV@=bC{dqF(Prx`YH$Us|5i!&umxFp&g2HSc39xjm zJZbk;?YvYMnNbV6b-MxRy#NiN+PJk#Dk?Pb22@|23Z5a4l{(i>ddfbNe)dYIV&F}g z6)o_=U9`!;y2$a62XU#+D*-Qa)o|cuF?&sWG z8-6)AR(bYCihmp`P|!k^i4DUt-~N(Au*a?FlTcl0C-3plJuff%?d@$1HQB3ft%xas zSj*puW>Jsl)z7)iDqag3O5*q?sh-?f_3iqAHk9=^=WFW8_Ci?n)#L@okHUgI3pSPX zy|vV3j$Q$Rahr1d1NB1D&ouLvc450P)Rl|BA;^fBC3$?(HgG~I=0Hi$>j58b&?GPI zRYXPBe5UQ(S$87Wd<)wLLp?9~XeK`IP9*CN#FzWCO64kJT)qiJNw`J$$!9O2Psh*) zi(ir~QF4#Elir^b>?wY>e36^Zf1X!4V;^jINw{j*IT}mE+o3Q19X{p$OB&~iHz=~M zsIC9uwtOs_`uLGOG_yTeJ7vtcbILX1sGDVgiHp_rsP>1URfWw9192}uznJUqrhnck zt|E{!=tt%1YL8)bjhkUDFH{n*OMFyo)2%NRwl}$EXOT4kxzm>TJ(b6HQ_?}L!tp~s?@^*LFsl(H)yi;(w>O#CSkbCnV$>DTrajYz6}Lh*$s-oO~qs7kBPs-w=%l+TT5S#RwEL4OIJ+( zdf)yE&*!fCeYpk4b5h(n7KkX1r%nE*PhX4-#9OJYy5s{Tinf? z8js{hyh56Rp#f94^3p|76aUt3#r=E`3%vT*zn{M&n8e6m#m{B^A$*`T_*hk`$1-DK z;~o`v3TSJ8DU4`Q#$?yxu5|ljQH&AtS!PFu0S(Aj%M~m#v;@i%R(!BkBcoHE-eXk(h{>k zuormG1`|hHAc};dKWlPF%V&?Oti1|4$Ognc{K<=j~@v#+F?HqvcUQAJFv#I)njJLOmHc z=yu5ur7QBv{_ghU{b*di_GZ@AI5wt%r3VR(MdZWR7vAfkBpDAjCgqdGKh?e%17SH2 z3;)=~eJ6--NLV-%S*ReQMf;1G%t%tTBZF-un{>BP=uxg*M?@{NV(_-yUx=-YLAVC( zbZx#J(nJgFmcd+>(!g1OtY#E1q3JWU{7Gu@f6mFta#NbZoxN!BQg&tPeByO`s7{nc z)>qb@{<{_+7>U9@vujwMS@0al#>7>VGa~YBh)QU(i$uHH!1Vw@kdGz!iRLypN!0$> z{vqKy!%&_I&+#dhYqPz*>4N`TR0WYv}(*2A)?lUr8fvHBu zuyuaQUYtaWI$#ii9GV&T>JUNvTd%Lx+AuC;n{sXsLn*Ds+}2*6ge_kBKBvUk;fm@`IiV)tkM9LQU!S?AES9nv=Us z?W>mQe-O_Mqa@$adgv>?d9_(+?6$=Lc2>Gzx{ADulNbOK-Oq4i0 z7A6B-`mMQ{RyCJ}J)Wl6ioT$i*I?t^$as=#b3q)ijJoCm)n{`Au1%weud*BVVwZsR z52R%v!C#$Yuk97droJr(x?2V67mgd-?i%;f$a~IE3o4BI{wq4DgukG-Bo+7YI_=FW zK6xm!MGa4(5p6(ttLyZA){4X;IiGokfsAelpI(k5=;3|2DT%oGL)^ZDG+kLgOJf3U z*DpP*A>RWu8^X^B5_wvpIJQZgo96wFcQkh7M+FNWE#%Lm?+|LVkvOd8dKi zBjgjs*?xtG>^7n+)z@35YWV~aN!nVU3u;BdaK>{+tL|kE7yEa*=I>vdx{l~~em3F4lTRbfAM{0e)Bj<)LItwn zp&xwQiB+GEdc{d;)8B7&Zv%O2pFLk05p{Xf&YV^>-BvFy<_dWu4QYc>lUs2>hKtcS zzKwRs9NOH?YN@Xih=9QjpH85yxM}Y?BwPsd9z^1o(L)6AALcLkl;y2%>WF9b#X4H) zbpn=EwwN}7%Y`EJVq2|ugUAXC5BZ<*q~#KdSvy+oFnIr;E+x-*;)0-PvdK%*jLXR1 z)0!&coX(H<uX3v54ccJ9`mo;O6 zpmqF(huoCvIIJP&g?nh!b?yafy?!u>)Jth05>xZ(HwoimA9k?hf)LWx#hRaULTzh` zedIZyjYuF_*O1!~q*s^GQ0!|R(tqpn|EbddeWVqvb+cJ7zVJ}u6`W#Gib$_@EV1<) z9#J-HiD!GcX*3lGX;h+v`Dj)X_ZP_E{t=zsbPlZ20^)LzB2HBN$+8Z(C> zckZTq7mSWapSji%`ifrR zdFFXnubRd4h2)&SMkZlCKGoz$yuGxLkJ`$v&ENL)HEG{jfHv3cKJl9BiQ1w@oNj)G zQveTm3OwLAcyA&{wf>5++S-y&gO|^%#VTdL^Mi2+KuLHh+vt{!t>QPYcvYJ$#ku%g ztN=Q5s|_Cg7Ec*_H{s+yS+s35`(pO+PLSq)Zxe-w!y7b=)Jt>G!eZWQg?Xx)fIGyV zGQ3$P;7uSMJKILmA4Eh&FX>5EelIC@MZu2ELZVoEW!YY3hYrRSKKzsLSyLvwRGgLw z1R-5fiaf0~Od33Tb|%Hj1`=Vb9v|e#VzHz62OKc^_S)A*I>!ac8r)u=A=to_;oC+f zBbHjw=XtFuU0P^?9c0~Ts+CCJbwn*K-QrtK)wAx_8piSMjl#jSrw1xHxO#QW5|ax~ zp&7`~571QjIEjp~sQR-79*orf#b9Q{aDW5uxO&^@$0_5hK~GQKavND7EiFNo#GASr z_HLL{{dmww9pQhEedoZD;OP{NdQRGsdc4kLr+WkPK!>17{<`m;IFvAtv0TPqQ{Efr z+l$MteNS>Bkmz=j=@u}!AYvtver@Y#DjtE8y6Q_>Ud7p+vcdiGWvj?3s#8=ZCj^ue z*&EWKNPeJLL7p|MHV3yaKdDAEh`33ST6lE#8tOD~du?7+#_3VqGAQAzj9FvxOob_c zWs1}e=6sUF{vxZB=f?7K9mqv4Z@3^Oes>k$s(kZ(rXef+N)DW&OgRm_8x#eE{S|Ko z15-YjT(2PVK03E$dF-s$r&C^G6|8o_L+^(^4#$b`>*Jjj4_}(=5Z$4S^(~ZH+cJc- z7}V>_pcYlNH!OXBV8=pmPB>cZ8!nq9h7cM@`(*Nb|C_ zS;LciLU6rhz=~}CEK)pwWAA&V=VQz|ix2KFY23tW(ObnK17;IOH%3)^(%Pv-N}@_sa?7&q8fjaxJQ=qQA$1Lr4e~%E$Ya%`fdeDM zwN6XIkpq4e0S(7?0v)lqhMv%$b)gp>jxSGvEd$*DUehWZ>U1=Ra@((5RJp z7J1N(kdpMZ8CnS}_q4^iY#8bcWfwjyp6Rl4qAuRROfB0$`p)J7# ze^dxLq|AZAo6803R^Ppv-oCTC^zJ*3Uu-o&PqWX~S*UGUUp6kvUZz+L|UlAPfSg7YK=Gk@5b3O*e$I zE3{q*$~K4Hba|F5LLQq-QR0tQo{mWI_e{;2nGI3Gq2jzk(3CxaCnv%5Ll3BZ-|4|u z5!-7T7;sAHCE>A!(N=W;pV)0vamQ76E;iO2b4V|6<$Td5H{vM?OYrYmEwvXsP{KNi zV-*G$3R}xS6(y2h6`XWQDr$wZXI}A^4k3Fs*+zwCQy-AS}uAHXYBB0`d0U+D#sj4!anFV)^1UV5O}@QqX`rolra8ol740l_Ge!!U&4b25*pCJJO~ z@7`69f8s%ekOdPs`dQOuT>qBOWkPmoUs-$XG=81Ie#UKGPmUVb%t-?e2RdD-abczD z=Wkca@inFZy3)+9@hTLKjE`#YWc(IB=m7y#x?>v+d0-XS;3&Ecni)Sne^ORF=C?QL z6Ok_BYp3iFr%qSkZx-VG8#i^6(Y~thYHCtkkXPvQ8y|HNp6d328aKcC zohEF6YLgV_Vg4c(4KLe2<1n~_)pm) zQKFLU41mc15YykC=9sj>4$!fLQ=^n?wM?f@bdhak2tn1W6|KtGvx3tQWTypAf6C@$ zA*HiZ*dyG)>!*8@1SFfh{@c2jpEGHPFs;_P+%=E*P^5$&9q`dYndPSP7qhlBCjN(W zLU-_n{)O9^RXaNE?5ZlG$sn#oO+ONxf-*@M$;+~Wd1WFHy5GMN^lR9{weO>0RxoWh z-8E;jos1a1ufF_lc7#(~o%j1Hg6U8~Koo<~nhftI220%{T@=t|)M@|8z8={GkGQVU z76>UMZe01h@hc3ou8_!^+{KB+?Xjd@A@ise-}3uusieVj{6oxMHYULQ{K*j{hDZ;H zdMGtx^xkI&s^or7stxbkxx`yywQ=Ci4&(WN_n+0?US;_)xF4sl#B^(ZW7BoJl{Wu# zI1^cAsxxjR5J3_r&TN3xJyY5Ty%utNTUyRC4tpq;!_ow^KxXCWu=9*iR7u;!TDm@H zV_xgdG}}PD!LvmSfXp_DYcdRZ`m`{TZZ%pY;#PTkm}%+~5~19eMWz-}60Z9F$5M$e zvaD1XnZnq3W*QI8T!seM3X}9c*2KIoVe?(1RM&QP`gWC}Y%HVKGwTDTDV3#?S|O@Mf&CR$_7`kQ1sZ!&>^*YzU%Z-QS`X6q2b<;!D9jkde%Yz3J}g~N&B3v zl@aCE;7s=gK+R;y5p!@3-1-&5FK)NP?ww915SApBiqP~4J?6IfV*H(ynnlhr! zI{6K>Ro$A~X&Yp}X#@}*qrS-UPe*SZWQKu7_W~ZBcjRxS_eDLCXQ1K+ksfeq4oIPK zwHp5oqo)2_5dAtQI^6tiK^dk9H(saDU1Bzk^Qj8wV%-AjwJ31&keJ4+uol<>hWhTz6W5!=9iE;aP1|LHsG?Wb(K8&MdwYk-PeJ| zLQKsH-39@P-jm4Uesd(F!7H_Ff{^6xj9CXXRV zxkEf%Tt!c){l@*5*}!d;=&;rA7DC<+VCSAaIP(Li7SU|~zns7Kz3$!j+Onr=MGH`J z?r-E_+47hsndrBl(uc-9QoD_HgOi2!Cm-&DW@hMI4%G0Q6sB4B!4GFw zcL_Iu|Dmon2N6Y1Vt(%u1df~*7fU%zTqfd0m(Zlhjchbbd?OI@`g;}x9p6;uPJ&4- zwxz=(PC>ejTc7|#){lRp!o8`|#W5dly@Z`4|n0(1f7-93DH(Nnp4FfGMl)zSNVW zn${an2mFX9DY`G#O{u-{M!FR-SC4tLIFV;IuniX6V=gG?1}^>JU5DE`-h;(s)}`u5 z`_n4yb&r~OKCKqI%#YWEk@NEa81I8Sx$nkU(Z$;BnYMYbjvHL7IZbgwJ`29M8PfCJ zIPexP6Vt>BCabZqT}NmLFO}mcDKQo>P=l$t-icX3c;MdsISPrJ!1H-;zD|^H2VL-o z(AE$s8b65&GEiTfO#&=eo^R>@M)K2AsLs{S5Yh(hkxmPgzpalOwo%j$(EEn?S9yFW zhHDpUkm#x8m?ht1@lY=^^eg=I39oV$DDatK+Wwaj<5(f}aoN7*v7QaK9raA2*j_E^ z8JXZ#jR-#XINvCs8SZ~U#6`eRd}{!&IJ2~Od#6A1f!0U#9zGTZA66+%8eT}Q<^$-u z^1?NF^_Mj&rFBH+n5=xe|>Urc={X zfdJ;j_CE81+jb7!%y`ThX@3>ppUWdFn!e%oIw7<-uI7}8^zVxUOL7>W@2GWr=IX$$ zD9-Y(mwvOs=fy8I-N*}ny(l3htlH_dx4fxxW3|plQQE;z#{DD5y$xIRS<>Z-IBvF_ z3}WYIw+bC}ePt;&qd{B67A@Hp)kn$(v_)MP{+19vl1V>SVQ{1;WABN|$DcB_`T6P@ ziJrt>+yxJ&PRK^#((m$ZIkKOS^5CxEG2ztZn(cy&ja8%-31u_ zI&IQ3>5GM}(vaw;Z`l!DYar;d6(y3%PD@x!Uyo_%7pk1+?IC8^9NKz zE3$CRf*i|>IPt#>@|?$ri4>YI6d~rQN_3%(#A;#J3Z;u4xkqiwKKO*qczk~&#IW+U zy?uLE<#8lQZYk}>X{OShhl}I8_8;^$`Fdi8nXt3OGyH4lQGD zl<~Ci3k4NFz_n{g_!k`eIK#X@c6K8Oyer2dQ^JUR^1+7MsNVZq?d$KLjCdEXa=l+j zik#V@O0@jlhzRb5t|cfF-XZM#D3gp5wJLm#XIM`2gxIv^-0@?S-eQLeauLR^l#+;A?n+oRU#9BLi2RJU$lDpHg{t1uRo`m3EId#wwt z81}FqPXEwMVrpo}7ZTmSPBSx3>*zso`zDiRz*kAksckCjxJ_|OqwrSo&^Y|X&yOym zwqkq=Q6U%F6cBSvuFKoIYs+I_R3Ex>ho6-`0hO|@ZdE!Lm8WPKZuF^~02>@q zIQw{~=W1WyA$$+~mDC!pa+{`(@>unNU^5^L^Zyxz=b0-y7M`V5e+8h$?!d(0( zeOpR>T0Zj8{zXTA&Y1(A7KWXymh`j~^f$Z0K~J^*QC8D*E5+!EgXs((flSj>FmkA- zlPY>tR=Si5aO5msafA@rlWi$4Kga$uyCGV!^h;KQw1A|t?bkbbL$>Iee0<8lZ{vWx zCrjaIO)J#YLS%;3AS@s>Y7K^v=u9*`7CE%-`C~m!IwkU+_fJWeHUE#Zjbv1_9+C*D zSW6Xw1U9qbHb7JBgfG!$56L2={bFLt9E$^UbC{a1$q+S-%T=@8dj1z+2>SHr?(R#4 z3741IPlAN!+44bC8v?x{;+~5QWD7I_rDm3yQiC``+#EI_yUcOuan$6M_;WiX)^hM8 z4h25=9YnRjn@P~aA2Wzsmk}}+27Yly&%}MvNSJZXZriD`NQ??RqS>EA!E6~kBJaaRYC{SP)t1lS~&I+1R{Ty=hFCTDpz7%OBB z-xK>i8vHP@<2(!MafkZ_0YWy0cbVic51uSMg?T({>Jw#C5(! z{BbZ_=Qac{EW}jytTVzgo&FJa+!I@mI1~|Dbq&>x1BjOoUWn}#c z1&|##YyDH`AmJ;zfWt$aG+eLWFvvY+*w`F-d$IEl8dhD8JNzdM9|s3aa_NPj74m$! zBZ1q|CBY;5k7)+3xD!?}mfeA2@N;nn&pU8?|91TIp9;^A_wRpD=6^eQSDn+YxtsKr zyfkvyy&3RG6UhCkwNrvs%qiu^Ypf%jd4XItXX6GvWqY{+DlfYrddX*hyfX$fjSO$1 zWl!Ti`b7iKV$&feM~CEhmp3ShG(xO>D@rCjVMqUj%uWyr{m^N7${zPeCr=ta4C1!_ z!v>#hgXm*ixl7x}CsDtlOq%XT+@yzqNiKf(j)q8c_PECqoG{t|^~;KCvKfp(m0jJ^ zWS&!Y9s{CyaCwHZeGS|$V>7RH9yPBEv61ES$L(zb0zYEkiwj0_twvm?vAm%T7vTa_ z&5o4t6cxh>OkmYz+Xyh$KvO?t+708s033&6Q!5Wi@xNA&fP<425x7*7 zb^gh>c3}H}zH4jY2i?Y>ba$>Ax#2_ZW!aWkY!ybwgm+@6^}s9L2(EXyuusJV8J`@xn+;u}Cpi49`|D zy^QS`v2U#w(Tk+apvg29OCC8F`tDMFdbtQCg_0^|)b(!@DMe)gPz_opiEgHD8Z8t< zy=q1&@GH#@+uxFVN&_Twh`u4sv7IhyX{_&SoB)z5D)g4gnaOu2d`Aw0) z$ji1=^AHhd^6wd&o<9?~6A9LP-$o)H+!|Z()j5^CmGIyJe=_bV zZc760i~)iJNm{LNPN)y>>GNN{$|E1$Us+gt+6$%RbwX2T zDQXZmY#LT!j7PM{Fm(T9E)uu(v4wp-hBKQ|004E18uad$ z^K@*R3g->p@r&nkzBH8bhj;9hmct|RV8@k{MU}VwUt8{i`h!s&RsjQ5dwF0HM-1X8 zQ~n2!ItVKbuzgAX31f2TRxvTUED9(Z=G7U^d(`g@4p0GWcc({tlASc{a^3U|m>kE& z27Ah~7o&Q*UCaqrYwY;v7$2HB_w|-xhq^^4CiQ=h(l^#|Sfub|?O1r=DZhQw?Po5M z^YAl1^^a~IOgFTwo)vGV^I#_)|0tFV z16w2BnzRj}?f)@>!?r@AgtaDbJcOT~n`SYUW?0suSg2Ty*JNwlbQp3P$EGJ6pDieKATAc+fyk_3@r?*^<5+X5C1Oc9smFU diff --git a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/meta.json index 74e1688748..d22d006684 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/meta.json @@ -1,37 +1,103 @@ { - "version":1, - "size":{ - "x":32, - "y":32 - }, - "license":"CC-BY-SA-3.0", - "copyright":"Taken from https://github.com/BeeStation/BeeStation-Hornet at commit 4ccd79de285e79e504308bcd6fa5908d6b7685f7", - "states":[ - { - "name":"vent_passive", - "directions" : 4 - }, - { - "name":"vent_off", - "directions" : 4 - }, - { - "name":"vent_welded", - "directions" : 4 - }, - { - "name":"vent_out", - "directions" : 4, - "delays":[ [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ] ] - }, - { - "name":"vent_in", - "directions" : 4, - "delays":[ [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ], [ 0.08, 0.08, 0.08, 0.08 ] ] - }, - { - "name":"vent_lockout", - "directions" : 4 - } - ] + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/32742/commits/44820f5b6e2c864a35bfad448e0a9437f01ad2e2", + "states": [ + { + "name": "vent_passive", + "directions": 4 + }, + { + "name": "vent_off", + "directions": 4 + }, + { + "name": "vent_welded", + "directions": 4 + }, + { + "name": "vent_out", + "directions": 4, + "delays": [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ] + ] + }, + { + "name": "vent_in", + "directions": 4, + "delays": [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ], + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ] + ] + }, + { + "name": "vent_lockout", + "directions": 4 + } + ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_in.png b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_in.png index cf1b050c0246a699f147b5c266fe21f404b4f2fe..17a740920f85f7902cdbd0bc8edebb1044023ad6 100644 GIT binary patch literal 4224 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 DsvmDi literal 1595 zcmY*a3pmqj82^ux4Q13iIl@pO!#qz%bj*ebDO5riA@@rZ$&zNail|gt(q&st&!J@N zI4p#@9TcJxl4CBJ>)giJ^54#X)v4z^&-cCG<$b^3@ArPs_q^X_Pj}}vDq1Q40IYF! zaoi7$WO+v@LAD+r*a84b3a*a!Uc~!?`$s%Jh60!TwTxA^WSi<~Zat`#S>hHEV3Kw_ z;(=k2o0SPGu{;xGfn>km6DX|xrS6fIN*D{R(mh)dZrjvR5rY<;+DWxjy@vQz@N^;G zM_;pl=4$ow?2fa51493Tx`Rv9o6x0}@$vB|65oBOZkZR#Nif&idgX+Yu-%ILk9qRx z(TqoS)Bx`Uk#t(=xL0)-i~gc@9)<| zP&|d@Ji6>MNZr)8Y&|mG6GG!cfkQ2p$){#G`t3M1d-d6c4|yW@1x(8Mc=*VEWxzdH zv19%qy`6pkPzvZfF+M{?XjW+KH2rxePJi(Aqp^}5D5u)6Y^Ubpsj{Mtohu8o>4Tpd zGl&jv`(dLu*v2Xj0>R#QyfX?Yl~vKB$Wz3`6yQ{WjKPlN*ftC>~*0B_kB`a}{gROU2 zRS?MQz{PWLENEtA_vg{Z#zBp)Uh}}uvR^bkTv*rai%o-y1Z%geWqF$B*lyswVkfNT zyuvPJR*y_B0rr!z<&M^P{IT^;8YxB9rBza|H;e~H*;Jw=TI2bpwVtR|LZOhJVj2ai zc*ivueYy$fbt;Q1FNDWxQuI2j)bsfMFM54^q@{)Dt3MTjZD9lM;aQP4|ZzTOV*4!{k@bVz7+ zR)2Nvtxi&!`t{Px9!wx<^o2clZBK#Jn@#POa?Sy+H=l8R8m6*0^y+NICf09ut*fh} z2!Kldx$=!&=_|~|MBGo0(wwztOcKr{4ARFd4kQvJUS%(>!WappZA+s@lsg_@%E1pq zQJGQV5b+>jM)x3)n;?vQbWK{aQ1k9%0tlFYeuuOp03ZOhq%k-XO(p>n*ciM_otKp_ zU(|~h6g$3#e4UU5&`w$N7pDY9k$^Hq)$ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_lockout.png b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_lockout.png index bf0b9c928eec6d868a5de6bcbfc05e05e547f4eb..b32003c69875377f1c74b926270c3bb17a93c7d0 100644 GIT binary patch delta 1176 zcmV;J1ZVq}3abf_BYyx1a7bBm000ie000ie0hKEb8vp3f2}b5!+P(`})7Lk*B!`rsZTPoI>|4c)sRm>>Cu#$UL< zbr_%$eJut^w_c+9`g;1dwpKdV-`^LQANf#Y8yg#;;xd@l7aCxFeVtNGd(N-#G&-Jf z&)w+mqPBFa`I}}y_bUZ$-1VzF2(7K_DVvHZ7G{c2FSKLB1?e{cigDtLSO^H{gTf$7{+?orD71EB8@ zaepJ+1#d4O^gsw74%~)@hO+v~K0zjqP&52;a8Dst2XAlQ=kkU3c5-61lnerXu z)FBlaf=e1+SER}2o36l%H-9|o==6#wpMOqF>Pr~_@GfZxJR6YFKqw@A~1mW z!vnrUd;V{spFKqxm4$t6+AJe0NDgBB@0l@km`wE*zx4u#rz<=;_ zcc8!;ZI@m;20N9oOHb>im$ZboIKen%j0Kv&V&g4lps?jJ6hmj6 z))W#F?-1UL)I_qRNP2AccabeU>HGCPz4uH1`$DZ&3!RJ}(SHGmMpppQ0f3;>|2DkMp=9RL6* zio$-j+=$>MKLAsHQvn#trFG;BD~`wkAe$LSJdt#KUeNrO0;sAAN~zC zkdI%~0fOK+6(B}-aWi)SAcfkt20{qpiKL+ydZT$vOn+wie@)X+F0ErUM$kVX+-rVU0`x}CV3?f6$c48kE*pCR0DsID7xKtlzlOOdPcbt+#oMG)eHbR^ z&>K19{O$wfZ#xG7N8^yq#B7%RK(bx+5C5d5|TVB=7)bfLI} z7tf!85PyPvVdYq^PN(|p-=RQ$Qvr6G``Dy=*w_m59;m&l9D{5e zvN1?0#l}_`n{*F5&3#ul9TdN*096{sgSj3QmsbG*>8l^%=bx6*Xf*KKAAcVO+Gqg4 zvHg`Q1(1TKg(S~AR1i(L(S~AR1i( zM1Kb$8eIWI2Ot_9FM#Feu-VsGjO-ff?K{nVROwOe&F`;4FZmt&1M2lUZsra!OwRJQ zn{*Ek=6Vck_vE$p!mF(#7vAzV8(U!%msk1m(HKGV&1=v60eguM0Ak;tqLZwPU2r+E+?N|-(wEh6U`E6%`*@urI%QAi~l@U)Q@$J2@`6I@*ZY#hd z`5mXhMxy~)mNEC_Dc>i{GA>^{@0i>TyykZ-09$^VnVv$qw9fZ4(}Lgdn&0({P=BGg z#0^Y(n0a@+hFAQq1Xx_i^YwXVQqbE~{DznOjs^HIbqN!bSr9__`n=wz;y1kJw=KX) z3y_2mWUgOxP3{DK@w>_b4Dm#g&&EM!0WbMoWdZ%m#mw{+G))UM3wX(I%Ok|Vh*|n! zKHh9*99I%?XqtBHQS}mj@VE5`ynIUpfUmvlx9qsS-MiOuf}r@@`UCW41GeoSkhu#h zo$ABJRv48kHMH}}AK*8?ZGQl>n=l9FFgeHDY|=ddDM*sU+j;E|@QdG-Kj6Ps5pv}Z t=oEB(QM4<7=m12cD}d+#M5E&c_!sU&0|$7TVR!%l002ovPDHLkV1iqXa%cbm diff --git a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_off.png b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_off.png index 6208c59db793f9026125288653ea9d2ffe249a05..8380b47e7c595a9d1bef7978146457b112ec41dd 100644 GIT binary patch delta 1202 zcmV;j1Wo(h2*nAIBYyx1a7bBm000ie000ie0hKEb8vp>K+uUrZC z_V(`BKHF$CocY`BwvvCW0O$ohg@pwt{%*HRyzpax_)DU2M-^S3$7necfPft&+_+dD-Uk9U|Adf?~0958N zhI0Ra#64Iwe^-8d0VYrifK3n}TY$$O{S* z1UNHX&+|6U5PlBM4043dBc=QTY#Z+jF77l_eEBG4iO(Y=mGC9 z9Dlg*0mkuL=Lax3Le22Y!9B&^UUXOnyti;*ay@u*qT(e5KOg0Xw-+6j0q-^6=g^#& z$PnC7@Uh{=@Xeu=JIW=%_fg_GAD*N*e#9zu{4j`#C&_3ML;wO_S2!L~?jIZuHHb^O zo==42H(mwcl4h?gM`WU9NQB}~ybK}&gMT1IRB6QL(|~XO!~!7vBu8KvNKQb5WJ`sB zZ+`2I5XK>b5162C1HSmJ1(4(O7=xiLABsP*06g|E^KyJXP59=w{sNGcfX@%`~bWMr$PDsIO%Z~8kaZ=MESjB zi{nU%R1;1&;S9{^c^pFEJkIq@$W4GFF;ZozpI0G`{Dj;oN*PBk0A(Dx0F-h30}z6R(yp-u QJOBUy07*qoM6N<$f~fj9OaK4? delta 1097 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 AH~;_u literal 2926 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 Bkd6QV literal 2958 zcmcguYitx%6rO?+3O14$k)Vdj)CY#n&Ugjw(XP9 z*tbSQqt_Uluc%fs05mHO1DT|atTAl*jEoJ`7U{Vv!J|V|Exe z8#V0?T-d&#L2YkQWsR6|A3i;!AO}h40X&mTn68ou5m~hQ4TKwJ#aq)O8)9+U%&$nzpyg|jqEQ?x)aEXjxp%_~e0&;JO7=4iT7ADNTKLT@3W z+4F3LqSEPfAk76Vr-@=@S*B=~Vp$SdkZzmlfedN7l?4wG=&FukdxmA=zDE$ZTD=f~ znC3!A+C{gfn@7D0F>HTtcX#POEOu6aJ}jj3L~G8lGbiRn+>UY=vu9g3ae9yW@RB7*QLSC`th9TNkCvYRBfx_p0xdaD(jv)94GgES zv_dn}XjY-=oN3I`485(SDW?eB6{bjU8t}ld#+s_=mXic1TSgKzLCQ9p2)wukO4v$R z4gyB(xWVJmaJbH~bR&U2xb<^q$Go6l=gRG({I= zAt(wmsd7P%j0-$R0$z)g41f#`Rh8!%y)Zvwsja?#{Q0?3(kvDE7@!vn>S8<|43c6{ zlt?k_P0~41P#IPe1t`I|R`6Eq7^s>-Vz5`AmFBb3;yfdA3@OXBOa^(LC1pmJNr6)( zEv^Gm6m`F5vNBX^3>U3&TfPbx!WH?agn?(3rvTNjs1Tw0YJiAAZrCW5kC7nf=ck(? za(We&8qh$4exDL7fyO9mr4wI#fEKO6Xo6` zxlGRSt24WcDJ6T(2sMbdH3fCtVh{dX-7=4FU2E6%`$jhKL1&f15IO+)kHwQ0dMTdW zpouEgK_|0{)k{xfSXpf}GOHnT>ZfO7)eZ6i8cJgvpMen5(KdwEta_gwxT_2Z!(K7R$ z<*Awd0@mI;_tuxbTsIMW^`cz%)#yt%pS$kYJ9?_R`NyWLt=w?;*c{7&|M}}rUpSIp zK6}hvtInRfv3bwVZ+d!`b$r-y;E=bW>f&>q+YfJ@cXDFqvjaSYj&%P~OsI|Q+jw+e%r}fyFNo}&{m>(S0!xn73;+NC diff --git a/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_welded.png b/Resources/Textures/Structures/Piping/Atmospherics/vent.rsi/vent_welded.png index b45ae1cb5fc160d9dc9635397c8cd049b0e6a306..0ecc5b4c9cd6d85d2552a81664729f424ec6b3c7 100644 GIT binary patch delta 1831 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 Date: Fri, 18 Apr 2025 23:36:05 +0000 Subject: [PATCH 02/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f491491794..b4c7676377 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Beck Thompson - changes: - - message: Defibrillator cooldowns are now clearly visible. - type: Tweak - id: 7740 - time: '2024-12-20T21:26:56.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/31251 - author: J C Denton changes: - message: Syndicate and NanoTrasen NPCs and turrets are now hostile to Dragons @@ -3912,3 +3905,10 @@ id: 8240 time: '2025-04-18T23:26:44.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32396 +- author: ScarKy0 + changes: + - message: Changed the air vent and scrubber sprites. + type: Tweak + id: 8241 + time: '2025-04-18T23:34:59.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/34223 From f8ff7aee92cbd9a681cc5628c077fc4e75bf34e3 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Fri, 18 Apr 2025 19:43:17 -0400 Subject: [PATCH 03/16] Local Material Silo (#36492) * Material Silo * fix board, fix copyright * a bit of review.... for the vibe.... * a tiny bit of review * 4 spaced * sloths no good very tiny nitpick * fix ui flickers * oops * slightly lower range * Sloth Review --------- Co-authored-by: ScarKy0 --- Content.Client/Lathe/UI/LatheMenu.xaml | 17 +- Content.Client/Materials/OreSiloSystem.cs | 6 + .../Materials/UI/MaterialStorageControl.xaml | 7 +- .../UI/MaterialStorageControl.xaml.cs | 8 +- .../Materials/UI/OreSiloBoundUserInterface.cs | 34 ++++ Content.Client/Materials/UI/OreSiloMenu.xaml | 42 +++++ .../Materials/UI/OreSiloMenu.xaml.cs | 64 +++++++ .../Materials/MaterialStorageSystem.cs | 10 +- Content.Server/Materials/OreSiloSystem.cs | 119 +++++++++++++ Content.Server/Pinpointer/NavMapSystem.cs | 9 +- .../Materials/MaterialStorageComponent.cs | 18 ++ .../OreSilo/OreSiloClientComponent.cs | 18 ++ .../Materials/OreSilo/OreSiloComponent.cs | 55 ++++++ .../Materials/OreSilo/SharedOreSiloSystem.cs | 168 ++++++++++++++++++ .../Materials/SharedMaterialStorageSystem.cs | 153 ++++++++++++---- .../Locale/en-US/lathe/ui/lathe-menu.ftl | 1 + Resources/Locale/en-US/materials/silo.ftl | 10 ++ .../Catalog/Cargo/cargo_materials.yml | 10 ++ .../Catalog/Fills/Crates/materials.yml | 16 ++ .../Circuitboards/Machine/production.yml | 13 ++ .../Structures/Machines/anomaly_equipment.yml | 1 + .../Structures/Machines/flatpacker.yml | 1 + .../Entities/Structures/Machines/lathe.yml | 7 + .../Entities/Structures/Machines/silo.yml | 61 +++++++ .../Structures/Machines/silo.rsi/meta.json | 40 +++++ .../Machines/silo.rsi/overlay_active.png | Bin 0 -> 336 bytes .../Structures/Machines/silo.rsi/silo.png | Bin 0 -> 1097 bytes .../Machines/silo.rsi/silo_active.png | Bin 0 -> 1888 bytes 28 files changed, 842 insertions(+), 46 deletions(-) create mode 100644 Content.Client/Materials/OreSiloSystem.cs create mode 100644 Content.Client/Materials/UI/OreSiloBoundUserInterface.cs create mode 100644 Content.Client/Materials/UI/OreSiloMenu.xaml create mode 100644 Content.Client/Materials/UI/OreSiloMenu.xaml.cs create mode 100644 Content.Server/Materials/OreSiloSystem.cs create mode 100644 Content.Shared/Materials/OreSilo/OreSiloClientComponent.cs create mode 100644 Content.Shared/Materials/OreSilo/OreSiloComponent.cs create mode 100644 Content.Shared/Materials/OreSilo/SharedOreSiloSystem.cs create mode 100644 Resources/Locale/en-US/materials/silo.ftl create mode 100644 Resources/Prototypes/Entities/Structures/Machines/silo.yml create mode 100644 Resources/Textures/Structures/Machines/silo.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/silo.rsi/overlay_active.png create mode 100644 Resources/Textures/Structures/Machines/silo.rsi/silo.png create mode 100644 Resources/Textures/Structures/Machines/silo.rsi/silo_active.png diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml b/Content.Client/Lathe/UI/LatheMenu.xaml index d5e3573148..28b79254c0 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml +++ b/Content.Client/Lathe/UI/LatheMenu.xaml @@ -127,12 +127,17 @@ HorizontalExpand="True" Orientation="Vertical">

@@ -449,11 +449,14 @@ public sealed partial class NavMapSystem : SharedNavMapSystem /// to from the nearest beacon. /// - public string GetNearestBeaconString(MapCoordinates coordinates) + public string GetNearestBeaconString(MapCoordinates coordinates, bool onlyName = false) { if (!TryGetNearestBeacon(coordinates, out var beacon, out var pos)) return Loc.GetString("nav-beacon-pos-no-beacons"); + if (onlyName) + return beacon.Value.Comp.Text!; + var gridOffset = Angle.Zero; if (_mapManager.TryFindGridAt(pos.Value, out var grid, out _)) gridOffset = Transform(grid).LocalRotation; diff --git a/Content.Shared/Materials/MaterialStorageComponent.cs b/Content.Shared/Materials/MaterialStorageComponent.cs index 7d8dd5c749..1911b3de6f 100644 --- a/Content.Shared/Materials/MaterialStorageComponent.cs +++ b/Content.Shared/Materials/MaterialStorageComponent.cs @@ -75,6 +75,24 @@ public enum MaterialStorageVisuals : byte Inserting } +/// +/// Collects all the materials stored on a +/// +/// The entity holding all these materials +/// A dictionary of all materials held +/// An optional specifier. Non-local sources (silo, etc.) should not add materials when this is false. +[ByRefEvent] +public readonly record struct GetStoredMaterialsEvent(Entity Entity, Dictionary, int> Materials, bool LocalOnly); + +/// +/// After using materials, removes them from storage. +/// +/// The entity that held the materials and is being used up +/// A dictionary of the difference of materials left. +/// An optional specifier. Non-local sources (silo, etc.) should not consume materials when this is false. +[ByRefEvent] +public readonly record struct ConsumeStoredMaterialsEvent(Entity Entity, Dictionary, int> Materials, bool LocalOnly); + /// /// event raised on the materialStorage when a material entity is inserted into it. /// diff --git a/Content.Shared/Materials/OreSilo/OreSiloClientComponent.cs b/Content.Shared/Materials/OreSilo/OreSiloClientComponent.cs new file mode 100644 index 0000000000..ff43c9c05a --- /dev/null +++ b/Content.Shared/Materials/OreSilo/OreSiloClientComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Materials.OreSilo; + +/// +/// An entity with that interfaces with an . +/// Used for tracking the connected silo. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedOreSiloSystem))] +public sealed partial class OreSiloClientComponent : Component +{ + /// + /// The silo that this client pulls materials from. + /// + [DataField, AutoNetworkedField] + public EntityUid? Silo; +} diff --git a/Content.Shared/Materials/OreSilo/OreSiloComponent.cs b/Content.Shared/Materials/OreSilo/OreSiloComponent.cs new file mode 100644 index 0000000000..45c86b1845 --- /dev/null +++ b/Content.Shared/Materials/OreSilo/OreSiloComponent.cs @@ -0,0 +1,55 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Materials.OreSilo; + +/// +/// Provides additional materials to linked clients across long distances. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedOreSiloSystem))] +public sealed partial class OreSiloComponent : Component +{ + /// + /// The that are connected to this silo. + /// + [DataField, AutoNetworkedField] + public HashSet Clients = new(); + + /// + /// The maximum distance you can be to the silo and still receive transmission. + /// + /// + /// Default value should be big enough to span a single large department. + /// + [DataField, AutoNetworkedField] + public float Range = 20f; +} + +[Serializable, NetSerializable] +public sealed class OreSiloBuiState : BoundUserInterfaceState +{ + public readonly HashSet<(NetEntity, string, string)> Clients; + + public OreSiloBuiState(HashSet<(NetEntity, string, string)> clients) + { + Clients = clients; + } +} + +[Serializable, NetSerializable] +public sealed class ToggleOreSiloClientMessage : BoundUserInterfaceMessage +{ + public readonly NetEntity Client; + + public ToggleOreSiloClientMessage(NetEntity client) + { + Client = client; + } +} + +[Serializable, NetSerializable] +public enum OreSiloUiKey : byte +{ + Key +} diff --git a/Content.Shared/Materials/OreSilo/SharedOreSiloSystem.cs b/Content.Shared/Materials/OreSilo/SharedOreSiloSystem.cs new file mode 100644 index 0000000000..729a710065 --- /dev/null +++ b/Content.Shared/Materials/OreSilo/SharedOreSiloSystem.cs @@ -0,0 +1,168 @@ +using Content.Shared.Power.EntitySystems; +using JetBrains.Annotations; +using Robust.Shared.Utility; + +namespace Content.Shared.Materials.OreSilo; + +public abstract class SharedOreSiloSystem : EntitySystem +{ + [Dependency] private readonly SharedMaterialStorageSystem _materialStorage = default!; + [Dependency] private readonly SharedPowerReceiverSystem _powerReceiver = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + + private EntityQuery _clientQuery; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnToggleOreSiloClient); + SubscribeLocalEvent(OnSiloShutdown); + Subs.BuiEvents(OreSiloUiKey.Key, + subs => + { + subs.Event(OnBoundUIOpened); + }); + + + SubscribeLocalEvent(OnGetStoredMaterials); + SubscribeLocalEvent(OnConsumeStoredMaterials); + SubscribeLocalEvent(OnClientShutdown); + + _clientQuery = GetEntityQuery(); + } + + private void OnToggleOreSiloClient(Entity ent, ref ToggleOreSiloClientMessage args) + { + var client = GetEntity(args.Client); + + if (!_clientQuery.TryComp(client, out var clientComp)) + return; + + if (ent.Comp.Clients.Contains(client)) // remove client + { + clientComp.Silo = null; + Dirty(client, clientComp); + ent.Comp.Clients.Remove(client); + Dirty(ent); + + UpdateOreSiloUi(ent); + } + else // add client + { + if (!CanTransmitMaterials((ent, ent), client)) + return; + + var clientMats = _materialStorage.GetStoredMaterials(client, true); + var inverseMats = new Dictionary(); + foreach (var (mat, amount) in clientMats) + { + inverseMats.Add(mat, -amount); + } + _materialStorage.TryChangeMaterialAmount(client, inverseMats, localOnly: true); + _materialStorage.TryChangeMaterialAmount(ent.Owner, clientMats); + + ent.Comp.Clients.Add(client); + Dirty(ent); + clientComp.Silo = ent; + Dirty(client, clientComp); + + UpdateOreSiloUi(ent); + } + } + + private void OnBoundUIOpened(Entity ent, ref BoundUIOpenedEvent args) + { + UpdateOreSiloUi(ent); + } + + private void OnSiloShutdown(Entity ent, ref ComponentShutdown args) + { + foreach (var client in ent.Comp.Clients) + { + if (!_clientQuery.TryComp(client, out var comp)) + continue; + + comp.Silo = null; + Dirty(client, comp); + } + } + + protected virtual void UpdateOreSiloUi(Entity ent) + { + + } + + private void OnGetStoredMaterials(Entity ent, ref GetStoredMaterialsEvent args) + { + if (args.LocalOnly) + return; + + if (ent.Comp.Silo is not { } silo) + return; + + if (!CanTransmitMaterials(silo, ent)) + return; + + var materials = _materialStorage.GetStoredMaterials(silo); + + foreach (var (mat, amount) in materials) + { + // Don't supply materials that they don't usually have access to. + if (!_materialStorage.IsMaterialWhitelisted((args.Entity, args.Entity), mat)) + continue; + + var existing = args.Materials.GetOrNew(mat); + args.Materials[mat] = existing + amount; + } + } + + private void OnConsumeStoredMaterials(Entity ent, ref ConsumeStoredMaterialsEvent args) + { + if (args.LocalOnly) + return; + + if (ent.Comp.Silo is not { } silo || !TryComp(silo, out var materialStorage)) + return; + + if (!CanTransmitMaterials(silo, ent)) + return; + + foreach (var (mat, amount) in args.Materials) + { + if (!_materialStorage.TryChangeMaterialAmount(silo, mat, amount, materialStorage)) + continue; + args.Materials[mat] = 0; + } + } + + private void OnClientShutdown(Entity ent, ref ComponentShutdown args) + { + if (!TryComp(ent.Comp.Silo, out var silo)) + return; + + silo.Clients.Remove(ent); + Dirty(ent.Comp.Silo.Value, silo); + UpdateOreSiloUi((ent.Comp.Silo.Value, silo)); + } + + /// + /// Checks if a given client fulfills the criteria to link/receive materials from an ore silo. + /// + [PublicAPI] + public bool CanTransmitMaterials(Entity silo, EntityUid client) + { + if (!Resolve(silo, ref silo.Comp)) + return false; + + if (!_powerReceiver.IsPowered(silo.Owner)) + return false; + + if (_transform.GetGrid(client) != _transform.GetGrid(silo.Owner)) + return false; + + if (!_transform.InRange(silo.Owner, client, silo.Comp.Range)) + return false; + + return true; + } +} diff --git a/Content.Shared/Materials/SharedMaterialStorageSystem.cs b/Content.Shared/Materials/SharedMaterialStorageSystem.cs index 2544aacadd..2fc03dd997 100644 --- a/Content.Shared/Materials/SharedMaterialStorageSystem.cs +++ b/Content.Shared/Materials/SharedMaterialStorageSystem.cs @@ -1,7 +1,6 @@ using System.Linq; using Content.Shared.Interaction; using Content.Shared.Interaction.Components; -using Content.Shared.Mobs; using Content.Shared.Stacks; using Content.Shared.Whitelist; using JetBrains.Annotations; @@ -58,16 +57,22 @@ public abstract class SharedMaterialStorageSystem : EntitySystem } /// - /// Gets the volume of a specified material contained in this storage. + /// Gets all the materials stored on this entity /// - /// - /// - /// - /// The volume of the material - [PublicAPI] - public int GetMaterialAmount(EntityUid uid, MaterialPrototype material, MaterialStorageComponent? component = null) + /// + /// Include only materials held "locally", as determined by event subscribers + /// + public Dictionary, int> GetStoredMaterials(Entity ent, bool localOnly = false) { - return GetMaterialAmount(uid, material.ID, component); + if (!Resolve(ent, ref ent.Comp, false)) + return new(); + + // clone so we don't modify by accident. + var mats = new Dictionary, int>(ent.Comp.Storage); + var ev = new GetStoredMaterialsEvent((ent, ent.Comp), mats, localOnly); + RaiseLocalEvent(ent, ref ev, true); + + return ev.Materials; } /// @@ -76,12 +81,27 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// /// /// + /// /// The volume of the material - public int GetMaterialAmount(EntityUid uid, string material, MaterialStorageComponent? component = null) + [PublicAPI] + public int GetMaterialAmount(EntityUid uid, MaterialPrototype material, MaterialStorageComponent? component = null, bool localOnly = false) + { + return GetMaterialAmount(uid, material.ID, component, localOnly); + } + + /// + /// Gets the volume of a specified material contained in this storage. + /// + /// + /// + /// + /// + /// The volume of the material + public int GetMaterialAmount(EntityUid uid, string material, MaterialStorageComponent? component = null, bool localOnly = false) { if (!Resolve(uid, ref component)) return 0; //you have nothing - return component.Storage.GetValueOrDefault(material, 0); + return GetStoredMaterials((uid, component), localOnly).GetValueOrDefault(material, 0); } /// @@ -89,26 +109,43 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// /// /// + /// /// The volume of all materials in the storage - public int GetTotalMaterialAmount(EntityUid uid, MaterialStorageComponent? component = null) + public int GetTotalMaterialAmount(EntityUid uid, MaterialStorageComponent? component = null, bool localOnly = false) { if (!Resolve(uid, ref component)) return 0; - return component.Storage.Values.Sum(); + return GetStoredMaterials((uid, component), localOnly).Values.Sum(); } + // TODO: Revisit this if we ever decide to do things with storage limits. As it stands, the feature is unused. /// /// Tests if a specific amount of volume will fit in the storage. /// /// /// /// + /// /// If the specified volume will fit - public bool CanTakeVolume(EntityUid uid, int volume, MaterialStorageComponent? component = null) + public bool CanTakeVolume(EntityUid uid, int volume, MaterialStorageComponent? component = null, bool localOnly = false) { if (!Resolve(uid, ref component)) return false; - return component.StorageLimit == null || GetTotalMaterialAmount(uid, component) + volume <= component.StorageLimit; + return component.StorageLimit == null || GetTotalMaterialAmount(uid, component, true) + volume <= component.StorageLimit; + } + + /// + /// Checks if a certain material prototype is supported by this entity. + /// + public bool IsMaterialWhitelisted(Entity ent, ProtoId material) + { + if (!Resolve(ent, ref ent.Comp)) + return false; + + if (ent.Comp.MaterialWhiteList == null) + return true; + + return ent.Comp.MaterialWhiteList.Contains(material); } /// @@ -118,8 +155,9 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// /// /// + /// /// If the amount can be changed - public bool CanChangeMaterialAmount(EntityUid uid, string materialId, int volume, MaterialStorageComponent? component = null) + public bool CanChangeMaterialAmount(EntityUid uid, string materialId, int volume, MaterialStorageComponent? component = null, bool localOnly = false) { if (!Resolve(uid, ref component)) return false; @@ -127,10 +165,10 @@ public abstract class SharedMaterialStorageSystem : EntitySystem if (!CanTakeVolume(uid, volume, component)) return false; - if (component.MaterialWhiteList == null ? false : !component.MaterialWhiteList.Contains(materialId)) + if (!IsMaterialWhitelisted((uid, component), materialId)) return false; - var amount = component.Storage.GetValueOrDefault(materialId); + var amount = GetMaterialAmount(uid, materialId, component, localOnly); return amount + volume >= 0; } @@ -140,14 +178,24 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// /// /// If the amount can be changed - public bool CanChangeMaterialAmount(Entity entity, Dictionary materials) + /// + public bool CanChangeMaterialAmount(Entity entity, Dictionary materials, bool localOnly = false) { if (!Resolve(entity, ref entity.Comp)) return false; + var inVolume = materials.Values.Sum(); + var stored = GetStoredMaterials((entity, entity.Comp), localOnly); + + if (!CanTakeVolume(entity, inVolume, entity.Comp)) + return false; + foreach (var (material, amount) in materials) { - if (!CanChangeMaterialAmount(entity, material, amount, entity.Comp)) + if (!IsMaterialWhitelisted(entity, material)) + return false; + + if (stored.GetValueOrDefault(material) + amount < 0) return false; } @@ -163,16 +211,27 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// /// /// + /// /// If it was successful - public bool TryChangeMaterialAmount(EntityUid uid, string materialId, int volume, MaterialStorageComponent? component = null, bool dirty = true) + public bool TryChangeMaterialAmount(EntityUid uid, string materialId, int volume, MaterialStorageComponent? component = null, bool dirty = true, bool localOnly = false) { if (!Resolve(uid, ref component)) return false; - if (!CanChangeMaterialAmount(uid, materialId, volume, component)) + + if (!CanChangeMaterialAmount(uid, materialId, volume, component, localOnly)) return false; + var changeEv = new ConsumeStoredMaterialsEvent((uid, component), new() {{materialId, volume}}, localOnly); + RaiseLocalEvent(uid, ref changeEv); + var remaining = changeEv.Materials.Values.First(); + var existing = component.Storage.GetOrNew(materialId); - existing += volume; + + var localUpperLimit = component.StorageLimit == null ? int.MaxValue : component.StorageLimit.Value - existing; + var localLowerLimit = -existing; + var localChange = Math.Clamp(remaining, localLowerLimit, localUpperLimit); + + existing += localChange; if (existing == 0) component.Storage.Remove(materialId); @@ -191,23 +250,54 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// Changes the amount of a specific material in the storage. /// Still respects the filters in place. /// - /// - /// /// If the amount can be changed - public bool TryChangeMaterialAmount(Entity entity, Dictionary materials) + public bool TryChangeMaterialAmount(Entity entity, Dictionary materials, bool localOnly = false) + { + return TryChangeMaterialAmount(entity, materials.Select(p => (new ProtoId(p.Key), p.Value)).ToDictionary(), localOnly); + } + + /// + /// Changes the amount of a specific material in the storage. + /// Still respects the filters in place. + /// + /// If the amount can be changed + public bool TryChangeMaterialAmount( + Entity entity, + Dictionary, int> materials, + bool localOnly = false) { if (!Resolve(entity, ref entity.Comp)) return false; - if (!CanChangeMaterialAmount(entity, materials)) - return false; - foreach (var (material, amount) in materials) { - if (!TryChangeMaterialAmount(entity, material, amount, entity.Comp, false)) + if (!CanChangeMaterialAmount(entity, material, amount, entity)) return false; } + var changeEv = new ConsumeStoredMaterialsEvent((entity, entity.Comp), materials, localOnly); + RaiseLocalEvent(entity, ref changeEv); + + foreach (var (material, remaining) in changeEv.Materials) + { + var existing = entity.Comp.Storage.GetOrNew(material); + + var localUpperLimit = entity.Comp.StorageLimit == null ? int.MaxValue : entity.Comp.StorageLimit.Value - existing; + var localLowerLimit = -existing; + var localChange = Math.Clamp(remaining, localLowerLimit, localUpperLimit); + + existing += localChange; + + if (existing == 0) + entity.Comp.Storage.Remove(material); + else + entity.Comp.Storage[material] = existing; + + } + + var ev = new MaterialAmountChangedEvent(); + RaiseLocalEvent(entity, ref ev); + Dirty(entity, entity.Comp); return true; } @@ -221,6 +311,7 @@ public abstract class SharedMaterialStorageSystem : EntitySystem /// The stored material volume to set the storage to. /// The storage component on . Resolved automatically if not given. /// True if it was successful (enough space etc). + [PublicAPI] public bool TrySetMaterialAmount( EntityUid uid, string materialId, @@ -268,7 +359,7 @@ public abstract class SharedMaterialStorageSystem : EntitySystem totalVolume += vol * multiplier; } - if (!CanTakeVolume(receiver, totalVolume, storage)) + if (!CanTakeVolume(receiver, totalVolume, storage, localOnly: true)) return false; foreach (var (mat, vol) in composition.MaterialComposition) diff --git a/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl b/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl index 907baf4ffc..076a70447c 100644 --- a/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl +++ b/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl @@ -25,6 +25,7 @@ lathe-menu-material-amount-missing = { $amount -> *[other] {NATURALFIXED($amount, 2)} {MAKEPLURAL($unit)} of {$material} ([color=red]{NATURALFIXED($missingAmount, 2)} {MAKEPLURAL($unit)} missing[/color]) } lathe-menu-no-materials-message = No materials loaded. +lathe-menu-silo-linked-message = Silo Linked lathe-menu-fabricating-message = Fabricating... lathe-menu-materials-title = Materials lathe-menu-queue-title = Build Queue diff --git a/Resources/Locale/en-US/materials/silo.ftl b/Resources/Locale/en-US/materials/silo.ftl new file mode 100644 index 0000000000..32d7de8b2e --- /dev/null +++ b/Resources/Locale/en-US/materials/silo.ftl @@ -0,0 +1,10 @@ +ore-silo-ui-title = Material Silo +ore-silo-ui-label-clients = Machines +ore-silo-ui-label-mats = Materials +ore-silo-ui-itemlist-entry = {$linked -> + [true] {"[Linked] "} + *[False] {""} +} {$name} ({$beacon}) {$inRange -> + [true] {""} + *[false] (Out of Range) +} diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_materials.yml b/Resources/Prototypes/Catalog/Cargo/cargo_materials.yml index 097a11185b..35830900a8 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_materials.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_materials.yml @@ -98,6 +98,16 @@ category: cargoproduct-category-name-materials group: market +- type: cargoProduct + id: MaterialSilo + icon: + sprite: Structures/Machines/silo.rsi + state: silo + product: CrateMaterialSilo + cost: 5000 + category: cargoproduct-category-name-materials + group: market + - type: cargoProduct id: MaterialFuelTank icon: diff --git a/Resources/Prototypes/Catalog/Fills/Crates/materials.yml b/Resources/Prototypes/Catalog/Fills/Crates/materials.yml index f6eb9a17af..80c6311f13 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/materials.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/materials.yml @@ -153,6 +153,22 @@ # for some reason, the selector here adds 1 to whatever value it generates, # so this is actually 2-4 +- type: entity + id: CrateMaterialSilo + parent: CrateGenericSteel + name: material silo crate + description: A package including all the materials to create a material silo. + components: + - type: StorageFill + contents: + - id: MaterialSiloMachineCircuitboard + - id: SheetSteel1 + amount: 5 + - id: MatterBinStockPart + amount: 4 + - id: CableApcStack1 + amount: 2 + - type: entity id: CrateMaterialBasicResource parent: CrateGenericSteel diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 812b495ee9..48af55da3f 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -1005,6 +1005,19 @@ Manipulator: 1 Steel: 1 +- type: entity + id: MaterialSiloMachineCircuitboard + parent: BaseMachineCircuitboard + name: material silo machine board + components: + - type: Sprite + state: supply + - type: MachineBoard + prototype: MachineMaterialSilo + stackRequirements: + MatterBin: 4 + Cable: 1 + - type: entity id: OreProcessorMachineCircuitboard parent: BaseMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index 1761f176da..6ef8f7262f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -270,6 +270,7 @@ - Sheet materialWhiteList: - Plasma + - type: OreSiloClient - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml index 78f1504003..f7f1bcba1b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml @@ -44,6 +44,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: AmbientSound enabled: false volume: 5 diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 0d008ed1e1..3b4b9cf5d2 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -112,6 +112,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: Lathe idleState: icon runningState: building @@ -184,6 +185,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: Lathe idleState: icon runningState: building @@ -273,6 +275,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: RequireProjectileTarget - type: entity @@ -321,6 +324,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: GuideHelp guides: - Robotics @@ -408,6 +412,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: LatheAnnouncing channels: [Security] @@ -443,6 +448,7 @@ - Sheet - RawMaterial - Ingot + - type: OreSiloClient - type: entity id: MedicalTechFab @@ -480,6 +486,7 @@ board: MedicalTechFabCircuitboard - type: StealTarget stealGroup: MedicalTechFabCircuitboard + - type: OreSiloClient - type: LatheAnnouncing channels: [Medical] diff --git a/Resources/Prototypes/Entities/Structures/Machines/silo.yml b/Resources/Prototypes/Entities/Structures/Machines/silo.yml new file mode 100644 index 0000000000..31bfe42572 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Machines/silo.yml @@ -0,0 +1,61 @@ +- type: entity + id: MachineMaterialSilo + parent: [ BaseMachinePowered, ConstructibleMachine ] + name: material silo + description: An advanced machine, capable of using bluespace technology to transmit materials to nearby machines. + components: + - type: Sprite + sprite: Structures/Machines/silo.rsi + layers: + - state: silo + map: [ "base" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + base: + True: { state: silo_active } + False: { state: silo } + - type: OreSilo + - type: MaterialStorage + whitelist: + tags: + - Sheet + - Ingot + - type: ActivatableUI + key: enum.OreSiloUiKey.Key + - type: ActivatableUIRequiresPower + - type: UserInterface + interfaces: + enum.OreSiloUiKey.Key: + type: OreSiloBoundUserInterface + - type: Machine + board: MaterialSiloMachineCircuitboard + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + density: 190 + mask: + - MachineMask + layer: + - MachineLayer + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + - type: WiresVisuals + - type: WiresPanel + - type: StaticPrice + price: 1500 diff --git a/Resources/Textures/Structures/Machines/silo.rsi/meta.json b/Resources/Textures/Structures/Machines/silo.rsi/meta.json new file mode 100644 index 0000000000..aa78616897 --- /dev/null +++ b/Resources/Textures/Structures/Machines/silo.rsi/meta.json @@ -0,0 +1,40 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/d74b67828394a9842578279a6b8ab2955bb08216. Created by MrDoomBringer (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "silo" + }, + { + "name": "silo_active", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "overlay_active", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Machines/silo.rsi/overlay_active.png b/Resources/Textures/Structures/Machines/silo.rsi/overlay_active.png new file mode 100644 index 0000000000000000000000000000000000000000..0a06e45676e51e077b0d35b277127ea486a80662 GIT binary patch literal 336 zcmV-W0k8gvP)Px$3Q0skRCt{2+aXTGKokJbzX`#iP-HCz#Tf_}Kx2?ANKmUd018EdK(0Y^flbeV z!r(Tf3dJhS;K+&z+iubhY2TBRw!bs;Tl4=!0000mK9k(w)5k^1jnAep+3Wu@Uo6w% ze#GZ@#QoKIqx<`ezt{GGZ8e>Asra40+%6d~r1<}y3>Z5Z00000001x+*-FXl!*#Yk ze|q!Sy0TK$DIFg~ynjWU9Zh=g57?&j{(z>F9;~WPX|+zNs#A7XhaR8OJ5V}4rFWoo ze4xD5+V>9t0000G5k2$=?4r;3o%aWnKDv5xdHcJVZ_jt*?p4Sc{NZUCu!Rf&IyGM` ii^$((a$<9hE0hkxdunf<=`=by_C!+Xa6TR?eZSb-QYE&+2yt!D{ zc*pP+jw?XmUJ%n`LS9-#(n(0M-oRqCy6%IKB-lc?5Ruv5k?D4k^Nj%awctqK|}5AHYW5S)svSHx{&^ z#3Zz0*-GhfJh{QmxUMseolzn z)etacViDRxf1&3|FCvf=DJ}&Yw^SMR2|`=FemQn_ceC=nGUVjBS)DGU_1|qZ z+ILmQ$~+0vFCH=p>FMdi%xRyn_W|WV|Cw6mryMy@Z$6An5g6kd$;w2&?`RV?`c|^-i~6SDS&q;$iB@bAQQ#h}1w#*vNKl#k$VvqeZnfNF#Pm^F z|HNiCkjN9YNys6Rax1pm?gCK+62RJK-G3e`g;2q(;|2zH<;?&_Rq!Oia P00000NkvXXu0mjf?0yDu literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/silo.rsi/silo_active.png b/Resources/Textures/Structures/Machines/silo.rsi/silo_active.png new file mode 100644 index 0000000000000000000000000000000000000000..f25218b2d2d559043f83795c79652f1302485f08 GIT binary patch literal 1888 zcmV-m2cP(fP)(yp|nH0V0# z?%vruckXoWba(Cz+xe31ea-YcbMCqGI$vfa40HGn7;LbztTY_&AMCAfNCS_cf?wzW zN?cz02#m`fYxZwA6tZl$Am<7e;ba)1i{It|Bu8QdOOB|XlVvet`{i-4U{*10hLhn0 z)%+F*3`UNaFkvEW3{He)wWrL!!l_fB@oW>6L<}*F;KNtOI34`bCqX1fOfd)nVg}%h zRL_YR!6W!oIonJqRK4Oi9e^GyiG`C85psatuRjCNefX_yoX$e1@0x9_GB_9Z)_y~H zL{8Afuk127DG-2{Uwj_6eYpd4z=>bz0MYv6u`xKqT#JK+;ZUHGUn&CV`qKq3`8`_# z1(WmP-&@C!&_iTrXG43a15`nl-{ydAU+spq)yph>y#xKE{QcBP=&O1&Ht=kfWxIWc zj+*sz7n)&QRwlGIoi_W*D}r$iSItixF!$*v!Z!x4la7gj@vv^gMn?nR-BM%LSH4;W z?=VKRw6vJ@tfE5OzCYI0lJe1q9||8hc*Hyt>*N{@x~KXpS)(I18``;J@{& z0N&qZ+XhMdumm}%=C?Uu)TohgbajShOfE9qYwl;7Jb_Nb^t|oo#42Hji{M=I z-_Ucl7urBf6vz$0^0n*C_MObwPUGRMv%8zrryKtZJxy**n41%xoP{oa(*a0c`oMkA zaP((b`qDypujUh*0gYGB2o3A&?+01nb^65VMq9rwe$xR3`LQ!BlD{&q0&?>5NgE$V z-dOXNIsU==NS&U9(vN&$F{G!b4`$zg4}Cs|&vr)cz;KPyIuBj^mI#=f8@T~N@~yk- zV0qPRq>bcA%9p*NF39}rJ7~`@h1})_vMujnB&5Xn8!Q5J@LTQ!F#IUc2pWcH$fZlI zq>d%F(TGf=jpQpH%z&-Uk^PvrEny@=LOe55;P{mMNy69NI{1kLE_ZdOjY%IJHh!ct zbp3|KF#4ile#Mivmkx_(jk0aef*M3gMF+2wKehx~TGM70O(lctH+@X%bY1SO`<|>( z3{$pb$51AKje1visEKo%*j50F91 z>I1UUt?z*oR){1D9r^%Q3K15ms1Ha;A(9IE09Oi;WWXzZz~S=BSc6NC4+S@!J^+yu zO_B5I@qOGYa2edx`T!m*|Gket<`{u-^#PwQE)x>0*!_#^{CrvUW+=?WclrSJ8bJAOi0knf$!l2ym?r07!`6bA5o@2vE)MxjsN90(A0wt`Fd6K(#&~ z9>3@M0Con}%$rU6RO$ob@q4Zh*cTjPkz!*>7-bNKpz z!H9i*fUgg*!i)U8Zhp`70Yec;=-~HMAK*qHp^IPHWiXyVLKnX>eSjN*gi8KlqYrSx zkd}a%qfbJ9UN`@c^Z_#Y`JoCVRP!gK58z?Z2c(a7Oi!!O2gvd#tPjBaJV}j5f%*B* z@17ytUzDCsgrDjI65&r+A8^?SLn4kqWMz>2JS6Y|1vmUuAAmME@#F0>MfBOhg5>H0 zlJEfq*Zc;mX#@!PMF-8obA5o@2uL=+R0MdLpO=XMFZrb+z{~tR9|5ZM0el1~*9Wi> zK(Es(^#N=Ii1@w#egFsM-w%kx@9P6-#jE^0o&$EQUPStJ=mYQ^(ErmmM}E)s0eJ8_ z^#OSBTE8EFW|t0 literal 0 HcmV?d00001 From 297a9a8762bcc37ad08a2e4ba79acb0d5e03aa21 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 18 Apr 2025 23:44:24 +0000 Subject: [PATCH 04/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b4c7676377..33b0a69a7a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: J C Denton - changes: - - message: Syndicate and NanoTrasen NPCs and turrets are now hostile to Dragons - and Carps - type: Tweak - id: 7741 - time: '2024-12-20T21:38:27.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/32515 - author: lzk228 changes: - message: Item's tool function now shows on examine. @@ -3912,3 +3904,11 @@ id: 8241 time: '2025-04-18T23:34:59.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/34223 +- author: EmoGarbage404 + changes: + - message: Added the material silo. This machine allows nearby machines to share + a pool of resources, cutting down on micromanagement. + type: Add + id: 8242 + time: '2025-04-18T23:43:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/36492 From 37f16c3abdcfa79e2952df4ef5b9bc0bd9fe2f50 Mon Sep 17 00:00:00 2001 From: OneZerooo0 <172208291+OneZerooo0@users.noreply.github.com> Date: Fri, 18 Apr 2025 20:04:44 -0400 Subject: [PATCH 05/16] Modular Grenades now fit in security belts/carriers (#34169) * Added PayloadCase component to secbelt whitelist * Replaced PayloadCase type whitelist with a tag * fucking hell * Add HandGrenade tag to all grenades Grenades are so unbelievably cooked right now. I've counted about 4 separate baseitems that they inherit from whenever they feel like it. Why? They're all the same. --------- Co-authored-by: Milon Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> --- Resources/Prototypes/Entities/Clothing/Belt/belts.yml | 1 + .../Entities/Objects/Weapons/Throwable/grenades.yml | 7 +++++++ .../Objects/Weapons/Throwable/projectile_grenades.yml | 3 +++ .../Objects/Weapons/Throwable/scattering_grenades.yml | 3 +++ Resources/Prototypes/tags.yml | 3 +++ 5 files changed, 17 insertions(+) diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index efae094765..27cd2921b8 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -481,6 +481,7 @@ - MagazineMagnum - CombatKnife - Truncheon + - HandGrenade components: - Stunbaton - FlashOnTrigger diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 8be5b5f8aa..ebfdf184f7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -35,6 +35,9 @@ enum.ConstructionVisuals.Layer: Primed: { state: primed } Unprimed: { state: icon } + - type: Tag + tags: + - HandGrenade - type: entity name: explosive grenade @@ -83,6 +86,7 @@ - Antagonists - type: Tag tags: + - HandGrenade - GrenadeFlashBang - type: entity @@ -312,6 +316,9 @@ map: [ "enum.ConstructionVisuals.Layer" ] - type: Item size: Small + - type: Tag + tags: + - HandGrenade - type: PayloadCase - type: Construction graph: ModularGrenadeGraph diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml index 6a111ef1c8..41fad224c4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml @@ -25,6 +25,9 @@ enum.ConstructionVisuals.Layer: Primed: { state: primed } Unprimed: { state: icon } + - type: Tag + tags: + - HandGrenade - type: entity parent: [ProjectileGrenadeBase, BaseSecurityContraband] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml index 38fde5c540..a3087f1f9e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml @@ -18,6 +18,9 @@ behaviors: - !type:TriggerBehavior - type: ScatteringGrenade + - type: Tag + tags: + - HandGrenade - type: entity parent: [ScatteringGrenadeBase, BaseSecurityContraband] diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index bd3644d53c..910c24b303 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -641,6 +641,9 @@ - type: Tag id: Handcuffs +- type: Tag + id: HandGrenade + - type: Tag id: HappyHonk From 181bb27797b2f54315178b79de7bafad5d4e3499 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 19 Apr 2025 00:05:50 +0000 Subject: [PATCH 06/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 33b0a69a7a..a5fda209ff 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: lzk228 - changes: - - message: Item's tool function now shows on examine. - type: Add - id: 7742 - time: '2024-12-20T22:15:40.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/32436 - author: Pinkbat5 changes: - message: Diona can now chirp. @@ -3912,3 +3905,10 @@ id: 8242 time: '2025-04-18T23:43:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/36492 +- author: Onezero0 + changes: + - message: Modular Grenades can now fit inside Security belts and carriers. + type: Tweak + id: 8243 + time: '2025-04-19T00:04:44.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/34169 From a6741e42c13dc1fbd717264e389074b4fa33bbe7 Mon Sep 17 00:00:00 2001 From: Jajsha <101492056+Zap527@users.noreply.github.com> Date: Fri, 18 Apr 2025 20:11:28 -0400 Subject: [PATCH 07/16] Un-Hardcode water evaporation & mopping behavior (#33399) * Un-harcode slipperiness * Make it actually work * Prettyfy * Cleanup GetEvaporatingReagents * Fix mopping with space lube + wrong solutions in absorbance * Remove LINQ and rename parameters * Change evaporation speed to fixedpoint2 * Add evaporating speed functionality * Remove unused imports * Swap around reagent evaporation speed and puddle evaporation speed. --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> --- .../Fluids/EntitySystems/AbsorbentSystem.cs | 22 +++++----- .../EntitySystems/PuddleSystem.Evaporation.cs | 10 +++-- .../Chemistry/Reagent/ReagentPrototype.cs | 17 ++++++-- .../Fluids/Components/EvaporationComponent.cs | 4 +- .../Fluids/SharedPuddleSystem.Evaporation.cs | 43 +++++++++++++++++-- Content.Shared/Fluids/SharedPuddleSystem.cs | 2 +- .../Reagents/Consumable/Drink/drinks.yml | 2 + 7 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs index 56e039a700..cb3cae10af 100644 --- a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs +++ b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs @@ -57,14 +57,14 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem var oldProgress = component.Progress.ShallowClone(); component.Progress.Clear(); - var water = solution.GetTotalPrototypeQuantity(PuddleSystem.EvaporationReagents); - if (water > FixedPoint2.Zero) + var mopReagent = solution.GetTotalPrototypeQuantity(_puddleSystem.GetAbsorbentReagents(solution)); + if (mopReagent > FixedPoint2.Zero) { - component.Progress[solution.GetColorWithOnly(_prototype, PuddleSystem.EvaporationReagents)] = water.Float(); + component.Progress[solution.GetColorWithOnly(_prototype, _puddleSystem.GetAbsorbentReagents(solution))] = mopReagent.Float(); } - var otherColor = solution.GetColorWithout(_prototype, PuddleSystem.EvaporationReagents); - var other = (solution.Volume - water).Float(); + var otherColor = solution.GetColorWithout(_prototype, _puddleSystem.GetAbsorbentReagents(solution)); + var other = (solution.Volume - mopReagent).Float(); if (other > 0f) { @@ -180,7 +180,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem } // Prioritize transferring non-evaporatives if absorbent has any - var contaminants = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, transferAmount, PuddleSystem.EvaporationReagents); + var contaminants = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, transferAmount, _puddleSystem.GetAbsorbentReagents(absorbentSoln.Comp.Solution)); if (contaminants.Volume > 0) { _solutionContainerSystem.TryAddSolution(refillableSoln, contaminants); @@ -205,7 +205,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem Entity absorbentSoln, Entity refillableSoln) { - var contaminantsFromAbsorbent = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, component.PickupAmount, PuddleSystem.EvaporationReagents); + var contaminantsFromAbsorbent = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, component.PickupAmount, _puddleSystem.GetAbsorbentReagents(absorbentSoln.Comp.Solution)); var absorbentSolution = absorbentSoln.Comp.Solution; if (contaminantsFromAbsorbent.Volume == FixedPoint2.Zero && absorbentSolution.AvailableVolume == FixedPoint2.Zero) @@ -222,7 +222,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem absorbentSolution.AvailableVolume; var refillableSolution = refillableSoln.Comp.Solution; - var waterFromRefillable = refillableSolution.SplitSolutionWithOnly(waterPulled, PuddleSystem.EvaporationReagents); + var waterFromRefillable = refillableSolution.SplitSolutionWithOnly(waterPulled, _puddleSystem.GetAbsorbentReagents(refillableSoln.Comp.Solution)); _solutionContainerSystem.UpdateChemicals(refillableSoln); if (waterFromRefillable.Volume == FixedPoint2.Zero && contaminantsFromAbsorbent.Volume == FixedPoint2.Zero) @@ -284,7 +284,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem // Check if we have any evaporative reagents on our absorber to transfer var absorberSolution = absorberSoln.Comp.Solution; - var available = absorberSolution.GetTotalPrototypeQuantity(PuddleSystem.EvaporationReagents); + var available = absorberSolution.GetTotalPrototypeQuantity(_puddleSystem.GetAbsorbentReagents(absorberSolution)); // No material if (available == FixedPoint2.Zero) @@ -296,8 +296,8 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem var transferMax = absorber.PickupAmount; var transferAmount = available > transferMax ? transferMax : available; - var puddleSplit = puddleSolution.SplitSolutionWithout(transferAmount, PuddleSystem.EvaporationReagents); - var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, PuddleSystem.EvaporationReagents); + var puddleSplit = puddleSolution.SplitSolutionWithout(transferAmount, _puddleSystem.GetAbsorbentReagents(puddleSolution)); + var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, _puddleSystem.GetAbsorbentReagents(absorberSolution)); // Do tile reactions first var transform = Transform(target); diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.Evaporation.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.Evaporation.cs index d78950b1d5..f92504e74c 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleSystem.Evaporation.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.Evaporation.cs @@ -1,4 +1,5 @@ using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Content.Shared.Fluids.Components; @@ -20,7 +21,7 @@ public sealed partial class PuddleSystem return; } - if (solution.GetTotalPrototypeQuantity(EvaporationReagents) > FixedPoint2.Zero) + if (solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) > FixedPoint2.Zero) { var evaporation = AddComp(uid); evaporation.NextTick = _timing.CurTime + EvaporationCooldown; @@ -45,8 +46,11 @@ public sealed partial class PuddleSystem if (!_solutionContainerSystem.ResolveSolution(uid, puddle.SolutionName, ref puddle.Solution, out var puddleSolution)) continue; - var reagentTick = evaporation.EvaporationAmount * EvaporationCooldown.TotalSeconds; - puddleSolution.SplitSolutionWithOnly(reagentTick, EvaporationReagents); + foreach ((string evaporatingReagent, FixedPoint2 evaporatingSpeed) in GetEvaporationSpeeds(puddleSolution)) + { + var reagentTick = evaporation.EvaporationAmount * EvaporationCooldown.TotalSeconds * evaporatingSpeed; + puddleSolution.SplitSolutionWithOnly(reagentTick, evaporatingReagent); + } // Despawn if we're done if (puddleSolution.Volume == FixedPoint2.Zero) diff --git a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs index 84cdb47494..cfca682e9b 100644 --- a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs +++ b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs @@ -1,5 +1,6 @@ using System.Collections.Frozen; using System.Linq; +using Content.Shared.FixedPoint; using System.Text.Json.Serialization; using Content.Shared.Administration.Logs; using Content.Shared.Body.Prototypes; @@ -7,14 +8,12 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reaction; using Content.Shared.EntityEffects; using Content.Shared.Database; -using Content.Shared.FixedPoint; using Content.Shared.Nutrition; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; using Robust.Shared.Utility; @@ -105,6 +104,18 @@ namespace Content.Shared.Chemistry.Reagent [DataField] public bool Slippery; + /// + /// The speed at which the reagent evaporates over time. + /// + [DataField] + public FixedPoint2 EvaporationSpeed = FixedPoint2.Zero; + + /// + /// If this reagent can be used to mop up other reagents. + /// + [DataField] + public bool Absorbent = false; + /// /// How easily this reagent becomes fizzy when aggitated. /// 0 - completely flat, 1 - fizzes up when nudged. @@ -206,7 +217,7 @@ namespace Content.Shared.Chemistry.Reagent .ToDictionary(x => x.Key, x => x.Item2); if (proto.PlantMetabolisms.Count > 0) { - PlantMetabolisms = new List (proto.PlantMetabolisms + PlantMetabolisms = new List(proto.PlantMetabolisms .Select(x => x.GuidebookEffectDescription(prototype, entSys)) .Where(x => x is not null) .Select(x => x!) diff --git a/Content.Shared/Fluids/Components/EvaporationComponent.cs b/Content.Shared/Fluids/Components/EvaporationComponent.cs index 5545bd7be5..9b46629439 100644 --- a/Content.Shared/Fluids/Components/EvaporationComponent.cs +++ b/Content.Shared/Fluids/Components/EvaporationComponent.cs @@ -18,8 +18,8 @@ public sealed partial class EvaporationComponent : Component public TimeSpan NextTick = TimeSpan.Zero; /// - /// How much evaporation per second. + /// Evaporation factor. Multiplied by the evaporating speed of the reagent. /// [DataField("evaporationAmount")] - public FixedPoint2 EvaporationAmount = FixedPoint2.New(0.3); + public FixedPoint2 EvaporationAmount = FixedPoint2.New(1); } diff --git a/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs b/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs index 023d024a05..8b937ed1a7 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs @@ -1,17 +1,52 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; namespace Content.Shared.Fluids; public abstract partial class SharedPuddleSystem { - [ValidatePrototypeId] - private const string Water = "Water"; + public string[] GetEvaporatingReagents(Solution solution) + { + var evaporatingReagents = new List(); + foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) + { + if (solProto.EvaporationSpeed > FixedPoint2.Zero) + evaporatingReagents.Add(solProto.ID); + } + return evaporatingReagents.ToArray(); + } - public static readonly string[] EvaporationReagents = [Water]; + public string[] GetAbsorbentReagents(Solution solution) + { + var absorbentReagents = new List(); + foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) + { + if (solProto.Absorbent) + absorbentReagents.Add(solProto.ID); + } + return absorbentReagents.ToArray(); + } public bool CanFullyEvaporate(Solution solution) { - return solution.GetTotalPrototypeQuantity(EvaporationReagents) == solution.Volume; + return solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) == solution.Volume; + } + + /// + /// Gets the evaporating speed of the reagents within a solution. + /// The speed at which a solution evaporates is the sum of the speed of all evaporating reagents in it. + /// + public Dictionary GetEvaporationSpeeds(Solution solution) + { + var evaporatingSpeeds = new Dictionary(); + foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) + { + if (solProto.EvaporationSpeed > FixedPoint2.Zero) + { + evaporatingSpeeds.Add(solProto.ID, solProto.EvaporationSpeed); + } + } + return evaporatingSpeeds; } } diff --git a/Content.Shared/Fluids/SharedPuddleSystem.cs b/Content.Shared/Fluids/SharedPuddleSystem.cs index f573c042c5..34ba8ba803 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.cs @@ -100,7 +100,7 @@ public abstract partial class SharedPuddleSystem : EntitySystem { if (CanFullyEvaporate(solution)) args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating")); - else if (solution.GetTotalPrototypeQuantity(EvaporationReagents) > FixedPoint2.Zero) + else if (solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) > FixedPoint2.Zero) args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating-partial")); else args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating-no")); diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml index f72733d15d..c722c42162 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml @@ -436,6 +436,8 @@ parent: BaseDrink desc: reagent-desc-water slippery: true + evaporationSpeed: 0.3 + absorbent: true physicalDesc: reagent-physical-desc-translucent flavor: water color: "#75b1f0" From 56feab4e0bc74fbbb4186d0d19a238ebe068a199 Mon Sep 17 00:00:00 2001 From: Aaron Date: Fri, 18 Apr 2025 20:14:44 -0400 Subject: [PATCH 08/16] Add PreventFTLComponent and changed FTL check (#34077) * Add PreventFTLComponent and changed FTL check * Remove component body. --------- Co-authored-by: Milon --- .../Shuttles/Systems/ShuttleSystem.FasterThanLight.cs | 2 +- .../Shuttles/Components/PreventFTLComponent.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 Content.Shared/Shuttles/Components/PreventFTLComponent.cs diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index cae6c443dd..40464e516f 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -243,7 +243,7 @@ public sealed partial class ShuttleSystem } } - if (HasComp(shuttleUid)) + if (HasComp(shuttleUid) || HasComp(shuttleUid)) { reason = Loc.GetString("shuttle-console-prevent"); return false; diff --git a/Content.Shared/Shuttles/Components/PreventFTLComponent.cs b/Content.Shared/Shuttles/Components/PreventFTLComponent.cs new file mode 100644 index 0000000000..343e1ffb06 --- /dev/null +++ b/Content.Shared/Shuttles/Components/PreventFTLComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Shuttles.Components; + +/// +/// Add to grids that you do not want to FTL, but still might want to pilot. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class PreventFTLComponent : Component; From 07c1a6fd45f47c625ce6cdd242ca3d71b5449e26 Mon Sep 17 00:00:00 2001 From: Alpaccalypse <21291379+Alpaccalypse@users.noreply.github.com> Date: Sat, 19 Apr 2025 01:24:26 +0100 Subject: [PATCH 09/16] Change 'Irish slammer' to 'Grenade Penguin' (#34181) * Changed irish slammer to grenade penguin. * changed DrinkGlass suffix to grenade penguin * Fixed typo * Added penguin squawk to reaction * Added comment as ID differs from localisation * Minor, post merge fix --- .../Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl | 4 ++-- .../Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml | 2 +- Resources/Prototypes/Recipes/Reactions/drinks.yml | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl b/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl index 962f0898b1..5a22328900 100644 --- a/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl +++ b/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl @@ -157,8 +157,8 @@ reagent-desc-hooch = Either someone's failure at cocktail making or attempt in a reagent-name-iced-beer = iced beer reagent-desc-iced-beer = A beer which is so cold the air around it freezes. -reagent-name-irish-slammer = Irish slammer -reagent-desc-irish-slammer = An unconventional mixture of irish cream and stout. +reagent-name-irish-slammer = Grenade Penguin +reagent-desc-irish-slammer = What's black and white and red all over? reagent-name-irish-cream = Irish cream reagent-desc-irish-cream = Whiskey-imbued cream. What else could you expect from the Irish. diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml index ca56fbcb35..1891ed71ec 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml @@ -1116,7 +1116,7 @@ - type: entity parent: DrinkGlass id: DrinkIrishSlammer - suffix: irish slammer + suffix: grenade penguin components: - type: SolutionContainerManager solutions: diff --git a/Resources/Prototypes/Recipes/Reactions/drinks.yml b/Resources/Prototypes/Recipes/Reactions/drinks.yml index a46dfa2969..b307166aa8 100644 --- a/Resources/Prototypes/Recipes/Reactions/drinks.yml +++ b/Resources/Prototypes/Recipes/Reactions/drinks.yml @@ -573,6 +573,8 @@ amount: 1 products: IrishSlammer: 2 + sound: + path: /Audio/Animals/penguin_squawk.ogg # Cocktail is called grenade penguin in localisation - type: reaction id: IrishCoffee From d569c3b73c26ac9ef94fde41e80c8fa23a2c2127 Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Sat, 19 Apr 2025 02:25:29 +0200 Subject: [PATCH 10/16] Make artifact module actually useful. (#33338) Init --- .../Entities/Objects/Specific/Robotics/borg_modules.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 44855ccfa3..f26cb0a041 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -606,6 +606,11 @@ - type: ItemBorgModule items: - NodeScanner + - Multitool + - Wrench + - SprayBottle + - Beaker + - Syringe - type: BorgModuleIcon icon: { sprite: Interface/Actions/actions_borg.rsi, state: node-scanner-module } From 7b78feb308730150dfdc1a4b627ed9abbe55c5fc Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 19 Apr 2025 00:25:32 +0000 Subject: [PATCH 11/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a5fda209ff..365d2a41f7 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: Pinkbat5 - changes: - - message: Diona can now chirp. - type: Add - - message: Nymphs can scream and laugh like adult diona. - type: Add - id: 7743 - time: '2024-12-20T22:34:44.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/32511 - author: ScarKy0 changes: - message: Syndicate uplinks now have 6 discounts instead of 3. @@ -3912,3 +3903,10 @@ id: 8243 time: '2025-04-19T00:04:44.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/34169 +- author: Alpaccalypse + changes: + - message: The cocktail "Irish slammer" has been renamed to "Grenade Penguin". + type: Tweak + id: 8244 + time: '2025-04-19T00:24:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/34181 From d0c2a6443623b429d447b5096826958b12864cfe Mon Sep 17 00:00:00 2001 From: August Sun <45527070+august-sun@users.noreply.github.com> Date: Fri, 18 Apr 2025 18:26:23 -0600 Subject: [PATCH 12/16] Resprited the Chief Engineer's mantle/manica (#36697) * Swapped sprites, updated JSON and name/description of item * Change RSI meta.json spacing --------- Co-authored-by: august-sun <45527070+august.sun@users.noreply.github.com> Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> --- .../Entities/Clothing/Neck/mantles.yml | 6 ++-- .../mantles/cemantle.rsi/equipped-NECK.png | Bin 817 -> 762 bytes .../Neck/mantles/cemantle.rsi/icon.png | Bin 393 -> 353 bytes .../Neck/mantles/cemantle.rsi/meta.json | 32 +++++++++--------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml index bd389bcf4a..586cc5e665 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml @@ -12,8 +12,8 @@ - type: entity parent: [ClothingNeckBase, BaseCommandContraband] id: ClothingNeckMantleCE - name: chief engineer's mantle - description: High visibility, check. RIG system, check. High capacity cell, check. Everything a chief engineer could need in a stylish mantle. + name: chief engineer's manica + description: A segmented arm covering for the experienced Chief Engineer, to signify the hazards of the job and the dangers faced to earn it. components: - type: Sprite sprite: Clothing/Neck/mantles/cemantle.rsi @@ -84,4 +84,4 @@ - type: Sprite sprite: Clothing/Neck/mantles/mantle.rsi - type: Clothing - sprite: Clothing/Neck/mantles/mantle.rsi + sprite: Clothing/Neck/mantles/mantle.rsi diff --git a/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/equipped-NECK.png b/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/equipped-NECK.png index 9ec0e02042445ad137b4b3b0060eb0d393ad06ef..9ad2fba78d8b35fee3e56851877935d1cfdf5cdd 100644 GIT binary patch delta 725 zcmV;`0xJEn2Koh%F@Lm4L_t(|ob8&wiyA=`$G?UI;&DidglmGGECd#rGG%$BdG*QurM4PZ0yA1PEzFdmYstuUW#>ePqV+&)p)#5 zv*^yu`@VT^XO^7@Fbu;m48t(qPy<8_kgh4TX)S)}nnF@**nd6`f*Q!dOaZjY2D~O= z5#vz^3WBaF)G8Y=#a-P&_)Y*dK&Eh<7q`xTmMw5p*{6E7L?BSTTB4)MK3TSiY&$!7 zi#h6tDV*^EKz}{R0RYa>gWApkZJ;;S_dMh1O+K1VLgFnFUgLV+kf~lOoE@`u*g94&%@i7T6cGxNPPQlM4te+@zUos0QeerivWP#ousef zu;`jHN$)83Pu~od4}z{KbaeviRzPy#|DC*=rfvmvb$_ygT}!UI+v2<=uck@vNnPT3l%WepUYN?^OdHK5p35ak)%H10L%>uV!$4G4S@k{PfK&I41OE6Ln# zeEubJ9oV!EhG7_nVHk#C7=~dOhGFgjaUFqgg2bSA zK;ed{^EeS&L+A+r#sv}?U@zqu`&Yq4?6`_DhM3o*9^}x8%eJm5)U7zRI^D|Vi>9QW zi{r)hL`qj_pq4dI{i&>^0Ag9(PRFiCp1E)HnNHy>k#+&VsTpXMx3gwoX=Db-GL-v} z1(7nqvIVq{X?%G#h)d7fiM(jIqrNRg6AZ&J48t%C!_4s)Dvo+ny8P9S00000NkvXX Hu0mjf26<#( delta 781 zcmV+o1M>X(1+fN@F@NhxL_t(|ob8&iYTHm0hJQ6(Y(!t6!CO!llObT^sbJ{fu@C}X zvjmLiJcJ1(LvV42LYH*t&^Iu2O5@_81VV)uS7=Bu9V~?J;Nf;qj&&t$<;s@r7|u6E z($)Eo&ONdq{{a|=VHk#CnC+ojwq(-rN|0?x*@m1aRxMkS)_<&0U$!Af7m!D_0|@{} zwF5c22(P8pf1xW50GN%Hz6 zo-Ba+@Bpy82ec~Avdu}A3a~cF2KwK_!J(u;LN>$QB-~Eun3popX%mNzB>Ae1?b*7MjeI7F8gDF z?yX}00B(Q|Yyd#wx&=}7n~yp`Pz*DlgJ=New?I?fq<_=jmbQLk0VoOGWOdf1h2owf zXlH*c!ft!)0Jl$F85E;)V{7NKlB8EnsTg#H`0)q1w{Mo}Hm%R#bEA9f82(rQm&?Cu zTUmf9jZG)OFbu;m48t%C!!QiPFbuBS2ruvxq-;c01)K5qZcPt2l!t^s_Bb$KpQ|E;g1D&Qgnb8^jWE# z$+dmz7Nv3~(9Qx#f)u)z>(BaIS!rg`SbySaC=g=mVIx7p_(Xf$V5T`=Z`J!9wtVw+mg3u6AsN>(F^sudw<)C1BfNe{eWJ#CFg#C zSeEBkGVpa(EEbC7Y1K^Tet=ao3-RCf?PQ?Swxv6TMVJWWMWR@+|Mp1~uY+mMA_RA; zHX8?Ji)nG+g?e*C!f5@PKL+0|?%&zK*zt@$4QbU(E}3QVdNVl!F#zk{EQkUO-)*8; zFm}8@hq2T^YFYwdNYc(I7F^>ci{BmaUFg3wvUzxVohjb}<-|NE$4OVj^9SbXk@DYe zLg^a*WbAlG6bl$pNqlDm8G}l@H5!dZqXA$AM|p+3W{n3h00000NkvXXu0mjfVGE*Q diff --git a/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/meta.json b/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/meta.json index a9b40d83e2..ea254a4b4f 100644 --- a/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/meta.json +++ b/Resources/Textures/Clothing/Neck/mantles/cemantle.rsi/meta.json @@ -1,18 +1,18 @@ { - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "made by emisse for ss14", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "made by augustsun(Discord)/august-sun(GitHub) for SS14", + "size": { + "x": 32, + "y": 32 }, - { - "name": "equipped-NECK", - "directions": 4 - } - ] -} \ No newline at end of file + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-NECK", + "directions": 4 + } + ] +} From f23851a30df80d1bca090f6ad4bcdd1a55d8e558 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 19 Apr 2025 00:27:30 +0000 Subject: [PATCH 13/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 365d2a41f7..0ecf50231c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,18 +1,4 @@ Entries: -- author: ScarKy0 - changes: - - message: Syndicate uplinks now have 6 discounts instead of 3. - type: Tweak - id: 7744 - time: '2024-12-21T02:14:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33950 -- author: JustinWinningham - changes: - - message: Wood walls no longer require girders and are built from barricades instead. - type: Tweak - id: 7745 - time: '2024-12-21T03:28:46.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33902 - author: ElectroJr changes: - message: Toolshed console commands have been reworked. Some old commands may no @@ -3910,3 +3896,17 @@ id: 8244 time: '2025-04-19T00:24:26.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/34181 +- author: ScarKy0 + changes: + - message: Added a couple more tools to the artifact borg module. + type: Tweak + id: 8245 + time: '2025-04-19T00:25:29.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/33338 +- author: august-sun + changes: + - message: Resprited the Chief Engineer's mantle. + type: Tweak + id: 8246 + time: '2025-04-19T00:26:24.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/36697 From cfda91e0f02b55cbbd47fa7d6d69c14b203f9db3 Mon Sep 17 00:00:00 2001 From: Preston Smith <92108534+thetolbean@users.noreply.github.com> Date: Fri, 18 Apr 2025 19:33:14 -0500 Subject: [PATCH 14/16] Correct mobster suffix (#33240) Correct mob grammar --- Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs index 0e9b0a34ef..5906bf3ed4 100644 --- a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs @@ -14,7 +14,7 @@ public sealed class MobsterAccentSystem : EntitySystem private static readonly Regex RegexUpperAr = new(@"(?<=\w)A[Rr](?=\w)"); private static readonly Regex RegexFirstWord = new(@"^(\S+)"); private static readonly Regex RegexLastWord = new(@"(\S+)$"); - + private static readonly Regex RegexLastPunctuation = new(@"([.!?]+$)(?!.*[.!?])|(? Date: Fri, 18 Apr 2025 20:38:33 -0400 Subject: [PATCH 15/16] Fix two zombie bugs (#34472) * fix two zombie bugs * add comment --- Content.Server/Zombies/ZombieSystem.cs | 8 +++++++- Content.Shared/Zombies/PendingZombieComponent.cs | 2 +- Resources/Prototypes/Entities/Mobs/Species/vox.yml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index e34ecb4ad5..054bd0f6ec 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -87,6 +87,13 @@ namespace Content.Server.Zombies private void OnPendingMapInit(EntityUid uid, IncurableZombieComponent component, MapInitEvent args) { _actions.AddAction(uid, ref component.Action, component.ZombifySelfActionPrototype); + + if (HasComp(uid) || HasComp(uid)) + return; + + EnsureComp(uid, out PendingZombieComponent pendingComp); + + pendingComp.GracePeriod = _random.Next(pendingComp.MinInitialInfectedGrace, pendingComp.MaxInitialInfectedGrace); } private void OnPendingMapInit(EntityUid uid, PendingZombieComponent component, MapInitEvent args) @@ -98,7 +105,6 @@ namespace Content.Server.Zombies } component.NextTick = _timing.CurTime + TimeSpan.FromSeconds(1f); - component.GracePeriod = _random.Next(component.MinInitialInfectedGrace, component.MaxInitialInfectedGrace); } public override void Update(float frameTime) diff --git a/Content.Shared/Zombies/PendingZombieComponent.cs b/Content.Shared/Zombies/PendingZombieComponent.cs index 0fb61c84df..b199edeb00 100644 --- a/Content.Shared/Zombies/PendingZombieComponent.cs +++ b/Content.Shared/Zombies/PendingZombieComponent.cs @@ -17,7 +17,7 @@ public sealed partial class PendingZombieComponent : Component { DamageDict = new () { - { "Poison", 0.2 }, + { "Poison", 0.4 }, } }; diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index dc93dc8fdf..4703bfd06b 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -43,7 +43,7 @@ damage: types: Heat: -0.07 - Poison: -0.2 + Poison: -0.2 # needs to be less than the PendingZombieComponent does or they never become zombies by the disease. groups: Brute: -0.07 - type: DamageVisuals From 46b13897aba71438809e564e354cf0416fe801b6 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 19 Apr 2025 00:39:40 +0000 Subject: [PATCH 16/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0ecf50231c..1748858c5d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: ElectroJr - changes: - - message: Toolshed console commands have been reworked. Some old commands may no - longer work. - type: Tweak - id: 7746 - time: '2024-12-21T06:45:48.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33598 - author: muburu changes: - message: Space Ninjas now have silent footsteps. @@ -3910,3 +3902,13 @@ id: 8246 time: '2025-04-19T00:26:24.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/36697 +- author: IProduceWidgets + changes: + - message: Vox are no longer immune to the zombie virus under certain circumstances + type: Fix + - message: The zombie virus no longer provides non-Initial Infected an undue grace + period before poisoning them. + type: Fix + id: 8247 + time: '2025-04-19T00:38:33.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/34472