Skip to content

Commit

Permalink
New script for reducing ammo & drugs in containers and on the ground
Browse files Browse the repository at this point in the history
  • Loading branch information
phobos2077 committed Jun 1, 2024
1 parent 4e94932 commit 3cbc98a
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 57 deletions.
9 changes: 5 additions & 4 deletions root/mods/ecco/combat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ destroy_weapon_percent=50
; comma-separated list of weapon PIDs that may be destroyed by "destroy_weapon_chance"
destroy_weapon_list=5,6,8,9,10,11,12,13,15,16,18,22,23,24,28,94,115,116,118,122,143,160,233,235,242,268,283,287,296,299,300,313,332,350,351,352,353,354,355,385,387,388,389,391,392,394,395,396,397,398,399,400,401,402,403,404,405,406,407,500,522,617,629,630,634,638,639,640,643,644,646,647,648

; set positive to reduce number of ammo (not including ammo loaded in guns) and/or drugs left in critters after death:
; set positive to reduce % of ammo (not including ammo loaded in guns) left in critters after death: <min_percent>,<max_percent>
; 100 means remove all, 50 mean roughly 50% of ammo will be deleted, etc.
reduce_ammo_percent_min=50
reduce_ammo_percent_max=90
reduce_drugs_percent=70
reduce_ammo_percent=50,90

; set positive to reduce % of drugs left in critters after death
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
Expand Down
15 changes: 15 additions & 0 deletions root/mods/ecco/misc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ fuel_consumption_base=75
fuel_cell_regulator_percent=30


[MAP_LOOT]
; 1 to enable all map loot tweaks, 0 to disable
enable_tweaks=0

; set positive to reduce number of ammo in containers on maps: <min_chance>,<max_chance>
; 100 means remove all, 50 mean roughly 50% of ammo will be deleted, etc.
reduce_ammo_percent=40,60

; set positive to reduce number of drugs in containers: <min_chance>,<max_chance>
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


[TOWN_REP]
0=47 ; ARROYO
Expand Down
2 changes: 1 addition & 1 deletion scripts_src/_pbs_craft/gl_pbs_craft.ssl
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ procedure mouseclick_handler begin
btn := get_sfall_arg;
//window := get_window_under_mouse;

display_msg(string_format("mouseclick (%d, %d) mode %x", get_mouse_x, get_mouse_y, get_game_mode));
//display_msg(string_format("mouseclick (%d, %d) mode %x", get_mouse_x, get_mouse_y, get_game_mode));
if (btn == 0 and mouse_over_button and can_enter_crafting) then begin
if (pressed) then begin
call draw_button(true);
Expand Down
133 changes: 133 additions & 0 deletions scripts_src/_pbs_headers/loot_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#ifndef PBS_LOOT_UTILS_H
#define PBS_LOOT_UTILS_H


#include "../sfall/lib.arrays.h"
#include "../sfall/lib.inven.h"

#include "../_pbs_headers/math_ext.h"
#include "../_pbs_headers/ecco_log.h"


procedure reduce_item_count(variable invenObj, variable item, variable newCount) begin
variable count := obj_is_carrying_obj(invenObj, item);
if (newCount >= count) then return;

count := rm_mult_objs_from_inven(invenObj, item, count - newCount);
destroy_object(item);
end

#define calc_reduced_ammo_range(count, percentRange) math_round_chance(count * (100 - random(percentRange[0], percentRange[1])) / 100.0)

/**
* Reduces number of individual bullets in an ammo stack by a percentage range.
* @arg {ObjectPtr} invenObj - Container or critter
* @arg {ObjectPtr} item - item stack object
* @arg {list} percentRange - [min, max] range of % to remove
* @ret {string}
*/
procedure reduce_ammo_in_stack(variable invenObj, variable item, variable percentRange) begin
if (percentRange[1] <= 0) then return "";

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_range(count, percentRange);

