From ac7550dd24b7e4f20b9caf6e7076d21a04a25af1 Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Sat, 6 Jul 2024 01:12:35 +0200 Subject: [PATCH] Map ammo reduction and map tweaker spatial script fix - Repurposed map_tweaks_loot to focus on deterministic ammo reduction with per-PID quantities for fine balance tuning - Fix spatials not created on tiles with some object (like a door) --- root/data/config/pbs_map_tweaks.ini | 6 +- root/mods/ecco/misc.ini | 59 ++++++--- scripts_src/_pbs_headers/loot_utils.h | 2 - ...ssl => gl_map_objs_proto_mismatch_fix.ssl} | 0 scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl | 11 +- .../_pbs_main/gl_pbs_map_tweaks_loot.ssl | 125 ++++++++++-------- .../_pbs_main/wip/gl_armorappearance.ssl | 48 ------- 7 files changed, 122 insertions(+), 129 deletions(-) rename scripts_src/_pbs_main/{gl_update_map_objs_from_proto.ssl => gl_map_objs_proto_mismatch_fix.ssl} (100%) delete mode 100644 scripts_src/_pbs_main/wip/gl_armorappearance.ssl diff --git a/root/data/config/pbs_map_tweaks.ini b/root/data/config/pbs_map_tweaks.ini index 25c8071..be9a77a 100644 --- a/root/data/config/pbs_map_tweaks.ini +++ b/root/data/config/pbs_map_tweaks.ini @@ -12,7 +12,7 @@ run_on_load=0 ; a::: - adds an object with given PID and count (defaults to 1 if omitted) ; r: - remove up to count items ; w: - makes critter wield an item with given PID in it's inventory (inactive = 1 to put weapon in left hand slot without actually wielding) -; s: - sets script ID for the main object on tile; if tile is empty and radius is set - creates a spatial script instead +; s: - sets script ID for the main object on tile; if radius is set - creates a spatial script instead ; ARCAVES @@ -127,8 +127,10 @@ run_on_load=0 [27_0] ; depolv1 (entrance) ; Remove rocket launcher 16334=r13 -; Grenades in crate 5 => 3 +; Grenades in crate 5 -> 3 16531=r25:2 +; 10mm Ammo in crate 6 -> 3 +16931=r29:3 [28_0] ; depolva l1 diff --git a/root/mods/ecco/misc.ini b/root/mods/ecco/misc.ini index 8c93dee..dfad6f6 100644 --- a/root/mods/ecco/misc.ini +++ b/root/mods/ecco/misc.ini @@ -125,23 +125,48 @@ car_blower_consumption_percent=25 [MAP_LOOT] -; 1 to enable all map loot tweaks, 0 to disable -enable_tweaks=0 - -; set positive to reduce number of items of each type in containers on maps -; 100 means remove all, 50 mean 50% of items will be deleted on average, etc. -reduce_weapons_percent=0 -; Ammo is deleted only in whole packs, not individual bullets -reduce_ammo_percent=25 -reduce_drugs_percent=50 - -; comma-separated list of drug pids to be subject of reduce -; Currently: Stimpak, Radaway, Antidote, Mentats, Buffout, Rad-X, Psycho, Super Stimpak, Healing powder -reduce_drugs_pids=40,48,49,53,87,109,110,144,273 - -; list of weapon pids for reduction -; Grenades -reduce_weapons_pids=25,26,27 +; 1 to enable or 0 to disable all map loot tweaks +enable_tweaks=1 +; 1 to remove ammo from all weapons on ground or in containers on first map load +unload_weapons=1 + + +[MAP_LOOT_AMMO_QTY] +; 10mm: 24->12 +29=12 +30=12 +; .44: 18->8 +31=8 +111=8 +; Flamer: 10->6 +32=6 +382=6 +; 14mm: 12->6 +33=6 +633=6 +; .223: 30->20 +34=20 +615=20 +; 5mm: 40->30 +35=30 +36=30 +; SEC: 20->10 +38=10 +; MFC: 30->20 +39=20 +; 12ga: 10->10 +;95=10 +;614=10 +;641=10 +; 9mm: 30->20 +121=20 +360=20 +; Needler: 10->10 +;361=10 +;362=10 +; 7.62: 20->20 +;363=20 +;642=20 [ENCOUNTERS] diff --git a/scripts_src/_pbs_headers/loot_utils.h b/scripts_src/_pbs_headers/loot_utils.h index 61d1460..66e12e5 100644 --- a/scripts_src/_pbs_headers/loot_utils.h +++ b/scripts_src/_pbs_headers/loot_utils.h @@ -56,7 +56,6 @@ procedure reduce_ammo_in_weapon(variable item, variable percentRange) begin if (percentRange[1] <= 0) then return ""; variable - pid := obj_pid(item), count := get_weapon_ammo_count(item), newCount; @@ -76,7 +75,6 @@ procedure reduce_ammo_on_ground(variable item, variable percentRange) begin if (percentRange[1] <= 0) then return ""; variable - pid := obj_pid(item), count := get_weapon_ammo_count(item), newCount := calc_reduced_ammo_range(count, percentRange); diff --git a/scripts_src/_pbs_main/gl_update_map_objs_from_proto.ssl b/scripts_src/_pbs_main/gl_map_objs_proto_mismatch_fix.ssl similarity index 100% rename from scripts_src/_pbs_main/gl_update_map_objs_from_proto.ssl rename to scripts_src/_pbs_main/gl_map_objs_proto_mismatch_fix.ssl diff --git a/scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl b/scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl index 273c0da..d61be02 100644 --- a/scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl +++ b/scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl @@ -161,10 +161,10 @@ procedure command_script(variable tileNum, variable elev, variable tileObj, vari debug_err_cmd("s: invalid sid", tileNum); return; end - if (tileObj) then begin + if (radius < 0) then begin // Set/remove script on object. - if (radius >= 0) then begin - debug_err_cmd("s: radius set but tile has object", tileNum); + if (not tileObj) then begin + debug_err_cmd("s: tile has no object and spatial radius is not set", tileNum); return; end if (sid > 0) then @@ -174,10 +174,7 @@ procedure command_script(variable tileNum, variable elev, variable tileObj, vari debug_log_cmd("set " + obj_name(tileObj) + " script to " + sid, tileNum); end else begin - if (radius < 0) then begin - debug_err_cmd("s: no object to change script", tileNum); - return; - end + // Create spatial script. if (sid > 0) then begin create_spatial(sid, tileNum, elev, radius); debug_log_cmd("created spatial script " + sid, tileNum); diff --git a/scripts_src/_pbs_main/gl_pbs_map_tweaks_loot.ssl b/scripts_src/_pbs_main/gl_pbs_map_tweaks_loot.ssl index fd1220b..0cff6ba 100644 --- a/scripts_src/_pbs_main/gl_pbs_map_tweaks_loot.ssl +++ b/scripts_src/_pbs_main/gl_pbs_map_tweaks_loot.ssl @@ -1,7 +1,9 @@ /* Map loot mod: - - Removes a portion of ammo and drugs from containers/ground on first map enter. + - Deterministically reduces certain amount of ammo in containers/ground on first map enter: + - All weapons are unloaded. + - Ammo items and ammo stacks in containers are reduced based on custom "pack size for pre-spawned ammo" from ini. */ #define SCRIPT_REALNAME "pbs_map_loot" @@ -12,6 +14,7 @@ #include "../sfall/lib.arrays.h" #include "../sfall/lib.inven.h" #include "../sfall/lib.math.h" +#include "../sfall/lib.misc.h" #include "../_pbs_headers/ecco_ids.h" #include "../_pbs_headers/ecco_ini.h" @@ -21,12 +24,60 @@ variable begin ini_enable_tweaks; - ini_reduce_weapons_percent; - ini_reduce_weapons_pids; - ini_reduce_ammo_percent; - ini_reduce_drugs_percent; - ini_reduce_drugs_pids; - //processed_containers_map; + ini_unload_weapons; + ini_map_loot_ammo_qty; +end + +procedure unload_weapon(variable item) begin + if (not ini_unload_weapons) then return ""; + + variable count := get_weapon_ammo_count(item); + if (count <= 0) then return ""; + + set_weapon_ammo_count(item, 0); + return string_format("%s mag ammo (%d -> 0)", obj_name(item), count); +end + +procedure calc_reduced_ammo_count(variable pid, variable packSize, variable count) begin + variable + ammoQtyPerPack := ini_map_loot_ammo_qty[pid]; + + if (ammoQtyPerPack <= 0) then return count; + return count * math_min(ammoQtyPerPack, packSize) / packSize; +end + +procedure reduce_ammo_in_stack_by_pack_qty(variable invenObj, variable item) begin + variable + pid := obj_pid(item), + packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE), + count := (obj_is_carrying_obj(invenObj, item) - 1) * packSize + get_weapon_ammo_count(item), + newCount := calc_reduced_ammo_count(pid, packSize, count); + + if (newCount >= count) then return ""; + + call reduce_item_count(invenObj, item, ceil(1.0 * newCount / packSize)); + // if number of items reduced, object reference will be different + item := obj_carrying_pid_obj(invenObj, pid); + if (item and newCount % packSize > 0) then + set_weapon_ammo_count(item, newCount % packSize); + + return obj_name(item)+" ("+count+" -> "+newCount+")"; +end + +procedure reduce_ammo_on_ground_by_pack_qty(variable item) begin + variable + pid := obj_pid(item), + packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE), + count := get_weapon_ammo_count(item), + newCount := calc_reduced_ammo_count(pid, packSize, count); + + if (newCount >= count) then return ""; + if (newCount > 0) then + set_weapon_ammo_count(item, newCount); + else + destroy_object(item); + + return string_format("%s (%d -> %d)", obj_name(item), count, newCount); end procedure reduce_container_loot(variable container) begin @@ -40,11 +91,9 @@ procedure reduce_container_loot(variable container) begin switch (subType) begin case item_type_weapon: - stats := reduce_item_in_stack(container, item, ini_reduce_weapons_pids, ini_reduce_weapons_percent); + stats := unload_weapon(item); case item_type_ammo: - stats := reduce_item_in_stack(container, item, 0, ini_reduce_ammo_percent); - case item_type_drug: - stats := reduce_item_in_stack(container, item, ini_reduce_drugs_pids, ini_reduce_drugs_percent); + stats := reduce_ammo_in_stack_by_pack_qty(container, item); case item_type_container: stats := reduce_container_loot(item); default: @@ -66,11 +115,9 @@ procedure reduce_ground_item_loot(variable item) begin //debug_log_fmt("processing %s (%d)...", obj_name(item), subType); switch (subType) begin case item_type_weapon: - return reduce_item_on_ground(item, ini_reduce_weapons_pids, ini_reduce_weapons_percent); + return unload_weapon(item); case item_type_ammo: - return reduce_item_on_ground(item, 0, ini_reduce_ammo_percent); - case item_type_drug: - return reduce_item_on_ground(item, ini_reduce_drugs_pids, ini_reduce_drugs_percent); + return reduce_ammo_on_ground_by_pack_qty(item); case item_type_container: begin return reduce_container_loot(item); end @@ -90,38 +137,6 @@ procedure reduce_loot_on_map begin end end -/* -procedure get_processed_containers_map begin - if (not processed_containers_map) then - processed_containers_map := load_create_array_map(ARR_LOOTED_CONTAINERS); - return processed_containers_map; -end - -#define processed_map_key(obj) ((cur_map_index * 0x100000) bwor get_object_data(obj, OBJ_DATA_ID)) - -procedure useanimobj_hook begin - variable user := get_sfall_arg, obj := get_sfall_arg; - if (user != dude_obj or obj_type(obj) != OBJ_TYPE_ITEM or obj_item_subtype(obj) != item_type_container) then return; - - variable stats, - processed := get_processed_containers_map, - key := processed_map_key(obj); - - display_msg_fmt("useobj %s key %x processed: %d", obj_name(obj), key, processed[key]); - - if (processed[key]) then return; - - stats := reduce_container_loot(obj); - if (stats != "") then - debug_log_fmt("Reduce loot [%d-%d] %s", elevation(obj), tile_num(obj), stats); - - processed[key] := 1; -end - -procedure useskillon_hook begin - display_msg("useskill "+obj_name(get_sfall_arg_at(1))); -end -*/ #define INI_FILE INI_MISC #define INI_SECTION "MAP_LOOT" @@ -131,11 +146,15 @@ procedure start begin load_bool_from_ini(enable_tweaks, false); if (not ini_enable_tweaks) then return; - load_num_from_ini(reduce_ammo_percent, 0, 0, 100); - load_num_from_ini(reduce_drugs_percent, 0, 0, 100); - load_num_from_ini(reduce_weapons_percent, 0, 0, 100); - load_int_list_from_ini(reduce_drugs_pids); - load_int_list_from_ini(reduce_weapons_pids); + // load_num_from_ini(reduce_ammo_percent, 0, 0, 100); + // load_num_from_ini(reduce_drugs_percent, 0, 0, 100); + // load_num_from_ini(reduce_weapons_percent, 0, 0, 100); + // load_int_list_from_ini(reduce_drugs_pids); + // load_int_list_from_ini(reduce_weapons_pids); + + load_bool_from_ini(unload_weapons, false); + + ini_map_loot_ammo_qty := get_ini_section_int_to_int(INI_FILE, "MAP_LOOT_AMMO_QTY", true); //register_hook_proc(HOOK_USEANIMOBJ, useanimobj_hook); //register_hook_proc(HOOK_USESKILLON, useskillon_hook); @@ -149,7 +168,7 @@ end procedure map_enter_p_proc begin //debug_log("cur_town = "+cur_town+", is_loading = "+is_loading_game+", map_first_run = "+map_first_run); - if (not ini_enable_tweaks or cur_town == -1 or is_loading_game or not map_first_run) then return; + if (not ini_enable_tweaks or is_loading_game or not map_first_run) then return; call reduce_loot_on_map; end diff --git a/scripts_src/_pbs_main/wip/gl_armorappearance.ssl b/scripts_src/_pbs_main/wip/gl_armorappearance.ssl deleted file mode 100644 index 85c3732..0000000 --- a/scripts_src/_pbs_main/wip/gl_armorappearance.ssl +++ /dev/null @@ -1,48 +0,0 @@ -/* - - WIP!!! - -*/ - -#include "sfall.h" -#include "define_lite.h" -#include "..\headers\artfid.h" - -variable - defaultFids, - armorPidMap, // maps armor PID to it's "type" - leather armor, metal, power armor, etc. - npcMap; - -procedure invenwield_handler begin - variable critter, item, slot, isWorn, loc1, loc2, s; - critter := get_sfall_arg; - item := get_sfall_arg; - slot := get_sfall_arg; - isWorn := get_sfall_arg; - - s := "Wield: " + obj_name(critter); - if (item) then - s += ", " + obj_name(item); - s += ", " + slot + ", " + isWorn; - display_msg(s); - - return; - - loc2 := critter_inven_obj(critter,0); - if (loc2) then display_msg("Current armor: " + obj_name(loc2)); - - if (slot == INVEN_TYPE_WORN and critter != dude_obj) then begin - if (isWorn == 0) then - begin - // Ustawianie grafiki dla golej postaci - metarule3(107,critter,FID_NMWARR,0); - end - end -end - -procedure start begin - if game_loaded then begin - register_hook_proc(HOOK_INVENWIELD, invenwield_handler); - end -end -