From 23ebb7edfacd96814288a4776a37f0ed0ad8b0ce Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Sat, 17 Jun 2023 21:22:29 +0200 Subject: [PATCH] ExpForKill redesign - Instead of kill counts, use accumulated exp for kills per kill type - For this, statistics of total kill exp per type is kept in a saved array - When loading existing save, initialize these stats based on kill count multiplied by minimum kill exp among each type --- root/data/scripts/gl_expforkill_mod.int | Bin 2164 -> 3910 bytes root/mods/ecco/combat.ini | 12 ++--- scripts_src/_pbs_main/gl_expforkill_mod.ssl | 57 ++++++++++++++++---- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/root/data/scripts/gl_expforkill_mod.int b/root/data/scripts/gl_expforkill_mod.int index a7972b3cd45dbe3bade47b7f613893d549d72660..609bfa7b126173212dfc64efa26d03384c459350 100644 GIT binary patch literal 3910 zcmbsrO=uit^qbw;%{JNHEZZV$4P}irv^6GmQ?N-(D?$ol(gvwP@Mk;O-E7wG?ku|- zX|c-NIY()C)uTxmM3POXZN+ile6uXGlj4pOHtH=0c!$~W4La;woU*RFKRt@UOfDG0af zG@I_~D#~-Zh|Fm^gR8YsYO3W{HJ4IZw_U9{{k8I%>t5FU6}PqG^s7$Gsn-NqXf^6x zr(Y{;?OJHR(d#!VJP>CXs@o+cXrE>+EV|XkYNJ*yYHSe+ibz4yidv725|Doy{g@<@i&r}} z(s^LA*mwJm4%RuhYtY%wN{_uD=hg8=_ADS@yVonOI6YMAwpnk*U2pe$BsW*9RNQws zNK+VB)P4=M&%d=)K6l}b^6RfHETCQ4NLI2Y`jU~ffhik>1=pzteIy%DosKI^QkSSF ze<7~-GiSht7j~g6c`p%#4fMAkFg=tuEUnL5CfI@*n7*OAC@It>m?bz1vxJEY|0hC^ z{77v>30{Wdv{qUs;w&hM)EM)qxa`EBL^7WenT7-L-ZaccG_4wGMw7sEsBxOsD3|1o zg*mkaLd&*WY)AYK*cxwtYq-4&w0Z<5wj!WVP(Np@LaXB5fSmz%y@H8BQ zqmYI%`j2g|+~lQ@XIK?}rcJD*3Ki}VtyFaq*aIJL=nS8syG>jsy4tQlEd_1VbVG`z zCVvlc>3o@b(d&R`K`w<_qI-x7P(LmXYKQJ;f2~hFs$le!yIMT4t_$AyZR$w;9{Nc< z$Qw^Q?jQx&_t8D_;x1v09OZi~n4wJ_8=4?fnld%Xu}U3^O7k_Dm??-@kvc5dW530R z)cYg}Gbk2X!e??HfJKMS=d4He;0$0bG+T@>QkMyiUg{6X+_cVuQv4;V802A&Rtc%G zxW>RK!r3B~ai@h6c>)q>He-eo#F3OtnMfwl##3IM_QcbD-w9L_9VIy7XN7RqbwlAL zXu`Zg-(~T~)U!3PW#V+Ub_DZ*-;-u4UGr%I`4DQ5J>7#m!)^!$qXM&oi)7Ces(J9U zP*9x?F9}qFXY^`#0tzq<2Yu`vTG1&)`{((VsC#I@RbdeY-y!3W@OdBGPZ10562Ip*+MA)j)I+*pY~8RdWh-;Sj$GQp<2kD^+w)u} z>4NE?$efUqPsdU7`g20&$HL&P`ZY&&F+x*APZ9Radr|oJQ+g4B*i`dj>9uEWIOSj zX=-MMv7futK$1!LQFwG8vv)?n<@X3_N-xWOfV=fJ?`FoOvV3jgWn%Zf%DgwInw(=! z1GTSZWWIt7#qAgR{w1CJNd5v_c%vKq=AFEW9HGe0gYyN&2^IG*xm~L`OHWN6v{B)7XAf!@K757 literal 2164 zcmbVN&1(}u6rcUbTBHdfdWbcLShZNKEmo=h0zqie+Ny|%h_GyuO&XeHLmMGN4=;O= z96Wdu52D4B2M?Y+dywMEKcOIq7d`n0sBhl9S+lXlVqjDC|AS{f^R zwOUXvyBjTU9l^BZY0Ph+pMiQ%l2$^bf=0>rTC47A5Uff2Vo)!5t&&&wDn5gb^79LS z$apIbS8CF@9IUTZYc&^r&E|#3t^}oOx$2kl63rtaj|@}@JAX>9qmpG#V9YV1+z*3oV&*?b3f4A(sEOY^=HOK=3MCxSdD z;Ru|DQ5b}rdCBu0Rsy5+>k#W@(IeGt2JPi1U84pp57_kk-h zx{RBB{oy{?S*{?XD+yI!1)S$f1VlQ?u?L8Wcfc09Vn*zg?2WwfaGdxB)hqip^CNFj zB<-OmlG54t`1VxYx`qmQ(l^LGfzOQ2(9ZX2|A6F{aS4P_D|0e1%Pdue35dWPVHVe` zuz6-0km>P2vnmWokVT@ew+X!8xlm=vIVV05Q+G|y)P<nPWL(i3SMg2?2x1po%&>)5hiO6cdvA3frD)y^?#QyOAv7Mit5-db_ z*OQ^l;lL6k>2?aVwz#ux-nHDt{(cLmx8yzdPG)?r3^+tSH>tX40(A%D-wa}I?<@K< zjQ)mv%Dx+qUeY-p+f=a!hWF+1b>tD>8uDh)EbZ>wlD_2^Lgf&iRlABP9F+|?!k diff --git a/root/mods/ecco/combat.ini b/root/mods/ecco/combat.ini index 853ef9d..9af3312 100644 --- a/root/mods/ecco/combat.ini +++ b/root/mods/ecco/combat.ini @@ -81,13 +81,13 @@ enable=1 [EXP_FOR_KILL] -; Reduces experience points for kills based on number of kills per kill type. -; Kill experience multiplier at and after falloff_end kills. Valid range: [0..1]. Set to 1 to disable this feature. +; Reduces experience points for kills based on accumulated kill exp per kill type. +; Kill experience multiplier at and after falloff_end experience. Valid range: [0..1]. Set to 1 to disable this feature. min_exp_mult=0.65 -; How many critters of given kill type reward with full exp amount before falloff begins. -falloff_start=20 -; After this many critters of a given kill type are killed, minimun exp amount will be applied. Must be greater than falloff_start. -falloff_end=50 +; How much total kill experience for a given kill type is rewarded in full, before falloff begins. +falloff_start=2000 +; After this much (unmodified) kill experience (per kill type), min_exp_mult will be applied for all kills of this type. Must be greater than falloff_start. +falloff_end=4000 [COMBAT_FREE_MOVE] diff --git a/scripts_src/_pbs_main/gl_expforkill_mod.ssl b/scripts_src/_pbs_main/gl_expforkill_mod.ssl index d520750..b387b1d 100644 --- a/scripts_src/_pbs_main/gl_expforkill_mod.ssl +++ b/scripts_src/_pbs_main/gl_expforkill_mod.ssl @@ -3,24 +3,29 @@ */ #include "../sfall/define_lite.h" +#include "../sfall/lib.arrays.h" #include "../sfall/lib.math.h" + #include "../_pbs_headers/ecco.h" #define INI_SECTION "EXP_FOR_KILL" #define debug_log(msg) debug_msg("gl_expforkill_mod: "+msg) -variable origExpMap; // associative array pid => original exp value +variable + origExpMap, // associative array pid => original exp value + killExpMap; // associative array killType => accumulated exp + variable ini_min_exp_mult, ini_falloff_start, ini_falloff_end; -procedure mod_exp(variable critterPid) begin +procedure mod_exp(variable critterPid, variable isDeath) begin variable killType := get_proto_data(critterPid, PROTO_CR_KILL_TYPE), killExp := get_proto_data(critterPid, PROTO_CR_KILL_EXP), - killExpProto := killExp; + killExpProto := killExp; // current exp value in proto (gets changed by this script) if (origExpMap[critterPid] == 0) then begin // Save default value. @@ -29,30 +34,54 @@ procedure mod_exp(variable critterPid) begin // Use previously saved default value as base. killExp := origExpMap[critterPid] if origExpMap[critterPid] > 0 else 0; end + + // Update kill exp statistic. + if (isDeath) then begin + killExpMap[killType] += killExp; + end variable - numKills := player_kill_count(killType) + 1, - expMult := get_clamped(1.0 - (1.0 - ini_min_exp_mult) * (numKills - ini_falloff_start) / (ini_falloff_end - ini_falloff_start), ini_min_exp_mult, 1.0); + totalExpForType := killExpMap[killType] + killExp, + expMult := get_clamped(1.0 - (1.0 - ini_min_exp_mult) * (totalExpForType - ini_falloff_start) / (ini_falloff_end - ini_falloff_start), ini_min_exp_mult, 1.0); killExp := round(killExp * expMult); if (killExp != killExpProto) then begin set_proto_data(critterPid, PROTO_CR_KILL_EXP, killExp); - debug_log("Modified kill exp for "+proto_data(critterPid, cr_name)+" ("+critterPid+"): "+killExp+"/"+origExpMap[critterPid]+", killType: "+killType+", kills: "+numKills); + debug_log("Modified kill exp for "+proto_data(critterPid, cr_name)+" ("+critterPid+"): "+killExp+"/"+origExpMap[critterPid]+", killType: "+killType+", totalExpForType: "+totalExpForType); end end - procedure ondeath_hook begin // Need to run mod_exp additionally after death to handle cases where we kill several critters in the same attack. variable critter := get_sfall_arg; if (critter and obj_type(critter) == OBJ_TYPE_CRITTER) then - call mod_exp(obj_pid(critter)); + call mod_exp(obj_pid(critter), true); end procedure combatdamage_hook begin variable critter := get_sfall_arg; if (critter and obj_type(critter) == OBJ_TYPE_CRITTER) then - call mod_exp(obj_pid(critter)); + call mod_exp(obj_pid(critter), false); +end + +procedure migrate_kill_statistics begin + variable pid, killType, killExp; + variable minExpPerType := temp_array_map; + // Find minimum kill exp per type among all criter prototypes. + for (pid := 0x01000001; pid < 0x01000400; pid++) begin + if (not proto_data(pid, it_pid)) then break; + + killType := get_proto_data(pid, PROTO_CR_KILL_TYPE); + killExp := get_proto_data(pid, PROTO_CR_KILL_EXP); + if minExpPerType[killType] == 0 or killExp < minExpPerType[killType] then + minExpPerType[killType] := killExp; + end + killExpMap := create_array_map; + save_array(ARR_KILL_EXP, killExpMap); + foreach (killType: killExp in minExpPerType) begin + killExpMap[killType] := player_kill_count(killType) * killExp; + end + debug_log("Migrated kill exp stats based on kill counts: "+debug_array_str(killExpMap)); end procedure start begin @@ -63,10 +92,16 @@ procedure start begin float_from_ini_file_clamped(min_exp_mult, INI_COMBAT, INI_SECTION, 0.0, 1.0); if (ini_min_exp_mult == 1.0) then return; - int_from_ini_file_clamped(falloff_start, INI_COMBAT, INI_SECTION, 0, 99999); - int_from_ini_file_clamped(falloff_end, INI_COMBAT, INI_SECTION, ini_falloff_start + 1, 99999); + int_from_ini_file_clamped(falloff_start, INI_COMBAT, INI_SECTION, 0, 999999); + int_from_ini_file_clamped(falloff_end, INI_COMBAT, INI_SECTION, ini_falloff_start + 1, 999999); origExpMap := create_array_map; + killExpMap := load_array(ARR_KILL_EXP); + if not killExpMap then + call migrate_kill_statistics; + else + debug_log("Loaded kill exp stats: "+debug_array_str(killExpMap)); + register_hook_proc(HOOK_ONDEATH, ondeath_hook); register_hook_proc(HOOK_COMBATDAMAGE, combatdamage_hook); end