Skip to content

Commit

Permalink
Map ammo reduction and map tweaker spatial script fix
Browse files Browse the repository at this point in the history
- 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)
  • Loading branch information
phobos2077 committed Jul 5, 2024
1 parent ea48a38 commit ac7550d
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 129 deletions.
6 changes: 4 additions & 2 deletions root/data/config/pbs_map_tweaks.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ run_on_load=0
; a<pid>:<count>:<ammo>:<ammoPid> - adds an object with given PID and count (defaults to 1 if omitted)
; r<pid>:<count> - remove up to count items
; w<pid>:<inactive> - 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<sid>:<radius> - sets script ID for the main object on tile; if tile is empty and radius is set - creates a spatial script instead
; s<sid>:<radius> - sets script ID for the main object on tile; if radius is set - creates a spatial script instead


; ARCAVES
Expand Down Expand Up @@ -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
Expand Down
59 changes: 42 additions & 17 deletions root/mods/ecco/misc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 0 additions & 2 deletions scripts_src/_pbs_headers/loot_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);

Expand Down
11 changes: 4 additions & 7 deletions scripts_src/_pbs_main/gl_pbs_map_tweaker.ssl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
125 changes: 72 additions & 53 deletions scripts_src/_pbs_main/gl_pbs_map_tweaks_loot.ssl
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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"
Expand All @@ -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);
Expand All @@ -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
48 changes: 0 additions & 48 deletions scripts_src/_pbs_main/wip/gl_armorappearance.ssl

This file was deleted.

0 comments on commit ac7550d

Please sign in to comment.