Skip to content

Commit

Permalink
ExpForKill redesign
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
phobos2077 committed Jun 17, 2023
1 parent eb6dc90 commit 23ebb7e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
Binary file modified root/data/scripts/gl_expforkill_mod.int
Binary file not shown.
12 changes: 6 additions & 6 deletions root/mods/ecco/combat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
57 changes: 46 additions & 11 deletions scripts_src/_pbs_main/gl_expforkill_mod.ssl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 23ebb7e

Please sign in to comment.