Qylr4Ix(oXDls;OE+)TYpci+y
z!%-KvRRDj!6d}J>#bGUI&_~-}ahKml9FxGV-qH-RRAL8?mqhUBvo)z|l4Ern=-BG)
z?gjg>X3d&nDF=2dF7B!7h%YT96HnThwKpv#3?5S4j_Mtz`6f~68qxVz`vS(3hg5S0
zSr?#f4fL$A)Z!XaA3R?yyoKNAj=96TWf$g*%|!zwZA;L9H31;^6oRFUc9cv+|#M)`VwgwrFSr!qCcJ^
z^C^sC*RZRVu4nD9WN)loUI98YU1%`2`jMo+q!*Qz^-WHq!-#r5vA1ejH}+W-nkw&F
zjxDu95Yx?T+L~rcCfvD%(2v1%c|@bb-{H7!szt3Fk~S`1QXyRcNG~HB7TnM29i>5E
z_lu(!PU&s&pD)J0X^x`q5*l^u;)Ehc)73H#p-e2Cpn6OBd(TzK9$;z#lHTdCKmDCT
zmf0?J@pAUYDY@ue9Zio^Ifr$M0;&1Q{70zTIFtS2P)*iWA7|U%ePW~+Fe)$}^rJ($
z<8Ms3u@d4p#0!okV;!MS@in>N)YmwP*de8S>nhExye1TfP%c8hjHy#PD)eelY8Y7$
z9qZ-^5Xupg(T@)(GB>88M|)6KHWYo4;kNIeEDLFsG#~8b!K!6C~T<5*L@u^
zztMKaVv8@)e9m}rF?A;U6*-HpVTO$*0zC=cVGAJbSpkX>4|>BCbY|t)IzhT!0@&&d
z2Eyr#}DK;NO^rs(ibH_VV2qI$bcKH-v_reh74-n?>_LDnCWbIFslvdZd2r$00M+
zY`xD&{LgkqP1i%>=5R8cwaIT1n5ZXE)3djqSmc6a|KG|1Z;xRxQNtzX-L@KE%$T+2
z3^}Ip*#&IU@2vULZAV$$i&_GM06JEdHaC{qg@Ny$3$)4z|1qlUPG)wv_)BJ~ZJxCx
zeU9I0B;2b+$4#FonSo_J6)ypX1FnoW2U5q3IEldMPiJb96v*=Nmq0sFDC(x7ENw&?cBnsW!w
zn5lK=!c(b$2qXvl#QP4}?2YVLGZGz&wG6Wa`13ObQZKSslw9}XzeKnhy9t}z-aw*G
z<|BRHq(Q^a3c1SCeP~t3Sk#%xwN!*$uD+&`y>O}q!9W_96^XL_=WGsV;(YI!L<>@*
zvJ^;5od!n{uIeqLmFYmF8c-IwAR%yFV#uUkQ(?&Lp>GZcle1Pj^&r9g%0M}Msn;E{
z9eb!o=ZSGVtl&7kYm2WT_30q^Nsw=N+0@G!O&3RTzv&lFH`L_x3is$ZyXQK5_Di;DvBArM7PCA+|FoPut;
z1mi{$)1oV7@Pzbit*`RQ*6WJ;^9E#-Mzc`zhXYTNZM?r)3n{Khx}iZe?a5``bU6^Y
zib8I2_g;VC;SLj)w^>DQXFw*JuIqV2+$q1ODbdUycRk+(yNL}O9?e^oxK~r5=LqIS
za=#j;Rf}LcEfxMhwIIGPmuu7@S=@rruQR`!OridZBUMK)Qw@+=^k9RN#M$$W<(o0-
z@z40WpGA*#a6-Q7lJ~pBL3DxjYy-nPFf1j@3iA~Jtr$^I>h5t#)_utN)EqHQaoZL(
zdokbo21?@v2^zSzK?2M301_yjT7BgMKZqkiK<#N9x1)W*9u^0D+rSsMd@;Euu)CJ<
z=|w_>6POUttv$#h9W9ZT1LaX5EjLzirG7$H8OawU>0QM^#q4Yc`GkS=wG!|_shfpB
zk=K85H2zigVgSg^6^%B$02?zoBe{$-mDaKAvbDWu2|?;bXc9=fWsnroKn}KOWDmlu
z7Qix%e9n$IVx_<@U&KUFCn}U{r^fs1FaK
zQ;QPO-{C-KRLX#iYok#{x<-23B2($JWyp`5f5XHtlcmH^pmWkgvjgsm;Xp?u8pAv#
zmabZFd){lv`h6b>-2o%fllfT&5^MFAS6d~57V-4_0$&40V3~HZyrIzN0m2O4))EFF
z7SVC9-J+_p(3he6ACQxY2hQL6x*y^iHISf;!@O=d<^@}c&^i5iNVWKc#>%77(^A%a
zwm2#q5k}X;3Z1zLJ?iod{f9JbwkAaw?6fpc>^}E}hP7Yd^;g0c4D@Q*T);wy19*QH
z@UR~7rF!Yndqb&X#P^$Q(u9jk+&wsYUMx-YJr7te!q=eQD*bbJkUVPCD^yZ%ycRUu
zpuMLmE3zuT#;)~}j2^dxsW@;@Pa!)~`GeBlVM}OSK=H|cNncqA$nY6#8|{0oBgh$K
zK1lsb!_@rxMf7F~w)A1*jqouMZo22HvF@_=@lMgsaFj>=c$`j}t2va+H2g8M+ZRgf(Ba8LVo#0zdghu+qo)q_0FMBJ-)
ze=X`T{)b~8C}%!pdF0au_Fj-eeZp`AlcCE%wAW0o2!tXL1x+Zgci3#acAjhzRr_7-
z2)e*k=B#4msXNIA9;$&4>8}4rEX=4mCo(aHz(9ijXDSigXgP<9R}yVIRR8E;Be?CC
zS`nkm83>F#k$=NXDx5X?eTgON8Z$&P8YtXd#Chg{3j#i
zk#48@?piAEf5~v3SU*x0B@5|I-Xap<{DvJ$A}^0@7$p^bMXm)#!X5E+h3iVIAznrl
z%#c~ajiFSTO)SW8lPxr}Pq?%dzF)>2LWYB>JI{k`KNHevKGI}~5lQsDiA9m{s<#wT
zUt@(p3=2CszeiJSSE*iAg{2d$hjkYkRo{oay(dt$@s^c%>@{a;gv!H-&jO7DL
z?Rbyps=AJ^Mr!=|kl+c)AQb+p8wVTKcC;-Y=rmkCbDFO9)E+8Ci;0agP`$!$;^fXQ`P}q3yj9-?69-=w;
z#So%-21Tyi%QR5Nd+y$1;gk91N*NJP>fxjLS>!e|7lOsoZ-A4W1ck~~
zR*G1qR~GV2?p?dP6e9VkmcV!Bw}`C*0`}tH)SC;u$b}Eir|p7US@&Qag}JHPDZK~o
z%ZVd9=SNqrG{Z|77g6!;J`X-F=l@3>?0nT_=NJaYQJPH>$e5uZ{$H|;p0;@TsL{M#n=c18o5Y2lN=6bi1ziI+&WIeaoF+SIUp|z&
z<7vFUX^C-MYR`l3t%pbwk0v6iEoD*B3emNFXXx@8_n$yddV^82Z_ccF?BbmYPLr2O
zmo?e5tepmNUD%gSdz*Psia(L1Y$@XXL-OwIwoufM7_cn>MpS@~MzP12pyFPcz;R4>
z3JJ>d4?W^Ozkl-*7_D8oEGDCIBy**vV{P60`_bS00l0kvoh{_7nlS_&YHIfBVjSn3
z246wb^-dFJG@W@vS(SC5B|^AnaZ5SA65|sg+H#I(mz)M&FAg`p@g-g4z|sHnQ4u_0
zyp(j3B?QzD&J5;X>#4Xn>;crA0ZzWDWRX*V9bG=y)IJ$RO?cW?7d!Y1gq*e%iYwXoj_1DV6;uSb6BRiw5?5{DN5
zSBY!n>wj7oY$y^MBlTgJfMrk9dxt~7P`_6Cm+LIs5g;&K$OkOt5#JwZ!wpY_V5&1aKK>;^B8}IdXipkLD`V)m&U*CRas3bj^faR?U)>bhbI7
zruAlU*7B+nn%lZlSQ_wY{Bq*bgomZ<7ky5mEnMWoWsV-08|cLw`PKwt);`nB;Olo*
zL}OVQ{I?BV>y2pghKgy6z%cBzu6K9}yOh_EPJg?ot)e|emyeWr{&p`
ztEtBo_W$mwM7qBpH6Q)MqZwZ|!Wa#4jDq`>vx|bnNnK3K#F^4GCi$tk@4`lvswl$K<;Tj&}+>nJT=Kj^E5j1P#pKGvagcw
zaAA~SzN*+19rQtKCjV}s9FbqsR5&Ud21WZPBcF?PIYUfL9EgS0cR%u#ErkC=MPZ7s
zMiUjlb|i$`qO-h%n!Q1?q8w|)9+P!W!qrW)jmHHP9dea5gMfn-f`=bLY_$!mb)L5-fR$p;>3j1j(75
zH&3M@`QaCT7&Qx0WgFv6w<{a(gLh`Z*t@*4&klh5dZ)VIAFICnr2cbvQYl*T+Ar#B
zo?#liFedD{WHM-njY;>vrKb|?CS7>%a>`EFKp)i&&m5`uWJxgRIeWewS=TDgb
zPJ6*B4Ks8JHx7oO#b8s!b(UE#o!a8g3j7wNM1WC7m_h?fTnhdxzsaH3Q*r#8mk&_jk(*#7<8&_}=|
zhpV@o@ipGSFV|Pr(Ob%nkQLe<+H5Z1f``K`rT!E~n+PM;CzSr40{ap^=4+tieS7p+
zJ4gKgvm1IUQodY}!<*USn}Fk?d7tTDl7L_qvT4=~Y7~MlGdmlV0=G3X`oN&E*68nQ
zk@tktR_FPcKbSUndQoSvY3#kjVTE;f*xaQA@O
zr!p?BvhH6vZ-|pm^7_o`=T06R$X_|ZT!{3?^YQ|d8$>y$
zJ%j$@b8jHl_Z5vi?kp&aD6l34v-reov^^iuJe=LEPRBwT`WWl@mI%*h?TVK@(3u
uE0FEKTrS@Nh9*Y_omcwsEZ_cjPiL_2`q_9DOHMWfey-^lY1eAqj{HC73yJvv
delta 12007
zcmYLPcOaGT+ds#aRgsZd$g!f#jF1%}LfNwS499+)6ghVGO328}kv+>-_AVUjh>&??
zZ|~jj_kG{D|Ej~e@8`L$>$9$fGRl`FlyO`TtG}Lsmy*p3D^CY^F9$bQ7|b_wBfic__(K)H>GnGYcI{fSEQHOB%OS*
zE#d)1NUHm5sTx}x?{kS&@G4ZSWQcnzS>i4dCbu2pLP_8y;szVkog5pNIBhHm;MY{3
zLPVApN61WW&qIc$o(}>1qzkGk5w%~IqJCL(abF#{Ce4~fR!)}+b`QvHQXz_J-CI%uymYFG5YNr)0lyR#!5{!R*|`WREzA<6>tybo|rI
zxHkU!DY2=o`b^9Am&s5Qc(@51UTXp;SX+Yjzj$OKgO}}w7&Y>+?MuC!;@r`aZ-3@E
zQwpG|qhD8UryBl{x;;DV_$)rbCjUus!-zf~Qa@r-J)_Hp8;SKDEWWhXQ>%ZHEcwxQ
zL2QsmIYM0g>3;eh*+=cd8j%Gugw0V34n;p7CD53sk2?3gA5J~}BSZCogY4y1iSD#B
zsO(AnE8!iP8Id!Y*5!kf^A>ZpY+kgRk9E}twa|hVx$ZBkvO_Y}j7gf(YbSe=ZC85f
z&DX|m*@eIJAA_Gu%sna{dSFD3t8jb3+Ay#ZfPeq+qcxR;M`iF}LpITeh8LDsyvgp7
z`f}iis3oq8$eB5r=s9>1xjDv@!
zy!#EOItrcjtnOm^(_p==z!`_5-@^>_kMe((`1fz9R5H9m^%>S|{mKzK$Z@`L>~-&M
zjdNwH*tD`PozQB4YkIEa-1-bV(kX$7^@G_P%fZndU#!P;0e*b&Q;!|azE2=oy&Yoe
z{)UrifX=!LC1Kjkp9zMQv0LV(
zOO4gt9}@LoTCY(o5ATlq5AZL0a8v%ulombK`sK&dE`QsghLMOs*E?(=wYr;&@kkI?
zA>H8J5bnstMiv@z|NGBnuUS^vSA1}&Kb;PGS+lrh%X8I*?s*c7>&uYt;AGjyRW=Tv
z{Y^-o?HF^VV^*IlC2yjUIcp!|+$S6tR`s<~yYQl-SU0ceBv|%FdnqZ^oMjQK0&8dU
zOCN8Na!IXwczzurPPN)9jn6#yuC4WZkn%--S{b%8yObi-G)`44{*t(t-fWf?I`dHF
zZQty>zRCSPRQA`2_oLXx(;Gzn(qx2b9xM`8==tr0)*MqEhG$c!%+YCPA4Q`iq=%LN
z2rYef`b|9dkS-w4f+Jj8>ROOV0GZl3WoQJO6k(j0$>-vqo=sG{Po<9>ymY)znBH4s
z=l2l%)53Ack~JItCw|Wah|L^BH6Sg#WKWaRFkJ_{S&d7AHpV|Y3A!#L2*=j+vD--&hUPP|sEz9C-~~#*OllY
zrZ_obGg0L~MXef)PE5DqZYROb(LF|9-n3B`jpu4})msRH-rw1DI
zHm17{V?izO*T?_)5EDdsNV3JQ)p9z0#2iSP_r#%&zGF6=bMOVGCybdZEykI8wPWme
zm#rcxJY#o-y8H^-iVi}~H_i_i(lC7EgD573(u-Tj1M`eCPLDwqyfg4Sb``Z<0tGK`
zXY9|4ZAurLepG;%or%}1;LMQLCM6$^?^n>f$46^AiZEKeJPNh`l3YZ6HCU|3dl{1r
zgTAL1v;CoAml@QYY}Eg#x|BDO(RoK88y2-@60c;n8YhbLZbPnxAw$_%T8<8Y*g
zqo(3JMIl=kio_w!Vi+2@K)qhxk(?=4p$^k;O`UZn|CtrTnunR50Y%X}Wu-rZInm9!
zZHjFYvFs(cRFms@%oDTC1$Qu)%HQ|2#Ru<8#d~&aRykYhRmne2k(RdLh(_#NaxH7G
zb^S;Xl4F2Db&4mHxQf<>m^s4l{>a$L$I}|B;zCN5NH@kVzusE|*Ee%*5`L`B=GsI?
z4UD{!qPX(D(QY@W0VXP#QR{W&DkytaK6|=TBsOQ7$T6K?`tv&IRTXJ2;~E3uYhPsl
zjHW9ll`QWqe`fT17s2Np#E)*4_$nV3{jHDLDLU2&YK4|g_D)y}WoWt{e&j`JV-tiW
z?%oFPl+v+T(h8mH^2BTB_Swwjuf-1TQe1zGHmCn<<+tc-xB`F=35!lCDpj%%tL_0}e*Z
zG|h<32BV`ch}DT)WKD^{fKoBcJ8Hm>LlAkLCDys;x+|ws-3aC=)s_+|V9Z5S&$TnW
zEXgO9|M<+_q5`7!RW-Zk-X7jMoa*4@v`d!6OSbo5=SDAmybXo4-X-s5;kbzV51%;o
z8`O0Dni*cqIQI;!6@GfuJEpf6mPP4L*bp)~q+Uedhj06Qg|F(fIe`OLwW@c&bsW^U
zru=@8uHzGD1~Y&IFtD@Xv$v!4+3Yp-McUXYW%t%AnFU*pxmZ@ojyj7-=iS0kyDXhq
zv56vhl3v>@YNd~DWp(KS3NXerIy5#K5u&KspqSMOEo=@8wIyaND*`oqagPLR%2#^x$Mu-Bs}17)a(RBt_JbCnMoll?CB
z18yr|%rZ6|E1(|ai4oJ6-C)08SH#e^c1X(aer3_-E+_-`p(x7=Iug&&g+!~FJMk=m
zZ>w*^f-h~8wtW~_hXn5*<(B49>y>!kPF9o)Ju7lHXWuH2GsY2azqN@xxjASoA4EfY
z`^}i$+dJrW=pVX{3x)`1(c%lght=L)Z)-6Unx2a{tTQR=+~1q<$L=Ihhh=B3Wv$
z@op64AsALPi^@Cix%tf7=iPbXFB`flzk74_6=Y^-G+)g*a>9d?LD{1=l(I;u@|*12f+RQW$Z?b?tM1iv!dAa
zTwmhu2Xp~D$%4n2FzJxv^6C(m^oh-!`zhLkRna|@#OcrK3*N=qM7}$B6-Oa+Cycuq
z^9pYcHc~*>=%`jOZn>AUN@cHhq
z4R~guetoY9jc?#ZS0JrLEY2&KqrYjC=v^;Q%blpGx&o|+E&X&IkG-u$`Wo{Xwr@YvF}pJbcmlJgfhXV>
z(4dSc#W9TzPj<$t!*6ANfut}TWztL2n~}k{oa)SLox@-j*m;ZQJ8#9N723uNbzXEB
zw-B?a2o??J5XM&c(Ih7+#)P4oq@6?;gyVQn;d=oPW75s&x*GWdr1efIFZv90#mS4P
z(Bn<#2bE{7PZ>+-LPW|wI`+|)6t?U^htEDs+c8v=v5|_aRvv`R&M7f=MJH=Me?lpy
zc;Tu`7rRm)MA;!$$2{Xta(V)w&C;p(cL`xkgw?!m
z!n~Jc!(YTKyhHA9UR;}dU{SiA1Ln}=`os#{ij%PeR4yxvJ9{K1+
z=Y8`ebs>>ddoeiyygESsz99DLzsle0d7Hg;b_~GBpDsW;&ZPfNOSN%Ere*1NZxP2_
zG`2$KqM{ia@xqCf;CeJutKN0$kR2B{e+u;vrRG9XQ=+Or>G(K53p&-=31*bQHiuev
z+9bf|_wN!EM_%GGchQ9OTQ}M7Pb@_+xQhA^^{^V?LM5H*8fb`02g7
z=>pRp;VO@-n^z>-<=>GL9@#Q#WU5U{uod%)@PV*_tzUg=??vMs2Rw>-)AbH&AYq>qYv4Iz8EQF~Ti0tzLawvyg}z
zOS{Uf+%V$_Z7(hhd>0udEC6#%I=Hmq`X6Y~+gvay42qfD60)W`0MvOIqcW;Od^wo$
zVJF6eb5J@9sagS!EgBbTi8sp<)AVI36f{=4rQ9thhhcsoccIq1KP((~Lqiq)Pj9(!
zoXVK}zRp5tTS1KT=1AHSe-Wj&Dz34tNMpLB4Ppi_MP(|3+MC3-A8!F>lwn2dvj>7&
zzx%bwRK;n}mw#q
zPG0CAY~uxfb#0O+@Y*415moRqpU?@(R;^CPZ+1}X7i^MeKY0F0_rEE@*b19okX$V1
zMJu*FR27#C@u3OJC9JB7*z>R_kvEp5;x4?#6S0KafVv&XBn^I>H}B~bwktKVsJ
z>339hDDX2yw|U`#00GL3njGs#me{KcibKH#6^qg@AXv+IdhzjE-vjO!6R^`ud}Jcp
zxQ=iy7f~`ozdqK<19w;J)0@KO_-_3<UtIe-8nky$$xe7iGF|m
z$Rry-PLV9=lgk#!Noj4*`^+jtft7>CsD@GXkJv1H)?6CGR@I{R9N%;c;q8S1>
zvEO^)lceP!0E0b7cVSLZvP4mivUyb&91s$)H|CC6U&gMhd|i&Y^ylLt$u^NI3!TMl
z4TDZmjqy$e5mUPb7rho77o>Wsx=}rE_Y7+!SxL4z92F0%015oMia%~yy7S5rtJyHG
z9-}L+sS{YpnUNCM%4Vcq-s->mn*vuKz2K_E+OkO;JnGTItizqdYQbUJOK%qf;loif
z#hnsC+@48{B%G2+8X|8Fa3i*k`wmWuS&!QQz4CFKZ9t8+|ZUo
z@%>ECClA(^cc+d3{njM>#N1~E@vLt7k=sll$&-Q%yRMfzpy$QgoC8J=UZG^{cr}?R
zl({8e_tn2$i|!v^a$Jy&nS7%V#E3*WiV(HTlxecTwLUkm&;qHp
zYLp+oH`mQzGq2sqUOk)%YiSd^ktkL+h?C+j_3n(?IoK__m
z0vx3l-q=vx?E-puFh`v@8}L^%z$1}41i7()8<}%;_lWlUJR{eV9G`p~#_eFhoHC{)2O6kvd
zJ65b$VCy+>ZMV|ud2b_+U6BY#;#b8=%ISr>igfd^E2t)S8UV5jlY!7B$c(*X!{ifu_Ps3
z($JxsU01Ta=gEza(ekUJeWvr$j@|xLHsJm^L&t0wFmY@m19tr(-wuzSGsHmT%zgob
zV!oBvB&I`J$}0Icz2G$Bu)zU_VR_twAVuByuJ(eK@2-~Pe1?(kj|)nZT_EchPxk8f
zGWT7H!AAt?6x{gv^v~7wynJ%R^n)%Zg*78+f{rwbCZm=@?rqfhN`GUQ-`j!6yytnr
z;AU6+$hWyU2HnB|E}Okg!+x5^i(Uq@$zUe8)mqGNOslo5*OX-z#8TKqVF&
zv;*HVXNl-_aE}SA$vSGC1OdFtp&MFUiq=}mynySKU2*i4Mtq4xZ_7K@Ch|+^&vzqx
z#|pjl&w%MM>uGD3wP3r;7=#Gc%FZ`wR_tf!A(#SeDQR=EHh|6VyKJpC_Vq8rL%+N`
zRcxqEn!7$%PhD-&-rzQl%ngPYRZ;i`jg%1x1kT*sB%w8v!1;rXH)uf
zIUEy~5o@dyk_
z8$t|V5hNE|U;OOw=kPKM_PmFxSI`b8C=8nf6HY#%jSc6-B*aP$IcVxvA)3*jHZ%`j
zqfAaqQri=RdioXu%K9FKx0~JMF716x5(hrCASR{hO5w9n&J}-T3cy3JA}|xFI(WK2
z9=yDbm%UKO`w+|a=CG@idT&SSoW8j|BzK38sR
z*V9M(?B|Z<=CNsBIlIzYM`-*wZN+^1EX>wJ#c%EZ>XYI(k+;TgoWZ{m(503-?AE
z!;+}9pGNm?soYD&jXC$0wunrH~JWRnl)2o)J-)
z+TSzLA#aYch9s)DALKoeg{YFwB=M4q;o5s`O5(@?x{gPPp9x5Srf%@8uLd0#fHNlR
zDx?S2M>ug6y-GZI4{*m-P-ds30MStNeMn%d8niOW4|ZAN)N~gA#ixWhri~DPy>OhL
zURKZq=5@T-boggULpk>fUNlV}k)=Rlurh6(31bP1i>5vgh1E6PK_`8xSO0%D*J6$0
zP#Ec<06NfExn`3{Qsm0tG4a5GDUd<=(&-K$V0a#~ZsVE>pkifP%!P7H
z1q6-jSh3SC5PDt~QSir99&)t~`D)8e
zrT74GJE~eTX9;DG#^8v2^c4d!
z!dycf!H+-lxsp_Xk@|8u)lChbQiw8-({=P4L6shA5mmxZ!N|@6vC4%$AQ^zE2Cl?H
z{nX=AS90z#&=6*OWMYVAu6E4cN)+?8tjKyJD#&D2mdGI#rB4mZFxLG6O_yob#5Q?8
z*L)i_;4f*kJdZ-`XEsS6JLu6{hqmyT8WMhl!DwM>N(y?BfTaWgw&I*C)$sKIvObda
zyNUBKB*5qe!5=
z*|lV=S766)6l(1U!u*9BBYNwOlak2Z=*)v=fkS{R_G!E@&|63v?C8DFZ$AW3;9)s<{-
z?E;Uq(x2+ObmqO$Q8d8Cp;de=D;@r1HACaomk}7(f2%3tHz~j-!RKurJ)y7`a~z2b
z3(5BVPTpmmblQ7$w)+KwFRQPNiamP@>m_kv^r5f&Yr7aa;_fy#45Rq^GISMrQZT=b-!%`K@ag0A|vnB(E0lNw#H;1c2k
zP~kXIt-;{Mqp#(-to<1F5;LB`(lc&0We?-q1Pj3TP#trp+VDwNw7GA|k@raGh0eN7
z^$T0e@vI0-H{tCjQq&2U7Pq%t^fI@xiqQwTf?HKv<@q0QIys8bS
zz|7OhXTke4Rp2RP5FZ1hVHp14t%pI(Kkm0eF+L=WW6*g!m?mnG`KA9nVC;&yT^-0M
z_+mD`zv(s=R$j}vl$jMPnmh4G{Ex<%djQCXfc*W{aEuB7qmNyMn7R>l!40A&9Z1mT
zgbfV1r;J@Xz4YwfncJNx*`CG3CUNQ2@$oUxk_@LHpPZWAeJLS*=gr-jZg1CdIF@(nI-Mg&hm`K}c?kA(BcnKK#O3;x^tA0B!Xa;&^ufrZYl{{uu3sKHIr
z&F;oL;1hd{$_0L+>FNuH7X7pph{3xw=L_H(GK{B;a|#&EK#2%))4q$^O8~U1(I!%+
zN6h2i-H^2tZ;Ibl&QV=E>!m;UKW`Vn(Qd>01pzsj5}xk1DClGQ(F(q$(?x7NzF)HQ
z5Ex%0v6t*IMNem=0j*9_($`LTA3THUPy{vD-gb-2csgeo^3!wR)_J}`Iv?YlYbs3j
z{39h`l~EVlFJw1#73cygJ;i?sCf>oy!O!z-B44>}o9pWc|ECx~9OB_>1#L=6ENDNZ
z*KMad>gPynaA3^f!CFxI?=(1wG|MSu06`iTsg0-Sh5rFuIwajO3<5;0jdc>ql#1_KT0`&*-hW;Rs1OK%3GcFE|H;TQ*o(d;
z*J|AnV-xv-lM5*I8t|(~Y}iP*o&!gN@6-Dr>g0tl!g1NaUR8b%(&u2LJ-Z+Bb76Nj
zlkB->T1NWijN#2BJ0LvS;THtT#Tzd&J?FP6_(ZmQ5jj2k_F~6453_g7K49i7I>e`5{v5qe|^gh2zvTwTu-5YqZ_i=bw_imBGx}vQp@krEbB%uu*0=yAfX-kR$g>{lQfzaown%D>C|s!
z2m>DUJDbP}x{k=U2w<<;fm_@LV&PR$#=o%c;TuZ_8k01r_59O9;)?>rOCnu525HO@
zTlv?XXkYHP^2GAU3}@2dS8v^*9O0)};3){;nu*a+JUL-nl{4m{f6-Mn^IU#tesCCF=`~B&5yOk#>3t;ByZq^DNxy=f#Z9`x
z#dv^Nw304p%MXo?$05p{yyKcWl-g!OFpsGWw$-ks7_N!cu3MzRzPk-~u5xirFTT*&
zRAB7-QX`S|rq*TP`t4-Ft77B-Ib{5Nj3PVYf)-Z+5#&Q>SB`>ZK?(UiO)V5$MwL#x
zqt?Xjn}_#7hB=&(RmX5hF^5Fq9{(CbZj@W=6!;ip!lvxdmduM{3xpKpD5<
zeud;m_6z=;Neu>i4nDE9<4#U+M=iFFS2=r#QU21O6YHgSOUsy;c{CDcrEeusu
zBUtq4a|s0uY7B@l1&D9_A{@zrzK0Y-&C8lkr%vI!By7?#QzWx#r-2H`2G3ub_lS!rh3mHwlQS1KWpT&gO9HtLHyaP7H4px7Hd1vN&_E8Y
z{0ZIv0BhEpU^-O`YRTADqe`&KLQ{R^AT2i)bjhO(P`4lDE}(;oQ8?UpDIp*^m{i`$
zn^At)qle}wxLJ>nDjP&?$*NZj=RPkaLPT^R>!N+5p)+lbo)4VL7^o~=+$(H7@qKGp
zUrv``t@7^Z*E?>jCJ>tl8fStqV0mixa|$yPp3QHuZ61^24gPh!xcq7oaStI4CijPr
z&0PHRXc(kn`u^v>v3RHj2Rl&%NSTFeS1JBgMAAf$M&|8Prb>UBDMWZMA&5tbZ64Ha
z4$y{h$%7>XGEJR6kW)M+46l24Fa$3@44&CJJAP?H5sy@5&>{M6a8%L7jrF|dReC>#
z3#Q)S<3(co1=B(9=5rIK{@1`;SgaU^vLsX3j@Ct7{+f=`At%~B`P_OwWZI}7j;L`@
zfT=ydmibe2->6llh^142Wt21QG4CA6;`$zs2ZsJz&(!jAe1!4DfxYyCi5HI=IWsas
zngG(|*8M)&qikTY#1eG!<~806IY^X#NI=v}zhl_m{5`(^p`Btdgr59vu6b+7zV8*l
zXr@H6)FiR#ac$IKpsKhaouN0g6thPabt=~(X#MSgvk(x*c`|mbN1Gu5MWv9}25(6@
zDbE&Ft1~NTtb=`TGwy38kfA7qZkF6`icA(9V3T`#_SmWAU(Bvk9Ex2f0LJ>GHe;Q2
z(-;}30w$A+R9)$^rRy+b>*zOF3b>i_`To_Ty=!l(!UA~F&EoFe9zAT&ekrj3S`5km~JuqO%2v=UCWEe=cDYZ!pawi%ulX$Wn-a)^g97TN%
zz_9Z-DEi0fx~f)6FpyvvNJe5UD^^bSWQOX#n9!rZxPI3Y9VG#FDFh+Cwat6I^eF)F
z0WMSSzJ-BB2&Kx}#0bMHWP1X}nZ4IHGgz@EAOzI%+WIs`2Qu=d#eZ~!J
zuav*X+|(I!Uxs_x+VjFZGw-T}eEhNxcDWBRy+eeS
zz4ScVw|re#DVu;3+GS58O;3&Uo@Bpn%WD88YOQzvnuMj;C{iBKS8kcM~st+iex`
zXL|u2A;{LR7Yx2a1tMh^{^d=rzkiQ&^_A}{-6Ni8%P2s+WoC-~=rR1kVDNf>C1RiL
zk1bCPkZ=A)8cHl3vz7pB({dSae9Q?nBS>6b;Z4MM)1dHT*F_lIgkvG%MAg3Mwc={3
z;wPFqqHvr?4{rOcAq~l-K%TmnH)+JFSE~+3Uh<;l
zXhI``IXbK5Z3UZv6mlH1Kc{+5Mpm8a&ydu8nHAf2dpVEmA7edvZq~w6+G~NIu5@tM
zzvBDzU(1CKDGDVYGNxw;gU}SIw@iL#4r%=&5(px&s3QV^Sgz-KKM&yk+KgRgZArp$
z85or+bK`OIC`S|k?&U72Vfr&S3%mA
zuVVGhd@vf6-02gC!zsiPH4&u=sV64Y12bqrYSTD+gpOUPAh>2bprPel#r?VTr#O
z%S0!%&9GuwKB&;7f?Y~^x`3yE8{ZEjEv4^7qtA|tT-TD8o0E@bI
z{hQZ<4fv>Vp{u?t1Tn7s{hnoB9*y)#WajSHWZM;93^H=a#(XTS2WYgh?HK%^*(SQ}_ltg`G4E
z)hJ*b<;d1I2($^4yrkCAt19G$Uak1iN{q8l?gW1rs?VqAFo;NIm5FVy3=x!J3tyj
z)#33Qndu1@fSIK+yn(GPKQJAJbWEaFXiJcXH$`5$Kh{xeAoLe7&seda^Co)3Q6`_A
z<44Od!2Fr1k(l{$ce{n2zHtNC6ffG?=I-~>k9NlDKjyk{8+0M-ta|O>#*Kh4gtY%Qx?-3o1KX_
zt9%h5rC?X%b7LvKUuzfMY`o}yTB~$D|wSErN^c#l6&pt8M(oK
z{P1k#X|QCwg@!d=(O*hctzPnBMntFWeV#Z+hW@{+cusNoO~1mJEa^TB{83ZZQYwG&
H{N?`u;8u{q
From d7d9536056596b75e16eb07e7130280a5d732a77 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Mon, 10 Feb 2025 18:09:48 +0000
Subject: [PATCH 16/52] grab functionality
---
code/datums/movement/mob.dm | 2 +-
.../modules/mining/drilling/cave_generator.dm | 5 ++--
code/modules/mob/living/carbon/resist.dm | 6 ++++
.../superior_animal/golem/types/coal.dm | 2 +-
.../superior_animal/golem/types/platinum.dm | 3 ++
.../carbon/superior_animal/superior_animal.dm | 30 +++++++++++++++++++
6 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm
index 4d348bbd4f2..243ebfe35ad 100755
--- a/code/datums/movement/mob.dm
+++ b/code/datums/movement/mob.dm
@@ -249,7 +249,7 @@
to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!")
return MOVEMENT_STOP
- for(var/obj/item/grab/G in mob.grabbed_by)
+ for(var/G in mob.grabbed_by)
return MOVEMENT_STOP
/* TODO: Bay grab system
if(G.stop_move())
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 0db1c7b4473..91e85caea4b 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -622,7 +622,8 @@
if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random
var/melee_weights = list(
/mob/living/carbon/superior_animal/golem/iron = 4,
- /mob/living/carbon/superior_animal/golem/coal = 2,
+ /mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = (seismic_lvl == 4) ? 2 : 0,
/mob/living/carbon/superior_animal/golem/platinum = 3,
/mob/living/carbon/superior_animal/golem/plasma = (seismic_lvl == 4) ? 2 : 0)
@@ -639,7 +640,7 @@
if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem
var/melee_weights = list(
/mob/living/carbon/superior_animal/golem/iron = 3,
- /mob/living/carbon/superior_animal/golem/coal = 2,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
/mob/living/carbon/superior_animal/golem/platinum = 3,
/mob/living/carbon/superior_animal/golem/plasma = 2,
/mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0)
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index 6c9ec381e04..fa782466457 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -76,6 +76,12 @@
if(prob(conditionsapply * (5 + max((stats?.getStat(STAT_ROB)) - G.assailant.stats?.getStat(STAT_ROB), 1) ** 0.8))) // 4% minimal chance
visible_message("[src] has broken free of [G.assailant]'s headlock!")
qdel(G)
+ for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they do not have stats nor hands
+ resisting++
+ if(prob(((5 * stats?.getStat(STAT_ROB)) ** 0.75) / max(grabbed_by.len / 1.5, 1)))
+ G_mob.breakgrab()
+ visible_message("[src] has broken free of [G_mob]'s grip!")
+
if(resisting)
setClickCooldown(20)
visible_message("[src] resists!")
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
index 5a17a7d7c42..8baa84514c5 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
@@ -40,7 +40,7 @@
if(istype(A, /mob/living/carbon))
visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"), 1)
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- A.Stun(COAL_STUN_DURATION)
+ simplegrab(target_mob)
else // if they're not a carbon just attack them normally. this includes things like simple animals
. = ..()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index 82fbe1b71ef..58b5603108c 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -89,3 +89,6 @@
#undef PLATINUM_CHARGE_DAMAGE_OBSTACLES
#undef PLATINUM_CHARGE_DAMAGE_TARGET
+#undef PLATINUM_CHARGE_CD
+#undef PLATINUM_CHARGE_WINDUP
+#undef PLATINUM_CHARGE_RANGE
diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
index 5af2d4fdaf7..d50b69a9f9d 100644
--- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
@@ -101,6 +101,8 @@
var/grabbed_by_friend = FALSE //is this superior_animal being wrangled?
var/ticks_processed = 0
+ var/mob/living/grabbing // the currently grabbed mob
+
// Armor related datum
var/datum/armor/armor
@@ -229,6 +231,8 @@
else
canmove = TRUE
set_density(initial(density))
+ if(!lying && grabbing)
+ canmove = FALSE // don't move if we're grabbing someone
/mob/living/carbon/superior_animal/proc/handle_ai()
@@ -346,6 +350,8 @@
handle_cheap_environment(environment)
updateicon()
ticks_processed = 0
+ if(grabbing && !Adjacent(grabbing))
+ breakgrab()
if(handle_cheap_regular_status_updates()) // They have died after all of this, do not scan or do not handle AI anymore.
return PROCESS_KILL
@@ -377,3 +383,27 @@
if(istype(mover, /obj/item/projectile))
return stat ? TRUE : FALSE
. = ..()
+
+/mob/living/carbon/superior_animal/death()
+ breakgrab()
+ . = ..()
+
+/mob/living/carbon/superior_animal/proc/simplegrab(var/mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs
+ if(!target && target_mob)
+ target = target_mob // if no target was specified, but we have a target, default to them
+ else if(!target || !Adjacent(target))
+ return
+
+ visible_message("[src] has grabs [target]!")
+ target.grabbed_by += src
+ grabbing = target
+ cheap_update_lying_buckled_and_verb_status_()
+
+
+/mob/living/carbon/superior_animal/proc/breakgrab()
+ if(grabbing)
+ grabbing.grabbed_by -= src
+ grabbing = null
+ cheap_update_lying_buckled_and_verb_status_()
+
+
From 45d0ecb45c9c8a2e735fdeef313fd8eb7ef6067e Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Mon, 10 Feb 2025 19:32:29 +0000
Subject: [PATCH 17/52] slight adjustments
---
code/modules/mob/living/carbon/resist.dm | 4 ++--
.../mob/living/carbon/superior_animal/golem/types/coal.dm | 4 +---
.../mob/living/carbon/superior_animal/superior_animal.dm | 2 +-
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index fa782466457..bb44b31aaac 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -76,9 +76,9 @@
if(prob(conditionsapply * (5 + max((stats?.getStat(STAT_ROB)) - G.assailant.stats?.getStat(STAT_ROB), 1) ** 0.8))) // 4% minimal chance
visible_message("[src] has broken free of [G.assailant]'s headlock!")
qdel(G)
- for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they do not have stats nor hands
+ for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they have neither stats nor hands
resisting++
- if(prob(((5 * stats?.getStat(STAT_ROB)) ** 0.75) / max(grabbed_by.len / 1.5, 1)))
+ if(prob(max(((stats?.getStat(STAT_ROB) ** 0.9) / grabbed_by.len),20)))
G_mob.breakgrab()
visible_message("[src] has broken free of [G_mob]'s grip!")
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
index 8baa84514c5..cc2b49dfc19 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
@@ -1,5 +1,3 @@
-#define COAL_STUN_DURATION 10
-
/mob/living/carbon/superior_animal/golem/coal
name = "coal golem"
desc = "A moving pile of rocks with coal clumps in it."
@@ -31,7 +29,7 @@
// Loot related variables
ore = /obj/item/ore/coal
-// enhanced coal golems will "grab" (stun) players, leaving them vulnerable to very high damage golems like gold and platinum
+// enhanced coal golems will grab players, leaving them vulnerable to very high damage golems like gold and platinum
/mob/living/carbon/superior_animal/golem/coal/enhanced
name = "graphite golem"
desc = "A moving pile of rocks with unusually large hands and graphite chunks in it."
diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
index d50b69a9f9d..9f09eb232c0 100644
--- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
@@ -394,7 +394,7 @@
else if(!target || !Adjacent(target))
return
- visible_message("[src] has grabs [target]!")
+ visible_message("[src] grabs [target]!")
target.grabbed_by += src
grabbing = target
cheap_update_lying_buckled_and_verb_status_()
From 49406ba906fe43a144ed2c7eff866b9ce5195c67 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 00:00:54 +0000
Subject: [PATCH 18/52] adjust golem AI
---
.../modules/mining/drilling/cave_generator.dm | 12 +--
.../carbon/superior_animal/golem/golem.dm | 78 ++++++++++++++++++-
.../superior_animal/golem/types/gold.dm | 10 ++-
.../superior_animal/golem/types/platinum.dm | 8 +-
4 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 91e85caea4b..1cff4423c69 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -31,8 +31,8 @@
//minimum distance between spawned clusters. the spawn is canceled if it's lower than this.
#define GOLEM_SPAWN_SPACING 7.5 //
//chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)"
-#define GOLEM_SPAWN_CHANCE_BASE 1.6
-#define GOLEM_SPAWN_CHANCE_SCALING 0.4 // 2% on level 1, 4% on level 6.
+#define GOLEM_SPAWN_CHANCE_BASE 2.8
+#define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6.
//////////////////////////////
// Generator used to handle underground caves
@@ -610,16 +610,16 @@
var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list()
switch(seismic_lvl)
- if(1,2) //easy: pick 5 random golems
+ if(1,2) //easy: pick 3 random golems
var/weights = list(
/mob/living/carbon/superior_animal/golem/iron = 3,
/mob/living/carbon/superior_animal/golem/coal = 2,
/mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2.
- for(var/c = 0, c < 5, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution
+ for(var/c = 0, c < 3, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution
golems_to_spawn += pickweight(weights)
- if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random
+ if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 2 random
var/melee_weights = list(
/mob/living/carbon/superior_animal/golem/iron = 4,
/mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0,
@@ -634,7 +634,7 @@
golems_to_spawn += pickweight(melee_weights)
golems_to_spawn += pickweight(ranged_weights)
- for(var/c = 0, c < 3, c++)
+ for(var/c = 0, c < 2, c++)
golems_to_spawn += pickweight(melee_weights + ranged_weights)
if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 9370381dfe0..dfe2ca12bfc 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -21,9 +21,9 @@
#define GOLEM_REGENERATION 10 // Healing by special ability of uranium golems
-GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies
+GLOBAL_LIST_EMPTY(all_golems) // golems check this list to loop over allies
+GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with a current target mob
-// OneStar patrol borg that defends OneStar facilities
/mob/living/carbon/superior_animal/golem
icon = 'icons/mob/golems.dmi'
@@ -47,6 +47,8 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies
meat_amount = 0
stop_automated_movement_when_pulled = 0
wander = FALSE
+ viewRange = 8
+ kept_distance
destroy_surroundings = TRUE
@@ -68,12 +70,16 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies
// Type of ore to spawn when the golem dies
var/ore
+ var/aiticks = 0
+ var/targetrecievedtime = -250
+
/mob/living/carbon/superior_animal/golem/Initialize(var/mapload)
GLOB.all_golems += src
.=..()
/mob/living/carbon/superior_animal/golem/Destroy()
GLOB.all_golems -= src
+ GLOB.active_golems -= src
..()
/mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage)
@@ -105,3 +111,71 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies
var/obj/structure/obstacle = locate(/obj/structure) in T
if(obstacle)
obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE)
+
+/mob/living/carbon/superior_animal/golem/loseTarget()
+ GLOB.active_golems -= src
+ . = ..()
+
+/mob/living/carbon/superior_animal/golem/handle_ai()
+
+ objectsInView = null
+
+ //CONSCIOUS UNCONSCIOUS DEAD
+
+ if (!check_AI_act())
+ return FALSE
+
+ switch(stance)
+ if(HOSTILE_STANCE_IDLE)
+ if (!busy) // if not busy with a special task
+ stop_automated_movement = FALSE
+ target_mob = findTarget()
+ if (target_mob)
+ stance = HOSTILE_STANCE_ATTACK
+ for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems)
+ if(!ally.target_mob && (get_dist(ally, src) < 5))
+ ally.stance = HOSTILE_STANCE_ATTACK
+ ally.target_mob = target_mob
+ ally.targetrecievedtime = world.time
+
+ if(HOSTILE_STANCE_ATTACK)
+ if(destroy_surroundings)
+ destroySurroundings()
+
+ stop_automated_movement = TRUE
+ stance = HOSTILE_STANCE_ATTACKING
+ set_glide_size(DELAY2GLIDESIZE(move_to_delay))
+ if(!kept_distance)
+ walk_to(src, target_mob, 1, move_to_delay)
+ else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance))
+ walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away
+ else if(kept_distance)
+ step_to(src, target_mob, kept_distance)
+
+ if(HOSTILE_STANCE_ATTACKING)
+ if(destroy_surroundings)
+ destroySurroundings()
+
+ if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target
+ attemptAttackOnTarget()
+ else
+ prepareAttackOnTarget()
+
+ //random movement
+ if(wander && !stop_automated_movement && !anchored)
+ if(isturf(loc) && !resting && !buckled && canmove)
+ turns_since_move++
+ if(turns_since_move >= turns_per_move)
+ if(!(stop_automated_movement_when_pulled && pulledby))
+ var/moving_to = pick(cardinal)
+ set_dir(moving_to)
+ step_glide(src, moving_to, DELAY2GLIDESIZE(0.5 SECONDS))
+ turns_since_move = 0
+
+ //Speaking
+ if(speak_chance && prob(speak_chance))
+ visible_emote(emote_see)
+
+ return TRUE
+
+
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index 527a9e841ff..e9ab44018b4 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -52,12 +52,18 @@
turfstoattack += potentialturf
for(var/turf/targetturf in turfstoattack)
- new /obj/golem_spike(targetturf)
+ var/obj/golem_spike/spike = new /obj/golem_spike(targetturf)
+ spike.parent = src
/obj/golem_spike
icon = 'icons/mob/golems.dmi'
icon_state = "goldspike_tip"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ var/parent
+ var/attacktext = list(
+ "skewered",
+ "impaled,",
+ "punctured")
/obj/golem_spike/Initialize()
. = ..()
@@ -67,7 +73,7 @@
var/turf/turf = get_turf(src)
for(var/mob/living/victim in turf.contents)
if(!istype(victim, /mob/living/carbon/superior_animal/golem))
- victim.adjustBruteLoss(GOLD_SPIKE_DAMAGE)
+ victim.attack_generic(parent, GOLD_SPIKE_DAMAGE, pick(attacktext), FALSE, TRUE, FALSE, 1)
playsound(src, 'sound/weapons/slice.ogg', 30)
victim.shake_animation(4)
animate(src, alpha = 0, time = 20, easing = BACK_EASING|EASE_IN)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index 58b5603108c..d240ac75e0c 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -36,6 +36,7 @@
ore = /obj/item/ore/osmium
var/charge_verbs = list("launches itself", "charges", "rams")
+ var/charge_hit_verbs = list("crashes into", "smashes", "slams into")
var/charge_cooldown = 0
/mob/living/carbon/superior_animal/golem/platinum/handle_ai() // half of this proc is just the visuals. the visuals are irritatingly difficult with this method of actually charging
@@ -52,8 +53,7 @@
var/turf/lastvalidturf // I am not even going to pretend I understand how this proc works
passedturfs -= passedturfs[(passedturfs.len)] // cut off the end of the line so we stop right before the target
var/vfxindex = passedturfs.len - 1
- var/vfxfalloff = 250 / (passedturfs.len - 1)
-
+ var/vfxfalloff = 250 / max((passedturfs.len - 1),1)
for(var/turf/targetturf in passedturfs)
if(turf_clear_ignore_cables_and_mobs(targetturf))
@@ -62,7 +62,7 @@
new /obj/effect/decal/cleanable/rubble(targetturf)
- if(vfxindex >= 0) //every turf except the one we end on.
+ if((vfxindex >= 0) && (passedturfs.len >= 1)) //every turf except the one we end on.
var/obj/effect/temp_visual/long/charge_effect = new /obj/effect/temp_visual/long(targetturf)
charge_effect.icon = icon
charge_effect.icon_state = icon_state // copy over the icon and direction
@@ -82,7 +82,7 @@
forceMove(lastvalidturf)
if(Adjacent(target_mob))
- UnarmedAttack(target_mob, 1, PLATINUM_CHARGE_DAMAGE_TARGET)
+ target_mob.attack_generic(src, PLATINUM_CHARGE_DAMAGE_TARGET, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1)
playsound(loc, 'sound/weapons/melee/blunthit.ogg', attack_sound_volume, 1)
walk_to(src, target_mob, 1, move_to_delay) // continue moving towards the target once the charge is finished
From 5b8447d1b46e7a3bb92e81201a0dd5fdfebb0770 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 00:32:50 +0000
Subject: [PATCH 19/52] Update golem.dm
---
code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index dfe2ca12bfc..e07e2d9250c 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -48,7 +48,6 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
stop_automated_movement_when_pulled = 0
wander = FALSE
viewRange = 8
- kept_distance
destroy_surroundings = TRUE
From d35467c78377204c0784dc3b07b7d11cbff75d44 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 14:55:40 +0000
Subject: [PATCH 20/52] tweaks + re-add uranium healing
---
.../carbon/superior_animal/golem/golem.dm | 21 +++++++++++++++----
.../superior_animal/golem/types/ansible.dm | 2 +-
.../superior_animal/golem/types/gold.dm | 2 +-
.../superior_animal/golem/types/silver.dm | 2 +-
.../superior_animal/golem/types/uranium.dm | 9 ++++++++
5 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index e07e2d9250c..6a3fa1375e1 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -48,6 +48,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
stop_automated_movement_when_pulled = 0
wander = FALSE
viewRange = 8
+ kept_Distance = 0
destroy_surroundings = TRUE
@@ -69,7 +70,6 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
// Type of ore to spawn when the golem dies
var/ore
- var/aiticks = 0
var/targetrecievedtime = -250
/mob/living/carbon/superior_animal/golem/Initialize(var/mapload)
@@ -126,10 +126,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
switch(stance)
if(HOSTILE_STANCE_IDLE)
- if (!busy) // if not busy with a special task
+ if(!busy) // if not busy with a special task
stop_automated_movement = FALSE
target_mob = findTarget()
- if (target_mob)
+ if(target_mob)
stance = HOSTILE_STANCE_ATTACK
for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems)
if(!ally.target_mob && (get_dist(ally, src) < 5))
@@ -148,7 +148,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
walk_to(src, target_mob, 1, move_to_delay)
else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance))
walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away
- else if(kept_distance)
+ else
step_to(src, target_mob, kept_distance)
if(HOSTILE_STANCE_ATTACKING)
@@ -177,4 +177,17 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
return TRUE
+/mob/living/carbon/superior_animal/golem/prepareAttackOnTarget()
+ stop_automated_movement = 1
+
+ if (!target_mob || !isValidAttackTarget(target_mob))
+ loseTarget()
+ return
+
+ if ((get_dist(src, target_mob) >= (viewRange + kept_distance)) || src.z != target_mob.z) //golems with a kept distance need to be further away to lose their gargets, to avoid losing targets by trying to keep distance
+ loseTarget()
+ return
+
+ attemptAttackOnTarget()
+
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 3a6368e0605..01b73dca5e3 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -40,7 +40,7 @@
ranged_cooldown = 3 SECOND
fire_verb = "fires"
acceptableTargetDistance = 6
- kept_distance = 3
+ kept_distance = 5
// Cooldown of special ability
var/teleport_cooldown = -90 SECONDS // negative so that it isn't on cooldown at round start
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index e9ab44018b4..b22945c8663 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -30,7 +30,7 @@
rad = 0
)
- kept_distance = 4
+ kept_distance = 3
retreat_on_too_close = TRUE
// Loot related variables
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
index f5aef3c8497..d3b205d1351 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
@@ -39,7 +39,7 @@
ranged_cooldown = 3 SECOND
fire_verb = "hurls a spike"
acceptableTargetDistance = 6
- kept_distance = 4
+ kept_distance = 3
/obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems
name = "stun plasma bolt"
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index 63ae5de579c..da9e21eaebc 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -42,3 +42,12 @@
set_light(0)
. = ..()
+/mob/living/carbon/superior_animal/golem/uranium/handle_ai()
+ . = ..()
+ if(target_mob)
+ for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems)
+ if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE))
+ log_world("[src] trying to heal [ally]")
+ ally.adjustBruteLoss(-GOLEM_REGENERATION)
+ ally.adjustFireLoss(-GOLEM_REGENERATION)
+
From 7f86edd3983144b8a185941574bee35568c586b8 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 14:56:25 +0000
Subject: [PATCH 21/52] typo
---
code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 6a3fa1375e1..eec5497a0e7 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -48,7 +48,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
stop_automated_movement_when_pulled = 0
wander = FALSE
viewRange = 8
- kept_Distance = 0
+ kept_distance = 0
destroy_surroundings = TRUE
From f4e3b2f1a71f183435b8e240b531fb4a3875f104 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 16:30:03 +0000
Subject: [PATCH 22/52] adjust how retreating golems update pathfinding
---
.../carbon/superior_animal/golem/golem.dm | 18 +++++++++++-------
.../superior_animal/golem/types/ansible.dm | 1 +
.../carbon/superior_animal/golem/types/gold.dm | 2 +-
.../superior_animal/golem/types/silver.dm | 2 +-
.../carbon/superior_animal/superior_animal.dm | 5 +++++
5 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index eec5497a0e7..44e9b183a5c 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -143,18 +143,16 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
stop_automated_movement = TRUE
stance = HOSTILE_STANCE_ATTACKING
- set_glide_size(DELAY2GLIDESIZE(move_to_delay))
- if(!kept_distance)
- walk_to(src, target_mob, 1, move_to_delay)
- else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance))
- walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away
- else
- step_to(src, target_mob, kept_distance)
+
+ updatePathFinding()
if(HOSTILE_STANCE_ATTACKING)
if(destroy_surroundings)
destroySurroundings()
+ if(retreat_on_too_close)
+ updatePathFinding() //retreating enemies need to update their pathfinding way more often
+
if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target
attemptAttackOnTarget()
else
@@ -190,4 +188,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
attemptAttackOnTarget()
+/mob/living/carbon/superior_animal/golem/proc/updatePathFinding() // moved to a separate proc to avoid code repeats
+ set_glide_size(DELAY2GLIDESIZE(move_to_delay))
+ if(!retreat_on_too_close || (get_dist(loc, target_mob.loc) > kept_distance)) // if this AI doesn't retreat or the target is further than our retreat distance, walk to them.
+ walk_to(src, target_mob, kept_distance + 1, move_to_delay)
+ else
+ walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough awaye)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 01b73dca5e3..54bf7b2cbd4 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -41,6 +41,7 @@
fire_verb = "fires"
acceptableTargetDistance = 6
kept_distance = 5
+ retreat_on_too_close = TRUE
// Cooldown of special ability
var/teleport_cooldown = -90 SECONDS // negative so that it isn't on cooldown at round start
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index b22945c8663..74e806d67c0 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -30,7 +30,7 @@
rad = 0
)
- kept_distance = 3
+ kept_distance = 5
retreat_on_too_close = TRUE
// Loot related variables
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
index d3b205d1351..f5aef3c8497 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
@@ -39,7 +39,7 @@
ranged_cooldown = 3 SECOND
fire_verb = "hurls a spike"
acceptableTargetDistance = 6
- kept_distance = 3
+ kept_distance = 4
/obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems
name = "stun plasma bolt"
diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
index 9f09eb232c0..2a307e3fa9f 100644
--- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
@@ -269,6 +269,11 @@
if(destroy_surroundings)
destroySurroundings()
+ if(kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance))
+ walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away
+ else if(kept_distance)
+ step_to(src, target_mob, kept_distance)
+
prepareAttackOnTarget()
//random movement
From 7c0e07664a661518badab2cf057e646aa9fdee3c Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 16:53:31 +0000
Subject: [PATCH 23/52] activate allies' AI when sharing targets
limited CPU and its consequences on the human race
---
code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 44e9b183a5c..4e937a1a7eb 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -136,6 +136,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
ally.stance = HOSTILE_STANCE_ATTACK
ally.target_mob = target_mob
ally.targetrecievedtime = world.time
+ try_activate_ai() // otherwise we attack alone even if a target is set
if(HOSTILE_STANCE_ATTACK)
if(destroy_surroundings)
From d4ba6047190c522162330cd7ff83818276cc715a Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 16:53:50 +0000
Subject: [PATCH 24/52] Update golem.dm
---
code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 4e937a1a7eb..7fd03381980 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -136,7 +136,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
ally.stance = HOSTILE_STANCE_ATTACK
ally.target_mob = target_mob
ally.targetrecievedtime = world.time
- try_activate_ai() // otherwise we attack alone even if a target is set
+ ally.try_activate_ai() // otherwise we attack alone even if a target is set
if(HOSTILE_STANCE_ATTACK)
if(destroy_surroundings)
From a5f74983f97a11aaae7514e48c93cea63dbb6eff Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Tue, 11 Feb 2025 23:20:20 +0000
Subject: [PATCH 25/52] remove a debug print
---
.../mob/living/carbon/superior_animal/golem/types/uranium.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index da9e21eaebc..3ad57179a46 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -47,7 +47,6 @@
if(target_mob)
for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems)
if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE))
- log_world("[src] trying to heal [ally]")
ally.adjustBruteLoss(-GOLEM_REGENERATION)
ally.adjustFireLoss(-GOLEM_REGENERATION)
From 8249ed9c946bc34a688b2d20533a0dc78d75f3ba Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Wed, 12 Feb 2025 00:19:59 +0000
Subject: [PATCH 26/52] reduce silver bolt pain, increase burn
it knocks players out in only a few shots- it's disproportionately strong for the level it's introduced at.
---
.../mob/living/carbon/superior_animal/golem/types/silver.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
index f5aef3c8497..dba5225872e 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
@@ -44,7 +44,7 @@
/obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems
name = "stun plasma bolt"
taser_effect = 1
- damage_types = list(HALLOSS = 30, BURN = 5)
+ damage_types = list(HALLOSS = 20, BURN = 10)
impact_type = /obj/effect/projectile/stun/impact
/obj/item/projectile/plasma/stun/golem/Bump(atom/A as mob|obj|turf|area, forced = FALSE)
From 545f64546fd9bfd6196da4a0b3ead7c613611c1d Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Wed, 12 Feb 2025 14:08:52 +0000
Subject: [PATCH 27/52] tweak some stuff
---
code/modules/mining/drilling/cave_generator.dm | 8 +++++---
.../mob/living/carbon/superior_animal/golem/attack.dm | 6 +-----
.../living/carbon/superior_animal/golem/types/platinum.dm | 7 +++++--
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 1cff4423c69..283ed76b500 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -656,10 +656,12 @@
golems_to_spawn += pickweight(ranged_weights)
golems_to_spawn += pickweight(ranged_weights + melee_weights)
- // Spawn golem at free location
+ var/potentialturfs = list()
+ for(var/turf/floor/asteroid/cave/potential_turf in range(1, turf))
+ potentialturfs += potential_turf
+
for(var/golem in golems_to_spawn)
- var/spawnturf = get_turf(locate(turf.x + rand(-1,1), turf.y + rand(-1,1), turf.z)) // slightly randomize the spawn turfs so golems don't spawn in a doomstack
- new golem(spawnturf)
+ new golem(pick_mobless_turf_if_exists(potentialturfs))
for(var/c = 1 to golem_spawn_points.len)
log_world(golem_spawn_points[c])
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/attack.dm b/code/modules/mob/living/carbon/superior_animal/golem/attack.dm
index 3db71afe240..8b137891791 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/attack.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/attack.dm
@@ -1,5 +1 @@
-/mob/living/carbon/superior_animal/golem/isValidAttackTarget(atom/O)
- // Golems can actively try to attack the drill
- if(istype(O, /obj/machinery/mining/deep_drill))
- return TRUE
- return ..()
+
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index d240ac75e0c..66b18887898 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -50,8 +50,11 @@
var/list/passedturfs = getline(src, target_mob) // do this at the start of the windup, so that the golem's charge doesn't track the target (and it can be dodged)
spawn(PLATINUM_CHARGE_WINDUP)
- var/turf/lastvalidturf // I am not even going to pretend I understand how this proc works
- passedturfs -= passedturfs[(passedturfs.len)] // cut off the end of the line so we stop right before the target
+ var/turf/lastvalidturf
+ var/turf/lineend = passedturfs[(passedturfs.len)]
+ if(target_mob in lineend.contents) //if the target hasn't moved, cut off the end of the line so we don't end up on top of them
+ passedturfs -= lineend
+
var/vfxindex = passedturfs.len - 1
var/vfxfalloff = 250 / max((passedturfs.len - 1),1)
From bb817c83f27e2fcefe44f06522131940d578a602 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Wed, 12 Feb 2025 14:15:52 +0000
Subject: [PATCH 28/52] slightly increase platinum's stats
---
.../living/carbon/superior_animal/golem/types/platinum.dm | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index 66b18887898..11aa81e0bd0 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -11,16 +11,16 @@
icon_living = "golem_platinum"
// Health related variables
- maxHealth = GOLEM_HEALTH_MED
- health = GOLEM_HEALTH_MED
+ maxHealth = GOLEM_HEALTH_HIGH
+ health = GOLEM_HEALTH_HIGH
// Movement related variables
move_to_delay = GOLEM_SPEED_SLUG
turns_per_move = 5
// Damage related variables
- melee_damage_lower = GOLEM_DMG_FEEBLE
- melee_damage_upper = GOLEM_DMG_LOW
+ melee_damage_lower = GOLEM_DMG_LOW
+ melee_damage_upper = GOLEM_DMG_MED
// Armor related variables
armor = list(
From b00e9bc640ec015cd66fbaebe9361299d4025820 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 14 Feb 2025 18:46:57 +0000
Subject: [PATCH 29/52] suggested change
---
code/datums/movement/mob.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm
index 243ebfe35ad..d141d374249 100755
--- a/code/datums/movement/mob.dm
+++ b/code/datums/movement/mob.dm
@@ -249,7 +249,7 @@
to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!")
return MOVEMENT_STOP
- for(var/G in mob.grabbed_by)
+ if(mob.grabbed_by.len)
return MOVEMENT_STOP
/* TODO: Bay grab system
if(G.stop_move())
From cc5445ecc326b1884b76e5e53beff268d7f55e2f Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Sun, 9 Mar 2025 22:25:08 +0000
Subject: [PATCH 30/52] completely rewrite golem spawns
---
cev_eris.dme | 1 +
.../modules/mining/drilling/cave_generator.dm | 95 ++++---------
code/modules/mining/drilling/difficulties.dm | 128 ++++++++++++++++++
3 files changed, 155 insertions(+), 69 deletions(-)
create mode 100644 code/modules/mining/drilling/difficulties.dm
diff --git a/cev_eris.dme b/cev_eris.dme
index 71e0832d7a5..da9ed277ae5 100644
--- a/cev_eris.dme
+++ b/cev_eris.dme
@@ -1848,6 +1848,7 @@
#include "code\modules\mining\drilling\cave_generator.dm"
#include "code\modules\mining\drilling\cave_mineral.dm"
#include "code\modules\mining\drilling\deep_drill.dm"
+#include "code\modules\mining\drilling\difficulties.dm"
#include "code\modules\mining\drilling\scanner.dm"
#include "code\modules\mob\animations.dm"
#include "code\modules\mob\death.dm"
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 283ed76b500..719096242e4 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -28,8 +28,9 @@
#define CAVE_GOLD 9
#define CAVE_PLATINUM 10
-//minimum distance between spawned clusters. the spawn is canceled if it's lower than this.
-#define GOLEM_SPAWN_SPACING 7.5 //
+#define GOLEM_SPAWN_INTERVAL 15 // the spacing along each corridor that each golem squad will spawn
+#define GOLEM_SPAWN_SPACING 10 //squads WILL NOT spawn closer than this no matter what, even if corridors intersect or run too close.area
+
//chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)"
#define GOLEM_SPAWN_CHANCE_BASE 2.8
#define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6.
@@ -59,7 +60,15 @@
var/list/blacklist = list(/mob/observer,
/obj/machinery/nuclearbomb,
/obj/item/disk/nuclear)
- var/list/generated_golems = list() //golems use this for targeting allies
+ var/list/golem_spawn_nodes = list()
+ var/list/datum/cave_difficulty_level/difficulties = list(
+ new /datum/cave_difficulty_level/beginner,
+ new /datum/cave_difficulty_level/novice,
+ new /datum/cave_difficulty_level/adept,
+ new /datum/cave_difficulty_level/experienced,
+ new /datum/cave_difficulty_level/expert,
+ new /datum/cave_difficulty_level/nightmare
+ )
/obj/cave_generator/Initialize()
// Initialize and not New to ensure SSmapping.maploader has been created
@@ -124,8 +133,12 @@
// Draw a 2-wide corridor
for(var/i = x0 to x1 + 1)
+ if((y0 == y1) && ((i % GOLEM_SPAWN_SPACING) == 0) && check_spawn_overlap(locate(x + i,y + y0,z), golem_spawn_nodes))
+ golem_spawn_nodes |= locate(x + i,y + y0,z) //i would use lists of x,y (like the rest of the generation code) but neither the | or the in operators work with nested lists so turfs it is
for(var/j = y0 to y1 + 1)
map[i][j] = CAVE_FREE
+ if((x0 == x1) && ((j % GOLEM_SPAWN_SPACING) == 0) && check_spawn_overlap(locate(x + x0,y + j,z), golem_spawn_nodes))
+ golem_spawn_nodes |= locate(x + x0,y + j,z)
// If this is the last corridor
if(N == 0)
@@ -595,77 +608,22 @@
// Spawn golems on free turfs depending on seismic level
/obj/cave_generator/proc/place_golems(seismic_lvl)
- var/list/turf/golem_spawn_points = list()
-
- for(var/i = 1 to CAVE_SIZE)
- for(var/j = 1 to CAVE_SIZE)
- if(map[i][j] == CAVE_FREE && prob(GOLEM_SPAWN_CHANCE_BASE + seismic_lvl * GOLEM_SPAWN_CHANCE_SCALING) && check_spawn_overlap(get_turf(locate(x + i, y + j, z)), golem_spawn_points))
-
- var/turf/turf = get_turf(locate(x + i, y + j, z))
-
- golem_spawn_points += turf
-
- //var/list/mob/golems_to_spawn = list()
-
- var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list()
+ var/list/datum/cave_difficulty_level/current_difficulty = difficulties[seismic_lvl]
- switch(seismic_lvl)
- if(1,2) //easy: pick 3 random golems
- var/weights = list(
- /mob/living/carbon/superior_animal/golem/iron = 3,
- /mob/living/carbon/superior_animal/golem/coal = 2,
- /mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2.
+ for(var/turf/floor/asteroid/cave/spawnloc in golem_spawn_nodes) //filtering to only asteroid turfs avoids headaches with POIs and null locs that come from god knows where
- for(var/c = 0, c < 3, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution
- golems_to_spawn += pickweight(weights)
+ var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = current_difficulty.get_golem_spawns()
- if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 2 random
- var/melee_weights = list(
- /mob/living/carbon/superior_animal/golem/iron = 4,
- /mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0,
- /mob/living/carbon/superior_animal/golem/coal/enhanced = (seismic_lvl == 4) ? 2 : 0,
- /mob/living/carbon/superior_animal/golem/platinum = 3,
- /mob/living/carbon/superior_animal/golem/plasma = (seismic_lvl == 4) ? 2 : 0)
+ var/potentialturfs = list()
- var/ranged_weights = list(
- /mob/living/carbon/superior_animal/golem/silver = 3,
- /mob/living/carbon/superior_animal/golem/uranium = 1)
+ for(var/turf/floor/asteroid/cave/potential_turf in range(1, spawnloc))
+ potentialturfs += potential_turf
- golems_to_spawn += pickweight(melee_weights)
- golems_to_spawn += pickweight(ranged_weights)
-
- for(var/c = 0, c < 2, c++)
- golems_to_spawn += pickweight(melee_weights + ranged_weights)
-
- if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem
- var/melee_weights = list(
- /mob/living/carbon/superior_animal/golem/iron = 3,
- /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
- /mob/living/carbon/superior_animal/golem/platinum = 3,
- /mob/living/carbon/superior_animal/golem/plasma = 2,
- /mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0)
-
- var/ranged_weights = list(
- /mob/living/carbon/superior_animal/golem/silver/enhanced = 3,
- /mob/living/carbon/superior_animal/golem/gold = 3,
- /mob/living/carbon/superior_animal/golem/uranium = 2,
- /mob/living/carbon/superior_animal/golem/ansible = (seismic_lvl == 6) ? 2 : 0)
-
- for(var/c = 0, c < 2, c++)
- golems_to_spawn += pickweight(melee_weights)
- golems_to_spawn += pickweight(ranged_weights)
- golems_to_spawn += pickweight(ranged_weights + melee_weights)
-
- var/potentialturfs = list()
- for(var/turf/floor/asteroid/cave/potential_turf in range(1, turf))
- potentialturfs += potential_turf
-
- for(var/golem in golems_to_spawn)
- new golem(pick_mobless_turf_if_exists(potentialturfs))
-
- for(var/c = 1 to golem_spawn_points.len)
- log_world(golem_spawn_points[c])
+ if(potentialturfs)
+ for(var/golem in golems_to_spawn)
+ new golem(pick_mobless_turf_if_exists(potentialturfs))
+//crude check if a point is within a given distance of any point in the given list
/obj/cave_generator/proc/check_spawn_overlap(target_turf,list/pointlist)
if(!(target_turf && pointlist))
return FALSE
@@ -673,7 +631,6 @@
for(var/turf/t in pointlist)
if(get_dist_euclidian(target_turf, t) < GOLEM_SPAWN_SPACING)
return FALSE
-
return TRUE
//////////////////////////////
diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm
new file mode 100644
index 00000000000..bcace7fb46d
--- /dev/null
+++ b/code/modules/mining/drilling/difficulties.dm
@@ -0,0 +1,128 @@
+/datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process
+ var/golem_ore_mult = 1
+
+ //number of golems to spawn *per squad*
+ var/golem_count_melee = 0
+ var/golem_count_ranged = 0
+ var/golem_count_mixed = 0 // the "mixed" pool is the concatenation of the melee and ranged pools
+
+ //lists of types and weights
+ var/list/golem_weights_melee = list()
+ var/list/golem_weights_ranged = list()
+
+/datum/cave_difficulty_level/proc/get_golem_spawns()
+ var/list/golems_to_spawn = list() //list of golem types to spawn
+ if(golem_count_melee)
+ for(var/c = 0, c < golem_count_melee, c++)
+ golems_to_spawn += pickweight(golem_weights_melee)
+
+ if(golem_count_ranged)
+ for(var/c = 0, c < golem_count_ranged, c++)
+ golems_to_spawn += pickweight(golem_weights_ranged)
+
+ if(golem_count_mixed)
+ var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged
+ for(var/c = 0, c < golem_count_mixed, c++)
+ golems_to_spawn += pickweight(golem_weights_mixed)
+
+ return golems_to_spawn
+
+//Seismic Level 1
+//Easy enough to figure out the basics, but not very rewarding.
+/datum/cave_difficulty_level/beginner
+ golem_count_mixed = 3
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 3,
+ /mob/living/carbon/superior_animal/golem/coal = 2)
+
+//Seismic Level 2
+//Tougher, more rewarding.
+/datum/cave_difficulty_level/novice
+ golem_ore_mult = 1.75
+
+ golem_count_mixed = 3
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 3,
+ /mob/living/carbon/superior_animal/golem/coal = 2)
+
+ golem_weights_ranged = list(
+ /mob/living/carbon/superior_animal/golem/silver = 2)
+
+//Seismic Level 3
+//Ever harder. The golems introduced here are hard to fight alone. This is the limit for a solo miner on their roundstart gear.
+/datum/cave_difficulty_level/adept
+ golem_ore_mult = 2.5
+
+ golem_count_melee = 1
+ golem_count_ranged = 1
+ golem_count_mixed = 3
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 4,
+ /mob/living/carbon/superior_animal/golem/coal = 2,
+ /mob/living/carbon/superior_animal/golem/platinum = 3)
+
+ golem_weights_ranged = list(
+ /mob/living/carbon/superior_animal/golem/silver = 3,
+ /mob/living/carbon/superior_animal/golem/uranium = 1)
+
+//Seismic Level 4
+//Teams should start to have trouble here; graphite golems make plasma and platinum golems very dangerous.
+/datum/cave_difficulty_level/experienced
+ golem_ore_mult = 3.25
+
+ golem_count_melee = 1
+ golem_count_ranged = 1
+ golem_count_mixed = 3
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 4,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/platinum = 3,
+ /mob/living/carbon/superior_animal/golem/plasma = 2)
+
+ golem_weights_ranged = list(
+ /mob/living/carbon/superior_animal/golem/silver = 3,
+ /mob/living/carbon/superior_animal/golem/uranium = 1)
+
+//Seismic Level 5
+//All the lethal golems are out now. A lot of prep or a lot of manpower is necessary to survive this.
+/datum/cave_difficulty_level/expert
+ golem_ore_mult = 4
+
+ golem_count_melee = 2
+ golem_count_ranged = 2
+ golem_count_mixed = 1
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 3,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/platinum = 3,
+ /mob/living/carbon/superior_animal/golem/plasma = 2)
+ golem_weights_ranged = list(
+ /mob/living/carbon/superior_animal/golem/silver/enhanced = 3,
+ /mob/living/carbon/superior_animal/golem/gold = 3,
+ /mob/living/carbon/superior_animal/golem/uranium = 2)
+
+//Seismic Level 6
+//Hell. Ansibles will rip teams apart and diamonds are walking tanks unless you've invested in ballistics.
+/datum/cave_difficulty_level/nightmare
+ golem_ore_mult = 4
+
+ golem_count_melee = 2
+ golem_count_ranged = 2
+ golem_count_mixed = 1
+
+ golem_weights_melee = list(
+ /mob/living/carbon/superior_animal/golem/iron = 3,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/platinum = 3,
+ /mob/living/carbon/superior_animal/golem/plasma = 2,
+ /mob/living/carbon/superior_animal/golem/diamond = 2)
+ golem_weights_ranged = list(
+ /mob/living/carbon/superior_animal/golem/silver/enhanced = 3,
+ /mob/living/carbon/superior_animal/golem/gold = 3,
+ /mob/living/carbon/superior_animal/golem/uranium = 2,
+ /mob/living/carbon/superior_animal/golem/ansible = 2)
From a24a7d877379af1d3c20717920c325931f52ed65 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Mon, 10 Mar 2025 00:53:48 +0000
Subject: [PATCH 31/52] rewrite ore drops + add difficulty scaling
---
.../modules/mining/drilling/cave_generator.dm | 2 +-
code/modules/mining/drilling/difficulties.dm | 14 +++++++++++
.../carbon/superior_animal/golem/golem.dm | 23 +++++++++++--------
.../superior_animal/golem/types/ansible.dm | 9 +++++---
.../superior_animal/golem/types/coal.dm | 2 +-
.../superior_animal/golem/types/diamond.dm | 2 +-
.../superior_animal/golem/types/gold.dm | 2 +-
.../superior_animal/golem/types/iron.dm | 2 +-
.../superior_animal/golem/types/plasma.dm | 2 +-
.../superior_animal/golem/types/platinum.dm | 2 +-
.../superior_animal/golem/types/silver.dm | 2 +-
.../superior_animal/golem/types/uranium.dm | 2 +-
12 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 719096242e4..5fa0ef8277d 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -621,7 +621,7 @@
if(potentialturfs)
for(var/golem in golems_to_spawn)
- new golem(pick_mobless_turf_if_exists(potentialturfs))
+ new golem(pick_mobless_turf_if_exists(potentialturfs), current_difficulty)
//crude check if a point is within a given distance of any point in the given list
/obj/cave_generator/proc/check_spawn_overlap(target_turf,list/pointlist)
diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm
index bcace7fb46d..16f590cf619 100644
--- a/code/modules/mining/drilling/difficulties.dm
+++ b/code/modules/mining/drilling/difficulties.dm
@@ -1,4 +1,6 @@
/datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process
+ var/level //number value is easier to work with in some situations
+
var/golem_ore_mult = 1
//number of golems to spawn *per squad*
@@ -30,6 +32,8 @@
//Seismic Level 1
//Easy enough to figure out the basics, but not very rewarding.
/datum/cave_difficulty_level/beginner
+ level = 1
+
golem_count_mixed = 3
golem_weights_melee = list(
@@ -39,6 +43,8 @@
//Seismic Level 2
//Tougher, more rewarding.
/datum/cave_difficulty_level/novice
+ level = 2
+
golem_ore_mult = 1.75
golem_count_mixed = 3
@@ -53,6 +59,8 @@
//Seismic Level 3
//Ever harder. The golems introduced here are hard to fight alone. This is the limit for a solo miner on their roundstart gear.
/datum/cave_difficulty_level/adept
+ level = 3
+
golem_ore_mult = 2.5
golem_count_melee = 1
@@ -71,6 +79,8 @@
//Seismic Level 4
//Teams should start to have trouble here; graphite golems make plasma and platinum golems very dangerous.
/datum/cave_difficulty_level/experienced
+ level = 4
+
golem_ore_mult = 3.25
golem_count_melee = 1
@@ -90,6 +100,8 @@
//Seismic Level 5
//All the lethal golems are out now. A lot of prep or a lot of manpower is necessary to survive this.
/datum/cave_difficulty_level/expert
+ level = 5
+
golem_ore_mult = 4
golem_count_melee = 2
@@ -109,6 +121,8 @@
//Seismic Level 6
//Hell. Ansibles will rip teams apart and diamonds are walking tanks unless you've invested in ballistics.
/datum/cave_difficulty_level/nightmare
+ level = 6
+
golem_ore_mult = 4
golem_count_melee = 2
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 7fd03381980..d24bdc63df3 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -67,14 +67,20 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
// Damage multiplier when destroying surroundings
var/surrounds_mult = 0.5
- // Type of ore to spawn when the golem dies
- var/ore
+ // Ore datum the golem holds.
+ var/ore/mineral
+ var/mineral_name
var/targetrecievedtime = -250
-/mob/living/carbon/superior_animal/golem/Initialize(var/mapload)
+ var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops
+
+/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty)
GLOB.all_golems += src
- .=..()
+ if(mineral_name && (mineral_name in ore_data))
+ mineral = ore_data[mineral_name]
+ difficultylevel = difficulty
+ . = ..()
/mob/living/carbon/superior_animal/golem/Destroy()
GLOB.all_golems -= src
@@ -85,13 +91,12 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
. = ..()
// Spawn ores
- if(ore)
- var/nb_ores = rand(8, 13)
+ if(mineral)
+ var/nb_ores = ceil((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1))
for(var/i in 1 to nb_ores)
- new ore(loc)
+ new mineral.ore(loc)
- // Specials have a small chance to also drop a golem core
- if(prob(30) && !istype(src, /mob/living/carbon/superior_animal/golem/coal) && !istype(src, /mob/living/carbon/superior_animal/golem/iron))
+ if(prob(20))
new /obj/item/golem_core(loc)
// Poof
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 54bf7b2cbd4..363d8634192 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -28,9 +28,6 @@
rad = 0
)
- // Loot related variables
- ore = /obj/item/stock_parts/subspace/crystal
-
// Ranged attack related variables
ranged = TRUE // Will it shoot?
rapid = FALSE // Will it shoot fast?
@@ -54,6 +51,12 @@
set_light(0)
. = ..()
+/mob/living/carbon/superior_animal/golem/ansible/death()
+ if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward.
+ var/crystal = new /obj/item/bluespace_crystal(loc)
+ visible_message(SPAN_NOTICE("A [crystal] falls out of [src] as it disintegrates."), 1)
+ ..()
+
// Special capacity of ansible golem: it will focus and teleport a miner near other golems
/mob/living/carbon/superior_animal/golem/ansible/proc/teleport_target()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
index cc2b49dfc19..bceed7f70ac 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
@@ -27,7 +27,7 @@
)
// Loot related variables
- ore = /obj/item/ore/coal
+ mineral_name = ORE_CARBON
// enhanced coal golems will grab players, leaving them vulnerable to very high damage golems like gold and platinum
/mob/living/carbon/superior_animal/golem/coal/enhanced
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm
index c00d5e5f411..d1e03788207 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm
@@ -30,4 +30,4 @@
)
// Loot related variables
- ore = /obj/item/ore/diamond
+ mineral_name = ORE_DIAMOND
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index 74e806d67c0..ebf3ffc7f5f 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -34,7 +34,7 @@
retreat_on_too_close = TRUE
// Loot related variables
- ore = /obj/item/ore/
+ mineral_name = ORE_GOLD
var/spike_cooldown = 0
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm
index a7230a974ab..e9adeb47e2d 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm
@@ -27,4 +27,4 @@
)
// Loot related variables
- ore = /obj/item/ore/iron
+ mineral_name = ORE_IRON
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
index 2b16f665968..5f8c7ca0ec8 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
@@ -30,7 +30,7 @@
)
// Loot related variables
- ore = /obj/item/ore/plasma
+ mineral_name = ORE_PLASMA
// How much time before detonation
var/det_time = 2.5 SECONDS
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index 11aa81e0bd0..4da16bf7e57 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -33,7 +33,7 @@
)
// Loot related variables
- ore = /obj/item/ore/osmium
+ mineral_name = ORE_PLATINUM
var/charge_verbs = list("launches itself", "charges", "rams")
var/charge_hit_verbs = list("crashes into", "smashes", "slams into")
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
index dba5225872e..173f20b5a6f 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
@@ -28,7 +28,7 @@
)
// Loot related variables
- ore = /obj/item/ore/silver
+ mineral_name = ORE_SILVER
// Ranged attack related variables
ranged = TRUE // Will it shoot?
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index 3ad57179a46..c5b0c53d367 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -29,7 +29,7 @@
)
// Loot related variables
- ore = /obj/item/ore/uranium
+ mineral_name = ORE_URANIUM
kept_distance = 3
retreat_on_too_close = TRUE
From ef0910669be99013a67807fc33e61826347c49a9 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Mon, 10 Mar 2025 01:16:35 +0000
Subject: [PATCH 32/52] qol changes
---
code/game/objects/items/weapons/storage/bags.dm | 2 +-
code/modules/mining/ore.dm | 1 +
.../mob/living/carbon/superior_animal/golem/golem_core.dm | 3 ++-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index ecd2746cc11..af66b10b29d 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -109,7 +109,7 @@
icon_state = "satchel"
slot_flags = SLOT_BELT | SLOT_POCKET
w_class = ITEM_SIZE_NORMAL
- max_storage_space = 200
+ max_storage_space = 400 //stores 200 ore, not 400.
max_w_class = ITEM_SIZE_NORMAL
can_hold = list(/obj/item/ore)
diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm
index 4db44988dfa..68e96a7c177 100644
--- a/code/modules/mining/ore.dm
+++ b/code/modules/mining/ore.dm
@@ -2,6 +2,7 @@
name = "rock"
icon = 'icons/obj/mining.dmi'
icon_state = "ore2"
+ layer = OBJ_LAYER - 0.05 //slightly below other items so that ore piles don't bury anything on the same tile
w_class = ITEM_SIZE_SMALL
rarity_value = 25
bad_type = /obj/item/ore
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm
index 38ec962c72e..c72c15cddf4 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm
@@ -7,6 +7,7 @@
gender = PLURAL
icon = 'icons/mob/golems.dmi'
icon_state = "golem_core"
+ layer = OBJ_LAYER
w_class = ITEM_SIZE_SMALL
throwforce = 0
throw_speed = 4
@@ -34,7 +35,7 @@
if(!do_mob(user, M, 2 SECOND))
to_chat(user, SPAN_NOTICE("You must stand still to apply \the [src]."))
return TRUE
-
+
// Heal the target
M.adjustBruteLoss(-GOLEM_CORE_HEAL)
M.adjustFireLoss(-GOLEM_CORE_HEAL)
From 678b6586cb2930f65f3ed8ad7fe06b4cce9eb6ca Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Mon, 10 Mar 2025 21:32:02 +0000
Subject: [PATCH 33/52] commit spaghetti
i forgot to commit and then i made another change and then i was like "oh one more change" and i still didn't commit and now here we are
---
code/game/objects/items/weapons/tools/karl.dm | 22 ++++-
.../modules/mining/drilling/cave_generator.dm | 85 +++++++++++++------
code/modules/mining/drilling/cave_mineral.dm | 9 ++
code/modules/mining/drilling/deep_drill.dm | 32 +++++--
code/modules/mining/drilling/difficulties.dm | 9 ++
code/modules/mining/mine_items.dm | 7 --
code/modules/mining/mine_turfs.dm | 8 +-
.../carbon/superior_animal/golem/golem.dm | 2 +-
.../superior_animal/golem/types/ansible.dm | 4 +-
9 files changed, 124 insertions(+), 54 deletions(-)
diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm
index 43bb4d1de73..c148613a247 100644
--- a/code/game/objects/items/weapons/tools/karl.dm
+++ b/code/game/objects/items/weapons/tools/karl.dm
@@ -43,6 +43,7 @@
var/shot_sound // What sound should play when the gun fires
var/reqpower = 10 // Power needed to shoot
var/isPumping = FALSE // Whether someone is currently pumping the KARL to recharge it
+ var/pumping_time = 5 SECONDS
/obj/item/tool/karl/New()
. = ..()
@@ -97,18 +98,17 @@
if(isPumping)
to_chat(user, SPAN_NOTICE("You are already pumping \the [src] to recharge it."))
return
- var/pumping_time = wielded ? 1 SECOND : 2 SECONDS
isPumping = TRUE
if(do_after(user, pumping_time))
if(cell) // Check the cell is still there in case big brain player chose to remove it during pumping
- cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second
+ cell.give(use_power_cost * pumping_time)
to_chat(user, SPAN_NOTICE("You recharge \the [src] by pumping it, cell charge at [round(cell.percent())]%."))
// Continue pumping till user cancels the pumping
isPumping = FALSE
attack_self(user)
isPumping = FALSE
else
- to_chat(user, SPAN_NOTICE("\The [src]\'cell is fully charged'."))
+ to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged'."))
else
to_chat(user, SPAN_NOTICE("\The [src] is missing a cell to recharge."))
return
@@ -140,7 +140,7 @@
// Recharge upon successfull use when switched off
if(. && !switched_on && cell)
- cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second
+ cell.give(use_power_cost * 25)
/obj/item/tool/karl/proc/toggle_mode_verb()
set name = "Unique Action"
@@ -206,3 +206,17 @@
nano_ui_interact(user)
else
toggle_karl_mode(user)
+
+/obj/item/tool/karl/attackby(var/obj/item/I, var/mob/user)
+ if(istype(I, /obj/item/golem_core))
+ if(cell)
+ if(!cell.fully_charged())
+ cell.give(200)
+ to_chat(user, SPAN_NOTICE("You use the [I] to charge the [src] to [round(cell.percent())]%, destroying it in the process.")) //this makes no sense realistically, but ye olde gameplay over realism
+ qdel(I)
+ else
+ to_chat(user, SPAN_NOTICE("The [src] is already fully charged."))
+ else
+ to_chat(user, SPAN_NOTICE("Trying to recharge the [src] without a cell installed would be pointless."))
+ else
+ . = ..()
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 5fa0ef8277d..ca572521dd2 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -5,6 +5,10 @@
#define CAVE_CORRIDORS 10 // Number of corridors to guide cave generation
#define CAVE_WALL_PROPORTION 70 // Proportion of wall in random noise generation
#define CAVE_VWEIGHT 10 // Base mineral weight for choice of mineral vein
+#define CAVE_VEINS_MINIMUM 8
+#define CAVE_VEINS_MAXIMUM 20
+#define CAVE_VEINS_SIZE 2 //size factor for veins generated with RNG
+#define CAVE_VEINS_SIZE_FORCED 2 //size factor for veins forced to generate because RNG didn't generate any of that mineral type
#define CAVE_COOLDOWN 5 MINUTES
#define CAVE_COLLAPSE 3 MINUTES
@@ -27,14 +31,11 @@
#define CAVE_SILVER 8
#define CAVE_GOLD 9
#define CAVE_PLATINUM 10
+#define CAVE_HYDROGEN 11
#define GOLEM_SPAWN_INTERVAL 15 // the spacing along each corridor that each golem squad will spawn
#define GOLEM_SPAWN_SPACING 10 //squads WILL NOT spawn closer than this no matter what, even if corridors intersect or run too close.area
-//chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)"
-#define GOLEM_SPAWN_CHANCE_BASE 2.8
-#define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6.
-
//////////////////////////////
// Generator used to handle underground caves
//////////////////////////////
@@ -69,6 +70,9 @@
new /datum/cave_difficulty_level/expert,
new /datum/cave_difficulty_level/nightmare
)
+ var/datum/cave_difficulty_level/current_difficulty
+ var/list/veins_to_guarantee = list()
+ var/orecount = 0
/obj/cave_generator/Initialize()
// Initialize and not New to ensure SSmapping.maploader has been created
@@ -80,6 +84,11 @@
pool_pois += new cave_poi_tmpl
/obj/cave_generator/proc/generate_map(seismic_lvl = 1)
+
+ current_difficulty = difficulties[seismic_lvl]
+ golem_spawn_nodes = list()
+ orecount = 0
+
// Fill the map with random noise
random_fill_map()
@@ -121,7 +130,6 @@
// Draw a few straight lines in the initial random noise to guide the generation
/obj/cave_generator/proc/generate_corridors()
-
// Draw a vertical corridor from (CAVE_MARGIN, CAVE_SIZE/2) to (CAVE_SIZE/2, CAVE_SIZE/2)
// then recursively draw corridors that branches out from it
draw_recursive_corridor(CAVE_MARGIN, CAVE_SIZE/2, CAVE_SIZE/2, CAVE_SIZE/2, CAVE_CORRIDORS/2)
@@ -257,15 +265,29 @@
// Generate mineral veins once cave layout has been decided
/obj/cave_generator/proc/generate_mineral_veins(seismic_lvl)
+
+ veins_to_guarantee = list(/datum/cave_vein/carbon, //if these veins don't get spawned by RNG, force mini-veins to spawn
+ /datum/cave_vein/iron,
+ /datum/cave_vein/plasma,
+ /datum/cave_vein/silver,
+ /datum/cave_vein/gold,
+ /datum/cave_vein/uranium,
+ /datum/cave_vein/diamond,
+ /datum/cave_vein/platinum)
var/x_vein = 0
var/y_vein = 0
- var/N_veins = rand(15, 20 * (1 + 0.5 * (seismic_lvl - SEISMIC_MIN) / (SEISMIC_MAX - SEISMIC_MIN)))
+ var/N_veins = rand(20, 35)
var/N_trials = 50
while(N_veins > 0 && N_trials > 0)
N_trials--
x_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN)
y_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN)
- N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl)
+ N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl, CAVE_VEINS_SIZE)
+
+ for(var/datum/cave_vein/forcedvein in veins_to_guarantee)
+ x_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN)
+ y_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN)
+ N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl, CAVE_VEINS_SIZE_FORCED, forcedvein)
// Find a free spot in the cave
/obj/cave_generator/proc/find_free_spot(x_start, y_start, x_margin = 0, y_margin = 0)
@@ -437,7 +459,7 @@
QDEL_NULL(ladder_up)
// Place a mineral vein starting at the designated spot
-/obj/cave_generator/proc/place_mineral_vein(x_start, y_start, seismic_lvl)
+/obj/cave_generator/proc/place_mineral_vein(x_start, y_start, seismic_lvl, sizemult = 1, vein_path)
// Find closest available spot (wall tile near a free tile)
var/search_for = map[x_start][y_start] == CAVE_FREE ? CAVE_WALL : CAVE_FREE
@@ -481,23 +503,21 @@
// Choose which kind of mineral should the vein be made of
// Multiplier scale from 0 to 1
- // Carbon and iron always have same probability
- // Plasma, silver, gold scale up until medium seismic level
- // Uranium, diamond and platinum scale up until max seismic level
- var/seismic_mult = (seismic_lvl - SEISMIC_MIN) / (SEISMIC_MAX - SEISMIC_MIN)
- var/list/datum/cave_vein/cave_veins = list(/datum/cave_vein/carbon = CAVE_VWEIGHT,
- /datum/cave_vein/iron = CAVE_VWEIGHT,
- /datum/cave_vein/plasma = CAVE_VWEIGHT * min(1, 2 * seismic_mult),
- /datum/cave_vein/silver = CAVE_VWEIGHT * min(1, 2 * seismic_mult),
- /datum/cave_vein/gold = CAVE_VWEIGHT * min(1, 2 * seismic_mult),
- /datum/cave_vein/uranium = CAVE_VWEIGHT * seismic_mult,
- /datum/cave_vein/diamond = CAVE_VWEIGHT * seismic_mult,
- /datum/cave_vein/platinum = CAVE_VWEIGHT * seismic_mult)
- var/vein_path = pickweight(cave_veins)
+ var/list/datum/cave_vein/cave_veins = list(/datum/cave_vein/carbon = CAVE_VWEIGHT * 2,
+ /datum/cave_vein/iron = CAVE_VWEIGHT * 2,
+ /datum/cave_vein/plasma = CAVE_VWEIGHT,
+ /datum/cave_vein/silver = CAVE_VWEIGHT,
+ /datum/cave_vein/gold = CAVE_VWEIGHT,
+ /datum/cave_vein/uranium = CAVE_VWEIGHT,
+ /datum/cave_vein/diamond = CAVE_VWEIGHT * 0.75,
+ /datum/cave_vein/platinum = CAVE_VWEIGHT * 0.75,
+ /datum/cave_vein/hydrogen = CAVE_VWEIGHT * ((seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0))//only generate on max difficulty. super duper valuable.
+ vein_path ||= pickweight(cave_veins)
var/datum/cave_vein/CV = new vein_path()
+ veins_to_guarantee -= vein_path
// Place mineral vein at the available spot in a recursive manner
- place_recursive_mineral(x_start, y_start, CV.p_spread, CV.size_max, CV.size_min, CV.mineral)
+ place_recursive_mineral(x_start, y_start, CV.p_spread, ceil(CV.size_max * sizemult), floor(CV.size_min * sizemult), CV.mineral)
return 1
// Place a mineral vein in a recursive manner
@@ -586,6 +606,8 @@
turf_type = /turf/cave_mineral/gold
if(CAVE_PLATINUM)
turf_type = /turf/cave_mineral/platinum
+ if(CAVE_HYDROGEN)
+ turf_type = /turf/cave_mineral/hydrogen
else
turf_type = /turf/floor/asteroid/cave
@@ -594,7 +616,9 @@
T.ChangeTurf(turf_type)
if(istype(T, /turf/cave_mineral))
var/turf/cave_mineral/CM = T
- CM.seismic_multiplier = seismic_lvl
+ CM.seismic_multiplier = current_difficulty.vein_ore_mult
+ CM.cave_gen = src
+ orecount++
// Spawn points of interest at their respective position
/obj/cave_generator/proc/place_pois()
@@ -608,8 +632,6 @@
// Spawn golems on free turfs depending on seismic level
/obj/cave_generator/proc/place_golems(seismic_lvl)
- var/list/datum/cave_difficulty_level/current_difficulty = difficulties[seismic_lvl]
-
for(var/turf/floor/asteroid/cave/spawnloc in golem_spawn_nodes) //filtering to only asteroid turfs avoids headaches with POIs and null locs that come from god knows where
var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = current_difficulty.get_golem_spawns()
@@ -691,6 +713,12 @@
size_min = 4
size_max = 8
+/datum/cave_vein/hydrogen //valuable and scarce
+ name = "hydrogen vein"
+ mineral = CAVE_HYDROGEN
+ size_min = 3
+ size_max = 6
+
//////////////////////////////
// Ladders to enter and exit the cave
//////////////////////////////
@@ -727,6 +755,10 @@
#undef CAVE_CORRIDORS
#undef CAVE_WALL_PROPORTION
#undef CAVE_VWEIGHT
+#undef CAVE_VEINS_MINIMUM
+#undef CAVE_VEINS_MAXIMUM
+#undef CAVE_VEINS_SIZE
+#undef CAVE_VEINS_SIZE_FORCED
#undef CAVE_COOLDOWN
#undef CAVE_COLLAPSE
@@ -749,7 +781,6 @@
#undef CAVE_SILVER
#undef CAVE_GOLD
#undef CAVE_PLATINUM
+#undef CAVE_HYDROGEN
-#undef GOLEM_SPAWN_CHANCE_BASE
-#undef GOLEM_SPAWN_CHANCE_SCALING
#undef GOLEM_SPAWN_SPACING
diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm
index 8d012fa54fb..ce8e6a926c4 100644
--- a/code/modules/mining/drilling/cave_mineral.dm
+++ b/code/modules/mining/drilling/cave_mineral.dm
@@ -35,6 +35,7 @@
var/mineral_name
var/mined_ore = 0
var/seismic_multiplier = 1
+ var/obj/cave_generator/cave_gen
has_resources = 1
@@ -97,6 +98,9 @@
//Not even going to touch this pile of spaghetti
/turf/cave_mineral/attackby(obj/item/I, mob/living/user)
+ if(cave_gen)
+ cave_gen.orecount--
+
var/tool_type = I.get_tool_type(user, list(QUALITY_DIGGING), src, CB = CALLBACK(src, PROC_REF(check_radial_dig)))
switch(tool_type)
if(QUALITY_DIGGING)
@@ -122,6 +126,8 @@
/turf/cave_mineral/proc/GetDrilled()
+
+
if (mineral && mineral.result_amount)
// If the turf has already been excavated, some of it's ore has been removed
clear_ore_effects()
@@ -162,3 +168,6 @@
/turf/cave_mineral/platinum
mineral_name = ORE_PLATINUM
+
+/turf/cave_mineral/hydrogen
+ mineral_name = ORE_HYDROGEN
diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm
index 8730e69ef3d..e6046acb288 100644
--- a/code/modules/mining/drilling/deep_drill.dm
+++ b/code/modules/mining/drilling/deep_drill.dm
@@ -135,7 +135,7 @@
if(I.use_tool(user, src, WORKTIME_LONG, QUALITY_WELDING, FAILCHANCE_EASY, required_stat = STAT_ROB))
playsound(src, 'sound/items/Welder.ogg', 100, 1)
to_chat(user, "You finish repairing the damage to [src].")
- health = ((health + DRILL_REPAIR_AMOUNT) < maxHealth ? health + DRILL_REPAIR_AMOUNT : maxHealth) // increase health by the defined repair amount unless it would go over maxHealth, in which case just set heal to maxHealth instead.
+ health = min(maxHealth, health + DRILL_REPAIR_AMOUNT)
return
@@ -223,14 +223,28 @@
qdel(src)
/obj/machinery/mining/deep_drill/examine(mob/user, extra_description = "")
- if(health <= 0)
- extra_description += "\n\The [src] is wrecked."
- else if(health < maxHealth * 0.33)
- extra_description += SPAN_DANGER("\n\The [src] looks like it's about to break!")
- else if(health < maxHealth * 0.66)
- extra_description += SPAN_DANGER("\n\The [src] looks seriously damaged!")
- else if(health < maxHealth)
- extra_description += "\n\The [src] shows signs of damage!"
+ if(cave_connected)
+ switch(cave_gen.orecount)
+ if(-INFINITY to 3)
+ extra_description += SPAN_NOTICE("\nThe integrated ore scanner can't detect any ore in the attached cave.")
+ if(3 to 10)
+ extra_description += SPAN_NOTICE("\nThe integrated ore scanner barely detects any ore in the attached cave.")
+ if(10 to 50)
+ extra_description += SPAN_NOTICE("\nThe integrated ore scanner still detects plenty of ore in the attached cave.")
+ if(50 to INFINITY)
+ extra_description += SPAN_NOTICE("\nThe integrated ore scanner detects an abundance of ore in the attached cave.")
+ else //something has gone wrong
+ extra_description += SPAN_WARNING("\nThe integrated ore scanner seems to be malfunctioning.")
+ if(health < maxHealth)
+ switch(health)
+ if(-INFINITY to 0)
+ extra_description += "\n\The [src] is wrecked."
+ if(0 to 600)
+ extra_description += SPAN_DANGER("\n\The [src] looks like it's about to break!")
+ if(600 to 1200)
+ extra_description += SPAN_DANGER("\n\The [src] looks seriously damaged!")
+ else
+ extra_description += "\n\The [src] shows signs of damage!"
else
extra_description += "\n\The [src] is in pristine condition."
diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm
index 16f590cf619..bc91101cc50 100644
--- a/code/modules/mining/drilling/difficulties.dm
+++ b/code/modules/mining/drilling/difficulties.dm
@@ -1,7 +1,11 @@
+//Cave difficulty levels store most stats that affect cavegen based on seismic level.area
+//Golems also store a reference to the current difficulty, currently used only for golem_ore_mult
+
/datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process
var/level //number value is easier to work with in some situations
var/golem_ore_mult = 1
+ var/vein_ore_mult = 1
//number of golems to spawn *per squad*
var/golem_count_melee = 0
@@ -45,6 +49,7 @@
/datum/cave_difficulty_level/novice
level = 2
+ vein_ore_mult = 1.5
golem_ore_mult = 1.75
golem_count_mixed = 3
@@ -61,6 +66,7 @@
/datum/cave_difficulty_level/adept
level = 3
+ vein_ore_mult = 2
golem_ore_mult = 2.5
golem_count_melee = 1
@@ -81,6 +87,7 @@
/datum/cave_difficulty_level/experienced
level = 4
+ vein_ore_mult = 2.5
golem_ore_mult = 3.25
golem_count_melee = 1
@@ -102,6 +109,7 @@
/datum/cave_difficulty_level/expert
level = 5
+ vein_ore_mult = 3
golem_ore_mult = 4
golem_count_melee = 2
@@ -123,6 +131,7 @@
/datum/cave_difficulty_level/nightmare
level = 6
+ vein_ore_mult = 4
golem_ore_mult = 4
golem_count_melee = 2
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 896f5ac06b5..bf020639bfa 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -16,22 +16,15 @@
new /obj/item/clothing/glasses/powered/meson(src)
new /obj/item/clothing/shoes/color/black(src)
new /obj/item/storage/belt/utility(src)
- new /obj/item/cell/large/high(src)
- new /obj/item/cell/large/high(src)
new /obj/item/cell/medium/high(src)
new /obj/item/cell/medium/high(src)
new /obj/item/cell/small/high(src)
new /obj/item/cell/small/high(src)
- new /obj/item/tool_upgrade/augment/cell_mount(src)
- new /obj/item/tool_upgrade/productivity/motor(src)
new /obj/item/device/scanner/gas(src)
new /obj/item/storage/bag/ore(src)
new /obj/item/device/lighting/toggleable/flashlight/heavy(src)
new /obj/item/tool/shovel(src)
new /obj/item/tool/pickaxe(src)
- new /obj/item/tool/pickaxe/jackhammer(src)
- new /obj/item/gun/projectile/shotgun/doublebarrel(src)
- new /obj/item/ammo_magazine/ammobox/shotgun(src)
new /obj/item/device/t_scanner(src)
new /obj/item/gun/projectile/flare_gun(src)
new /obj/item/ammo_casing/flare(src)
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index b5bcb52d662..7b8b8859696 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -171,8 +171,8 @@
/turf/mineral/random
name = "Mineral deposit"
- var/mineralSpawnChanceList = list(ORE_URANIUM = 5, ORE_PLATINUM = 5, ORE_IRON = 35, ORE_CARBON = 35, ORE_DIAMOND = 1, ORE_GOLD = 5, ORE_SILVER = 5, ORE_PLASMA = 10, ORE_HYDROGEN = 1)
- var/mineralChance = 100 //10 //means 10% chance of this plot changing to a mineral deposit
+ var/mineralSpawnChanceList = list(ORE_URANIUM = 5, ORE_PLATINUM = 5, ORE_IRON = 35, ORE_CARBON = 35, ORE_DIAMOND = 1, ORE_GOLD = 5, ORE_SILVER = 5, ORE_PLASMA = 10)
+ var/mineralChance = 50 //%
/turf/mineral/random/New()
if (prob(mineralChance) && !mineral)
@@ -188,8 +188,8 @@
return TRUE
/turf/mineral/random/high_chance
- mineralChance = 100 //25
- mineralSpawnChanceList = list(ORE_URANIUM = 10, ORE_PLATINUM = 10, ORE_IRON = 20, ORE_CARBON = 20, ORE_DIAMOND = 2, ORE_GOLD = 10, ORE_SILVER = 10, ORE_PLASMA = 20, ORE_HYDROGEN = 1)
+ mineralChance = 75 //%
+ mineralSpawnChanceList = list(ORE_URANIUM = 10, ORE_PLATINUM = 10, ORE_IRON = 20, ORE_CARBON = 20, ORE_DIAMOND = 2, ORE_GOLD = 10, ORE_SILVER = 10, ORE_PLASMA = 20)
/**********************Asteroid**************************/
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index d24bdc63df3..9b54367514a 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -159,7 +159,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
if(retreat_on_too_close)
updatePathFinding() //retreating enemies need to update their pathfinding way more often
- if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target
+ if(((targetrecievedtime + 5 SECONDS) > world.time) && (target_mob.z == z)) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target
attemptAttackOnTarget()
else
prepareAttackOnTarget()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 363d8634192..8a89e1e7d58 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -53,8 +53,8 @@
/mob/living/carbon/superior_animal/golem/ansible/death()
if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward.
- var/crystal = new /obj/item/bluespace_crystal(loc)
- visible_message(SPAN_NOTICE("A [crystal] falls out of [src] as it disintegrates."), 1)
+ var/obj/item/bluespace_crystal/crystal = new /obj/item/bluespace_crystal(loc)
+ visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates."), 1)
..()
// Special capacity of ansible golem: it will focus and teleport a miner near other golems
From b4b4ac9476eceb79df1cdac353db50e103c81feb Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Thu, 13 Mar 2025 13:28:20 +0000
Subject: [PATCH 34/52] karl can no longer be toggled by ghosts, and fixes for
charge from using it to mine
---
code/game/objects/items/weapons/tools/karl.dm | 23 +++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm
index c148613a247..e8e10e2bdba 100644
--- a/code/game/objects/items/weapons/tools/karl.dm
+++ b/code/game/objects/items/weapons/tools/karl.dm
@@ -28,8 +28,8 @@
// Turn on-off related
toggleable = TRUE
tool_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used.
- switched_off_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5)
- switched_on_qualities = list(QUALITY_DIGGING = 30, QUALITY_WELDING = 10)
+ switched_off_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5)
+ switched_on_qualities = list(QUALITY_DIGGING = 45, QUALITY_WELDING = 10)
suitable_cell = /obj/item/cell/medium/high
use_power_cost = 1.5
passive_power_cost = 0.01
@@ -120,11 +120,13 @@
if(.)
to_chat(user, SPAN_NOTICE("A dangerous energy blade now covers the edges of the tool."))
update_force()
+ update_use_cost()
/obj/item/tool/karl/turn_off(mob/user)
..()
to_chat(user, SPAN_NOTICE("The energy blade swiftly retracts."))
update_force()
+ update_use_cost()
/obj/item/tool/karl/proc/update_force()
if(gunmode)
@@ -134,27 +136,40 @@
else
force = initial(force) // Back to standard damage when KARL is turned off
+/obj/item/tool/karl/proc/update_use_cost()
+ if(gunmode || !switched_on)
+ use_power_cost = 0
+ else
+ use_power_cost = initial(use_power_cost)
+
+
// Same values than /obj/item/proc/use_tool
/obj/item/tool/karl/use_tool(mob/living/user, atom/target, base_time, required_quality, fail_chance, required_stat, instant_finish_tier = 110, forced_sound = null, sound_repeat = 2.5 SECONDS)
. = ..() // That proc will return TRUE only when everything was done right, and FALSE if something went wrong, ot user was unlucky.
// Recharge upon successfull use when switched off
- if(. && !switched_on && cell)
- cell.give(use_power_cost * 25)
+ if(. && !switched_on && cell && (istype(target, /turf/cave_mineral) || istype(target, /turf/mineral)))
+ cell.give(initial(use_power_cost) * 25)
/obj/item/tool/karl/proc/toggle_mode_verb()
set name = "Unique Action"
set category = "Object"
set src in view(1)
+ if(usr.incapacitated() || !Adjacent(usr))
+ to_chat(usr, "You can't do that.")
+ return FALSE
+
toggle_karl_mode(usr)
/obj/item/tool/karl/proc/toggle_karl_mode(mob/user)
+
gunmode = !gunmode
to_chat(user, SPAN_NOTICE("\The [src] switches to [gunmode ? "gun" : "tool"] mode."))
no_double_tact = gunmode ? TRUE : FALSE // No double tact in gunmode
no_swing = gunmode ? TRUE : FALSE // No swinging in gunmode
update_force()
+ update_use_cost()
update_icon()
update_wear_icon()
From 5c3c827f2d14944712acbbb064568eba0c181807 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Thu, 13 Mar 2025 13:38:56 +0000
Subject: [PATCH 35/52] move miner spawns to the mining dock
map changes jumpscare
---
maps/CEVEris/_CEV_Eris.dmm | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/maps/CEVEris/_CEV_Eris.dmm b/maps/CEVEris/_CEV_Eris.dmm
index 2680ffb8233..a50fed8b336 100644
--- a/maps/CEVEris/_CEV_Eris.dmm
+++ b/maps/CEVEris/_CEV_Eris.dmm
@@ -91436,6 +91436,7 @@
/obj/machinery/light{
dir = 8
},
+/obj/landmark/join/start/mining,
/turf/floor/tiled/steel/panels,
/area/eris/quartermaster/miningdock)
"etI" = (
@@ -91443,6 +91444,7 @@
dir = 4
},
/obj/machinery/light,
+/obj/landmark/join/start/mining,
/turf/floor/tiled/steel/gray_platform,
/area/eris/quartermaster/miningdock)
"etJ" = (
@@ -95057,8 +95059,8 @@
/area/eris/medical/medeva)
"eCg" = (
/obj/landmark/join/start/mining,
-/turf/floor/carpet,
-/area/eris/quartermaster/misc)
+/turf/floor/tiled/steel/panels,
+/area/eris/quartermaster/miningdock)
"eCh" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/engineering{
@@ -212127,8 +212129,8 @@ ewW
cHz
ewZ
dII
-euJ
-euJ
+eCg
+eCg
etH
cHz
cHz
@@ -255136,10 +255138,10 @@ edM
eou
enR
ehh
-eCg
+eCl
edL
egq
-eCg
+eCl
ehh
enR
efW
@@ -255338,10 +255340,10 @@ eFf
ebN
ebN
eys
-eCg
+eCl
edL
egq
-eCg
+eCl
ehh
enR
exT
From 179c631df6d9114c65b929923d90479a3c064cf1 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Thu, 13 Mar 2025 14:53:30 +0000
Subject: [PATCH 36/52] a bundle of changes
- Remove tile-based resources and the noise datum that generates them. Nothing used them anyway.
- Remove advanced ore detector, it only existed to detect the now-removed tile resources.
- More KARL fixes
- Add some description_info text to mining equipment to make it more clear what to do.
---
cev_eris.dme | 1 -
code/controllers/subsystems/mapping.dm | 2 -
code/game/objects/items/weapons/tools/karl.dm | 5 +-
code/game/turfs/turf.dm | 2 -
code/modules/mining/drilling/cave_mineral.dm | 2 -
code/modules/mining/drilling/deep_drill.dm | 1 +
code/modules/mining/drilling/scanner.dm | 78 +------------
code/modules/mining/mine_turfs.dm | 4 +-
.../overmap/exoplanets/planet_types/barren.dm | 2 +-
.../exoplanets/planet_types/chlorine.dm | 2 +-
.../overmap/exoplanets/planet_types/desert.dm | 2 +-
.../exoplanets/planet_types/garbage.dm | 2 +-
.../exoplanets/planet_types/shrouded.dm | 2 +-
.../overmap/exoplanets/planet_types/snow.dm | 2 +-
.../exoplanets/planet_types/volcanic.dm | 2 +-
code/modules/overmap/exoplanets/turfs.dm | 3 +-
code/modules/random_map/noise/ore.dm | 106 ------------------
code/modules/research/designs/mining.dm | 4 +-
18 files changed, 21 insertions(+), 201 deletions(-)
delete mode 100644 code/modules/random_map/noise/ore.dm
diff --git a/cev_eris.dme b/cev_eris.dme
index da9ed277ae5..235cbac9c91 100644
--- a/cev_eris.dme
+++ b/cev_eris.dme
@@ -2545,7 +2545,6 @@
#include "code\modules\random_map\noise\desert.dm"
#include "code\modules\random_map\noise\magma.dm"
#include "code\modules\random_map\noise\noise.dm"
-#include "code\modules\random_map\noise\ore.dm"
#include "code\modules\random_map\noise\tundra.dm"
#include "code\modules\reagents\atomic_distillery.dm"
#include "code\modules\reagents\bonsai.dm"
diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm
index 76d34a05559..ef113db5dd2 100644
--- a/code/controllers/subsystems/mapping.dm
+++ b/code/controllers/subsystems/mapping.dm
@@ -19,8 +19,6 @@ SUBSYSTEM_DEF(mapping)
admin_notice("Error: ASTEROID_Z_LEVELS config wasn't given a number.")
// Now for the actual map generating. This occurs for every z-level defined in the config.
new /datum/random_map/automata/cave_system(null, 1, 1, z_level, 300, 300)
- // Let's add ore too.
- new /datum/random_map/noise/ore(null, 1, 1, z_level, 64, 64)
else
admin_notice("Error: No asteroid z-levels defined in config!")
diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm
index e8e10e2bdba..8b5417478c5 100644
--- a/code/game/objects/items/weapons/tools/karl.dm
+++ b/code/game/objects/items/weapons/tools/karl.dm
@@ -1,6 +1,7 @@
/obj/item/tool/karl
name = "K.A.R.L"
desc = "Kinetic Acceleration Reconfigurable Lodebreaker. Rock and stone to the bone, miner!"
+ description_info = "It can be recharged by applying a golem core to it, mining with the energy blade powered off, or by using it in-hand in gun mode."
flags = CONDUCT
slot_flags = SLOT_BELT
icon = 'icons/obj/karl_mining.dmi'
@@ -27,7 +28,7 @@
// Turn on-off related
toggleable = TRUE
- tool_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used.
+ tool_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used.
switched_off_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5)
switched_on_qualities = list(QUALITY_DIGGING = 45, QUALITY_WELDING = 10)
suitable_cell = /obj/item/cell/medium/high
@@ -101,7 +102,7 @@
isPumping = TRUE
if(do_after(user, pumping_time))
if(cell) // Check the cell is still there in case big brain player chose to remove it during pumping
- cell.give(use_power_cost * pumping_time)
+ cell.give(initial(use_power_cost) * pumping_time)
to_chat(user, SPAN_NOTICE("You recharge \the [src] by pumping it, cell charge at [round(cell.percent())]%."))
// Continue pumping till user cancels the pumping
isPumping = FALSE
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 28bec280614..d0b836a77ca 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -28,8 +28,6 @@
var/needs_air_update = FALSE
var/datum/gas_mixture/air
- var/has_resources
- var/list/resources // Mining resources (for the large drills)
var/list/initial_gas
var/list/decals
var/list/affecting_lights // List of light sources affecting this turf
diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm
index ce8e6a926c4..76b6fe3296e 100644
--- a/code/modules/mining/drilling/cave_mineral.dm
+++ b/code/modules/mining/drilling/cave_mineral.dm
@@ -37,8 +37,6 @@
var/seismic_multiplier = 1
var/obj/cave_generator/cave_gen
- has_resources = 1
-
/turf/cave_mineral/Initialize()
.=..()
if (mineral_name && (mineral_name in ore_data))
diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm
index e6046acb288..0a41309c521 100644
--- a/code/modules/mining/drilling/deep_drill.dm
+++ b/code/modules/mining/drilling/deep_drill.dm
@@ -18,6 +18,7 @@
/obj/machinery/mining/deep_drill
name = "deep mining drill head"
desc = "An enormous drill to dig out deep ores."
+ description_info = "Can be used to open caves on asteroid surfaces, with difficulty and ore level depending on the seismic level of the tile it's activated on.\nThe seismic level of a tile can be found with a subsurface ore detector."
icon_state = "mining_drill"
pixel_x = -16
diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm
index f73f2b52579..4222ad54900 100644
--- a/code/modules/mining/drilling/scanner.dm
+++ b/code/modules/mining/drilling/scanner.dm
@@ -7,87 +7,19 @@
matter = list(MATERIAL_PLASTIC = 2, MATERIAL_STEEL = 1, MATERIAL_GLASS = 1)
charge_per_use = 0.5
- var/precision = FALSE
/obj/item/device/scanner/mining/is_valid_scan_target(atom/O)
return istype(O, /turf)
-
/obj/item/device/scanner/mining/scan(turf/T, mob/user)
- scan_data = mining_scan_action(T, user, precision)
+ scan_data = mining_scan_action(T, user)
scan_title = "Subsurface ore scan - ([T.x], [T.y])"
show_results(user)
-/obj/item/device/scanner/mining/advanced
- name = "advanced subsurface ore detector"
- precision = TRUE
-
-/proc/mining_scan_action(turf/source, mob/user, precision)
- if(precision)
- return mining_scan_action_precise(source, user)
- var/list/metals = list("surface minerals" = 0,
- "precious metals" = 0,
- "nuclear fuel" = 0,
- "exotic matter" = 0
- )
- var/list/lines = list("Ore deposits found at [source.x], [source.y]:")
-
- for(var/turf/T in RANGE_TURFS(2, source))
- if(!T.has_resources)
- continue
-
- for(var/metal in T.resources)
- var/ore_type
-
- switch(metal)
- if(MATERIAL_GLASS, MATERIAL_PLASTIC, MATERIAL_IRON)
- ore_type = "surface minerals"
- if(MATERIAL_GOLD, MATERIAL_SILVER, MATERIAL_DIAMOND)
- ore_type = "precious metals"
- if(MATERIAL_URANIUM)
- ore_type = "nuclear fuel"
- if(MATERIAL_PLASMA, MATERIAL_OSMIUM, MATERIAL_TRITIUM)
- ore_type = "exotic matter"
-
- if(ore_type)
- metals[ore_type] += T.resources[metal]
-
- for(var/ore_type in metals)
- var/result = "no sign"
-
- switch(metals[ore_type])
- if(1 to 25) result = "trace amounts"
- if(26 to 75) result = "significant amounts"
- if(76 to INFINITY) result = "huge quantities"
+/proc/mining_scan_action(turf/source, mob/user)
- lines += "- [result] of [ore_type]."
-
- if(istype(source, /turf))
+ if(istype(source, /turf/floor/asteroid) || istype(source, /turf/floor/exoplanet))
var/turf/source_simulated = source
- lines += "Seismic activity (from 1 up to 6): [source_simulated.seismic_activity]"
- else
- lines += "Seismic activity: 1"
-
- return jointext(lines, "
")
-
-/proc/mining_scan_action_precise(turf/source, mob/user)
- var/list/lines = list("Ore deposits found at [source.x], [source.y]:")
- var/list/metals = list()
- for(var/turf/T in RANGE_TURFS(2, source))
- if(!T.has_resources)
- continue
-
- for(var/metal in T.resources)
- metals[metal] += T.resources[metal]
-
- for(var/ore_type in metals)
- var/result = "no sign"
-
- switch(metals[ore_type])
- if(1 to 25) result = "trace amounts"
- if(26 to 75) result = "significant amounts"
- if(76 to INFINITY) result = "huge quantities"
-
- lines += "- [result] of [ore_type]."
+ return "Seismic activity (from 1 up to 6): [source_simulated.seismic_activity]"
- return jointext(lines, "
")
+ return "Seismic activity: N/A - The deep drill cannot mine this ground."
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 7b8b8859696..f78a59b123f 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -35,8 +35,6 @@
var/obj/item/last_find
var/datum/artifact_find/artifact_find
- has_resources = 1
-
/turf/mineral/Initialize()
.=..()
icon_state = "rock[rand(0,4)]"
@@ -207,7 +205,6 @@
temperature = TCMB
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
var/overlay_detail
- has_resources = 1
/turf/floor/asteroid/New()
..()
@@ -215,6 +212,7 @@
if(prob(20))
overlay_detail = "asteroid[rand(0,8)]"
updateMineralOverlays(1)
+ seismic_activity = rand(1,6)
/turf/floor/asteroid/explosion_act(target_power, explosion_handler/handler)
. = ..()
diff --git a/code/modules/overmap/exoplanets/planet_types/barren.dm b/code/modules/overmap/exoplanets/planet_types/barren.dm
index 34a7edbc1b6..3132cc60165 100644
--- a/code/modules/overmap/exoplanets/planet_types/barren.dm
+++ b/code/modules/overmap/exoplanets/planet_types/barren.dm
@@ -5,7 +5,7 @@
planetary_area = /area/exoplanet/barren
rock_colors = list(COLOR_BEIGE, COLOR_GRAY80, COLOR_BROWN)
possible_themes = list(/datum/exoplanet_theme/mountains)
- map_generators = list(/datum/random_map/noise/exoplanet/barren, /datum/random_map/noise/ore/rich)
+ map_generators = list(/datum/random_map/noise/exoplanet/barren)
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
features_budget = 6
surface_color = "#847c6f"
diff --git a/code/modules/overmap/exoplanets/planet_types/chlorine.dm b/code/modules/overmap/exoplanets/planet_types/chlorine.dm
index 91ed9e9f57b..bc4d50dad02 100644
--- a/code/modules/overmap/exoplanets/planet_types/chlorine.dm
+++ b/code/modules/overmap/exoplanets/planet_types/chlorine.dm
@@ -5,7 +5,7 @@
planetary_area = /area/exoplanet/chlorine
rock_colors = list(COLOR_GRAY80, COLOR_PALE_GREEN_GRAY, COLOR_PALE_BTL_GREEN)
plant_colors = list("#eba487", "#ceeb87", "#eb879c", "#ebd687", "#f6d6c9", "#f2b3e0")
- map_generators = list(/datum/random_map/noise/exoplanet/chlorine, /datum/random_map/noise/ore/poor)
+ map_generators = list(/datum/random_map/noise/exoplanet/chlorine)
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
surface_color = "#a3b879"
water_color = COLOR_BOTTLE_GREEN
diff --git a/code/modules/overmap/exoplanets/planet_types/desert.dm b/code/modules/overmap/exoplanets/planet_types/desert.dm
index 93560d3ad6e..06348a422ea 100644
--- a/code/modules/overmap/exoplanets/planet_types/desert.dm
+++ b/code/modules/overmap/exoplanets/planet_types/desert.dm
@@ -6,7 +6,7 @@
rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN)
plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#420d22")
planet_colors = list(PIPE_COLOR_YELLOW, COLOR_AMBER)
- map_generators = list(/datum/random_map/noise/exoplanet/desert, /datum/random_map/noise/ore/rich)
+ map_generators = list(/datum/random_map/noise/exoplanet/desert)
surface_color = "#d6cca4"
water_color = null
diff --git a/code/modules/overmap/exoplanets/planet_types/garbage.dm b/code/modules/overmap/exoplanets/planet_types/garbage.dm
index a7c1ce64e94..77ab31e86b5 100644
--- a/code/modules/overmap/exoplanets/planet_types/garbage.dm
+++ b/code/modules/overmap/exoplanets/planet_types/garbage.dm
@@ -3,7 +3,7 @@
desc = "An arid exoplanet with unnatural formations covering the surface. Hotspots of radiation detected."
//color = "#a5a18b"
planetary_area = /area/exoplanet/garbage
- map_generators = list(/datum/random_map/noise/exoplanet/garbage, /datum/random_map/noise/ore/poor)
+ map_generators = list(/datum/random_map/noise/exoplanet/garbage)
ruin_tags_whitelist = RUIN_ALIEN|RUIN_NATURAL|RUIN_WRECK
plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#120309")
surface_color = "#a5a18b"
diff --git a/code/modules/overmap/exoplanets/planet_types/shrouded.dm b/code/modules/overmap/exoplanets/planet_types/shrouded.dm
index c1664703ce3..5d2600fd027 100644
--- a/code/modules/overmap/exoplanets/planet_types/shrouded.dm
+++ b/code/modules/overmap/exoplanets/planet_types/shrouded.dm
@@ -5,7 +5,7 @@
planetary_area = /area/exoplanet/shrouded
rock_colors = list(COLOR_INDIGO, COLOR_DARK_BLUE_GRAY, COLOR_NAVY_BLUE)
plant_colors = list("#3c5434", "#2f6655", "#0e703f", "#495139", "#394c66", "#1a3b77", "#3e3166", "#52457c", "#402d56", "#580d6d")
- map_generators = list(/datum/random_map/noise/exoplanet/shrouded, /datum/random_map/noise/ore/poor)
+ map_generators = list(/datum/random_map/noise/exoplanet/shrouded)
ruin_tags_blacklist = RUIN_HABITAT
planet_colors = list(COLOR_DEEP_SKY_BLUE, COLOR_PURPLE)
surface_color = "#3e3960"
diff --git a/code/modules/overmap/exoplanets/planet_types/snow.dm b/code/modules/overmap/exoplanets/planet_types/snow.dm
index 1674c78782c..7e7672fd3dc 100644
--- a/code/modules/overmap/exoplanets/planet_types/snow.dm
+++ b/code/modules/overmap/exoplanets/planet_types/snow.dm
@@ -5,7 +5,7 @@
planetary_area = /area/exoplanet/snow
rock_colors = list(COLOR_DARK_BLUE_GRAY, COLOR_GUNMETAL, COLOR_GRAY80, COLOR_DARK_GRAY)
plant_colors = list("#d0fef5","#93e1d8","#93e1d8", "#b2abbf", "#3590f3", "#4b4e6d")
- map_generators = list(/datum/random_map/noise/exoplanet/snow, /datum/random_map/noise/ore/poor)
+ map_generators = list(/datum/random_map/noise/exoplanet/snow)
planet_colors = list("#e8faff")
surface_color = "#e8faff"
water_color = "#b5dfeb"
diff --git a/code/modules/overmap/exoplanets/planet_types/volcanic.dm b/code/modules/overmap/exoplanets/planet_types/volcanic.dm
index a445ae0da94..550d402f344 100644
--- a/code/modules/overmap/exoplanets/planet_types/volcanic.dm
+++ b/code/modules/overmap/exoplanets/planet_types/volcanic.dm
@@ -6,7 +6,7 @@
rock_colors = list(COLOR_DARK_GRAY)
plant_colors = list("#a23c05","#3f1f0d","#662929","#ba6222","#7a5b3a","#120309")
possible_themes = list()
- map_generators = list(/datum/random_map/automata/cave_system/mountains/volcanic, /datum/random_map/noise/exoplanet/volcanic, /datum/random_map/noise/ore/filthy_rich)
+ map_generators = list(/datum/random_map/automata/cave_system/mountains/volcanic, /datum/random_map/noise/exoplanet/volcanic)
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
planet_colors = list("#8e3900", COLOR_RED)
surface_color = "#261e19"
diff --git a/code/modules/overmap/exoplanets/turfs.dm b/code/modules/overmap/exoplanets/turfs.dm
index 50e7937985f..41efe78190a 100644
--- a/code/modules/overmap/exoplanets/turfs.dm
+++ b/code/modules/overmap/exoplanets/turfs.dm
@@ -3,7 +3,6 @@
name = "space land"
icon = 'icons/turf/desert.dmi'
icon_state = "desert"
- has_resources = 1
var/diggable = 1
var/dirt_color = "#7c5e42"
initial_flooring = null
@@ -24,6 +23,8 @@
//Must be done here, as light data is not fully carried over by ChangeTurf (but overlays are).
if(E.planetary_area && istype(loc, world.area))
ChangeArea(src, E.planetary_area)
+
+ seismic_activity = rand(1,6)
..()
/turf/floor/exoplanet/attackby(obj/item/C, mob/user)
diff --git a/code/modules/random_map/noise/ore.dm b/code/modules/random_map/noise/ore.dm
deleted file mode 100644
index 69e11690cc9..00000000000
--- a/code/modules/random_map/noise/ore.dm
+++ /dev/null
@@ -1,106 +0,0 @@
-/datum/random_map/noise/ore
- descriptor = "ore distribution map"
- var/deep_val = 0.8 // Threshold for deep metals, set in new as percentage of cell_range.
- var/rare_val = 0.7 // Threshold for rare metal, set in new as percentage of cell_range.
- var/chunk_size = 4 // Size each cell represents on map
-
-/datum/random_map/noise/ore/New()
- rare_val = cell_range * rare_val
- deep_val = cell_range * deep_val
- ..()
-
-/datum/random_map/noise/ore/check_map_sanity()
-
- var/rare_count = 0
- var/surface_count = 0
- var/deep_count = 0
-
- // Increment map sanity counters.
- for(var/value in map)
- if(value < rare_val)
- surface_count++
- else if(value < deep_val)
- rare_count++
- else
- deep_count++
- // Sanity check.
- if(surface_count < MIN_SURFACE_COUNT)
- admin_notice(SPAN_DANGER("Insufficient surface minerals. Rerolling..."), R_DEBUG)
- return 0
- else if(rare_count < MIN_RARE_COUNT)
- admin_notice(SPAN_DANGER("Insufficient rare minerals. Rerolling..."), R_DEBUG)
- return 0
- else if(deep_count < MIN_DEEP_COUNT)
- admin_notice(SPAN_DANGER("Insufficient deep minerals. Rerolling..."), R_DEBUG)
- return 0
- else
- return 1
-
-/datum/random_map/noise/ore/apply_to_turf(var/x,var/y)
-
- var/tx = ((origin_x-1)+x)*chunk_size
- var/ty = ((origin_y-1)+y)*chunk_size
-
- for(var/i=0,i
Date: Thu, 13 Mar 2025 15:08:37 +0000
Subject: [PATCH 37/52] kill a stray apostrophe
---
code/game/objects/items/weapons/tools/karl.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm
index 8b5417478c5..92de3796cb2 100644
--- a/code/game/objects/items/weapons/tools/karl.dm
+++ b/code/game/objects/items/weapons/tools/karl.dm
@@ -109,7 +109,7 @@
attack_self(user)
isPumping = FALSE
else
- to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged'."))
+ to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged."))
else
to_chat(user, SPAN_NOTICE("\The [src] is missing a cell to recharge."))
return
From 59ed865a40847f6dbc7630643fedf628c4f3199d Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Fri, 14 Mar 2025 14:53:49 +0000
Subject: [PATCH 38/52] Apply suggestions from code review
Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com>
---
code/datums/movement/mob.dm | 2 +-
code/game/objects/items/weapons/tools/karl.dm | 4 ++--
code/modules/mob/living/carbon/superior_animal/attack.dm | 2 +-
.../mob/living/carbon/superior_animal/golem/types/gold.dm | 6 +++---
.../mob/living/carbon/superior_animal/superior_animal.dm | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm
index d141d374249..76ad9ea7fe1 100755
--- a/code/datums/movement/mob.dm
+++ b/code/datums/movement/mob.dm
@@ -249,7 +249,7 @@
to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!")
return MOVEMENT_STOP
- if(mob.grabbed_by.len)
+ if(length(mob.grabbed_by))
return MOVEMENT_STOP
/* TODO: Bay grab system
if(G.stop_move())
diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm
index 92de3796cb2..7c8319013a6 100644
--- a/code/game/objects/items/weapons/tools/karl.dm
+++ b/code/game/objects/items/weapons/tools/karl.dm
@@ -158,7 +158,7 @@
set src in view(1)
if(usr.incapacitated() || !Adjacent(usr))
- to_chat(usr, "You can't do that.")
+ to_chat(usr, SPAN_WARNING("You can't do that."))
return FALSE
toggle_karl_mode(usr)
@@ -223,7 +223,7 @@
else
toggle_karl_mode(user)
-/obj/item/tool/karl/attackby(var/obj/item/I, var/mob/user)
+/obj/item/tool/karl/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/golem_core))
if(cell)
if(!cell.fully_charged())
diff --git a/code/modules/mob/living/carbon/superior_animal/attack.dm b/code/modules/mob/living/carbon/superior_animal/attack.dm
index 59b1feff047..1c35dcd5eb7 100644
--- a/code/modules/mob/living/carbon/superior_animal/attack.dm
+++ b/code/modules/mob/living/carbon/superior_animal/attack.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/superior_animal/attack_ui(slot_id)
return
-/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, var/proximity, var/attackdamage)
+/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, proximity, attackdamage)
if(!..())
return
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index ebf3ffc7f5f..8358082536f 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -80,7 +80,7 @@
QDEL_IN(src, 20)
-
-
-
+#undef GOLD_SPIKE_COOLDOWN
+#undef GOLD_SPIKE_WINDUP
+#undef GOLD_SPIKE_DAMAGE
diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
index 2a307e3fa9f..94334d7ea0f 100644
--- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
@@ -393,7 +393,7 @@
breakgrab()
. = ..()
-/mob/living/carbon/superior_animal/proc/simplegrab(var/mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs
+/mob/living/carbon/superior_animal/proc/simplegrab(mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs
if(!target && target_mob)
target = target_mob // if no target was specified, but we have a target, default to them
else if(!target || !Adjacent(target))
From 90a22ff8fc26ba75f999efc2d516a2bda6f81d84 Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Fri, 14 Mar 2025 14:54:41 +0000
Subject: [PATCH 39/52] Update
code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com>
---
.../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
index 5f8c7ca0ec8..0ac46186a83 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
@@ -52,7 +52,7 @@
/mob/living/carbon/superior_animal/golem/plasma/UnarmedAttack(atom/A, proximity)
if(det_status == DET_STABLE)
- src.death(FALSE, FALSE)
+ death(FALSE, FALSE)
#undef DET_STABLE
From b7f2b523bfc348b22198b9a16b9114e68aa14038 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 14 Mar 2025 15:00:36 +0000
Subject: [PATCH 40/52] swap ceil() and floor() for CEIL() and FLOOR()
---
code/modules/mining/drilling/cave_generator.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index ca572521dd2..3e597ab1dc4 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -517,7 +517,7 @@
veins_to_guarantee -= vein_path
// Place mineral vein at the available spot in a recursive manner
- place_recursive_mineral(x_start, y_start, CV.p_spread, ceil(CV.size_max * sizemult), floor(CV.size_min * sizemult), CV.mineral)
+ place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult), FLOOR(CV.size_min * sizemult), CV.mineral)
return 1
// Place a mineral vein in a recursive manner
From 7cf82e38bc553b8082cbe1dac780342e0943781a Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 14 Mar 2025 18:00:27 +0000
Subject: [PATCH 41/52] requested changes
---
code/controllers/subsystems/mapping.dm | 1 +
.../controllers/subsystems/processing/mobs.dm | 3 +++
.../modules/mining/drilling/cave_generator.dm | 7 +++----
code/modules/mining/drilling/cave_mineral.dm | 4 +---
code/modules/mining/drilling/difficulties.dm | 6 +++---
.../carbon/superior_animal/golem/golem.dm | 19 ++++++++++---------
.../superior_animal/golem/types/uranium.dm | 2 +-
7 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm
index ef113db5dd2..34fabcf497e 100644
--- a/code/controllers/subsystems/mapping.dm
+++ b/code/controllers/subsystems/mapping.dm
@@ -7,6 +7,7 @@ SUBSYSTEM_DEF(mapping)
var/dmm_suite/maploader = null
var/list/teleportlocs = list()
var/list/ghostteleportlocs = list()
+ var/list/cave_ore_count
/datum/controller/subsystem/mapping/Initialize(start_timeofday)
if(config.generate_asteroid)
diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm
index 3dc36ade93e..cf6d5baff4d 100644
--- a/code/controllers/subsystems/processing/mobs.dm
+++ b/code/controllers/subsystems/processing/mobs.dm
@@ -10,6 +10,9 @@ PROCESSING_SUBSYSTEM_DEF(mobs)
var/list/mob_list
var/list/mob_living_by_zlevel[][]
+ var/list/golem_list = list()
+ var/list/golem_active_list = list()
+
/datum/controller/subsystem/processing/mobs/PreInit()
mob_list = processing // Simply setups a more recognizable var name than "processing"
MaxZChanged()
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index 3e597ab1dc4..a5bfbc67f0b 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -87,7 +87,7 @@
current_difficulty = difficulties[seismic_lvl]
golem_spawn_nodes = list()
- orecount = 0
+ SSmapping.cave_ore_count = 0
// Fill the map with random noise
random_fill_map()
@@ -517,7 +517,7 @@
veins_to_guarantee -= vein_path
// Place mineral vein at the available spot in a recursive manner
- place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult), FLOOR(CV.size_min * sizemult), CV.mineral)
+ place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult, 1), FLOOR(CV.size_min * sizemult, 1), CV.mineral)
return 1
// Place a mineral vein in a recursive manner
@@ -617,8 +617,7 @@
if(istype(T, /turf/cave_mineral))
var/turf/cave_mineral/CM = T
CM.seismic_multiplier = current_difficulty.vein_ore_mult
- CM.cave_gen = src
- orecount++
+ SSmapping.cave_ore_count++
// Spawn points of interest at their respective position
/obj/cave_generator/proc/place_pois()
diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm
index 76b6fe3296e..572b4d45bf5 100644
--- a/code/modules/mining/drilling/cave_mineral.dm
+++ b/code/modules/mining/drilling/cave_mineral.dm
@@ -35,7 +35,6 @@
var/mineral_name
var/mined_ore = 0
var/seismic_multiplier = 1
- var/obj/cave_generator/cave_gen
/turf/cave_mineral/Initialize()
.=..()
@@ -96,8 +95,7 @@
//Not even going to touch this pile of spaghetti
/turf/cave_mineral/attackby(obj/item/I, mob/living/user)
- if(cave_gen)
- cave_gen.orecount--
+ SSmapping.cave_ore_count--
var/tool_type = I.get_tool_type(user, list(QUALITY_DIGGING), src, CB = CALLBACK(src, PROC_REF(check_radial_dig)))
switch(tool_type)
diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm
index bc91101cc50..656cac60a21 100644
--- a/code/modules/mining/drilling/difficulties.dm
+++ b/code/modules/mining/drilling/difficulties.dm
@@ -19,16 +19,16 @@
/datum/cave_difficulty_level/proc/get_golem_spawns()
var/list/golems_to_spawn = list() //list of golem types to spawn
if(golem_count_melee)
- for(var/c = 0, c < golem_count_melee, c++)
+ for(var/c in 0 to golem_count_melee)
golems_to_spawn += pickweight(golem_weights_melee)
if(golem_count_ranged)
- for(var/c = 0, c < golem_count_ranged, c++)
+ for(var/c in 0 to golem_count_ranged)
golems_to_spawn += pickweight(golem_weights_ranged)
if(golem_count_mixed)
var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged
- for(var/c = 0, c < golem_count_mixed, c++)
+ for(var/c in 0 to golem_count_mixed)
golems_to_spawn += pickweight(golem_weights_mixed)
return golems_to_spawn
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 9b54367514a..fb7b26f8515 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -21,9 +21,6 @@
#define GOLEM_REGENERATION 10 // Healing by special ability of uranium golems
-GLOBAL_LIST_EMPTY(all_golems) // golems check this list to loop over allies
-GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with a current target mob
-
/mob/living/carbon/superior_animal/golem
icon = 'icons/mob/golems.dmi'
@@ -76,15 +73,17 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops
/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty)
- GLOB.all_golems += src
+ SSmobs.golem_list += src
if(mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
difficultylevel = difficulty
. = ..()
/mob/living/carbon/superior_animal/golem/Destroy()
- GLOB.all_golems -= src
- GLOB.active_golems -= src
+ SSmobs.golem_list -= src
+ SSmobs.golem_active_list -= src
+ difficultylevel = null
+ mineral = null
..()
/mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage)
@@ -92,7 +91,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
// Spawn ores
if(mineral)
- var/nb_ores = ceil((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1))
+ var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1), 1)
for(var/i in 1 to nb_ores)
new mineral.ore(loc)
@@ -117,7 +116,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE)
/mob/living/carbon/superior_animal/golem/loseTarget()
- GLOB.active_golems -= src
+ SSmobs.golem_active_list -= src
. = ..()
/mob/living/carbon/superior_animal/golem/handle_ai()
@@ -136,8 +135,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with
target_mob = findTarget()
if(target_mob)
stance = HOSTILE_STANCE_ATTACK
- for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems)
+ SSmobs.golem_active_list += src
+ for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_list)
if(!ally.target_mob && (get_dist(ally, src) < 5))
+ SSmobs.golem_active_list += ally
ally.stance = HOSTILE_STANCE_ATTACK
ally.target_mob = target_mob
ally.targetrecievedtime = world.time
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index c5b0c53d367..28c90d22dd0 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -45,7 +45,7 @@
/mob/living/carbon/superior_animal/golem/uranium/handle_ai()
. = ..()
if(target_mob)
- for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems)
+ for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_active_list)
if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE))
ally.adjustBruteLoss(-GOLEM_REGENERATION)
ally.adjustFireLoss(-GOLEM_REGENERATION)
From 46524408de90e493c3a9786d0a2d53b47a09ac31 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 14 Mar 2025 18:10:17 +0000
Subject: [PATCH 42/52] oh so THAT'S why they're failing
---
code/controllers/subsystems/mapping.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm
index 34fabcf497e..f43c6885061 100644
--- a/code/controllers/subsystems/mapping.dm
+++ b/code/controllers/subsystems/mapping.dm
@@ -7,7 +7,7 @@ SUBSYSTEM_DEF(mapping)
var/dmm_suite/maploader = null
var/list/teleportlocs = list()
var/list/ghostteleportlocs = list()
- var/list/cave_ore_count
+ var/cave_ore_count = 0
/datum/controller/subsystem/mapping/Initialize(start_timeofday)
if(config.generate_asteroid)
From 33ccdf79490e22d4fe2c5484574f434908e90ae5 Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Fri, 14 Mar 2025 18:42:47 +0000
Subject: [PATCH 43/52] Update
code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com>
---
.../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
index 0ac46186a83..bf3ad65f27c 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
@@ -38,7 +38,7 @@
/mob/living/carbon/superior_animal/golem/plasma/death(gibbed, message = deathmessage)
if(det_status == DET_STABLE)
- src.Stun(10) //prevent any movement. not actually sure if this is necessary for a dead mob.
+ Stun(10) // Prevents movement. Not actually sure if this is necessary for a dead mob.
det_status = DET_BLOWING
visible_message(SPAN_DANGER("\The [src] starts glowing!"))
icon_state = "golem_plasma_explosion"
From 8a38ef2b0bdbe2cb6b864962b9e2bd0b46ab1a6a Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Fri, 14 Mar 2025 18:44:32 +0000
Subject: [PATCH 44/52] Update
code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com>
---
.../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
index bf3ad65f27c..51cb24afb98 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
@@ -45,7 +45,7 @@
spawn(det_time)
// Plasma ball on location
visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!"))
- for(var/turf/floor/target_tile in range(2, loc))
+ for(var/turf/floor/target_tile as anything in RANGE_TURFS(2, loc))
new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1)
spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code
. = ..()
From e16d00ed5d99fa2cb8f9f68fe7fe8c5b3b14b937 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 14 Mar 2025 19:18:21 +0000
Subject: [PATCH 45/52] optimizations + fixes for plasma golems
---
.../living/carbon/superior_animal/golem/types/plasma.dm | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
index 51cb24afb98..cc2abe3c8fd 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm
@@ -38,21 +38,22 @@
/mob/living/carbon/superior_animal/golem/plasma/death(gibbed, message = deathmessage)
if(det_status == DET_STABLE)
- Stun(10) // Prevents movement. Not actually sure if this is necessary for a dead mob.
+ walk(src,0)
+ anchored = TRUE // Prevents movement.
det_status = DET_BLOWING
visible_message(SPAN_DANGER("\The [src] starts glowing!"))
icon_state = "golem_plasma_explosion"
spawn(det_time)
// Plasma ball on location
- visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!"))
+ visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning plasma!"))
for(var/turf/floor/target_tile as anything in RANGE_TURFS(2, loc))
new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1)
- spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code
+ target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code
. = ..()
/mob/living/carbon/superior_animal/golem/plasma/UnarmedAttack(atom/A, proximity)
if(det_status == DET_STABLE)
- death(FALSE, FALSE)
+ death(FALSE)
#undef DET_STABLE
From 76e7dd487256301a54e58397b8ee5a9b3b2fc975 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Sat, 15 Mar 2025 15:01:42 +0000
Subject: [PATCH 46/52] swap over to `getMobsInRangeChunked()`
---
code/controllers/subsystems/processing/mobs.dm | 3 ---
.../living/carbon/superior_animal/golem/golem.dm | 13 ++-----------
.../carbon/superior_animal/golem/types/ansible.dm | 7 +------
.../carbon/superior_animal/golem/types/uranium.dm | 5 ++---
4 files changed, 5 insertions(+), 23 deletions(-)
diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm
index cf6d5baff4d..3dc36ade93e 100644
--- a/code/controllers/subsystems/processing/mobs.dm
+++ b/code/controllers/subsystems/processing/mobs.dm
@@ -10,9 +10,6 @@ PROCESSING_SUBSYSTEM_DEF(mobs)
var/list/mob_list
var/list/mob_living_by_zlevel[][]
- var/list/golem_list = list()
- var/list/golem_active_list = list()
-
/datum/controller/subsystem/processing/mobs/PreInit()
mob_list = processing // Simply setups a more recognizable var name than "processing"
MaxZChanged()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index fb7b26f8515..2763fae1393 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -73,15 +73,12 @@
var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops
/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty)
- SSmobs.golem_list += src
if(mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
difficultylevel = difficulty
. = ..()
/mob/living/carbon/superior_animal/golem/Destroy()
- SSmobs.golem_list -= src
- SSmobs.golem_active_list -= src
difficultylevel = null
mineral = null
..()
@@ -115,10 +112,6 @@
if(obstacle)
obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE)
-/mob/living/carbon/superior_animal/golem/loseTarget()
- SSmobs.golem_active_list -= src
- . = ..()
-
/mob/living/carbon/superior_animal/golem/handle_ai()
objectsInView = null
@@ -135,10 +128,8 @@
target_mob = findTarget()
if(target_mob)
stance = HOSTILE_STANCE_ATTACK
- SSmobs.golem_active_list += src
- for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_list)
- if(!ally.target_mob && (get_dist(ally, src) < 5))
- SSmobs.golem_active_list += ally
+ for(var/mob/living/carbon/superior_animal/golem/ally in getMobsInRangeChunked(src, 5, TRUE))
+ if(!ally.target_mob)
ally.stance = HOSTILE_STANCE_ATTACK
ally.target_mob = target_mob
ally.targetrecievedtime = world.time
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 8a89e1e7d58..2ec9f5fae0e 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -62,12 +62,7 @@
// Teleport target to a random golem near the ansible golem
if(target_mob)
- var/list/teleport_destinations = list()
-
- for(var/mob/living/carbon/superior_animal/golem/td in range(ANSIBLE_TELEPORT_RANGE, get_turf(src)))
- teleport_destinations += td
-
- go_to_bluespace(get_turf(src), 1, TRUE, target_mob,pick(teleport_destinations))
+ go_to_bluespace(get_turf(src), 1, TRUE, target_mob, pick(getMobsInRangeChunked(src, ANSIBLE_TELEPORT_RANGE, TRUE)))
/mob/living/carbon/superior_animal/golem/ansible/proc/focus_target()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index 28c90d22dd0..3fbcff002ad 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -45,8 +45,7 @@
/mob/living/carbon/superior_animal/golem/uranium/handle_ai()
. = ..()
if(target_mob)
- for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_active_list)
- if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE))
+ for(var/mob/living/carbon/superior_animal/golem/ally in getMobsInRangeChunked(src, GOLEM_URANIUM_HEAL_RANGE, TRUE))
+ if((ally != src))
ally.adjustBruteLoss(-GOLEM_REGENERATION)
ally.adjustFireLoss(-GOLEM_REGENERATION)
-
From bfb2c21f6d5f58cd287c39decc377d9c20881522 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Sun, 16 Mar 2025 12:47:31 +0000
Subject: [PATCH 47/52] Update cave_generator.dm
---
code/modules/mining/drilling/cave_generator.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm
index a5bfbc67f0b..067bc848041 100644
--- a/code/modules/mining/drilling/cave_generator.dm
+++ b/code/modules/mining/drilling/cave_generator.dm
@@ -511,7 +511,7 @@
/datum/cave_vein/uranium = CAVE_VWEIGHT,
/datum/cave_vein/diamond = CAVE_VWEIGHT * 0.75,
/datum/cave_vein/platinum = CAVE_VWEIGHT * 0.75,
- /datum/cave_vein/hydrogen = CAVE_VWEIGHT * ((seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0))//only generate on max difficulty. super duper valuable.
+ /datum/cave_vein/hydrogen = (seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0)//only generate on max difficulty. super duper valuable.
vein_path ||= pickweight(cave_veins)
var/datum/cave_vein/CV = new vein_path()
veins_to_guarantee -= vein_path
From 4b6f9bd48fefa59cc29afa159cdec56d73f7da52 Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Sun, 16 Mar 2025 14:05:26 +0000
Subject: [PATCH 48/52] Update
code/modules/mob/living/carbon/superior_animal/superior_animal.dm
Co-authored-by: hyperioo <64754494+hyperioo@users.noreply.github.com>
---
.../mob/living/carbon/superior_animal/superior_animal.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
index 94334d7ea0f..36bcddefb79 100644
--- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm
@@ -399,7 +399,7 @@
else if(!target || !Adjacent(target))
return
- visible_message("[src] grabs [target]!")
+ visible_message(SPAN_WARNING("[src] grabs [target]!"))
target.grabbed_by += src
grabbing = target
cheap_update_lying_buckled_and_verb_status_()
From d1a6a8d17d124477d7a78981262cc92de3735c82 Mon Sep 17 00:00:00 2001
From: VmpOS2NHSkhkejA9
Date: Sun, 16 Mar 2025 14:05:37 +0000
Subject: [PATCH 49/52] Update code/modules/mob/living/carbon/resist.dm
Co-authored-by: hyperioo <64754494+hyperioo@users.noreply.github.com>
---
code/modules/mob/living/carbon/resist.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index bb44b31aaac..1c7e94c6007 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -80,7 +80,7 @@
resisting++
if(prob(max(((stats?.getStat(STAT_ROB) ** 0.9) / grabbed_by.len),20)))
G_mob.breakgrab()
- visible_message("[src] has broken free of [G_mob]'s grip!")
+ visible_message(SPAN_WARNING("[src] has broken free of [G_mob]'s grip!"))
if(resisting)
setClickCooldown(20)
From 356ea7723cb9f597ae469eb1c701ded579794761 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Sun, 16 Mar 2025 14:08:08 +0000
Subject: [PATCH 50/52] remove the 1s
---
.../mob/living/carbon/superior_animal/golem/types/ansible.dm | 2 +-
.../mob/living/carbon/superior_animal/golem/types/coal.dm | 2 +-
.../mob/living/carbon/superior_animal/golem/types/platinum.dm | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
index 2ec9f5fae0e..42ca9ed3183 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm
@@ -54,7 +54,7 @@
/mob/living/carbon/superior_animal/golem/ansible/death()
if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward.
var/obj/item/bluespace_crystal/crystal = new /obj/item/bluespace_crystal(loc)
- visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates."), 1)
+ visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates."))
..()
// Special capacity of ansible golem: it will focus and teleport a miner near other golems
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
index bceed7f70ac..51fde12f328 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm
@@ -36,7 +36,7 @@
/mob/living/carbon/superior_animal/golem/coal/enhanced/UnarmedAttack(atom/A, proximity)
if(istype(A, /mob/living/carbon))
- visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"), 1)
+ visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"))
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
simplegrab(target_mob)
else // if they're not a carbon just attack them normally. this includes things like simple animals
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index 4da16bf7e57..c5a0b751fa4 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -46,7 +46,7 @@
charge_cooldown = world.time + PLATINUM_CHARGE_CD
walk(src,0) // halt movement
- visible_message(SPAN_DANGER("[src] stops and prepares to charge at [target_mob]!"), 1)
+ visible_message(SPAN_DANGER("[src] stops and prepares to charge at [target_mob]!"))
var/list/passedturfs = getline(src, target_mob) // do this at the start of the windup, so that the golem's charge doesn't track the target (and it can be dodged)
spawn(PLATINUM_CHARGE_WINDUP)
@@ -81,7 +81,7 @@
victim.explosion_act(PLATINUM_CHARGE_DAMAGE_OBSTACLES * 4) //TEAR THROUGH ALL THAT IMPEDES YOU
break // if the turf is blocked (ie a wall/door/window), stop charging here
- visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!"), 1)
+ visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!"))
forceMove(lastvalidturf)
if(Adjacent(target_mob))
From a8f517f8040044b30278276ec820d786fcea6801 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Sun, 16 Mar 2025 18:08:30 +0000
Subject: [PATCH 51/52] Update golem.dm
---
.../mob/living/carbon/superior_animal/golem/golem.dm | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
index 2763fae1393..833b9b81429 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm
@@ -67,19 +67,19 @@
// Ore datum the golem holds.
var/ore/mineral
var/mineral_name
+ var/oremult = 1
var/targetrecievedtime = -250
- var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops
-
-/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty)
+/mob/living/carbon/superior_animal/golem/Initialize(mapload, var/datum/cave_difficulty_level/difficulty)
if(mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
- difficultylevel = difficulty
+
+ if(difficulty)
+ oremult = difficulty.golem_ore_mult
. = ..()
/mob/living/carbon/superior_animal/golem/Destroy()
- difficultylevel = null
mineral = null
..()
@@ -88,7 +88,7 @@
// Spawn ores
if(mineral)
- var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1), 1)
+ var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * oremult, 1)
for(var/i in 1 to nb_ores)
new mineral.ore(loc)
From cb46bbe2cfa36c6302895ca32b50a424fe7d7cc5 Mon Sep 17 00:00:00 2001
From: Wrill <86113712+WrillWasTaken@users.noreply.github.com>
Date: Fri, 21 Mar 2025 23:48:23 +0000
Subject: [PATCH 52/52] balance pass
---
code/modules/mining/drilling/difficulties.dm | 26 +++++++++----------
code/modules/mining/satchel_ore_boxdm.dm | 1 +
.../superior_animal/golem/types/gold.dm | 6 ++---
.../superior_animal/golem/types/platinum.dm | 11 ++++----
.../superior_animal/golem/types/silver.dm | 4 +--
.../superior_animal/golem/types/uranium.dm | 2 +-
6 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm
index 656cac60a21..2bdd282ada5 100644
--- a/code/modules/mining/drilling/difficulties.dm
+++ b/code/modules/mining/drilling/difficulties.dm
@@ -19,16 +19,16 @@
/datum/cave_difficulty_level/proc/get_golem_spawns()
var/list/golems_to_spawn = list() //list of golem types to spawn
if(golem_count_melee)
- for(var/c in 0 to golem_count_melee)
+ for(var/c = 1 to golem_count_melee)
golems_to_spawn += pickweight(golem_weights_melee)
if(golem_count_ranged)
- for(var/c in 0 to golem_count_ranged)
+ for(var/c = 1 to golem_count_ranged)
golems_to_spawn += pickweight(golem_weights_ranged)
if(golem_count_mixed)
var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged
- for(var/c in 0 to golem_count_mixed)
+ for(var/c = 1 to golem_count_mixed)
golems_to_spawn += pickweight(golem_weights_mixed)
return golems_to_spawn
@@ -71,12 +71,12 @@
golem_count_melee = 1
golem_count_ranged = 1
- golem_count_mixed = 3
+ golem_count_mixed = 2
golem_weights_melee = list(
- /mob/living/carbon/superior_animal/golem/iron = 4,
+ /mob/living/carbon/superior_animal/golem/iron = 5,
/mob/living/carbon/superior_animal/golem/coal = 2,
- /mob/living/carbon/superior_animal/golem/platinum = 3)
+ /mob/living/carbon/superior_animal/golem/platinum = 2)
golem_weights_ranged = list(
/mob/living/carbon/superior_animal/golem/silver = 3,
@@ -92,11 +92,11 @@
golem_count_melee = 1
golem_count_ranged = 1
- golem_count_mixed = 3
+ golem_count_mixed = 2
golem_weights_melee = list(
- /mob/living/carbon/superior_animal/golem/iron = 4,
- /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/iron = 8,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 4,
/mob/living/carbon/superior_animal/golem/platinum = 3,
/mob/living/carbon/superior_animal/golem/plasma = 2)
@@ -117,8 +117,8 @@
golem_count_mixed = 1
golem_weights_melee = list(
- /mob/living/carbon/superior_animal/golem/iron = 3,
- /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/iron = 6,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 4,
/mob/living/carbon/superior_animal/golem/platinum = 3,
/mob/living/carbon/superior_animal/golem/plasma = 2)
golem_weights_ranged = list(
@@ -139,8 +139,8 @@
golem_count_mixed = 1
golem_weights_melee = list(
- /mob/living/carbon/superior_animal/golem/iron = 3,
- /mob/living/carbon/superior_animal/golem/coal/enhanced = 2,
+ /mob/living/carbon/superior_animal/golem/iron = 8,
+ /mob/living/carbon/superior_animal/golem/coal/enhanced = 6,
/mob/living/carbon/superior_animal/golem/platinum = 3,
/mob/living/carbon/superior_animal/golem/plasma = 2,
/mob/living/carbon/superior_animal/golem/diamond = 2)
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index aca6c84753e..b8e6833b97b 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -9,6 +9,7 @@
density = TRUE
rarity_value = 10
spawn_tags = SPAWN_TAG_STRUCTURE_COMMON
+ climbable = TRUE
var/last_update = 0
var/list/stored_ore = list()
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
index 8358082536f..d85b8d45fdc 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm
@@ -1,6 +1,6 @@
-#define GOLD_SPIKE_COOLDOWN 50 // 5 seconds
-#define GOLD_SPIKE_WINDUP 20
-#define GOLD_SPIKE_DAMAGE 40 //equivalent to GOLEM_DMG_HIGH
+#define GOLD_SPIKE_COOLDOWN 5 SECONDS
+#define GOLD_SPIKE_WINDUP 2 SECONDS
+#define GOLD_SPIKE_DAMAGE 25
/mob/living/carbon/superior_animal/golem/gold
name = "gold golem"
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
index c5a0b751fa4..8f40f65eec9 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm
@@ -1,5 +1,5 @@
-#define PLATINUM_CHARGE_DAMAGE_OBSTACLES 50
-#define PLATINUM_CHARGE_DAMAGE_TARGET 50
+#define PLATINUM_CHARGE_DAMAGE_OBSTACLES 25
+#define PLATINUM_CHARGE_DAMAGE_TARGET 35
#define PLATINUM_CHARGE_CD 30 SECONDS
#define PLATINUM_CHARGE_WINDUP 1.5 SECONDS
#define PLATINUM_CHARGE_RANGE 5
@@ -70,15 +70,16 @@
charge_effect.icon = icon
charge_effect.icon_state = icon_state // copy over the icon and direction
charge_effect.dir = dir
- charge_effect.alpha = 250 - (vfxfalloff * vfxindex) // todo: linear interpolation math so that this looks consistent at all distances
+ charge_effect.alpha = 250 - (vfxfalloff * vfxindex)
animate(charge_effect, time = 25 - ((vfxfalloff * vfxindex) / 10), alpha = 0)
for(var/mob/living/victim in targetturf.contents)
if(victim != src)
- victim.adjustBruteLoss(PLATINUM_CHARGE_DAMAGE_OBSTACLES)
+ victim.attack_generic(src, PLATINUM_CHARGE_DAMAGE_OBSTACLES, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1)
else
for(var/atom/victim in targetturf.contents)
- victim.explosion_act(PLATINUM_CHARGE_DAMAGE_OBSTACLES * 4) //TEAR THROUGH ALL THAT IMPEDES YOU
+ if(victim.density)
+ victim.attack_generic(src, PLATINUM_CHARGE_DAMAGE_OBSTACLES, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1)
break // if the turf is blocked (ie a wall/door/window), stop charging here
visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!"))
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
index 173f20b5a6f..83ee78da849 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm
@@ -9,7 +9,7 @@
health = GOLEM_HEALTH_LOW
// Movement related variables
- move_to_delay = GOLEM_SPEED_HIGH
+ move_to_delay = GOLEM_SPEED_MED
turns_per_move = 5
// Damage related variables
@@ -44,7 +44,7 @@
/obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems
name = "stun plasma bolt"
taser_effect = 1
- damage_types = list(HALLOSS = 20, BURN = 10)
+ damage_types = list(HALLOSS = 15, BURN = 5)
impact_type = /obj/effect/projectile/stun/impact
/obj/item/projectile/plasma/stun/golem/Bump(atom/A as mob|obj|turf|area, forced = FALSE)
diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
index 3fbcff002ad..683f00ccea9 100644
--- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
+++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm
@@ -22,7 +22,7 @@
armor = list(
melee = 0,
bullet = GOLEM_ARMOR_MED,
- energy = GOLEM_ARMOR_ULTRA,
+ energy = GOLEM_ARMOR_HIGH,
bomb = 0,
bio = 0,
rad = 0