//display_msg("count: "+count+", pack: "+packSize+", new: "+newCount+" ("+ceil(1.0*newCount / packSize)+")");
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


/**
* Reduces number of individual bullets in an ammo stack by a percentage range.
* @arg {ObjectPtr} item - Weapon item
* @arg {list} percentRange - [min, max] range of % to remove
* @ret {string}
*/
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;

if (count <= 0) then return "";

newCount := calc_reduced_ammo_range(count, percentRange);
set_weapon_ammo_count(item, newCount);
return string_format("%s mag ammo (%d -> %d)", obj_name(item), count, newCount);
end

/**
* Reduces number of individual bullets in an ammo obj on the ground.
* @arg {ObjectPtr} item - item stack object
* @arg {list} percentRange - [min, max] range of % to remove
*/
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);

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


/**
* Reduces number of drug/misc items in stack by a percentage.
* @arg {ObjectPtr} invenObj - Container or critter
* @arg {ObjectPtr} item - item stack object
* @arg {list} pidList - list of pids allowed to be removed
* @arg {int} percent - % to remove
* @ret {string}
*/
procedure reduce_item_in_stack(variable invenObj, variable item, variable pidList, variable percent) begin
if (percent <= 0) then return "";

variable pid := obj_pid(item);
if (not is_in_array(pid, pidList)) then return "";

// reduce with probability formula
variable
count := obj_is_carrying_obj(invenObj, item),
newCount := count * (100 - percent) / 100.0;

//debug_log_fmt("reducing %d -> %d", count, newCount);
newCount := floor(newCount) + (random(0, 99) < (newCount - floor(newCount))*100);
call reduce_item_count(invenObj, item, newCount);

return obj_name(item)+" ("+count+" -> "+newCount+")";
end

/**
* Removes item on the ground with a given percentage chance.
* @arg {ObjectPtr} item - item stack object
* @arg {list} pidList - list of pids allowed to be removed
* @arg {int} percent - % chance to remove
*/
procedure reduce_item_on_ground(variable item, variable pidList, variable percent) begin
if (percent <= 0
or not is_in_array(obj_pid(item), pidList)
or random(0, 99) >= percent) then return "";

destroy_object(item);
return obj_name(item) + " (removed)";
end

#endif
66 changes: 14 additions & 52 deletions scripts_src/_pbs_main/gl_pbs_critter_loot.ssl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ procedure start;
#include "../_pbs_headers/ecco_ini.h"
#include "../_pbs_headers/ecco_msg.h"

#include "../_pbs_headers/loot_utils.h"

variable
ini_destroy_weapon_percent,
ini_destroy_weapon_list,
ini_weapon_drop_chance,
ini_weapon_drop_dist,
ini_weapon_drop_dir,
ini_reduce_ammo_percent_min,
ini_reduce_ammo_percent_max,
ini_reduce_ammo_percent,
ini_reduce_drugs_percent,
ini_reduce_drugs_pids;

Expand All @@ -40,7 +41,6 @@ variable destroyed_stats;
procedure destroy_critter_weapon(variable critter);
procedure drop_weapons(variable critter);
procedure reduce_loot(variable critter);
procedure reduce_item_count(variable invenobj, variable item, variable newCount);

#define INI_FILE INI_COMBAT
#define INI_SECTION "CRITTER_LOOT"
Expand All @@ -64,7 +64,7 @@ procedure ondeath_handler begin
return;

if (critter and obj_type(critter) == OBJ_TYPE_CRITTER) then begin
if (ini_reduce_ammo_percent_min > 0 or ini_reduce_drugs_percent > 0 or ini_destroy_weapon_percent > 0) then begin
if (ini_reduce_ammo_percent[1] > 0 or ini_reduce_drugs_percent > 0 or ini_destroy_weapon_percent > 0) then begin
call reduce_loot(critter);
end
if (ini_weapon_drop_chance > 0 and random(1, 100) <= ini_weapon_drop_chance) then begin
Expand All @@ -82,8 +82,7 @@ procedure start begin
load_num_from_ini(weapon_drop_dist, 0, 0, 10);
load_num_from_ini(weapon_drop_dir, 0, 0, 5);

