From b24738aec6929d936074f9fc011ddf92d701f753 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Wed, 19 Mar 2025 22:38:45 +0100 Subject: [PATCH] Unfound Loot 1.0rc2 --- mod/Unfound Loot.esp | Bin 0 -> 132179 bytes mod/Unfound Loot.url | 2 + src/EULxCalculateBaseRemovalChance.gek | 93 +++ src/EULxDelootifyCellItems.gek | 213 +++++++ src/EULxDelootifyContainer.gek | 168 ++++++ src/EULxDelootifyNPC.gek | 257 ++++++++ src/EULxINILoadSettings.gek | 70 +++ src/EULxINISaveSettings.gek | 64 ++ src/EULxMCMAddElement.gek | 50 ++ src/EULxMCMAddScale.gek | 24 + src/EULxOnCellEnter.gek | 32 + src/EULxOnDisintegration.gek | 15 + src/EULxOnDrop.gek | 27 + src/EULxOnDying.gek | 65 ++ src/EULxOnGameLoad.gek | 44 ++ src/EULxOnGameMode.gek | 18 + src/EULxOnLimbGone.gek | 52 ++ src/EULxOnNewGame.gek | 14 + src/EULxOnPause.gek | 14 + src/EULxOnSeen.gek | 106 ++++ src/EULxPrecalculateRemovalChance.gek | 41 ++ src/EULxPresetSetterFUNCTION.gek | 164 +++++ src/EULxProbabilityMultiplierFUNCTION.gek | 23 + src/EULxQuestScript.gek | 698 ++++++++++++++++++++++ src/EULxReduceItemHealth.gek | 79 +++ src/EULxWhitelistDeathItems.gek | 92 +++ 26 files changed, 2425 insertions(+) create mode 100644 mod/Unfound Loot.esp create mode 100644 mod/Unfound Loot.url create mode 100644 src/EULxCalculateBaseRemovalChance.gek create mode 100644 src/EULxDelootifyCellItems.gek create mode 100644 src/EULxDelootifyContainer.gek create mode 100644 src/EULxDelootifyNPC.gek create mode 100644 src/EULxINILoadSettings.gek create mode 100644 src/EULxINISaveSettings.gek create mode 100644 src/EULxMCMAddElement.gek create mode 100644 src/EULxMCMAddScale.gek create mode 100644 src/EULxOnCellEnter.gek create mode 100644 src/EULxOnDisintegration.gek create mode 100644 src/EULxOnDrop.gek create mode 100644 src/EULxOnDying.gek create mode 100644 src/EULxOnGameLoad.gek create mode 100644 src/EULxOnGameMode.gek create mode 100644 src/EULxOnLimbGone.gek create mode 100644 src/EULxOnNewGame.gek create mode 100644 src/EULxOnPause.gek create mode 100644 src/EULxOnSeen.gek create mode 100644 src/EULxPrecalculateRemovalChance.gek create mode 100644 src/EULxPresetSetterFUNCTION.gek create mode 100644 src/EULxProbabilityMultiplierFUNCTION.gek create mode 100644 src/EULxQuestScript.gek create mode 100644 src/EULxReduceItemHealth.gek create mode 100644 src/EULxWhitelistDeathItems.gek diff --git a/mod/Unfound Loot.esp b/mod/Unfound Loot.esp new file mode 100644 index 0000000000000000000000000000000000000000..fbafa3449b86ceafb138f11ac31880751e81d85b GIT binary patch literal 132179 zcmeFadyt$*av%83;Kjk4U^j>dA0LJs5Cnn23?3u_kRZXq0Gu^miy4Ag?kcFBnQoxP zp6=Q19)O@JdoLWPQ^ffsJM6PU3Y|mHE^*RI+SOXC)ylGDS?9eAdu7QE>v0Mz6xN30 zE);QLtwKJZ{f~6NUuIQ(^*y@>GuWjrZX_;f(ZNtwu zC(m8m96bHs{>*FNgJ0kN!NFkS^4UwH!Q}jWYpLB?Y8(pZE6v&F&DNptLc2aY+o*PK zHS4qW?#qY5^KVavGu6sMFpWB;;H_q@wbYysFSc6UaC~&EJ$E#?bar}XYjD2OXtb8P zm#>djI}5?NvomKOaj0BD-L=6;trT3i_SV%eZV7@57q7g*&ufOX5Pv^o%KyZF9vI*w zai2Ulb#8Mo`PRkvuUFfhdaD_n2dsghbN=GY^|exgRiDMv>-g_pqUsi@dhX)HRCB)i zesOUb!yxnRy<~i`!stc{#mBwVV0#=z%P$f`MM-8Z-PJr4QfqJ9TsTxodw<^uK zBz=P~3T4I(q%S5Q?TH{Mg$*opF}rtT2GGwW0PT(d36b;R1VW`F2F}kV;OvUvT&j2G z^1%GqkM53v`BFZZvkMEYJTQSFv>mfAC%|}PHnG%hSDSNp^FaOBkN#+E_EPtfV0i| zLM01=4meTZ-&Ye5JQS|AW?S7{6s(B&#RLEq5z>eA)pn(E;Z|!Y3k{u87LBhZpm=D! zxwKGe=AvN%{8B!EVhk+je?0*}IbX+OX|dW~Sn5`q`Q)%O`j-=6bVdu9<<01SoB*UV zS^)K!(Mnm{uYZz&=%9)*ekS$Xx(5`dIQ1QZ+lB2X5m-$;Op zaPnwW1n7j$@8F*&06irlf;c6{tq9nQ2G}hT! z$fpNmN>S9u^R3prk?ciiSymWI0E$>);#PH`(+4C=_KgWh5lWY;^ZfuiZYZ@W0q99b z_Op$-)~!~f52WnkzBvKQTipHr<;qAa3brKR_=|hgyPjaS=7aIZEd{1lyDwtE4%)T^ z7*C6elPCqr$|ehGdnP0ml`&%HLb8;8Gy%yIy33;UjszS}#Cd#_i;f+z$MV4xQQ8XJ z7Yr}{*7wHeSxI{f5KE8XgRMB8Xv^*VQI zkN)XEFg* z+lgv}!B7yk2ZI~`>!aBEmG|)cpfZiPnI~cb`AOtwJ_Px?>6yCwY zwK=t%R|8csz`~Q!Db-&ND$&9`f;WV+-e(wGRjSsw@Cx*rL;6~y1YGDA{90T z*CFTEpuP2FbP<&ei1G07$@1gDz)nGF(6pk3cSYp5utBLdSuRN%j|7A0%345SPX+_v zVdz&zza9ns27((KOK3U>kB^1>UbO|v!P7zQ5g<)`71odt1SL0s0v9%-FWXpTV-Vth z!|}1P@Zi1DIEeKu2|M3zaditvnuo%+?ij;4+2@5Lqep8aBOrBckN|c9j{$Txym4te z&>*lgui8eF9e5m_ScB2ti+@W2_!yf|46fH4fIb0u!`s;@KK%;VgFN#J`o0V843KYh zSYCZKKCD47Tb5yEc~k?d&fHj9*O_aEG(s5G-m-Da#&)$9wq-7v=b7rl;+Bn=Rbk!y zGjn&bx@BXn(W-RA8n-*O*h1z$CEixr?aJMEZ&%u3g{FrNTbr%ktT)5jQge8 z>G1pcaj0Gs>;#+i4viCM3{%I}!Oz7;b1LS4DPR@(1&>K{}+3X_QS@Jy)Sq-4gJv9800 zis4cNG)Zk`UC&9aJGbhMs)ao?6d_R$4~OF{F+}X!WFR81qyFjo_ejTvVxudplGGe! zfCWxOscY5wrMW8k=gn%R(Y+N7xi(~qx0>C0b4do(8~&l8)8XY-8++o$-9sU0-3jMg zVG|}lPU^7IyxYCSIX7GF)aR?6@QzrxI*0He(l%^$Z&ll27yRD|Ypph_-jN1DW9cSG zhO-0m22!U7E*!M@%!!S{)pl#PGFxxdyLT@wHM;f12JBns-?}_8Gj-*1*1U`6N^GZr zRZtMgZZ3hqL5e#wJ_$zdDfcXEn-Pygj>a4$x>jk6QTmFv&+9 zlNEEZxzuRjgA+h_*s^i@;`F&)5Y~x5LxSmv>(@2}Dy0G~N_ijqGy5wRT^|U(rX*JA z*q?2LB?p7LDYZUU28;8d-`=we?-X903~WknNR$k`lBFO+j+lCpi98N~Ensbpjkc+> zE?(08VwDYn$_`+74a+_0p-=1|p02D7Xxq~#s%HB1v*Y&Nr!Lzk?q2olm)+OavB12e z<%WvjFqcUDt$!k}2yO~=wVZ}xg+_cm@b97nN-os{|L!`~12z&bDo)R%ju5xjcJYJSbIb*BlvW3JkOXTvIgqn`G+6WYL_ zXkuqeP%nb^I)Vwu!@mJ}bgy&(ul8AJ;bObht)G)+|m@xp4F)I08#o(H(6gXy_Svq?FNHTJ+r{dp0ka}e2; zdK2Cd>Q4jc#`d7IRw(k7lA(y`Zd8VSg!Woo1fkRAEy4dla$ChvFx)^4$EaJcvAXp$ zP|5Cwmu;3 z0Hm#|?SHT%P@cF~dJ^Dv8gN)WyI8HF0nfpyggV<5(mJY}7ocwL-+!-k81MHRSPj|c zMZiL;9nfO2rc(bJMMoogjqidY>R=u?fYA(^oO}05NAUiDf!UdB*B8M@4+Qo1h6O5s z4&E!B0o0cWl{ynvTCCOK*{SgC91KeBYFKMjZuZ}Zw~hLJ8KOggK4Nf|nbbcl&YWk# z0H?}N1p`lF4|5|3u5#P7og1dwbJ!jQ&2e;M!@bfmls&{|3`29z1`Wg8uN4#BZUWbe zGH-T0JHZXy*M&FCTmU;`a>%sy$F~wLwB`?2=I1%B?SzW@nHXO-rOiEpX$)|k4Z*9} z6FtfKvrRTu>&^CR&(7d^baDjzwZ`qMjvl9m=Dom13okzWaFQE3Y|nIKCHpg-j_cii zC1YCIp3C+ZLPg|bwt!(#+sMXfI~&dU*qr75$nJUmpP^{aLn+RMT(&$D5Ua5rkG!R# zX?H!*KIm#2hK|OZewd~GgkaKp8N!TjWpaFtPSefavp{9K0@>fbQWJ=6#Wi!klCw%c z>9Livo45#xg=V1gEQn88lu4+dx<;^WM?p}vJuKRNLO&GiMDD6mjKJw|8tQEqI{Qsb zd_ck$tQB^uixnDj!ne+y$E!}*tj}R<12;Vs_(S3BQde~M+tv2n5JDFUIlM%3)x))R z9g0@t?kH5R)8SMTvbX~A1SKBY{z9wM4QDHz`W$xc)w%aNAyj(IP6Jlt&aFy&KD^Uv zzXv=bEbK0|1Gu99oet0G?!oPx+&+#3lTB_21(Bj`j;uhr)@+4!FqQ0nxdkH8>+KGl z&$X#0s~IvM9UI345VcZvcZTP5K`KIyJLW2N_Z1?-29-sS5193D0@M5$_bmPY^AR;N1H&zN;zN~W95R18+! zFbF+iMg3IsHq?$*`|bpyS-MWD#D-N#kkl$x0}VAIL+KFVk+3c2(4?0}lEll6x=e!D z2)tS8Op7k^27!i0!_(oFCTvIb+s3?;L5AMS%Q6taNPtZsO(2BMLshw)H1lDmm1|`6_-V7_A(N6DBAdocruy-qzIO(YGv+L*yb7$ zzH-<%Nl=dQwX-FmN6@rr=S;q~CZL`#^CNr0 zs3h6PluVja2#hb3GwTCk$sB8lUven0q&J0=RvH#w3v?9$;W}DG zU^y}Nl9&yJ=&MD9;c@!(AHHp${^6VUsq`1tO7dH91SV}LCx-d;>daS->1RX2a zPA=9LW-qjwFfcjm390hOAh#N?)OzyA#*4NMTkU^|Zv(KytQ`dY&Oc_|XrCJ2hMKbX zZ?DyVBb$oxiO`q!I`+i=huyNjqTvF|WEtDu+8VokKB-$>Is@tH8sydpU+@E=Z#(5nhLhfD zh||^XCtA0f&AV5c7LQ4)l5b*L)PT!lOjNq)qi#&Hw~~>EZK^YYbq-!QF|B8pR&23` zVCm!vC5sXJ$e9y?vOz`s0wpUv3GMC{wso^Wkk#y}DT`b}^`@$|jM<9SUFfCjtpL=O z7eq46YuHrRxS(W{X4lna^kICAov3vG%Hlr`{Hu4XHyf2sr%FHMU(I1Sj&3YeI`4g) zI3_`n;Z(aGdf4~=>)#iZrHA*+SB0Q7QCt~4DCzwQ{+n%k zsgA@HG0}rqGNuv1gT(MA)oQ4_P?ver0Q}<1&_3|D4gc}rhSg;*R2FF6@O2sL48M;5 z^iOq}Uk}t1Gz4Ad%lH6Tzw;cdmf}uf!HeVcCtSb_qsV+pU%=tAPBogH0n{s~FX4?Z zm0)%TCZCwP8eXb5>z68vIGC~s0sZQ$H?$gDf*Z7&T2wcp0^Jus1vB`cln(}L%E9#Z z;7apSA*%POlF-Rcz1ZVZ43TU#k9mAX=(y$Fr6pjog5!ltS?6 zT!g!H0tUO;3O42HKC|_W>Bd`pB*H4T^00=8W5B`o+CQOTph+EBkUT({tC)k8wG=99 zww^%^%gR&-V|=kyp-p`_LH6PF0!pLuxk|T^>O`LDSKDPZ>4TdsW&=xFU8{Dwl{S1V zoZ0AP4EAtxB!?|sqF6Y_)(q>o4xc*37U3C(Vj+QY_^4b!3GSNL$tu28^1sfE$jizQ zIenL$H}u9vI|+JFwcK???dj9o@^p3PGt|fN$Grppwew4l4@4GAyZiI@3}EG8FD9D? zCF?xfJEZgMG0Zb4_t-NaX6rd@8;%DjpuB5joP(OccovevI6ZcW)8n~d zPZ_Sc+7sL;(8;kKZUpg4J|Fg9mh@xg#ma&LVOM1fwKb|kUV0h;_<@|%V@TCkXsLgzA-qAE>ZXD5pksK0@$q< z?D3ZbY{CUR6ku1>(*<0IR^_{io^bJW(%~1S!<%h~cfyT40Q|$wivZ2ugg3r5ED{Yn zFmC7K_-};AbSrAG|Exh-<@IG#;`6ci=gsNfZ*jd>pdjjT-NrcrZS{cibE3^{^4SfE zc(PLN^X)69okQnQvve{}LZi~pnfwV&scNC7? z90i{Mhz)3rA_qRS19Y$SEEvW@sf3?hf&dY>L-ruM*i_=CUOhe~-FZ8#r|mftcDYN& zL0Du|SY*A$U?+CFJJ9Ed;T@yH__lvPqevgY|An2=AUqMi;@^>@nvJ{gomJJJ*MdnLg#G&%cv_*RjRoY}uh}N-KvLv( zj#!a<+XPpv#gLp=iOQ&v1D)sTnHy=2qA0*Z$daKp3PT;CxI4q%3|Iz)Z~)h#ph#Lg z?%!X=cw%rtt{cBwA_1LE25(7LG0Tk6B!o7E4;To1Bs}OQ%Z=X@9;l7sGyXdqj*XrO z(GSF}9Ff`ZP5a%7Z}-L3WJ~u-$3c|m0#R;+v^T?64ZX{ZFScDih|WC4r`V$6mVi;m1>?iy@BA-r3 zC4RbB+K=JgogUt>)^06em>mz3W3O%J+{2oUw@pA3S=0$-Btmlb3+#j!+%3d6!QI|# zp}Ki(txdoBs8!*e7UVpK&gw)Lv<-={idW3?B=#r`0hdRy%;;}1TfKpR@OZp9bm}@b zrHvN6`}OM-;`WEQDP6pH{Fh9JN<+_nZP^$_k5gIc%;*7PsKyL{&iN<+#nYZPma(6h zV2%LBVCI{S9F?4|2-A?OAm*yHBPae{%~>RgOgoy7=-1&3hFaKNzQkOz1inf9a9gR! z?>%=CAq zy!0X-wMk^TkHF3@`w*d2jG}TonZeE$Lh6jA)>eNL+-N4yR!9S!q3WK-0&o*rO&yw% z8V=d3;wTnUzr#aQrl(j4G?FDwWOa~Nya>sJdJKZ=@PL%DfPiTCWV~v1H#yAUM!&s* zBIaI6bP!54#skbSp-*ymMcLwsg>+LnyD(pt!a6u@{{tx8PO^H+(cOu_cm3?f=#VY4xbwFCeJRtkHb}!_TB51cAXi2z$fSBOyltM zFm}AkEaXhgF@|tb3t$u~!n+t=R@Xpd)Puy;v|$|nb6w88FK)TLo16bbS><{vqgnD zgI8Hxgvp={F@|lC-Jt?iuE!$WaJalsHQ})`P$E9_gn`V+V?xPfbyP6)I2ayC)WSxe z+kFjQLnkJx^+u?K!baabK#*X^k0XUk3$rkTv}vH=R-wMI*r+bRdoBmzRo2C+4?e@` z!HDppH)Iv`+D&xCmy>;34icl6rjt=LFcJDWq32_O<#d_m2E*M6x=SZ>7?`|dxl31z z)1maddZ{{fO*jOHi|a!44oIWE;az7~BQ;+ecU%?drn=eCh8zyV`yi zSarH>9Fz%%WxF}7=V0eJ2F*O(_Jpwf5Dv!zdG{*HZO!XTd|3L#BwPCQM_v1s zxxn;Ybh7s~*9Nm-GN$93zX0^`R~~_}6@S*}ygi^TO15%(hya+|b}xhCtg5_#(=Wop8%%Q zE`&qk-!m@>+z1+xcVP(`b=sG&Pfv!&#^5SDTgGwaqrvpyc+%2#RZdBELcdn1)keoo zyzqymaR6OrB^u3f4i$Lq6TG6>69Ig+vBdNpCr*qW7sN(`fy2S{fjqXtzgq7gz^*XlQyaAJ(%4wtIUB}T@S(P!kRVTCXE zSpl)Yhv@jZ@dqV3wNbnIe;^?D4Lwvnz%ZR3dyY}Z3^*niHUDo6wK{pumf;%@gXz67 zBAf~@OGogfoiGm6>MCpg6FA%j(7paGDLkn;QFm>gdVI z;|3!+=B+UIfHpe?=62NCY_r!M%K>SU+sfxt<8PdJal!|gfkUjq#M$%b&ifUJ1N|#N zoc@(RDZ^vDIhfuMT&~_>91CKM)*}Q7lzKFn-W*)TQ9K6Lm`@w<2|l4sj6p&|8f4^< zm?TC@@Q`+H?9O{M+k@#%zY{^6udbF#orIDZC$7l7&)O6q=`X50>0 z@dy~;$h!z+s^4bJSa{>f;eh9Nqmc9ys5&lHH8Lc-DnNxdjGG+^m?8k>;2^Uq;e;+4 ze;Tm%2AL49EOL63;T{HGGotJZB_^XNB}>bSw-b>w8x2fospN2Zr%*}?H6 z?^Y#ot_Zb{aMYjf`%Dx}4d(;?NY0b@1KU-(Upfu=`xEeE=yY*v?+7$@?8vqS7pgcu zi{nb#`_BE+OQ@c1@n!aArrvE-$MdT8ME0m9goi9!D?s+>5f9l-fkcXh)HQ+Vt341s zY7i~^)vzxzNBVoBdu;jW9*d(p(P}SZtHt=d-sm24=z7&6bX9`9z|0T(g*QWRT`?Om zHu6FdCnI{U+WknPqw0*~M`?&yEn z_cY|L)dYf^l6VYNkrA9)14Na!fPPHl6cBP1OqOwS-@PB)9ZZ*` zW%WuhO@N+M0T5*2D=vbdDb^E8sYOLDrI^2Q{h=73eUi>=IjHFpjmvzPZB?h*xSkSvmOFi z`4Co{ER!CAbut1>b?AD-ts}A?Vg#UumZ1|x{eLo;-i7|dE;%0+m%ss3AaKqYCM4Nm z8S-d93>myWS;h+G+F2{hw8?x9JdjyEgA-(D-j2nNpe*tCvN~Kqe(GGt$>ZR>_fR-p7noRP4@e~u!ZxUD!DY@eERzSx&CX51JDkFpJFg2( z)F(&8kutLkaik4;#fF0EwE?|>C{sq6Tu^5hk9)l8aLDOyRaMm|ho%s}_Zj$uz$MbQGfua%tw5p+6O6kfk*rd+{I0-V-IC z5Y~L!vL+)td&qL{k zP({wdS*AF}!D%FbL@brfa*8@3>R?BfBE2*f53{C3l4}Z34YF$0ron03JO#p`VA{lz zLEq8!A@rs}ID1zYoi5URsdQSwoESzgdd-PvP^OPL@hpnwZJc=*({Yih|4+hgC1@eyr-&w5AL9P@JJ1iq9X5Jc1 z4+ZuxALYag=moalse-b5lUoB=>JUmfg~F3_vi*~*0Yb^l&$5S$Aj$;*EQRY`^4oQ= zjuf>!9i{Ro#4)pkK8r;^6rB^Hi`dE~wl3$YwF(xKk0dTR@2gW0`%pK({hCdaHXaOe zMEKvXU?f-+-Qx?$1j~HE2{f>imYvy065^fvd3lIXq1|VNvJ73`xCFM;VR%9SYHh|>rk#?nTeH5NuwS=jedQqun+O?nM~o?!dM3YmV}M$eX59iK zyo_>D%q!Ax5#jWJ4g6%uCNOiFnC7nnjFYJHlNtletv2;EV$4u&d>wb4+-?x%fp6wy zCONFB0r|~U!`q5*Tw9atXa;h?1oIIW5%k4TpNNfUI^76H7M$F zGvL}juE)({Ifz~Fc9`O^ul9@ww84x4CgG$hCLL7fu;)ieID3`@+E&(Q$6AavPuF&c zJ)Zg5VYVytv*W$pnV%i=(GZtz+n)M>3YGPl%qjhT!hE))@`4?e*vQ953^RvVB z+04%l)sf844mCz*7mN}Pk7ayzqjVtiGbM)%;`5oG9dFCoE)Xv|8wDC4b*R0NRr{!8 zAR56_m>+eh9nSphP#ews>`*(B_4$~ac4Ou znM>RBt=1g|D2b@eS>J3KyS}|n5hW+|pwvi3zSt__>?w9@=OlYuV#7waVPr>lj zrKJxZ3pGyMY#`xsqnC~1BRO1yZFvgZ!Bfr#YS8=kYel8ghQgxKX**p}>EjtzJz5g? z<>2kvA9n_CR2s~qHy<8Ap2OC{0({Ta`RDJ8l{Ond%z*hw@Fw!-%^}6n{nA)&n=vEe z5cJjxj}O)7?w8)ot#jNrJnjo7h-CxuILIu4gT{ymBLoECSSwM^Iw%U18KUj4lY_}L z>n+o8mfSCm7BbCtAWWMSf_#{o6#KfO(O4;8+%KKYrOCKYlRber!P*N#6hV;L5hbg6 z5n*HFw>pFk3}KUc%l*=eg_O;=c0F7Q^Ke@>bH^yWJ4WG{S?;?+VAT*_2+qSlpX+v_ z)Wp#dWb5au`;p|8P71_#U7?t49kQASYjT=69i1;G%a=swd^y-4=2u#@Z%cG04zP(4 zD6EL#8o~tI&$ljOzr}NU(>UTRHMCt&O<)gL*am#teaKPfM zokm((Q+?k2E2_Lhl*+(lS#2ahwAcXd;0*v)HasrTlV!DW174wxJR6)2+7?)hjT3=A zjS*M79&aPh`s&)ivYdl5SN6&BYnGDOzCIeLVbe1Wfu1F$=lh0^8}To0Zg~gSuHo;O zUyG?KqJ~eFU$sEtTiGUN&^XBQazH9iov|RrqOQjlA`2GK+_@Z>O3Dcfb5Af`_DrmC zWFKD+VCtZg<<~7>@l=?TD{-j1mIGC}HBJIC;KpI@UJgv<*!W1%wiO4tXE`9Lh$aW0 zrm#53y~_bfWo@z?AE?N376<%9FmAN`N>|(1{Vp^O@y<)Cm!1-Hh4$>~di0bci!WzI%aWv z)hr$dI=UR7S&D&L(c?gmECZ+*3MR{OBKSu4IOwrr&=ln=&Ywq^M?rX#G0=;i`;lCB zl8S)xi&!le#!|*Nu8KO`d%yXEzwmlW#qC`ycs5>(La~op=i;>}@%pM|SI=Vgv^S{N z--;tZX6s!m_;!Y#`2f|pYW7j>-zQq*y4Xjx0A2IVnOyt&sFv(opCg&9*5^q(MKN*;YMlE_Nj7m{|B<-a?FF+J3_NLAu3R$9$dB0L$73k=k zrxO7!(Co3(Zqsze?#FrzH7{XcKY8RfHdHvL>x}D>#RQ15>itqPV<|s)>ZA!ey~4ZG##FG#0~3=7O(RcUGxt2?+!7nzj8MzzLhM5IREOWd(z;@4m;L%~DnmV7=;^V#^wC|(v;uj6hT z)ru-+lBciSL)bw-Eg| z0z?|(C^b{qh?fF{AiX1J#b|g1eu1`Ja>}sUl;C!SluOk*E!eSX0^KIL8!WR{~3gf1@&_91@>XcGWsbg1e^fT21moUtKm&XjoXX@O+BSQ zTkYPFT)R?>hy1lRjsihSLZZl6;60WCy}HX(MCOMMZw{`uk%<$ti6V+E7@1w2kIxxp ziK)V#y%3lS#B}j7q!I>5MNY?|a{_&<^g$u?&m`#<+0bSF7@0g8zKP^0$Y1bkc$3-s z@noV#A-B;{2v?QHvsL<56;*cDpJ|K@_*UsoAwHk#fe-UMtO_zz1-?~!zYv*sdLhF^ zI;(;WS^Qh2?=QsW-5%Jem}BVXs-Q&PTq*aMbY82150#3Q4%i$Mm#qpm)DXT^`ds0F z&Gr~DTusrCR3JRWwJKO~=k~4A4;Nzf*&bNc;Gn@hh@9hk;bEr*O?DnfJb)~S8aid-efar_?l+5IbiV(@W?%)({eC^UL z#3u^dz##^#-MrxCCJ$dkdkM5MmOO+J2d@hL|5ynAPLGKK4aU0ejCygi)#Aww>KPoV z)tN53XZ`rB;;M~(OjdDa#gEG>u1vc!$+pU?xH9_6xMww2ajsDJSEzQa-YTw3(Z_8S z*PZmod==N-`O0{G#jAL1e<8Nr`=!5CDAcPxg!-Jhi)=MTxLA+xm+lrK_URsowOg~T z?y9UPVwJvM`hh}pZuLM1H`roTzsWTIt4b>6{T0s0C0y~ns#qzruMDeIr5^>?ZcJr*{>{h!xtf_pEK6O+wJqWViM7>b#B!2H%+Am)e3N#b(RON_Y5 zdp{#r1=|}JnXLvHT$pBWy4zZmmLzSdJ|P`sEBv6fFpJGP4WO+%)%ksrzm14!9(v|W zA&Bs}WWvh;Bkz%{5UCj19)iv34T1V;a}{P^rikL2lj%C|BIl(~el{rPY#K)TU8Ip> zvb{y@`;g4gH#Ne#Q=COgk{(`yu@xJPH(KvczW)IAO$tGvpdCzNj5JYRb}1q(*`j)* zoXRiNKem}wV~EDC0h=jIIfZ74EL{*a;Ujt?Ff4|*dOR(OdzhxP77oYC zO6IF!pgCQK3!@TVs?5W1d!2`KNp+tj?A_INOH)5FofB-eI++U)^HW^)z{@YH>9dH} zOr_SHL6)g%V@$F`_KA`3OLqTb?MyK17TdYd!ZkbB>a(*Lp9}5Q9H#sO5g)L7LT5&sCloV#om_W>{DCnRD z>gW=YQ!tkA%VcSaUCEeJ&(PGY`NQ_=VK6{Wh3tl8c1tCdR^f0mX2Hvj=AEz`4u=!@ z$SnW8HI)Y`otZ2X3i+Y0Zn(pT(tA@WuW{Fn*f}vE@HRd88Zxn*F4&x9aR{MHTBbwa zUq{@z$YpgTcKQ%#Ohh@%meUcN%`6Tf))7xkkpJt3>H3;FmO*>Zgm>jQB3FfRL~&f3 zoSvL1W(8Y;$?fM`&F8T6E+H!8PJK?7c@iIbgova|xZW9X$HQYUhQn@}i2}k#FhyOj zpq`q0ynO(uI)<7iCz=^3E;HUW6=)2a%%mnxM<~s3JUf~SV7#MHHOhHmb?=~9PS!L9 z$#RgUl9os4oQo5>fO`S@z*-%v*mIf8Y7Tcja)por&A8SFs6^g12T6`qcz}vP^~QS~ zlB=%-Z9V!AIKqdqRBb)#oCt?|CT$z$vM1@hxohfgl!PK+&GYp}b&>~zJK-=!BrA`b z%=n^V_qRw){ARlpU9uAAUi2v|znhL8zs$6dy-hI810kf09WT|u5Y)4+NBW1mcE}1B zOhdVDM4Iqsa&jV~P!Z=Gw_`J}sEfE~p2uq%kYV!06@kD+&N#Q|f#X*LF1qn3k18Z= zW?nfDAPZcSymLi(*-6n)nS428p`b($K&Fc}v?2<{=-AITBoMX4q)85Frc@D*n0N&l0zJqXx6T*AmHC)FL~1k@ z52{z9I&Y_V5nNBA^p-ijOY~^U@LPu9W27>+%L{U^^}~{aGNdbzf>M7aQcwY`Pznl= zl}bUyBzCo;WtW^$77p~JprXM*tArFOsvk)~ss6xHP-?GG3MvNKQZP^F@TN--R_~LC zdq63kFeZazpH1};&^o@xEozo3A<@}p9iguMaEG3l^~909=%=QCEY_ecsN+xAtvj`Z~Ceytok)4S$`DmU^+v5`MFdH(EM7kh2x zT_v-bkL~4)>_OHDz*|oxWItT0E6#30<0@d7EwF_^%;5RAE>Fx%UAc_SJhs7LgHd31>CB@7g|7>12h;&g5qYegX-V;9jL*3g+-u8%o( z3v~AZ?VA}cpS=Eg7EU#w7=x>`4b0RH2dwORp1;#eR4ElnC>`>O=6M@kmU-Sm*av$U@TYIB-SOxBer`_j8C4Tbu^Q@O|!{O z07>)g(JZRkjc)JSS>%jub9;lxqNd&I_O6{pN4wqaS^HRGU6)aaZ*~(f%qVz*KYDaZ zArxvn&n-1@8qF;3*8fA!!Gb^y%4xB}O|Ei=sv0S(X8a05YHSv1i4_?i8ajO(Thr+` zue=>zoSL3tQ&>y#wr){nqf>J2@-$7zH$gVOq!}I%xOrg~HX}8n36_$d(=?(q!pCO!v-FE{UFatTNv% zhbLgUsMRyGVf$DYK}_<+>J5u(FwrhHV`S|1y8ofci5U0}i-sbCCa0}GL^13?o+Gr} zWk%8wx^?D+U1z2z&R*i&;;NTR&~25MYo!? z{Ya~DIApSJ_#DEM_`^STuP=O+p)V=FWh3APW@%F~E9LMAn_*fG{I6L_(+wDkJnxlSc5nrx4O@1{Kn$~+y?sF3+>_7|%a=C-Ixl0m@s*;6bG69^YX zW)~GBkrgjC*xa;g#twH*TPcxaX-ZJPfEq@n%%+AC*-P{3HJaM$4Zp7=&iH~+WnJ6( zsF#-EvfJavFT1tGmaxCJ3g?elqjDNc>>c}St#AO%PLgMdqL3kvni)IIWUD!I)UGW# z6je8IcBAQSX|hc)PR1A(&RW@|X1ABzzxLN!@qCSEKldn_*yr}wmf0U>(~`U1?2aY& z!^yVtM$YUdvRjJ+f3n+580(U4a^#}jnjJ(>3T0dD3Yj=p3dvS7ZCLAH3KfpAXPlz9 zFgbsuaj%R7&xA>Og^IZeO>?P6=%u3W7i{p7Xm^Gz;2rJt2^={^6gHVnZ!}yasvQzH# zO}x>(z9W9B&G*eZZxxRz|E`-L?&sy$5)Dw4pS4(FU2(J#QG?57mY0Ler0@LjZS zwHp1x8_%cPaU#f|+Esvc0XE@$Z|af9S8M7Ci?7bqV~FB%rk)I^j912hQphi7>e=zkn-Ivw1)|xY@qW1^UqB;; z7NUWQjtumMF{9@<1xT zc#_rVB9ZxrI+{zGWRg$hc*SG)K~T+n32Nr0D{oCt9=>vY@*3OfFs?cRrzvsz0>|1h zTm*H#@$6F8Sx}$=GFiR3Lqgol0wxaGk6)FgBhQs(uatm86#j-)y;H(CzASS`BtvYi zF#~BQ`@rq5++`D{^D2Ct5jjQ!qo(&w1NwuUBj~$+8AZ|P8g2c-d!{a^@5(I|eGHtj zHT2!RmEU4fL~LV*=o_2j>n(~}GKPr0TjC~qnfG3xd6j0FQp27N=o^Cvx)P&^1lHTs zHwG)YE5jh-$q=QDHlAs?h%F6fLl7;5kvGd*a3G2mZ2lG_2GuQ4v8C)m7My->+9(>3 z#a}e9Y&9KGx1<+|6N{EtrBCGJwewlL@0dwIV_B$bGd6mv?Ep=hpW=mIO~g)z)OjCEkS99~TBhoxFAcP8|}@?j}f z%bhdDXg+MUYISGYLsY6Vmi`q?riZ3dt?v5%&=soX+M9}*^*gUlW$a*Az!eWcol4nN zY`~VU!>#~j>+@RSWg10`u?_oLC5+Xp_7Ija8#cB|czO=Ihe_Pkoq^&Ke3w`6gHzW!N zlgHmEJrWGE@PjSw71L$A7zBXV z?x)?;Z+)-*`bGEdOYZ4s+|!rc)3#6B8k^nI7WcH(J^h@k@$>HKEAHtV?&-H31~Z?t zkbl{I{WbUWkKNO+x~J`~wMX644)^q!d-^A?#xJ<1uezsSbWdM%Pru}zzV4p({+b=j zzjQPW+7{>aPuQp5+i0IQxOe~XO*>j&kP*B(^Ir^ew~i^RZUgsBo|`&19B3l1)@)_A z-l%u)Uc!|z^~DCRk+GTWz-4b=UWAv_JquK|2HclL*ZC-G~0ur1gU+`-ep;3Gk> z9uH-_s0{^=;LiE5hW|ahGuVvA@l;#ScdwLDr?w{8h!^JNLC(%W)O?H|wg%yif6IA7 zFsLH{*BF3n0Fc*Qoi7gs1CIpP@wmp_dG(1wd*>Byy2YCWN35&Qd(zq9AYpZ?AsR@xkRlrrU$ z3lQtRS^gs_zdjI*O-Y@AG1vj7EGFdjYfq=pi4PG9U7fkNS1VJ>@X5-9-9{dy6I^;? z;5k(Iqjf=`i=c{uKUx=wf&UHP1_svz18V{NCrZy_1`h}ReF3M!X-%jXE-hj(*;qJo zv$H1HiS>CcW`EdO8-(qFfdBA9;PAr_%McV727`4$$awcM#K46$nDXIqeO~K5ujBLh z7{vntZcYH?jlKeKLvUd|a0|x;+6LBo`9wLuYYH8{9ttiD0ih7Vb@F2)e;{m6er)o; zZ1#U_@qcX9AIGH5HvSlWQK4=3i#@78j#{iK1bs5_>R*fXjtJ|=1Z#y?^5K>FV{G(A zX?Caog(P-8+U5V)?f=;0|JdvQc*6hjr2pe7|Hsq*kI?_I&;K#ZABffzM4!hs}wduPpNjL){k}!WkM3SQ(N%#zkuZzY(CWe;q31udU zM>XL*bZ47(=a{m;;duRF$flJH+4P5*Oh=_}W-{pyGnr7#kxj{N*j?wWu)Ce6!tQpc zg!AkVp{M<^JbE4_J-1tWa&ATxJf_$wQ|YtN>P4N4FER}3pazp8;-LYXHZHf(~+O0MjH7&JV3eQ*)5NKgsjnLQX`*V$@c^=7a zb-LkFv(9TGtp-FL8};;SBn=S8dl@?GClDZuf4g_F2R!C0h}@ON_1=C(Z?HaqI!+GI)(%Hezu)^sb+acT3I= z_rYXRj{6+b0ZpYxs=plTf|LW3H5w7?fIzi&Yau*&;>gJ{RyjF#g;Od`rcuNlYmK|l`!r1)dj?#rlW0rJcfzI461F&Z!&}HXjVouD zYBk=|)&<|Bpj_kWkO<+__xLGf8IE+X-Ra?+@9xxZ&iBMQ-JDW=Oiv|DB3FV1m+D(T zGfp7(o^evF=Zuq5Su+kKO<|XwaS2(ZsOcFn@BSvTnK^`JXP1;r&q1676rn{fse~}w zbg>X3P!GQ_UnLe2JQG4r-{sBTQQ~}oC(|J--)@>eGH&M)sg;76${B*bVD_V&nfsj7 zcA>!Ks%Bcw*|U^3-qdLLn8!S1Ytw?pCr)yPN|rocsj|?b)M|*HTxs6z z-V#e`B%`vY?$PA*PEXxAf8SE` zJ={%O?LY~+31xb*KKC9}@ukHSh_tW}{V<|)p=enD3!)3gipAMb z)|Jt8sWdmDNl+q=piH;y!HO}CPRqDxz_Ifc>R;v{ukD>QlG48*t9_D6p|q-yRVrKL zNXZn$lu#jE-ONvYP1R3`m00b>w^ZHqfVzg`pHel`gFHr7K)JNY;WTiWgyUS0Ejo_H zreXG~pT+N)?DS%Kvi3Xo`y57@LaBk`KqPo0f3C$kEXCsV?|-gkGg%*$S-pwYC)u>Y zED`0HFh$f9A0{~byU+bDI)bh*na5ar@tl(*9?Eu3ECVch{G)>iu?)I^8)s4~mSN|Q z?4iGlW!D8X4dF2!Xb^=1WCa04Ap-pd0Yt9<rNAS(#qA34|hO5E~Mus{?d zu>8P)D5xL`IVcWNP?!GInSVJf;~13wBJQ|*JRqB&t2S^Gb-i|XqS|QiR``zRwkxCN z*Ea^ih(H*?mvd*ozERzFn_p$nkKm zbO3Pn1t0)!+N;q0+=UqxdKW2hh~}TgMQE|3K%|TgfEI{wxY0(?#2Ivq)^zFIh;(jq z)VX~??n!iR1TBf1^TxM^H=-#t-Q=u{cV{Rd-UEU+YtZB6^>$<8vpOXlF*c=%vDpzr zfr7@z)m!FjZSjEebE3_y@_D@_<wiikwmozO5_at zpU4m;(fWu)Pk>0fl;K1`I>ET_)o}lQ##~7Z7D;#_d}Sx(yo?)vb28s6Jp)ocVOipX zYP%ImD*T?*Ql{O8+7#JqEk^fB$MEWq8Jljq(z$gAx#r~lL}xdjyG6GkOkLo^Mor}= zqQ#zIa2Ng;W`!fR*U=>XTGWI;Gdgqa`XYpJp9m-9d}(!slM-bsXv{^6Y=kuh{Hif9 zW&vr!TZjm;P927jWr!9oY8dGoe{Vm>5bL+BtX!saAazchou8KwD7X!9>JF?QcDRaT zZqVZjA~Dg@ytpQC*=H3(0Bc$cqk+Zi?}J|$vorkx*baZ+e$6(KBL=vNcS0)%ZbJ@` z;phqv@fyn~x_%5G_Xp=0N(+}pW$r!1Yav9d$$%}`f?N`Qyd6a)paBjjgX{563ElnO z(pE5(!6@Kc%VO7B3=tm+_nRXl>b{|blQu^MW;v+sqgW(vcp<)T#@h3to;ZRIM;qq_V?^dyJUtCRcfRN>BpDc`Z1PsFzY#-r}b}Hi6 zSon&l8EYUyVM~XoXGdyFP`dje@B_q9=lZV0b$NocZ)C@X%9u4N3z5N6vfY zUTGYpe>S*QonM+GxHu&82SADvXP^Qvg1aNV#1HM|z0wKr+Y7-o2hSmr8on`a0xFUu z#V!zU4R|8FaS3ahP#uVsfa(^nqa#hqfOMynn6VWIVWTb}pa({+Iv{!+CB(KjXiyDKAIYbqVems9`%$uoZ8xxErIo48o^Sw>%t z+Z*f#PGeoV3AL{deM`Gb&(%dpPf{BcnrhBh-#43avlHNWbZEsgJ>B}NaXMjF=M%hmTe(AsMRjNnS*B?;2CPB!^M{-`^iHUk*__C`_CyhUFyV%UXX zu+YsZM}hND2~DS%ly$*nb7VWU+=259PCnVq4Y~0~8ICX)C3`If?3-wMLYBmxY7^>* zSKs#JxDSvq z3uZo0Y-13rpm|UQYJby0JT)JWc~L-BFZLjx0^DJOSB>kw56b4sFB@N<66gLT_vg6v zqf2xQ2tU=4$Te9ABAJmTY%=$-zMvs9=gFB26xeMb;1&Svb0IX`PvH_}Jq?>O90Q5w zjF_U5REhhWhy?83GNB3(Zg!oDUAcnR+%l!wQB_kgr@Nc6PhNRfUE@Ho%DXqJA{CDv zJ8|Op@nhn%8cLwj*Zvxqkp_;BmOls%vn$wcw*^oF5n8NrcH=7~4B18%B(um&x0Vnd zg_tB=Aib4_?4pM&&Tw@}7E~hSVZZ$Cz3bRAD9fT&ids~~q0{hq(gZ2@;TaBbYgH%U(rrr%L4zt>ELKM4J)baHb-StB*YI2YbU%@hX7cp zbmtfepdisp!N(8>J+~djeouSexC=N2QU=SXn8q1e;>@AyW8TDr$Z~3yw&ldI)wyDV zDm5jPlM*w*F4EAP_wSDuMyoEXHZ25*)K4>gUJ1pwrvg}kLv0hsGPp582g;yKgN`Es zwaoYmbTgr5dIVtEsQZTX-v%Gt!txPmtw}5(fcmonrLjsc*NHbrZ1Ud-FY_d$h1ogP znKt$zAIAitfMSLfDTYtc8X2ci0)amE4cwwcZ17#$H+X3K(wZXB59JZMrpX5pm21=T z=~zU@XsS6rV{5?X?9%%a%LCia{4S=Do%WICwmh0F4?qr9sf+D_tFBxBp_v$igrS)! za|TAZ(-Nw$<{y4djbVSrIUJ+Vc9q=msc0k>v5S8ome&|PKbH7lYWVbDjzJISJ7b$q z9|1=mgYd!dK%#VbM2vsBW`e^es`W;w6y&K|1#m{}f2YICOAE7D4BIqea*3)hEHDv0cVaQ7$1p#ESzyv90?+frmHlrXj9r{9T7Kjev8Yng~l6Bjw7U-(LbVa;&(I7Fm}`P7#{X$tF`1c8Z)$8Y3dDQC2Kw-H4-urneIw`@dljW5{( z({A#w`)BWOXUqulR8Y$`(Iu(m7p9siIR)M}C1D?q{qbP(%;$c@9DkPmr75Wq3{hd0 zeBu)&X&s3@oOQ_*-xHOLJsA|Jx|otr$G#(60nHOFmfR31FPoxavZ(oOiV7c@qWcm> z13ub!@KX;KZ zzwVyS{G9=l{$ry{WHIEPHo2!q+|zHky8p~Q{ZZE@qxh%p-IvELWG0bNT<*EAueo+L zrs(R-|Mdcj;qPZrkN?`E>5s-ETrOXo05F@GViyYj0s8+eYruuU*p@%oqOmQH!PW3< z_%<*&5UhO$|E!nz6XRzJZ%mdELjZp~JYVXNAAlEY3p^BXZ_`VpzL{~nI2e#ul71^} zhTzVE11I!dAhiLwa@2WyuktJ%kT%? zE1d*hM+4V>72ym>!l3~=+>%~tp1VuL4or1KI^f&$DV%t$9!W3v~?(%Z58suGnr z+W$D{>Y*e{F;wSXi5|x75pmzE-jz`)$2i4R!Zk~*#LP~QMwMn;E&7z3wVYbVPiEC> z!gG_VWuh5K%<(Y>P~9s%g~lF_8dJk2tqaAKUzW;d-rH$0SAn6X1z$&fv9R{I_EV!A z98=F#+LhbbXyM=7#&39$ObN^*GqAKB@zG9

eC-v2O`5^VJH>HB?CxVDiFKb}(px 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 PnxAVf605g-e%pTlSA_Bg literal 0 HcmV?d00001 diff --git a/mod/Unfound Loot.url b/mod/Unfound Loot.url new file mode 100644 index 0000000..d976917 --- /dev/null +++ b/mod/Unfound Loot.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://mod.pub/falloutnv/24-unfound-loot diff --git a/src/EULxCalculateBaseRemovalChance.gek b/src/EULxCalculateBaseRemovalChance.gek new file mode 100644 index 0000000..1dd806e --- /dev/null +++ b/src/EULxCalculateBaseRemovalChance.gek @@ -0,0 +1,93 @@ +scn EULxCalculateBaseRemovalChance + +ref rActor +float fRemovalChance +int iTemp +float fTemp + +begin function { rActor } + + set fRemovalChance to EULxActorBaseRemovalChance / 100 + + DebugPrint "Base removal chance for %n: %.2f" rActor fRemovalChance + + + ; Luck factor + + set fTemp to (( EULxLuckModifier / 10 ) * playerRef.getAV luck) / 100 + set fTemp to 1 - fTemp + set fRemovalChance to fRemovalChance * fTemp + + DebugPrint "Base removal chance (luck factored in) : %.2f" fRemovalChance + + + ; Creature type factor + + set iTemp to rActor.GetCreatureType + + if iTemp == -1 ; NPC + + if rActor.GetIsRace Ghoul + DebugPrint "Target is intelligent ghoul" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorGhoulMod + else + DebugPrint "Target is human" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorHumanMod + endif + + else + + set fTemp to 0 + + if iTemp == 5 + DebugPrint "Target is lootless (feral ghoul or other)" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorFeralGhoulMod + elseif iTemp == 4 ; supermutant + DebugPrint "Target is mutant" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorSupermutantMod + elseif iTemp == 6 ; robot + DebugPrint "Target is robot" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorRobotMod + set fTemp to playerRef.getAV repair + else + DebugPrint "Target is butcherable (insect, animal, abomination)" + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance EULxActorAnimalMod + set fTemp to playerRef.getAV survival + endif + + ; Skill factor + + if fTemp + if EULxActorSkillMod + set fTemp to EULxActorSkillMod * fTemp / 1000 ;0 = no effect, 0.5 = half as likely item removal, 1 = no item removal + set fTemp to 1 - fTemp + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance fTemp + endif + endif + + endif + + DebugPrint "Base removal chance (creature/npc type and player skills factored in) : %.2f" fRemovalChance + + + ; Limb damage factor (unfortunately, available only after killed NPC ends ragdolling) + +; set iTemp to 14 +; set fTemp to 0 ; num severed limbs +; while iTemp > -1 +; set iTemp to iTemp - 1 +; if rActor.isLimbGone iTemp +; set fTemp to fTemp + 1 +; DebugPrint "%n's limb %g is gone." rActor iTemp +; endif +; loop +; +; set fTemp to 1 + (fTemp * 0.5) +; set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fRemovalChance fTemp +; +; DebugPrint "Base removal chance (corpse limb damage factored in) : %.2f" fRemovalChance + + + SetFunctionValue fRemovalChance + +end \ No newline at end of file diff --git a/src/EULxDelootifyCellItems.gek b/src/EULxDelootifyCellItems.gek new file mode 100644 index 0000000..6fdfe07 --- /dev/null +++ b/src/EULxDelootifyCellItems.gek @@ -0,0 +1,213 @@ +scn EULxDelootifyCellItems + +ref rCell +ref rItem +int iType +int iEquipType +ref rBase +long iValue +long iCount +float fCount +float fRemovalChance + +begin function { rCell } + + DebugPrint "Scanning cell %n for removable items" rCell + + set rItem to GetFirstRefInCell rCell 201 0 0 + + while rItem + + set rBase to rItem.GetBaseForm + set iType to GetType rBase + + if iType == 31 ; misc + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set fRemovalChance to EULxCalcMiscRemovalChance + endif + elseif iType == 47 ; ingestible + + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to EULxCalcMedsRemovalChance + elseif iEquipType == 10 ; chems + set fRemovalChance to EULxCalcChemsRemovalChance + elseif iEquipType == 13 ; alcohol + set fRemovalChance to EULxCalcAlcoholRemovalChance + else ; food + set fRemovalChance to EULxCalcFoodRemovalChance + endif + + elseif iType == 41 ; ammo + set fRemovalChance to EULxCalcAmmoRemovalChance + elseif iType == 40 ; weapon + set fRemovalChance to EULxCalcWeaponRemovalChance + elseif iType == 24 ; armor + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + set fRemovalChance to EULxCalcArmorRemovalChance + elseif iType == 116 ; currency + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set rItem to GetNextRef + continue + endif + + if IsQuestItem rBase + DebugPrint "%n is a quest item, skipping." rBase + set rItem to getNextRef + continue + endif + + if iType == 40 || iType == 24 ; weapons and armor + call EULxReduceItemHealth playerRef rItem + endif + + if rItem.GetDisabled + DebugPrint "%n is disabled, skipping." rBase + set rItem to getNextRef + continue + endif + + if rItem.GetReferenceFlag 33554432 + DebugPrint "%n has the No AI Acquire flag, skipping." rItem + set rItem to getNextRef + continue + endif + + if rItem.GetOwner + DebugPrint "%n is an owned item, skipping." rBase + set rItem to getNextRef + continue + endif + + set iValue to GetSourceModIndex rBase + + if iValue > GetSourceModIndex rItem + + DebugPrint "%n is a mod-added item, added via ref override, skipping." rBase + + set rItem to getNextRef + continue + + elseif iValue > EULxDLCIndex ; Mod-added base + if GetSourceModIndex rBase != GetSourceModIndex rCell ; Different origin from the cell (same would mean new area or DLC - normal processing) + if GetSourceModIndex rItem != GetSourceModIndex rCell ; item placed by other mod + + ; Mod-added foreign base AND reference in a cell of any origin. Skip this. + ; Cells with matching base or item origin are processed normally. + + DebugPrint "%n is a mod-added item, skipping." rBase + + set rItem to getNextRef + continue + + endif + endif + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + set rItem to getNextRef + continue + endif + if GetWeight rBase + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + set rItem to getNextRef + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + set rItem to getNextRef + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n is an expensive item, skipping." rBase + set rItem to getNextRef + continue + endif + + if AuxiliaryVariableGetFloat "S" 0 rBase == 0 ; the item is encountered for the first time + DebugPrint "Adding %n to ever scanned list, should only see this once" rBase + AuxiliaryVariableSetFloat "S" 1 0 rBase + set rItem to getNextRef + continue + endif + + set iCount to rItem.GetRefCount + + if iCount > 1 ; Item stack + + DebugPrint "Found stack: %g %n, removal chance %g." iCount rBase fRemovalChance + + set fRemovalChance to Rand 0 fRemovalChance + + DebugPrint "Rolled a dice, removing %g%% from the stack." fRemovalChance + + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + + ; iCount items to remove + + set iValue to rItem.GetRefCount + set iCount to iValue - iCount + + ; iCount items to leave + + if iCount <= 0 + DebugPrint "Disabling full stack of %g %n." iValue rBase + rItem.disable + rItem.MarkForDelete + elseif iCount < iValue + DebugPrint "Reducing stack of %g %n to %g items." iValue rBase iCount + rItem.SetRefCount iCount + else + DebugPrint "Stack of %g %n, removal chance 0, skipping." iValue rBase + endif + + elseif GetRandomPercent < fRemovalChance + + DebugPrint "Disabling %n." rBase + rItem.disable + rItem.MarkForDelete + + endif + + set rItem to GetNextRef + + loop + +end \ No newline at end of file diff --git a/src/EULxDelootifyContainer.gek b/src/EULxDelootifyContainer.gek new file mode 100644 index 0000000..139e7b2 --- /dev/null +++ b/src/EULxDelootifyContainer.gek @@ -0,0 +1,168 @@ +scn EULxDelootifyContainer + +ref rCell +ref rContainer +ref rItem +int iType +int iEquipType +ref rBase +int i +int iLimit +long iValue +long iCount +float fCount +float fRemovalChance +array_var itemsToRemoveRefs +array_var itemsToRemoveCounts + +begin function { rCell, rContainer } + + DebugPrint "Delootifying %n..." rContainer + + foreach rItem <- rContainer + + set rBase to rItem.GetBaseForm + set iType to GetType rBase + + DebugPrint "Scanning %n: found %n" rContainer rBase + + if iType == 31 ; misc + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + set fRemovalChance to EULxCalcMiscRemovalChance + endif + elseif iType == 47 ; ingestible + + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to EULxCalcMedsRemovalChance + elseif iEquipType == 10 ; chems + set fRemovalChance to EULxCalcChemsRemovalChance + elseif iEquipType == 13 ; alcohol + set fRemovalChance to EULxCalcAlcoholRemovalChance + else ; food + set fRemovalChance to EULxCalcFoodRemovalChance + endif + + elseif iType == 41 ; ammo + set fRemovalChance to EULxCalcAmmoRemovalChance + elseif iType == 40 ; weapon + set fRemovalChance to EULxCalcWeaponRemovalChance + elseif iType == 24 ; armor + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set fRemovalChance to EULxCalcArmorRemovalChance + elseif iType == 116 ; currency + set fRemovalChance to EULxCalcCurrencyRemovalChance + else + DebugPrint "%n is non-removable, type %g." rBase iType + continue + endif + + if IsQuestItem rBase + DebugPrint "%n is a quest item, skipping." rBase + continue + endif + + if iType == 24 || iType == 40 ; weapons and armor + call EULxReduceItemHealth rContainer rItem + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + continue + endif + if GetWeight rBase > 0 + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n value exceeds maximum, skipping." rBase + continue + endif + + if AuxiliaryVariableGetFloat "S" 0 rBase == 0 ; the item is encountered for the first time + DebugPrint "Adding %n to ever scanned list, should only see this once" rBase + AuxiliaryVariableSetFloat "S" 1 0 rBase + continue + endif + + set iCount to rItem.GetRefCount + DebugPrint "Found %g %n(s) in %n." iCount rBase rContainer + + if iCount > 1 + if iType != 41 && rBase != Caps001 ; do not apply random removal to ammo and caps + set fRemovalChance to Rand 0 fRemovalChance + endif + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + DebugPrint "Removing %g of %n, removal chance %.2f." iCount rBase fRemovalChance + elseif GetRandomPercent >= fRemovalChance + DebugPrint "%n was skipped because due to removal chance %.2f." rBase fRemovalChance + continue + endif + + if iCount > 0 + ; RemoveMeIR and variations cause CTD here. + + if itemsToRemoveRefs == 0 + let itemsToRemoveRefs := ar_construct "array" + let itemsToRemoveCounts := ar_construct "array" + endif + + ar_append itemsToRemoveRefs rBase + ar_append itemsToRemoveCounts iCount + else + DebugPrint "%n was skipped because due to removal chance %.2f." rBase fRemovalChance + endif + loop + + set i to 0 + set iLimit to ar_size itemsToRemoveRefs + + while i < iLimit + let rBase := itemsToRemoveRefs[i] + let iCount := itemsToRemoveCounts[i] + DebugPrint "Removing %g of %n from %n" iCount rBase rContainer + rContainer.RemoveItem rBase iCount 1 + set i to i + 1 + loop + + let itemsToRemoveRefs := ar_null + let itemsToRemoveCounts := ar_null + +end \ No newline at end of file diff --git a/src/EULxDelootifyNPC.gek b/src/EULxDelootifyNPC.gek new file mode 100644 index 0000000..6c94c34 --- /dev/null +++ b/src/EULxDelootifyNPC.gek @@ -0,0 +1,257 @@ +scn EULxDelootifyNPC + +ref rNPC +ref rItem +int iType +int iEquipType +ref rBase +long iValue + +float fBasefRemovalChance +float fRemovalChance + +int i +int iLimit +array_var itemsToRemoveRefs +array_var itemsToRemoveCounts + +float fCount +int iCount + +int bDisintegrated + +begin function { rNPC, bDisintegrated } + + set fBasefRemovalChance to call EULxCalculateBaseRemovalChance rNPC + + if fBasefRemovalChance <= 0 + DebugPrint "Base removal chance for %n <= 0, skipping." rNPC + return + endif + + DebugPrint "Scanning %n's inventory." rNPC + + let itemsToRemoveRefs := ar_construct "array" + let itemsToRemoveCounts := ar_construct "array" + + foreach rItem <- rNPC + + set rBase to rItem.GetBaseForm + set iType to GetObjectType rBase + + if iType == 24 || iType == 40 || iType == 41 + + if IsPlayable rBase == 0 + DebugPrint "Skipping non-playable item: %n" rBase + continue + endif + + if iType == 24 ; armor + + if bDisintegrated == 0 + + call EULxReduceItemHealth rNPC rItem + + if rItem.IsEquipped + DebugPrint "Skipping equipped item in OnDying (IsEquipped): %n" rBase + continue + endif + + ; Sometimes, IsEquipped stops working, we fallback to GetEquipped + if rNPC.GetEquipped rBase + DebugPrint "Skipping equipped item in OnDying (GetEquipped): %n" rBase + continue + endif + + endif + + if ListGetFormIndex EULxProtectedItemsArmor rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iType == 40 && bDisintegrated == 0 + + call EULxReduceItemHealth rNPC rItem + + if EULxActorRemoveEquippedWeapons == 0 + if rItem.IsEquipped + DebugPrint "Skipping equipped item in OnDying (IsEquipped): %n" rBase + continue + endif + endif + + endif + + endif + + if iType == 46 + DebugPrint "Skipping key: %n" rItem + continue + endif + + if iType == 25 + DebugPrint "Skipping book: %n" rItem + continue + endif + + if iType == 49 + DebugPrint "Skipping note: %n" rItem + continue + endif + + if iType == 103 + DebugPrint "Skipping weapon mod: %n" rItem + continue + endif + + if iType == 108 + DebugPrint "Skipping casino chip: %n" rItem + continue + endif + + if iType == 115 + DebugPrint "Skipping caravan card: %n" rItem + continue + endif + + if IsQuestItem rBase + DebugPrint "Skipping quest item: %n" rBase + continue + endif + + if ListGetFormIndex EULxDeathItems rBase != -1 + DebugPrint "Skipping death item: %n" rBase + continue + endif + + set iValue to GetValue rBase + + if iType == 31 && rBase != Caps001 ; misc item + + if iValue < 5 + if iValue == 0 + DebugPrint "%n has zero value, skipping." rBase + continue + endif + if GetWeight rBase > 0 + DebugPrint "%n is trash, cutting removal chance in half." rBase + set fRemovalChance to fRemovalChance / 2 + endif + endif + + if IsScripted rBase + DebugPrint "%n is scripted, skipping." rBase + continue + endif + + if ListGetFormIndex EULxProtectedItemsMisc rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + endif + + if iValue > EULxMaxItemValue + DebugPrint "%n value exceeds max value, skipping." rBase + continue + endif + + if iType == 41 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorAmmoRemovalMod + elseif iType == 24 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorArmorRemovalMod + elseif iType == 40 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorWeaponRemovalMod + elseif iType == 116 + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorCurrencyRemovalMod + elseif iType == 31 + if rBase == Caps001 || rBase == PrewarMoney + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorCurrencyRemovalMod + else + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorMiscRemovalMod + endif + elseif iType == 47 + if ListGetFormIndex EULxProtectedItemsFood rBase != -1 + DebugPrint "%n is a protected item, skipping." rBase + continue + endif + + set iEquipType to GetEquipType rBase + + if iEquipType == 11 || GetIngestibleFlag rBase 4 ; meds + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorMedsRemovalMod + elseif iEquipType == 10 ; chems + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorChemsRemovalMod + elseif iEquipType == 13 ; alcohol + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorAlcoholRemovalMod + else + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorFoodRemovalMod + endif + else + continue + endif + + set fRemovalChance to fRemovalChance * 100 + + if fRemovalChance <= 0 + DebugPrint "Removal chance of %n is 0, skipping." rBase + continue + endif + + if bDisintegrated + set fRemovalChance to fRemovalChance * EULxActorDisintegratedMod + DebugPrint "%n has been disintegrated/gooified, setting removal chance to %.2f%%" rNPC fRemovalChance + endif + + set iCount to rItem.GetRefCount + + DebugPrint "Removal chance of %n: %g vs total in corpse %g" rBase fRemovalChance iCount + + if iCount > 1 + if iType != 41 && rBase != Caps001 ; do not apply random removal to ammo and caps + set fRemovalChance to Rand 0 fRemovalChance + endif + set fCount to iCount * ( fRemovalChance / 100 ) + if Ceil fCount - fCount > 0.5 ; Number rounding implementation + set iCount to Floor fCount + else + set iCount to Ceil fCount + endif + DebugPrint "Removing %g of %n, removal chance %g." iCount rBase fRemovalChance + elseif GetRandomPercent >= fRemovalChance + DebugPrint "%n was skipped." rBase + continue + endif + + if iCount > 0 + ar_Append itemsToRemoveRefs rBase + ar_Append itemsToRemoveCounts iCount + else + DebugPrint "%n was skipped." rBase + endif + loop + + printd "SCAN COMPLETE!" + + ; NB: The game will CTD if we remove items in the main loop. + + set i to 0 + set iLimit to ar_size itemsToRemoveRefs + + while i < iLimit + let rBase := itemsToRemoveRefs[i] + let iCount := itemsToRemoveCounts[i] + DebugPrint "Removing %g of %n from %n" iCount rBase rNPC + rNPC.removeItem rBase iCount 1 + set i to i + 1 + loop + + let itemsToRemoveRefs := ar_null + let itemsToRemoveCounts := ar_null + + printd "Corpse loot reduction block exited." + +end diff --git a/src/EULxINILoadSettings.gek b/src/EULxINILoadSettings.gek new file mode 100644 index 0000000..657b69a --- /dev/null +++ b/src/EULxINILoadSettings.gek @@ -0,0 +1,70 @@ +scn EULxINILoadSettings + +string_var sFile + +begin function {} + + if FileExists "config\Unfound Loot.ini" == 0 + MessageBoxEx "File Data\Config\Unfound Loot.ini was not found!" + return + endif + + if GetINIFloat "General:Saved" "Unfound Loot.ini" == 0 + MessageBoxEx "Unfound Loot.ini was not saved through the panel, won't reload." + return + endif + + let sFile := "Unfound Loot.ini" + + ; General + + set EULxMaxItemValue to GetINIFloat "General:MaxItemValue" $sFile + set EULxLuckModifier to GetINIFloat "General:LuckModifier" $sFile + set EULxMaxWeaponCondition to GetINIFloat "General:MaxWeaponCondition" $sFile + set EULxMaxArmorCondition to GetINIFloat "General:MaxArmorCondition" $sFile + + ; World + + set EULxWorldLootRemovalEnabled to GetINIFloat "World:LootRemovalEnabled" $sFile + set EULxWorldBaseRemovalChance to GetINIFloat "World:BaseRemovalChance" $sFile + set EULxWorldSkipLocked to GetINIFloat "World:SkipLocked" $sFile + + set EULxWorldWeaponRemovalMod to GetINIFloat "World:WeaponRemovalMod" $sFile + set EULxWorldAmmoRemovalMod to GetINIFloat "World:AmmoRemovalMod" $sFile + set EULxWorldArmorRemovalMod to GetINIFloat "World:ArmorRemovalMod" $sFile + set EULxWorldCurrencyRemovalMod to GetINIFloat "World:CurrencyRemovalMod" $sFile + set EULxWorldAlcoholRemovalMod to GetINIFloat "World:AlcoholRemovalMod" $sFile + set EULxWorldChemsRemovalMod to GetINIFloat "World:ChemsRemovalMod" $sFile + set EULxWorldMedsRemovalMod to GetINIFloat "World:MedsRemovalMod" $sFile + set EULxWorldFoodRemovalMod to GetINIFloat "World:FoodRemovalMod" $sFile + set EULxWorldMiscRemovalMod to GetINIFloat "World:MiscRemovalMod" $sFile + + ; Actors + + set EULxActorLootRemovalEnabled to GetINIFloat "Actors:LootRemovalEnabled" $sFile + set EULxActorBaseRemovalChance to GetINIFloat "Actors:BaseRemovalChance" $sFile + set EULxActorRemoveEquippedWeapons to GetINIFloat "Actors:RemoveEquippedWeapons" $sFile + set EULxActorBreakOnDecapitation to GetINIFloat "Actors:BreakOnDecapitation" $sFile + + set EULxActorWeaponRemovalMod to GetINIFloat "Actors:WeaponRemovalMod" $sFile + set EULxActorAmmoRemovalMod to GetINIFloat "Actors:AmmoRemovalMod" $sFile + set EULxActorArmorRemovalMod to GetINIFloat "Actors:ArmorRemovalMod" $sFile + set EULxActorCurrencyRemovalMod to GetINIFloat "Actors:CurrencyRemovalMod" $sFile + set EULxActorAlcoholRemovalMod to GetINIFloat "Actors:AlcoholRemovalMod" $sFile + set EULxActorChemsRemovalMod to GetINIFloat "Actors:ChemsRemovalMod" $sFile + set EULxActorMedsRemovalMod to GetINIFloat "Actors:MedsRemovalMod" $sFile + set EULxActorFoodRemovalMod to GetINIFloat "Actors:FoodRemovalMod" $sFile + set EULxActorMiscRemovalMod to GetINIFloat "Actors:MiscRemovalMod" $sFile + + set EULxActorAnimalMod to GetINIFloat "Actors:AnimalMod" $sFile + set EULxActorRobotMod to GetINIFloat "Actors:RobotMod" $sFile + set EULxActorFeralGhoulMod to GetINIFloat "Actors:FeralGhoulMod" $sFile + set EULxActorHumanMod to GetINIFloat "Actors:HumanMod" $sFile + set EULxActorGhoulMod to GetINIFloat "Actors:GhoulMod" $sFile + set EULxActorSupermutantMod to GetINIFloat "Actors:SupermutantMod" $sFile + + set EULxActorDisintegratedMod to GetINIFloat "Actors:DisintegratedMod" $sFile + + sv_destruct sFile + +end diff --git a/src/EULxINISaveSettings.gek b/src/EULxINISaveSettings.gek new file mode 100644 index 0000000..64ecbbe --- /dev/null +++ b/src/EULxINISaveSettings.gek @@ -0,0 +1,64 @@ +scn EULxINISaveSettings + +string_var sFile + +begin function {} + + let sFile := "Unfound Loot.ini" + + ; Control mark + + SetINIFloat "General:Saved" 1 $sFile + + ; General + + SetINIFloat "General:MaxItemValue" EULxMaxItemValue $sFile + SetINIFloat "General:LuckModifier" EULxLuckModifier $sFile + SetINIFloat "General:MaxWeaponCondition" EULxMaxWeaponCondition $sFile + SetINIFloat "General:MaxArmorCondition" EULxMaxArmorCondition $sFile + + ; World + + SetINIFloat "World:LootRemovalEnabled" EULxWorldLootRemovalEnabled $sFile + SetINIFloat "World:BaseRemovalChance" EULxWorldBaseRemovalChance $sFile + SetINIFloat "World:SkipLocked" EULxWorldSkipLocked $sFile + + SetINIFloat "World:WeaponRemovalMod" EULxWorldWeaponRemovalMod $sFile + SetINIFloat "World:AmmoRemovalMod" EULxWorldAmmoRemovalMod $sFile + SetINIFloat "World:ArmorRemovalMod" EULxWorldArmorRemovalMod $sFile + SetINIFloat "World:CurrencyRemovalMod" EULxWorldCurrencyRemovalMod $sFile + SetINIFloat "World:AlcoholRemovalMod" EULxWorldAlcoholRemovalMod $sFile + SetINIFloat "World:ChemsRemovalMod" EULxWorldChemsRemovalMod $sFile + SetINIFloat "World:MedsRemovalMod" EULxWorldMedsRemovalMod $sFile + SetINIFloat "World:FoodRemovalMod" EULxWorldFoodRemovalMod $sFile + SetINIFloat "World:MiscRemovalMod" EULxWorldMiscRemovalMod $sFile + + ; Actors + + SetINIFloat "Actors:LootRemovalEnabled" EULxActorLootRemovalEnabled $sFile + SetINIFloat "Actors:BaseRemovalChance" EULxActorBaseRemovalChance $sFile + SetINIFloat "Actors:RemoveEquippedWeapons" EULxActorRemoveEquippedWeapons $sFile + SetINIFloat "Actors:BreakOnDecapitation" EULxActorBreakOnDecapitation $sFile + + SetINIFloat "Actors:WeaponRemovalMod" EULxActorWeaponRemovalMod $sFile + SetINIFloat "Actors:AmmoRemovalMod" EULxActorAmmoRemovalMod $sFile + SetINIFloat "Actors:ArmorRemovalMod" EULxActorArmorRemovalMod $sFile + SetINIFloat "Actors:CurrencyRemovalMod" EULxActorCurrencyRemovalMod $sFile + SetINIFloat "Actors:AlcoholRemovalMod" EULxActorAlcoholRemovalMod $sFile + SetINIFloat "Actors:ChemsRemovalMod" EULxActorChemsRemovalMod $sFile + SetINIFloat "Actors:MedsRemovalMod" EULxActorMedsRemovalMod $sFile + SetINIFloat "Actors:FoodRemovalMod" EULxActorFoodRemovalMod $sFile + SetINIFloat "Actors:MiscRemovalMod" EULxActorMiscRemovalMod $sFile + + SetINIFloat "Actors:AnimalMod" EULxActorAnimalMod $sFile + SetINIFloat "Actors:RobotMod" EULxActorRobotMod $sFile + SetINIFloat "Actors:FeralGhoulMod" EULxActorFeralGhoulMod $sFile + SetINIFloat "Actors:HumanMod" EULxActorHumanMod $sFile + SetINIFloat "Actors:GhoulMod" EULxActorGhoulMod $sFile + SetINIFloat "Actors:SupermutantMod" EULxActorSupermutantMod $sFile + + SetINIFloat "Actors:DisintegratedMod" EULxActorDisintegratedMod $sFile + + sv_destruct sFile + +end diff --git a/src/EULxMCMAddElement.gek b/src/EULxMCMAddElement.gek new file mode 100644 index 0000000..09e42f8 --- /dev/null +++ b/src/EULxMCMAddElement.gek @@ -0,0 +1,50 @@ +scn EULxMCMAddElement + +int i +int iSlot +string_var sTitle +float fType +float fValue + +begin _function { fType, sTitle, fValue } + + set i to 36 + while i > 0 + if 1 == GetMCMFloat 1 i "_enable" + set iSlot to i + 1 + break + endif + set i to i - 1 + loop + + if iSlot == 0 + set iSlot to 1 + endif + + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_enable" 1 + SetUIString "StartMenu/MCM/*:1/*:" + $iSlot + "/_title" $sTitle + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_type" fType + + if fType == 2 || fType == 4 || fType == 5 + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_value" fValue + elseif fType == 2.5 + SetUIStringEx "StartMenu/MCM/*:1/*:" + $iSlot + "/value/*:1/string" "%.1f" fValue + elseif fType == 0 + + if sTitle + ; header font + if 0 < GetUIFloat "HUDMainMenu\_DUIF3" ; DarnifiedUI + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_altFont" 3 + else + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_altFont" 1 + endif + endif + + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_highlight" 0 + SetUIFloat "StartMenu/MCM/*:1/*:" + $iSlot + "/_brightness" 180 + + endif + + sv_destruct sTitle + +end diff --git a/src/EULxMCMAddScale.gek b/src/EULxMCMAddScale.gek new file mode 100644 index 0000000..5fa3483 --- /dev/null +++ b/src/EULxMCMAddScale.gek @@ -0,0 +1,24 @@ +scn EULxMCMAddScale + +string_var sTitle +string_var sSuffix +float fValue +float fDecimals +float fValueMin +float fValueMax +float fValueIncrement + +begin function { sTitle, fValue, sSuffix, fValueMin, fValueMax, fDecimals, fValueIncrement } + + SetUIString "StartMenu/MCM/*:2/_title" $sTitle + SetUIString "StartMenu/MCM/*:2/_suffixText" $sSuffix + SetUIFloat "StartMenu/MCM/_Value" fValue + SetUIFloat "StartMenu/MCM/_ValueDecimal" fDecimals + SetUIFloat "StartMenu/MCM/_ValueIncrement" fValueIncrement + SetUIFloat "StartMenu/MCM/_ValueMax" fValueMax + SetUIFloat "StartMenu/MCM/_ValueMin" fValueMin + + sv_destruct sTitle + sv_destruct sSuffix + +end diff --git a/src/EULxOnCellEnter.gek b/src/EULxOnCellEnter.gek new file mode 100644 index 0000000..35a1e52 --- /dev/null +++ b/src/EULxOnCellEnter.gek @@ -0,0 +1,32 @@ +scn EULxOnCellEnter + +ref rCell +array_var aCells +int i + +begin function { rCell } + + if GetCellFlag rCell 0 ; interior + if IsCellVisited rCell + return + endif + call EULxOnSeen rCell + else + let aCells := GetBufferedCells 0 + let i := ar_size aCells + while i > 0 + let i -= 1 + let rCell := aCells[i] + if IsCellVisited rCell == 0 + if RefMapGetFlt "*v" rCell == 0 + RefMapSetFlt "*v" 1 rCell + call EULxOnSeen rCell + endif + elseif RefMapGetType "*v" rCell + RefMapErase "*v" rCell + endif + loop + let aCells := ar_null + endif + +end diff --git a/src/EULxOnDisintegration.gek b/src/EULxOnDisintegration.gek new file mode 100644 index 0000000..4b3828a --- /dev/null +++ b/src/EULxOnDisintegration.gek @@ -0,0 +1,15 @@ +scn EULxOnDisintegration + +ref rActor +ref rBaseEffect + +begin function { rActor, rBaseEffect } + + if rActor == playerRef + return + endif + + DebugPrint "%n has been disintegrated/gooified, making second pass" rActor + call EULxDelootifyNPC rActor 1 + +end diff --git a/src/EULxOnDrop.gek b/src/EULxOnDrop.gek new file mode 100644 index 0000000..5a82171 --- /dev/null +++ b/src/EULxOnDrop.gek @@ -0,0 +1,27 @@ +scn EULxOnDrop + +ref rDropper +ref rItem +int iType + +begin function { rDropper, rItem } + + if rDropper == playerRef + return + endif + + if rDropper.GetDead ; items, dropped on death, handled in OnDying + return + endif + + DebugPrint "%n dropped %n being alive, skipping removal." rDropper rItem + + set iType to rItem.GetType + + if iType != 40 && iType != 24 + return + endif + + call EULxReduceItemHealth playerRef rItem + +end diff --git a/src/EULxOnDying.gek b/src/EULxOnDying.gek new file mode 100644 index 0000000..0456d6f --- /dev/null +++ b/src/EULxOnDying.gek @@ -0,0 +1,65 @@ +scn EULxOnDying + +ref rActor +ref rTemp +int i +int iType +float fBasefRemovalChance +float fRemovalChance +array_var aItems + +begin function { rActor } + + if EULxActorLootRemovalEnabled == 0 || rActor == playerRef + return + endif + + if rActor.GetPlayerTeammate + DebugPrint "%n is a teammate, skipping" rActor + return + endif + + DebugPrint "%n has been killed" rActor + + call EULxDelootifyNPC rActor 0 + + let aItems := rActor.GetDroppedRefs + set i to ar_size aItems + + if i > 0 + + set fBasefRemovalChance to call EULxCalculateBaseRemovalChance rActor + + while i > 0 + set i to i - 1 + let rTemp := aItems[i] + + if EULxActorRemoveEquippedWeapons == 0 + call EULxReduceItemHealth playerRef rTemp + continue + endif + + ; Normally, NPCs do not drop anything besides weapons, we skip other types for now + if rTemp.GetType != 40 + continue + endif + + set fRemovalChance to call EULxProbabilityMultiplierFUNCTION fBasefRemovalChance EULxActorWeaponRemovalMod + set fRemovalChance to fRemovalChance * 100 + + DebugPrint "%n dropped %n, removal chance %.2f%%" rActor rTemp fRemovalChance + + if GetRandomPercent >= fRemovalChance + call EULxReduceItemHealth playerRef rTemp + else + DebugPrint "Disabling dropped %n" rTemp + rTemp.disable + rTemp.MarkForDelete + endif + loop + + elseif i == 0 + let aItems := ar_null + endif + +end diff --git a/src/EULxOnGameLoad.gek b/src/EULxOnGameLoad.gek new file mode 100644 index 0000000..b7863dc --- /dev/null +++ b/src/EULxOnGameLoad.gek @@ -0,0 +1,44 @@ +scn EULxOnGameLoad + +; NB: the print function is silent in the PostLoadGame event handlers + +int iSuccess + +begin function { iSuccess } + + ; Get main DLCs' indexes for better detection of mod-added items + set EULxDLCIndex to 0 + + if IsModLoaded "TaleOfTwoWastelands.esm" + set EULxDLCIndex to GetModIndex "TaleOfTwoWastelands.esm" + elseif IsModLoaded "GunRunnersArsenal.esm" + set EULxDLCIndex to GetModIndex "GunRunnersArsenal.esm" + elseif IsModLoaded "LonesomeRoad.esm" + set EULxDLCIndex to GetModIndex "LonesomeRoad.esm" + elseif IsModLoaded "OldWorldBlues.esm" + set EULxDLCIndex to GetModIndex "OldWorldBlues.esm" + elseif IsModLoaded "HonestHearts.esm" + set EULxDLCIndex to GetModIndex "HonestHearts.esm" + elseif IsModLoaded "DeadMoney.esm" + set EULxDLCIndex to GetModIndex "DeadMoney.esm" + endif + + SetGameMainLoopCallback EULxOnGameMode 1 3 1 + + RefMapDestroy "*v" + + if EULxVersion < 3 + set EULxVersion to 3 + + set EULxActorDisintegratedMod to 2 + + if EULxSaveToINI + if FileExists "config\Unfound Loot.ini" + if GetINIFloat "General:Saved" "Unfound Loot.ini" + SetINIFloat "Actors:DisintegratedMod" EULxActorDisintegratedMod "Unfound Loot.ini" + endif + endif + endif + endif + +end diff --git a/src/EULxOnGameMode.gek b/src/EULxOnGameMode.gek new file mode 100644 index 0000000..6e8a1bc --- /dev/null +++ b/src/EULxOnGameMode.gek @@ -0,0 +1,18 @@ +scn EULxOnGameMode + +begin function {} + + SetGameMainLoopCallback EULxOnGameMode 0 + + SetJohnnyOnDyingEventHandler EULxActorLootRemovalEnabled EULxOnDying 0 + SetJohnnyOnLimbGoneEventHandler EULxActorBreakOnDecapitation EULxOnLimbGone 0 + + if IsModLoaded "JIP MiniMap.esp" == 0 + SetJohnnySeenDataEventHandler EULxWorldLootRemovalEnabled EULxOnSeen 0 + endif + + if GetGameRestarted + SetEventHandler "OnMagicEffectHit" EULxOnDisintegration "second"::EULxDisintegrationEffects + endif + +end diff --git a/src/EULxOnLimbGone.gek b/src/EULxOnLimbGone.gek new file mode 100644 index 0000000..e4d04f9 --- /dev/null +++ b/src/EULxOnLimbGone.gek @@ -0,0 +1,52 @@ +scn EULxOnLimbGone + +ref rActor +int iLimb +ref rItem + +begin function { rActor, iLimb } + + if EULxActorBreakOnDecapitation == 0 + SetJohnnyOnLimbGoneEventHandler 0 EULxOnLimbGone 0 + return + endif + + if rActor.GetIsCreature + return + endif + + if iLimb == 1 + + set rItem to rActor.GetEquippedItemRef 9 ; headband + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 10 ; hat + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 11 ; eyeglasses + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 14 ; mask + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + set rItem to rActor.GetEquippedItemRef 16 ; mouth object + if rItem + DebugPrint "%n has been decapitated, setting %n condition to 0" rActor rItem + rItem.SetItemRefCurrentHealth 0 + endif + + endif + +end diff --git a/src/EULxOnNewGame.gek b/src/EULxOnNewGame.gek new file mode 100644 index 0000000..7bc4887 --- /dev/null +++ b/src/EULxOnNewGame.gek @@ -0,0 +1,14 @@ +scn EULxOnNewGame + +begin function {} + + call EULxOnGameLoad 1 + + if FileExists "config\Unfound Loot.ini" + if GetINIFloat "General:Saved" "Unfound Loot.ini" + call EULxINILoadSettings + set EULxSaveToINI to 1 + endif + endif + +end diff --git a/src/EULxOnPause.gek b/src/EULxOnPause.gek new file mode 100644 index 0000000..2d7fa49 --- /dev/null +++ b/src/EULxOnPause.gek @@ -0,0 +1,14 @@ +scn EULxOnPause + +int iMenuMode + +begin function { iMenuMode } + + printd "Unfound Loot: Starting MCM quest" + + ; Safeguard from rogue value changers + SetValue EULxMCMMiscItem 23370 + + StartQuest EULxQuest + +end diff --git a/src/EULxOnSeen.gek b/src/EULxOnSeen.gek new file mode 100644 index 0000000..9fdc4d1 --- /dev/null +++ b/src/EULxOnSeen.gek @@ -0,0 +1,106 @@ +scn EULxOnSeen + +ref rCell +ref rTemp +ref rItem +int iTemp +int iPrecalc +int bSkip + +begin function { rCell } + + if EULxWorldLootRemovalEnabled == 0 + return + endif + + if GetOwnerOfCell rCell + DebugPrint "%n is an owned cell, skipping." rCell + return + endif + + if ListGetFormIndex EULxProtectedCells rCell != -1 + DebugPrint "%n is a protected cell, skipping." rCell + return + endif + + ; Splitting this into separate UDFs is nice and all, but not very performance-friendly. + ; Instead, we do most basic checks here, and all the hard work in separate functions. + + + ; Do not call EULxDelootifyCellItems if the cell has no items + + if GetFirstRefInCell rCell 201 0 0 + set iPrecalc to 1 + call EULxPrecalculateRemovalChance + call EULxDelootifyCellItems rCell + endif + + + DebugPrint "Scanning %n (%i) for containers" rCell rCell + + set iTemp to GetSourceModIndex rCell + + set rTemp to GetFirstRefInCell rCell 27 0 0 + + while rTemp + + set bSkip to 0 + + if rTemp.GetDisabled + DebugPrint "%n is disabled, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.IsPersistent + DebugPrint "%n is persistent, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.GetContainerInventoryCount == 0 + DebugPrint "%n is empty, skipping." rTemp + set rTemp to GetNextRef + continue + elseif rTemp.GetLocked && EULxWorldSkipLocked + DebugPrint "%n is locked, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.HasScriptBlock 2 ; OnActivate + DebugPrint "%n is scripted, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.GetReferenceFlag 33554432 + DebugPrint "%n has the No AI Acquire flag, skipping loot reduction." rTemp + set bSkip to 1 + elseif rTemp.GetOwner + DebugPrint "%n is owned, skipping loot reduction." rTemp + set bSkip to 1 + elseif eval 0 < ar_size (rTemp.GetAllItems 49) + DebugPrint "%n contains a note, skipping loot reduction." rTemp + set bSkip to 1 + endif + + if bSkip == 0 + if GetSourceModIndex rTemp != iTemp + DebugPrint "%n is a mod-added container, skipping." rTemp + set bSkip to 1 + endif + endif + + if bSkip + foreach rItem <- rTemp + if rItem.GetType == 24 || rItem.GetType == 40 + call EULxReduceItemHealth rTemp rItem + endif + loop + set rTemp to GetNextRef + continue + endif + + if iPrecalc == 0 + set iPrecalc to 1 + call EULxPrecalculateRemovalChance + endif + + call EULxDelootifyContainer rCell rTemp + + set rTemp to GetNextRef + + loop + +end diff --git a/src/EULxPrecalculateRemovalChance.gek b/src/EULxPrecalculateRemovalChance.gek new file mode 100644 index 0000000..61f52cb --- /dev/null +++ b/src/EULxPrecalculateRemovalChance.gek @@ -0,0 +1,41 @@ +scn EULxPrecalculateRemovalChance + +float fTemp + +begin function {} + + set fTemp to (( EULxLuckModifier / 10 ) * playerRef.getAV luck) / 100 + set fTemp to 1 - fTemp + set fTemp to EULxWorldBaseRemovalChance * fTemp + set fTemp to fTemp / 100 + + ;DebugPrint "Base removal chance %g, luck effect %g%% - new base removal chance %g%%" EULxWorldBaseRemovalChance EULxLuckModifier fTemp + + set EULxCalcArmorRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldArmorRemovalMod + set EULxCalcArmorRemovalChance to EULxCalcArmorRemovalChance * 100 + + set EULxCalcMiscRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldMiscRemovalMod + set EULxCalcMiscRemovalChance to EULxCalcMiscRemovalChance * 100 + + set EULxCalcWeaponRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldWeaponRemovalMod + set EULxCalcWeaponRemovalChance to EULxCalcWeaponRemovalChance * 100 + + set EULxCalcAmmoRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldAmmoRemovalMod + set EULxCalcAmmoRemovalChance to EULxCalcAmmoRemovalChance * 100 + + set EULxCalcCurrencyRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldCurrencyRemovalMod + set EULxCalcCurrencyRemovalChance to EULxCalcCurrencyRemovalChance * 100 + + set EULxCalcChemsRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldChemsRemovalMod + set EULxCalcChemsRemovalChance to EULxCalcChemsRemovalChance * 100 + + set EULxCalcMedsRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldMedsRemovalMod + set EULxCalcMedsRemovalChance to EULxCalcMedsRemovalChance * 100 + + set EULxCalcAlcoholRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldAlcoholRemovalMod + set EULxCalcAlcoholRemovalChance to EULxCalcAlcoholRemovalChance * 100 + + set EULxCalcFoodRemovalChance to call EULxProbabilityMultiplierFUNCTION fTemp EULxWorldFoodRemovalMod + set EULxCalcFoodRemovalChance to EULxCalcFoodRemovalChance * 100 + +end diff --git a/src/EULxPresetSetterFUNCTION.gek b/src/EULxPresetSetterFUNCTION.gek new file mode 100644 index 0000000..c1b91dc --- /dev/null +++ b/src/EULxPresetSetterFUNCTION.gek @@ -0,0 +1,164 @@ +scn EULxPresetSetterFUNCTION + +int iPreset ; 1=balanced, 2=hardcore, 3=realistic +int bAll + +begin function { iPreset, bAll } + + printToConsole "Unfound Loot: Setting up preset %g" iPreset + + if bAll || EULxQuest.iSubMenu == 1 + + ; General + + set EULxMaxItemValue to 5000 ; excludes most uniques + set EULxMaxWeaponCondition to 40 ; 40% condition + set EULxMaxArmorCondition to 40 ; 40% condition + set EULxLuckModifier to 10 ; 10% luck effect + + endif + + if bAll || EULxQuest.iSubMenu == 2 + + ; World-placed Items + + set EULxWorldLootRemovalEnabled to 1 + set EULxWorldBaseRemovalChance to 85 + set EULxWorldSkipLocked to 1 + + set EULxWorldWeaponRemovalMod to 1.0 + set EULxWorldArmorRemovalMod to 0.5 ; less chance of removing rad suits and such + + set EULxWorldAlcoholRemovalMod to 1.0 + set EULxWorldChemsRemovalMod to 1.0 + set EULxWorldMedsRemovalMod to 1.0 + set EULxWorldFoodRemovalMod to 1.3 + + set EULxWorldMiscRemovalMod to .60 ; keep interiors pretty + set EULxWorldAmmoRemovalMod to 1.0 + set EULxWorldCurrencyRemovalMod to 1.2 + + endif + + if bAll || EULxQuest.iSubMenu == 3 + + ; Corpse Loot + + set EULxActorLootRemovalEnabled to 1 + set EULxActorBaseRemovalChance to 80 + set EULxActorSkillMod to 1.0 ; from 95/90 to 90/85 percent removal at 100 skill (robot and animal only) + set EULxActorAnimalMod to 0.6 ; animals usually have stuff on them + set EULxActorRobotMod to 1.0 + set EULxActorFeralGhoulMod to 1.0 + set EULxActorHumanMod to 1.0 + set EULxActorGhoulMod to 1.0 + set EULxActorSupermutantMod to 1.0 + set EULxActorWeaponRemovalMod to 1.0 + set EULxActorArmorRemovalMod to 1.0 + + set EULxActorAlcoholRemovalMod to 1.0 + set EULxActorChemsRemovalMod to 1.0 + set EULxActorMedsRemovalMod to 1.0 + set EULxActorFoodRemovalMod to 1.0 + + set EULxActorMiscRemovalMod to 1.0 + set EULxActorCurrencyRemovalMod to 0.8 + set EULxActorAmmoRemovalMod to 0.3 ; leave a little more ammo for the player + set EULxActorRemoveEquippedWeapons to 0 + set EULxActorBreakOnDecapitation to 1 + set EULxActorDisintegratedMod to 2 + + endif + + if bAll == 0 + return + endif + + if iPreset == 1 ; Balanced + + set EULxMaxItemValue to 3500 + set EULxMaxWeaponCondition to 30 + set EULxMaxArmorCondition to 30 + + set EULxWorldBaseRemovalChance to 95 + set EULxWorldArmorRemovalMod to 1.0 + set EULxWorldMiscRemovalMod to .80 ;sparse interiors + set EULxWorldAmmoRemovalMod to 2.0 ;too much ammo as is + set EULxWorldCurrencyRemovalMod to 1.0 + + set EULxWorldAlcoholRemovalMod to 1.0 + set EULxWorldChemsRemovalMod to 1.0 + set EULxWorldMedsRemovalMod to 1.0 + set EULxWorldFoodRemovalMod to 1.3 + + set EULxActorBaseRemovalChance to 95 + set EULxActorAnimalMod to 0.75 ;sparse animals + set EULxActorAmmoRemovalMod to 0.4 + set EULxActorCurrencyRemovalMod to 1.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.8 + + elseif iPreset == 2 ; Hardcore + + set EULxMaxItemValue to 9999 ; remove almost anything + set EULxMaxWeaponCondition to 20 + set EULxMaxArmorCondition to 20 + set EULxLuckModifier to 0 + + set EULxWorldSkipLocked to 0 + + set EULxWorldBaseRemovalChance to 95 + set EULxWorldWeaponRemovalMod to 1.5 + set EULxWorldArmorRemovalMod to 0.6 + set EULxWorldMiscRemovalMod to 0.33 ; junk doesnt get picked up + set EULxWorldAmmoRemovalMod to 1.3 + set EULxWorldCurrencyRemovalMod to 1.5 + + set EULxWorldAlcoholRemovalMod to 1.5 + set EULxWorldChemsRemovalMod to 1.2 + set EULxWorldMedsRemovalMod to 1.2 + set EULxWorldFoodRemovalMod to 1.5 ; + + set EULxActorBaseRemovalChance to 90 + set EULxActorAnimalMod to 0.1 ;animals usually have stuff on them + set EULxActorRobotMod to 0.5 + set EULxActorFeralGhoulMod to 2.0 + set EULxActorMiscRemovalMod to 2.0 + set EULxActorCurrencyRemovalMod to 2.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.2 + + elseif iPreset == 3 ; Realistic + + set EULxMaxWeaponCondition to 35 + set EULxMaxArmorCondition to 35 + + set EULxWorldBaseRemovalChance to 66 + set EULxWorldWeaponRemovalMod to 1.5 + set EULxWorldCurrencyRemovalMod to 2.0 + + set EULxWorldAlcoholRemovalMod to 2.0 + set EULxWorldChemsRemovalMod to 1.5 + set EULxWorldMedsRemovalMod to 1.2 + set EULxWorldFoodRemovalMod to 2.0 + + set EULxActorBaseRemovalChance to 66 + set EULxActorAnimalMod to 0.1 ;animals usually have stuff on them + set EULxActorCurrencyRemovalMod to 2.0 + + set EULxActorAlcoholRemovalMod to EULxWorldAlcoholRemovalMod + set EULxActorChemsRemovalMod to EULxWorldChemsRemovalMod + set EULxActorMedsRemovalMod to EULxWorldMedsRemovalMod + set EULxActorFoodRemovalMod to 0.2 + + endif + + call EULxPrecalculateRemovalChance + +end \ No newline at end of file diff --git a/src/EULxProbabilityMultiplierFUNCTION.gek b/src/EULxProbabilityMultiplierFUNCTION.gek new file mode 100644 index 0000000..11e4f2a --- /dev/null +++ b/src/EULxProbabilityMultiplierFUNCTION.gek @@ -0,0 +1,23 @@ +scn EULxProbabilityMultiplierFUNCTION + +float fBaseProbability +float fMultiplier +float fTemp +float fBaseProbabilityOfNotHappening + +begin function { fBaseProbability, fMultiplier } + + set fBaseProbabilityOfNotHappening to 1 - fBaseProbability + + if fMultiplier < 1 + set fTemp to fBaseProbability * fMultiplier + else + set fTemp to pow fBaseProbabilityOfNotHappening fMultiplier + set fTemp to 1 - fTemp + endif + + ;DebugPrint "ProbabilityMultiplierFunction called, prob %.4f mult: %.4f, returning %.4f" fBaseProbability fMultiplier fTemp + + setFunctionValue fTemp + +end diff --git a/src/EULxQuestScript.gek b/src/EULxQuestScript.gek new file mode 100644 index 0000000..34543d7 --- /dev/null +++ b/src/EULxQuestScript.gek @@ -0,0 +1,698 @@ +scn EULxQuestScript + +int iMouseover +int iOption +int iSubMenu +float fValue +ref rTemp + +begin GameMode + StopQuest EULxQuest ; No zombies allowed! +end + +begin MenuMode 4 + + StopQuest EULxQuest + + if GetGameRestarted == 0 + return + endif + + if GetPluginVersion "JohnnyGuitarNVSE" < 305 + print "Unfound Loot requires JohnnyGuitar NVSE 3.05+" + MessageBoxEx "Unfound Loot requires JohnnyGuitar NVSE 3.05+" + endif + + if GetPluginVersion "JIP NVSE Plugin" < 55.45 + print "Unfound Loot requires JIP LN NVSE 55.45+" + MessageBoxEx "Unfound Loot requires JIP LN NVSE 55.45+" + endif + + if IsModLoaded "The Mod Configuration Menu.esp" + + set fValue to GetModIndex "The Mod Configuration Menu.esp" + set rTemp to BuildRef fValue 2790 + ListAddForm rTemp EULxMCMMiscItem + + SetOnMenuOpenEventHandler EULxOnPause 1 1013 ; start MCM quest on pause + + else + print "Unfound Loot: MCM not found" + endif + + if IsModLoaded "DeadMoney.esm" + set rTemp to StringToRef "DeadMoney.esm:29E4" ; Sierra Madre Vault + ListAddForm EULxProtectedCells rTemp + endif + + if IsModLoaded "Fallout3.esm" + set rTemp to StringToRef "Fallout3.esm:1B56C" ; TaftTunnel01 + ListAddForm EULxProtectedCells rTemp + set rTemp to StringToRef "Fallout3.esm:CAFDF" ; Gold Ribbon Grocers + ListAddForm EULxProtectedCells rTemp + endif + + set rTemp to 0 + + SetEventHandler "NewGame" EULxOnNewGame + SetEventHandler "PostLoadGame" EULxOnGameLoad + SetEventHandler "OnDrop" EULxOnDrop + + if IsModLoaded "JIP MiniMap.esp" + print "Unfound Loot: JIP MiniMap detected, running in compatibility mode." + SetEventHandler "OnCellEnter" EULxOnCellEnter + endif + + call EULxWhitelistDeathItems + +end + +begin MenuMode 1013 + + if GetUIFloat "StartMenu/MCM/_ActiveMod" != GetSelfModIndex + return + endif + + if GetUIFloat "StartMenu/MCM/_ActiveMenu" != GetValue EULxMCMMiscItem + return + endif + + set iOption to GetUIFloat "StartMenu/MCM/_ActiveOption" + set fValue to GetUIFloat "StartMenu/MCM/_Value" + + if GetUIFloat "StartMenu/MCM/*:5/SubMenu1/_enable" == 0 + SetUIFloat "StartMenu/MCM/_ActiveSubMenu" 1 + + SetUIFloat "StartMenu/MCM/*:5/SubMenu1/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu1/text/string" "General Options" + SetUIString "StartMenu/MCM/*:8/SubTitle1/string" "General Options" + + SetUIFloat "StartMenu/MCM/*:5/SubMenu2/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu2/text/string" "World Items" + SetUIString "StartMenu/MCM/*:8/SubTitle2/string" "World Items Reduction" + + SetUIFloat "StartMenu/MCM/*:5/SubMenu3/_enable" 1 + SetUIString "StartMenu/MCM/*:5/SubMenu3/text/string" "Corpse Loot" + SetUIString "StartMenu/MCM/*:8/SubTitle3/string" "Corpse Loot Reduction" + endif + + set iSubMenu to GetUIFloat "StartMenu/MCM/_ActiveSubMenu" + + if GetUIFloat "StartMenu/MCM/_Reset" ; 1 - RESET + SetUIFloat "StartMenu/MCM/_Reset" 0 ; don't run twice + + SetMCMFloatMass 1 1 36 "_enable" 0 + + if iSubMenu == 1 + + SetMCMFloat 1 0 "_columns" 1 + + call EULxMCMAddElement 2 "Max item value" EULxMaxItemValue + call EULxMCMAddElement 2 "Luck effect on base removal chance" EULxLuckModifier + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 2 "Max weapon condition" EULxMaxWeaponCondition + call EULxMCMAddElement 2 "Max armor condition" EULxMaxArmorCondition + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 1 "Select preset (overwrites ALL options)" 0 + call EULxMCMAddElement 1 "Reset all settings" 0 + call EULxMCMAddElement 5 "Enable debug mode for the session" GetDebugMode + + call EULxMCMAddElement 0 "" 0 + + if FileExists "config\Unfound Loot.ini" + call EULxMCMAddElement 0 "Unfound Loot.ini" 0 + call EULxMCMAddElement 5 "Save settings to INI" EULxSaveToINI + call EULxMCMAddElement 1 "Reload settings from INI" 0 + endif + + elseif iSubMenu == 2 + + SetMCMFloat 1 0 "_columns" 2 + + call EULxMCMAddElement 4 "Enabled" EULxWorldLootRemovalEnabled + call EULxMCMAddElement 2 "Base removal chance" EULxWorldBaseRemovalChance + call EULxMCMAddElement 5 "Skip locked containers" EULxWorldSkipLocked + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Weapons" EULxWorldWeaponRemovalMod + call EULxMCMAddElement 2.5 "Ammo" EULxWorldAmmoRemovalMod + call EULxMCMAddElement 2.5 "Apparel" EULxWorldArmorRemovalMod + call EULxMCMAddElement 2.5 "Currencies" EULxWorldCurrencyRemovalMod + call EULxMCMAddElement 2.5 "Alcohol" EULxWorldAlcoholRemovalMod + call EULxMCMAddElement 2.5 "Chems" EULxWorldChemsRemovalMod + call EULxMCMAddElement 2.5 "Meds" EULxWorldMedsRemovalMod + call EULxMCMAddElement 2.5 "Food" EULxWorldFoodRemovalMod + call EULxMCMAddElement 2.5 "Misc items" EULxWorldMiscRemovalMod + + elseif iSubMenu == 3 + + SetMCMFloat 1 0 "_columns" 2 + + call EULxMCMAddElement 4 "Enabled" EULxActorLootRemovalEnabled + call EULxMCMAddElement 2 "Base removal chance" EULxActorBaseRemovalChance + call EULxMCMAddElement 5 "Remove equipped weapons" EULxActorRemoveEquippedWeapons + call EULxMCMAddElement 5 "Gear breaks on decapitation" EULxActorBreakOnDecapitation + call EULxMCMAddElement 2.5 "Disintegration modifier" EULxActorDisintegratedMod + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers by item type" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Weapons" EULxActorWeaponRemovalMod + call EULxMCMAddElement 2.5 "Ammo" EULxActorAmmoRemovalMod + call EULxMCMAddElement 2.5 "Apparel" EULxActorArmorRemovalMod + call EULxMCMAddElement 2.5 "Currencies" EULxActorCurrencyRemovalMod + call EULxMCMAddElement 2.5 "Alcohol" EULxActorAlcoholRemovalMod + call EULxMCMAddElement 2.5 "Chems" EULxActorChemsRemovalMod + call EULxMCMAddElement 2.5 "Meds" EULxActorMedsRemovalMod + call EULxMCMAddElement 2.5 "Food" EULxActorFoodRemovalMod + call EULxMCMAddElement 2.5 "Misc items" EULxActorMiscRemovalMod + + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 0 "Removal chance multipliers by species" 0 + call EULxMCMAddElement 0 "" 0 + + call EULxMCMAddElement 2.5 "Creatures" EULxActorAnimalMod + call EULxMCMAddElement 2.5 "Robots" EULxActorRobotMod + call EULxMCMAddElement 2.5 "Feral Ghouls" EULxActorFeralGhoulMod + call EULxMCMAddElement 2.5 "Humans" EULxActorHumanMod + call EULxMCMAddElement 2.5 "Ghouls" EULxActorGhoulMod + call EULxMCMAddElement 2.5 "Supermutants" EULxActorSupermutantMod + + + endif + + elseif GetUIFloat "StartMenu/MCM/_Default" ; 2 - DEFAULT + SetUIFloat "StartMenu/MCM/_Default" 0 ; dont run twice + SetUIFloat "StartMenu/MCM/_Reset" 1 ; reset ui + + call EULxPresetSetterFUNCTION 0 0 + + elseif GetUIFloat "StartMenu/MCM/_NewValue" ; 3 - NEW VALUE + SetUIFloat "StartMenu/MCM/_NewValue" 0 ; don't run this section twice + SetUIFloat "StartMenu/MCM/_Reset" 1 ; refresh ui + + if iSubMenu == 1 + + set iOption to GetUIFloat "StartMenu/MCM/_ActiveOption" + set fValue to GetUIFloat "StartMenu/MCM/_Value" + + if iOption == 1 + set EULxMaxItemValue to fValue + elseif iOption == 2 + set EULxLuckModifier to fValue + + elseif iOption == 4 + set EULxMaxWeaponCondition to fValue + + elseif iOption == 5 + set EULxMaxArmorCondition to fValue + + elseif iOption == 7 ; Global Preset + call EULxPresetSetterFUNCTION fValue 1 + + elseif iOption == 8 ; Reset settings + if fValue == 1 + Call EULxPresetSetterFUNCTION 0 1 + SetDebugMode 0 + endif + + elseif iOption == 9 ; Debug mode + SetDebugMode fValue + return + + elseif iOption == 12 + set EULxSaveToINI to fValue + if fValue + call EULxINISaveSettings + endif + + elseif iOption == 13 + if fValue == 1 + call EULxINILoadSettings + SetUIFloat "StartMenu/MCM/_Reset" 1 + else + return + endif + + endif + + elseif iSubMenu == 2 + + if iOption == 1 + set EULxWorldLootRemovalEnabled to fValue + SetJohnnySeenDataEventHandler fValue EULxOnSeen 0 + + elseif iOption == 2 + set EULxWorldBaseRemovalChance to fValue + elseif iOption == 3 + set EULxWorldSkipLocked to fValue + + elseif iOption == 9 + set EULxWorldWeaponRemovalMod to fValue + elseif iOption == 10 + set EULxWorldAmmoRemovalMod to fValue + elseif iOption == 11 + set EULxWorldArmorRemovalMod to fValue + elseif iOption == 12 + set EULxWorldCurrencyRemovalMod to fValue + elseif iOption == 13 + set EULxWorldAlcoholRemovalMod to fValue + elseif iOption == 14 + set EULxWorldChemsRemovalMod to fValue + elseif iOption == 15 + set EULxWorldMedsRemovalMod to fValue + elseif iOption == 16 + set EULxWorldFoodRemovalMod to fValue + elseif iOption == 17 + set EULxWorldMiscRemovalMod to fValue + endif + + elseif iSubMenu == 3 + + if iOption == 1 + set EULxActorLootRemovalEnabled to fValue + SetJohnnyOnDyingEventHandler fValue EULxOnDying 0 + + elseif iOption == 2 + set EULxActorBaseRemovalChance to fValue + elseif iOption == 3 + set EULxActorRemoveEquippedWeapons to fValue + elseif iOption == 4 + set EULxActorBreakOnDecapitation to fValue + SetJohnnyOnLimbGoneEventHandler fValue EULxOnLimbGone 0 + elseif iOption == 5 + set EULxActorDisintegratedMod to fValue + + elseif iOption == 11 + set EULxActorWeaponRemovalMod to fValue + elseif iOption == 12 + set EULxActorAmmoRemovalMod to fValue + elseif iOption == 13 + set EULxActorArmorRemovalMod to fValue + elseif iOption == 14 + set EULxActorCurrencyRemovalMod to fValue + elseif iOption == 15 + set EULxActorAlcoholRemovalMod to fValue + elseif iOption == 16 + set EULxActorChemsRemovalMod to fValue + elseif iOption == 17 + set EULxActorMedsRemovalMod to fValue + elseif iOption == 18 + set EULxActorFoodRemovalMod to fValue + elseif iOption == 19 + set EULxActorMiscRemovalMod to fValue + + elseif iOption == 25 + set EULxActorAnimalMod to fValue + elseif iOption == 26 + set EULxActorRobotMod to fValue + elseif iOption == 27 + set EULxActorFeralGhoulMod to fValue + elseif iOption == 28 + set EULxActorHumanMod to fValue + elseif iOption == 29 + set EULxActorGhoulMod to fValue + elseif iOption == 30 + set EULxActorSupermutantMod to fValue + + endif + + endif + + call EULxPrecalculateRemovalChance + + if EULxSaveToINI + call EULxINISaveSettings + endif + + elseif GetUIFloat "StartMenu/MCM/_ShowList" == 1 ;4 - SHOW LIST + SetUIFloat "StartMenu/MCM/_ShowList" 2 + + if iSubMenu == 1 + + if iOption == 7 + SetUIString "StartMenu/MCM/*:3/_title" "Select global preset (overwrites ALL options)" + + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:3/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:4/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Balanced (recommended)" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Hardcore" + SetUIString "StartMenu/MCM/*:3/*:3/text/string" "Realistic" + SetUIString "StartMenu/MCM/*:3/*:4/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 4 + endif + + if iOption == 8 + SetUIString "StartMenu/MCM/*:3/_title" "Reset entire mod" + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Confirm - reset everything" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 2 + endif + + if iOption == 13 + SetUIString "StartMenu/MCM/*:3/_title" "Reload settings from INI" + SetUIFloat "StartMenu/MCM/*:3/*:1/_enable" 1 + SetUIFloat "StartMenu/MCM/*:3/*:2/_enable" 1 + SetUIString "StartMenu/MCM/*:3/*:1/text/string" "Confirm - reload settings" + SetUIString "StartMenu/MCM/*:3/*:2/text/string" "Cancel - retain existing settings" + SetUIFloat "StartMenu/MCM/_Value" 2 + endif + + endif + + elseif GetUIFloat "StartMenu/MCM/_ShowScale" == 1 ;5 - SHOW SCALE + SetUIFloat "StartMenu/MCM/_ShowScale" 2 + + if iSubMenu == 1 + + if iOption == 1 + call EULxMCMAddScale "Max value of items affected by UL" EULxMaxItemValue " caps" 0 9999 0 10 + + elseif iOption == 2 + call EULxMCMAddScale "Luck effect" EULxLuckModifier "%" 0 100 0 1 + + elseif iOption == 4 + call EULxMCMAddScale "Max weapon condition" EULxMaxWeaponCondition "%" 1 100 0 1 + + elseif iOption == 5 + call EULxMCMAddScale "Max armor condition" EULxMaxArmorCondition "%" 1 100 0 1 + + endif + + elseif iSubMenu == 2 + + if iOption == 2 + call EULxMCMAddScale "Base removal chance" EULxWorldBaseRemovalChance "%" 0 100 0 1 + + elseif iOption == 9 + call EULxMCMAddScale "Weapon multiplier" EULxWorldWeaponRemovalMod "x" 0 10 1 0.1 + elseif iOption == 10 + call EULxMCMAddScale "Ammo multiplier" EULxWorldAmmoRemovalMod "x" 0 10 1 0.1 + elseif iOption == 11 + call EULxMCMAddScale "Armor multiplier" EULxWorldArmorRemovalMod "x" 0 10 1 0.1 + elseif iOption == 12 + call EULxMCMAddScale "Currencies multiplier" EULxWorldCurrencyRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 13 + call EULxMCMAddScale "Alcohol multiplier" EULxWorldAlcoholRemovalMod "x" 0 10 1 0.1 + elseif iOption == 14 + call EULxMCMAddScale "Chems multiplier" EULxWorldChemsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 15 + call EULxMCMAddScale "Meds multiplier" EULxWorldMedsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 16 + call EULxMCMAddScale "Food multiplier" EULxWorldFoodRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 17 + call EULxMCMAddScale "Misc items multiplier" EULxWorldMiscRemovalMod "x" 0 10 1 0.1 + endif + + elseif iSubMenu == 3 + + if iOption == 2 + call EULxMCMAddScale "Base removal chance" EULxActorBaseRemovalChance "%" 0 100 0 1 + + elseif iOption == 5 + call EULxMCMAddScale "Disintegration multiplier" EULxActorDisintegratedMod "x" 0 10 1 0.1 + + elseif iOption == 11 + call EULxMCMAddScale "Weapon multiplier" EULxActorWeaponRemovalMod "x" 0 10 1 0.1 + elseif iOption == 12 + call EULxMCMAddScale "Ammo multiplier" EULxActorAmmoRemovalMod "x" 0 10 1 0.1 + elseif iOption == 13 + call EULxMCMAddScale "Armor multiplier" EULxActorArmorRemovalMod "x" 0 10 1 0.1 + elseif iOption == 14 + call EULxMCMAddScale "Currencies multiplier" EULxActorCurrencyRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 15 + call EULxMCMAddScale "Alcohol multiplier" EULxActorAlcoholRemovalMod "x" 0 10 1 0.1 + elseif iOption == 16 + call EULxMCMAddScale "Chems multiplier" EULxActorChemsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 17 + call EULxMCMAddScale "Meds multiplier" EULxActorMedsRemovalMod "x" 0 10 1 0.1 + elseif iOption == 18 + call EULxMCMAddScale "Food multiplier" EULxActorFoodRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 19 + call EULxMCMAddScale "Misc items multiplier" EULxActorMiscRemovalMod "x" 0 10 1 0.1 + + elseif iOption == 25 + call EULxMCMAddScale "Creatures multiplier" EULxActorAnimalMod "x" 0 10 1 0.1 + elseif iOption == 26 + call EULxMCMAddScale "Robots multiplier" EULxActorRobotMod "x" 0 10 1 0.1 + elseif iOption == 27 + call EULxMCMAddScale "Feral Ghouls multiplier" EULxActorFeralGhoulMod "x" 0 10 1 0.1 + elseif iOption == 28 + call EULxMCMAddScale "Humans multiplier" EULxActorHumanMod "x" 0 10 1 0.1 + elseif iOption == 29 + call EULxMCMAddScale "Ghouls multiplier" EULxActorGhoulMod "x" 0 10 1 0.1 + elseif iOption == 30 + call EULxMCMAddScale "Supermutants multiplier" EULxActorSupermutantMod "x" 0 10 1 0.1 + + endif + + endif + + elseif GetUIFloat "StartMenu/MCM/_DefaultScale" ;6 - DEFAULT SCALE + SetUIFloat "StartMenu/MCM/_DefaultScale" 0 + SetUIFloat "StartMenu/MCM/_ShowScale" 2 + + if iSubMenu == 1 + + if iOption == 1 + SetUIFloat "StartMenu/MCM/_Value" 5000 + elseif iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 10 + elseif iOption == 4 + SetUIFloat "StartMenu/MCM/_Value" 40 + elseif iOption == 5 + SetUIFloat "StartMenu/MCM/_Value" 40 + endif + + elseif iSubMenu == 2 + + if iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 85 + + elseif iOption == 9 ; weapons + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 10 ; ammo + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 11 ; armor + SetUIFloat "StartMenu/MCM/_Value" 0.5 + elseif iOption == 12 ; currencies + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 13 ; alcohol + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 14 ; chems + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 15 ; meds + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 16 ; food + SetUIFloat "StartMenu/MCM/_Value" 1.3 + + elseif iOption == 17 ; misc + SetUIFloat "StartMenu/MCM/_Value" 0.3 + + endif + + elseif iSubMenu == 3 + + if iOption == 2 + SetUIFloat "StartMenu/MCM/_Value" 80 + + elseif iOption == 5 ; disintegration + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 11 ; weapons + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 12 ; ammo + SetUIFloat "StartMenu/MCM/_Value" 0.8 + elseif iOption == 13 ; armor + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 14 ; currencies + SetUIFloat "StartMenu/MCM/_Value" 2.0 + + elseif iOption == 15 ; alcohol + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 16 ; chems + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 17 ; meds + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 18 ; food + SetUIFloat "StartMenu/MCM/_Value" 0.8 + + elseif iOption == 19 ; misc + SetUIFloat "StartMenu/MCM/_Value" 1.0 + + elseif iOption == 25 ; creatures + SetUIFloat "StartMenu/MCM/_Value" 0.5 + elseif iOption == 26 ; robots + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 27 ; feral ghouls + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 28 ; humans + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 29 ; ghouls + SetUIFloat "StartMenu/MCM/_Value" 1.0 + elseif iOption == 30 ; supermutants + SetUIFloat "StartMenu/MCM/_Value" 1.0 + + endif + + endif + endif + + if iMouseover != GetUIFloat "StartMenu/MCM/*:1/_optionID" ;7 - MOUSE-OVER + set iMouseover to GetUIFloat "StartMenu/MCM/*:1/_optionID" + if iMouseover + if iSubMenu == 1 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Maximum value of items to remove. Items worth more than this will be left alone." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "10% effect -> 10 Luck reduces removal by 10%, 1 Luck - by 1%. 100% effect -> 10 Luck reduces it by 100% (modifiers are still in play!), 1 Luck - by 10%. 0 - disable Luck factor." + + elseif iMouseover == 4 + SetUIString "StartMenu/MCM/*:9/string" "Max condition of weapons found in the world. Some containers and items may not be affected. To disable it and use vanilla values, set to 100%." + elseif iMouseover == 5 + SetUIString "StartMenu/MCM/*:9/string" "Max condition of armor found in the world. Some containers and items may not be affected. To disable it and use vanilla values, set to 100%." + + elseif iMouseover == 7 + SetUIString "StartMenu/MCM/*:9/string" "Apply a preset to the entire mod. Overrides all existing settings." + elseif iMouseover == 8 + SetUIString "StartMenu/MCM/*:9/string" "Completely resets all options!" + elseif iMouseover == 9 + SetUIString "StartMenu/MCM/*:9/string" "Show debug info in console for the current session." + + elseif iMouseover == 12 + SetUIString "StartMenu/MCM/*:9/string" "Always save settings to Data\Config\Unfound Loot.ini." + elseif iMouseover == 13 + SetUIString "StartMenu/MCM/*:9/string" "Rewrite existing settings with values from Unfound Loot.ini." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + elseif iSubMenu == 2 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Enable or disable world items reduction." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance for world-placed and container items. We get a random number between 0 and 100 and compare it with 100. If the number is smaller, the item gets removed." + elseif iMouseover == 3 + SetUIString "StartMenu/MCM/*:9/string" "Do not remove items from locked containers." + + elseif iMouseover == 9 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for weapons. Higher = greater chance of these items being removed." + elseif iMouseover == 10 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for ammo. Higher = greater chance of these items being removed." + elseif iMouseover == 11 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for armor. Higher = greater chance of these items being removed." + elseif iMouseover == 12 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for currencies. Higher = greater chance of these items being removed." + + elseif iMouseover == 13 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for alcohol. Higher = greater chance of these items being removed." + elseif iMouseover == 14 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for chems. Higher = greater chance of these items being removed." + elseif iMouseover == 15 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for healing items. Higher = greater chance of these items being removed." + elseif iMouseover == 16 + SetUIStringEx "StartMenu/MCM/*:9/string" "Removal chance multiplier for food, water, and soft drinks. Higher = greater chance of these items being removed." + + elseif iMouseover == 17 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for misc items. Higher = greater chance of these items being removed." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + elseif iSubMenu == 3 + + SetUIFloat "StartMenu/MCM/*:9/visible" 1 + + if iMouseover == 1 + SetUIString "StartMenu/MCM/*:9/string" "Enable or disable corpse loot reduction." + elseif iMouseover == 2 + SetUIString "StartMenu/MCM/*:9/string" "Percentage of corpse's items that will be removed." + elseif iMouseover == 3 + SetUIString "StartMenu/MCM/*:9/string" "Apply removal chance to equipped weapons as well." + elseif iMouseover == 4 + SetUIString "StartMenu/MCM/*:9/string" "Set headgear condition to 0 on decapitation." + elseif iMouseover == 5 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for disintegrated and gooified corpses. Higher = greater chance of these items being removed." + + elseif iMouseover == 11 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for weapons. Higher = greater chance of these items being removed." + elseif iMouseover == 12 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for ammo. Higher = greater chance of these items being removed." + elseif iMouseover == 13 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for armor. Higher = greater chance of these items being removed." + elseif iMouseover == 14 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for currencies. Higher = greater chance of these items being removed." + + elseif iMouseover == 15 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for alcohol. Higher = greater chance of these items being removed." + elseif iMouseover == 16 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for chems. Higher = greater chance of these items being removed." + elseif iMouseover == 17 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for healing items. Higher = greater chance of these items being removed." + elseif iMouseover == 18 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for food, water, and soft drinks. Higher = greater chance of these items being removed." + + elseif iMouseover == 19 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for misc items. Higher = greater chance of these items being removed." + + elseif iMouseover == 25 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for creature corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 26 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for robots. Higher = greater chance of these items being removed." + elseif iMouseover == 27 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for feral ghoul corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 28 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for human corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 29 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for ghoul corpses. Higher = greater chance of these items being removed." + elseif iMouseover == 30 + SetUIString "StartMenu/MCM/*:9/string" "Removal chance multiplier for supermutant corpses. Higher = greater chance of these items being removed." + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + else + SetUIFloat "StartMenu/MCM/*:9/visible" 0 + endif + + endif + +end \ No newline at end of file diff --git a/src/EULxReduceItemHealth.gek b/src/EULxReduceItemHealth.gek new file mode 100644 index 0000000..27c5c72 --- /dev/null +++ b/src/EULxReduceItemHealth.gek @@ -0,0 +1,79 @@ +scn EULxReduceItemHealth + +ref rContainer +ref rItem +int iType +int iBaseHealth +int iTargetHealth +int iCurrentHealth +int iMaxCondition + +begin function { rContainer, rItem } + + set iType to rItem.GetType + + if iType == 40 + if rItem.GetWeaponType >= 10 ; mines and throwables + DebugPrint "%n is a mine/throwable, skipping health reduction." rItem + return + endif + set iMaxCondition to EULxMaxWeaponCondition + elseif iType == 24 + set iMaxCondition to EULxMaxArmorCondition + else + return + endif + + if iMaxCondition == 100 + ; use vanilla condition with 100% max health + return + endif + + set iBaseHealth to rItem.GetBaseHealth + + DebugPrint "%n base health: %g points." rItem iBaseHealth + + set iTargetHealth to iMaxCondition + 1 + set iTargetHealth to Rand 1 iTargetHealth + + DebugPrint "%n target health: %g%%" rItem iTargetHealth + + if rContainer == playerRef ; world items + + set iCurrentHealth to rItem.GetCurrentHealth / ( iBaseHealth / 100 ) + + DebugPrint "%n current health (world item): %g%%" rItem iCurrentHealth + + if iCurrentHealth > iTargetHealth + DebugPrint "Changing %n condition: %g%% to %g%%" rItem iCurrentHealth iTargetHealth + set iTargetHealth to iBaseHealth * ( iTargetHealth / 100 ) + + ; Keep at least one point of health for the item to remain equippable + if iTargetHealth < 1 + set iTargetHealth to 1 + endif + + rItem.SetCurrentHealth iTargetHealth + endif + + else ; container or NPC + + set iCurrentHealth to rItem.GetItemRefCurrentHealth / ( iBaseHealth / 100 ) + + DebugPrint "%n current health (inventory item): %g%%" rItem iCurrentHealth + + if iCurrentHealth > iTargetHealth + DebugPrint "Changing %n condition: %g%% to %g%%" rItem iCurrentHealth iTargetHealth + set iTargetHealth to iBaseHealth * ( iTargetHealth / 100 ) + + ; Keep at least one point of health for the item to remain equippable + if iTargetHealth < 1 + set iTargetHealth to 1 + endif + + rItem.SetItemRefCurrentHealth iTargetHealth + endif + + endif + +end \ No newline at end of file diff --git a/src/EULxWhitelistDeathItems.gek b/src/EULxWhitelistDeathItems.gek new file mode 100644 index 0000000..d2d9ccc --- /dev/null +++ b/src/EULxWhitelistDeathItems.gek @@ -0,0 +1,92 @@ +scn EULxWhitelistDeathItems + +int i +int n +ref rPerk +int iEntryCount +ref rList +ref rItem +ref rCertifiedTechItemList +int iModsNum + +begin function {} + + ; Get main DLCs' indexes for better detection of mod-added items + set EULxDLCIndex to 0 + + if IsModLoaded "TaleOfTwoWastelands.esm" + set EULxDLCIndex to GetModIndex "TaleOfTwoWastelands.esm" + elseif IsModLoaded "GunRunnersArsenal.esm" + set EULxDLCIndex to GetModIndex "GunRunnersArsenal.esm" + elseif IsModLoaded "LonesomeRoad.esm" + set EULxDLCIndex to GetModIndex "LonesomeRoad.esm" + elseif IsModLoaded "OldWorldBlues.esm" + set EULxDLCIndex to GetModIndex "OldWorldBlues.esm" + elseif IsModLoaded "HonestHearts.esm" + set EULxDLCIndex to GetModIndex "HonestHearts.esm" + elseif IsModLoaded "DeadMoney.esm" + set EULxDLCIndex to GetModIndex "DeadMoney.esm" + endif + + ListClear VATSSmallExplodingCreatureLIST ; hijacking unused formlists + ListClear EmptyFormList + + set iModsNum to GetNumLoadedMods + set i to EULxDLCIndex + 1 + while i < iModsNum + GetLoadedType VATSSmallExplodingCreatureLIST 86 i 1 + set i to i + 1 + loop + + if ListGetCount VATSSmallExplodingCreatureLIST == 0 + return + endif + + set rCertifiedTechItemList to StringToRef "LonesomeRoad.esm:C42D" + + set i to 0 + while rPerk := ListGetNthForm VATSSmallExplodingCreatureLIST i + + set iEntryCount to GetPerkEntryCount rPerk + set n to 0 + + while n < iEntryCount + if GetNthPerkEntryFunction rPerk n == 21 ; Add Leveled List On Death + + set rList to GetNthPerkEntryForm rPerk n + + if rList + if GetType rList == 52 && rList != rCertifiedTechItemList + ListAddForm EmptyFormList rList + endif + endif + + endif + + set n to n + 1 + loop + + set i to i + 1 + loop + + ListClear VATSSmallExplodingCreatureLIST + + set i to 0 + while rList := ListGetNthForm EmptyFormList i + + set n to 0 + while rItem := GetNthLevItem rList n + + if GetType rItem != 52 ; not leveled list + ListAddForm EULxDeathItems rItem + endif + + set n to n + 1 + loop + + set i to i + 1 + loop + + ListClear EmptyFormList + +end