load_num_from_ini(reduce_ammo_percent_min, 0, 0, 100);
load_num_from_ini(reduce_ammo_percent_max, ini_reduce_ammo_percent_min, ini_reduce_ammo_percent_min, 100);
load_range_from_ini(reduce_ammo_percent, 0, 0, 0, 100);
load_num_from_ini(reduce_drugs_percent, 0, 0, 100);
load_int_list_from_ini(reduce_drugs_pids);

Expand Down Expand Up @@ -172,67 +171,30 @@ procedure reduce_loot(variable critter) begin
variable
item,
list,
count,
newCount,
packSize,
pid,
removeStats,
weaponStats;
removeStats;

list := inven_as_array(critter);
removeStats := "";
foreach item in list begin
if (item == 0) then
continue;
pid := obj_pid(item);
if (obj_item_subtype(item) == item_type_ammo) then begin
if (ini_reduce_ammo_percent_min > 0) then begin
// reduce ammo in measures of individual rounds, not packs
packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE);
count := (obj_is_carrying_obj(critter, item) - 1) * packSize + get_weapon_ammo_count(item);
newCount := round(count * (100 - random(ini_reduce_ammo_percent_min, ini_reduce_ammo_percent_max)) / 100.0);
//display_msg("count: "+count+", pack: "+packSize+", new: "+newCount+" ("+ceil(1.0*newCount / packSize)+")");
call reduce_item_count(critter, item, ceil(1.0*newCount / packSize));
// if number of items reduced, object reference will be different
item := obj_carrying_pid_obj(critter, pid);
if (item and newCount % packSize > 0) then
set_weapon_ammo_count(item, newCount % packSize);

removeStats += obj_name(item)+" ("+count+" -> "+newCount+"), ";
end
removeStats += reduce_ammo_in_stack(critter, item, ini_reduce_ammo_percent);
end
else if (obj_item_subtype(item) == item_type_drug) then begin
if (ini_reduce_drugs_percent > 0 and is_in_array(pid, ini_reduce_drugs_pids)) then begin
// reduce with probability formula
count := obj_is_carrying_obj(critter, item);
newCount := count * (100 - ini_reduce_drugs_percent) / 100.0;
newCount := floor(newCount) + (random(0, 99) < (newCount - floor(newCount))*100);
call reduce_item_count(critter, item, newCount);
removeStats += obj_name(item)+" ("+count+" -> "+newCount+"), ";
end
removeStats += reduce_item_in_stack(critter, item, ini_reduce_drugs_pids, ini_reduce_drugs_percent);
end
else if (obj_item_subtype(item) == item_type_weapon) then begin
if (ini_destroy_weapon_percent > 0 and is_in_array(pid, ini_destroy_weapon_list)) then
if (try_destroy_weapon(critter, item)) then
if (ini_destroy_weapon_percent > 0
and is_in_array(obj_pid(item), ini_destroy_weapon_list)
and try_destroy_weapon(critter, item)) then
removeStats += obj_name(item)+", ";
else
removeStats += reduce_ammo_in_weapon(item, ini_reduce_ammo_percent);
end
end
if (removeStats != "") then
debug_log("removed loot for "+obj_name(critter)+": "+removeStats);
end


procedure reduce_item_count(variable invenobj, variable item, variable newCount) begin
variable count := obj_is_carrying_obj(invenobj, item);
if (newCount >= count) then return;

count := rm_mult_objs_from_inven(invenobj, item, count - newCount);
destroy_object(item);
debug_log("Removed loot for "+obj_name(critter)+": "+removeStats);
end







Loading

0 comments on commit 3cbc98a

Please sign in to comment.