Skip to content

Commit 3cbc98a

Browse files
committed
New script for reducing ammo & drugs in containers and on the ground
1 parent 4e94932 commit 3cbc98a

File tree

6 files changed

+289
-57
lines changed

6 files changed

+289
-57
lines changed

root/mods/ecco/combat.ini

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,12 @@ destroy_weapon_percent=50
107107
; comma-separated list of weapon PIDs that may be destroyed by "destroy_weapon_chance"
108108
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
109109

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

116117
; comma-separated list of drug pids to be subject of reduce
117118
; Currently: Stimpak, Radaway, Antidote, Mentats, Buffout, Rad-X, Psycho, Super Stimpak, Healing powder

root/mods/ecco/misc.ini

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ fuel_consumption_base=75
120120
fuel_cell_regulator_percent=30
121121

122122

123+
[MAP_LOOT]
124+
; 1 to enable all map loot tweaks, 0 to disable
125+
enable_tweaks=0
126+
127+
; set positive to reduce number of ammo in containers on maps: <min_chance>,<max_chance>
128+
; 100 means remove all, 50 mean roughly 50% of ammo will be deleted, etc.
129+
reduce_ammo_percent=40,60
130+
131+
; set positive to reduce number of drugs in containers: <min_chance>,<max_chance>
132+
reduce_drugs_percent=50
133+
134+
; comma-separated list of drug pids to be subject of reduce
135+
; Currently: Stimpak, Radaway, Antidote, Mentats, Buffout, Rad-X, Psycho, Super Stimpak, Healing powder
136+
reduce_drugs_pids=40,48,49,53,87,109,110,144,273
137+
123138

124139
[TOWN_REP]
125140
0=47 ; ARROYO

scripts_src/_pbs_craft/gl_pbs_craft.ssl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ procedure mouseclick_handler begin
214214
btn := get_sfall_arg;
215215
//window := get_window_under_mouse;
216216

217-
display_msg(string_format("mouseclick (%d, %d) mode %x", get_mouse_x, get_mouse_y, get_game_mode));
217+
//display_msg(string_format("mouseclick (%d, %d) mode %x", get_mouse_x, get_mouse_y, get_game_mode));
218218
if (btn == 0 and mouse_over_button and can_enter_crafting) then begin
219219
if (pressed) then begin
220220
call draw_button(true);

scripts_src/_pbs_headers/loot_utils.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#ifndef PBS_LOOT_UTILS_H
2+
#define PBS_LOOT_UTILS_H
3+
4+
5+
#include "../sfall/lib.arrays.h"
6+
#include "../sfall/lib.inven.h"
7+
8+
#include "../_pbs_headers/math_ext.h"
9+
#include "../_pbs_headers/ecco_log.h"
10+
11+
12+
procedure reduce_item_count(variable invenObj, variable item, variable newCount) begin
13+
variable count := obj_is_carrying_obj(invenObj, item);
14+
if (newCount >= count) then return;
15+
16+
count := rm_mult_objs_from_inven(invenObj, item, count - newCount);
17+
destroy_object(item);
18+
end
19+
20+
#define calc_reduced_ammo_range(count, percentRange) math_round_chance(count * (100 - random(percentRange[0], percentRange[1])) / 100.0)
21+
22+
/**
23+
* Reduces number of individual bullets in an ammo stack by a percentage range.
24+
* @arg {ObjectPtr} invenObj - Container or critter
25+
* @arg {ObjectPtr} item - item stack object
26+
* @arg {list} percentRange - [min, max] range of % to remove
27+
* @ret {string}
28+
*/
29+
procedure reduce_ammo_in_stack(variable invenObj, variable item, variable percentRange) begin
30+
if (percentRange[1] <= 0) then return "";
31+
32+
variable
33+
pid := obj_pid(item),
34+
packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE),
35+
count := (obj_is_carrying_obj(invenObj, item) - 1) * packSize + get_weapon_ammo_count(item),
36+
newCount := calc_reduced_ammo_range(count, percentRange);
37+
38+
//display_msg("count: "+count+", pack: "+packSize+", new: "+newCount+" ("+ceil(1.0*newCount / packSize)+")");
39+
call reduce_item_count(invenObj, item, ceil(1.0 * newCount / packSize));
40+
// if number of items reduced, object reference will be different
41+
item := obj_carrying_pid_obj(invenObj, pid);
42+
if (item and newCount % packSize > 0) then
43+
set_weapon_ammo_count(item, newCount % packSize);
44+
45+
return obj_name(item)+" ("+count+" -> "+newCount+")";
46+
end
47+
48+
49+
/**
50+
* Reduces number of individual bullets in an ammo stack by a percentage range.
51+
* @arg {ObjectPtr} item - Weapon item
52+
* @arg {list} percentRange - [min, max] range of % to remove
53+
* @ret {string}
54+
*/
55+
procedure reduce_ammo_in_weapon(variable item, variable percentRange) begin
56+
if (percentRange[1] <= 0) then return "";
57+
58+
variable
59+
pid := obj_pid(item),
60+
count := get_weapon_ammo_count(item),
61+
newCount;
62+
63+
if (count <= 0) then return "";
64+
65+
newCount := calc_reduced_ammo_range(count, percentRange);
66+
set_weapon_ammo_count(item, newCount);
67+
return string_format("%s mag ammo (%d -> %d)", obj_name(item), count, newCount);
68+
end
69+
70+
/**
71+
* Reduces number of individual bullets in an ammo obj on the ground.
72+
* @arg {ObjectPtr} item - item stack object
73+
* @arg {list} percentRange - [min, max] range of % to remove
74+
*/
75+
procedure reduce_ammo_on_ground(variable item, variable percentRange) begin
76+
if (percentRange[1] <= 0) then return "";
77+
78+
variable
79+
pid := obj_pid(item),
80+
count := get_weapon_ammo_count(item),
81+
newCount := calc_reduced_ammo_range(count, percentRange);
82+
83+
if (newCount > 0) then
84+
set_weapon_ammo_count(item, newCount);
85+
else
86+
destroy_object(item);
87+
88+
return string_format("%s (%d -> %d)", obj_name(item), count, newCount);
89+
end
90+
91+
92+
/**
93+
* Reduces number of drug/misc items in stack by a percentage.
94+
* @arg {ObjectPtr} invenObj - Container or critter
95+
* @arg {ObjectPtr} item - item stack object
96+
* @arg {list} pidList - list of pids allowed to be removed
97+
* @arg {int} percent - % to remove
98+
* @ret {string}
99+
*/
100+
procedure reduce_item_in_stack(variable invenObj, variable item, variable pidList, variable percent) begin
101+
if (percent <= 0) then return "";
102+
103+
variable pid := obj_pid(item);
104+
if (not is_in_array(pid, pidList)) then return "";
105+
106+
// reduce with probability formula
107+
variable
108+
count := obj_is_carrying_obj(invenObj, item),
109+
newCount := count * (100 - percent) / 100.0;
110+
111+
//debug_log_fmt("reducing %d -> %d", count, newCount);
112+
newCount := floor(newCount) + (random(0, 99) < (newCount - floor(newCount))*100);
113+
call reduce_item_count(invenObj, item, newCount);
114+
115+
return obj_name(item)+" ("+count+" -> "+newCount+")";
116+
end
117+
118+
/**
119+
* Removes item on the ground with a given percentage chance.
120+
* @arg {ObjectPtr} item - item stack object
121+
* @arg {list} pidList - list of pids allowed to be removed
122+
* @arg {int} percent - % chance to remove
123+
*/
124+
procedure reduce_item_on_ground(variable item, variable pidList, variable percent) begin
125+
if (percent <= 0
126+
or not is_in_array(obj_pid(item), pidList)
127+
or random(0, 99) >= percent) then return "";
128+
129+
destroy_object(item);
130+
return obj_name(item) + " (removed)";
131+
end
132+
133+
#endif

scripts_src/_pbs_main/gl_pbs_critter_loot.ssl

Lines changed: 14 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ procedure start;
2323
#include "../_pbs_headers/ecco_ini.h"
2424
#include "../_pbs_headers/ecco_msg.h"
2525

26+
#include "../_pbs_headers/loot_utils.h"
27+
2628
variable
2729
ini_destroy_weapon_percent,
2830
ini_destroy_weapon_list,
2931
ini_weapon_drop_chance,
3032
ini_weapon_drop_dist,
3133
ini_weapon_drop_dir,
32-
ini_reduce_ammo_percent_min,
33-
ini_reduce_ammo_percent_max,
34+
ini_reduce_ammo_percent,
3435
ini_reduce_drugs_percent,
3536
ini_reduce_drugs_pids;
3637

@@ -40,7 +41,6 @@ variable destroyed_stats;
4041
procedure destroy_critter_weapon(variable critter);
4142
procedure drop_weapons(variable critter);
4243
procedure reduce_loot(variable critter);
43-
procedure reduce_item_count(variable invenobj, variable item, variable newCount);
4444

4545
#define INI_FILE INI_COMBAT
4646
#define INI_SECTION "CRITTER_LOOT"
@@ -64,7 +64,7 @@ procedure ondeath_handler begin
6464
return;
6565

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

85-
load_num_from_ini(reduce_ammo_percent_min, 0, 0, 100);
86-
load_num_from_ini(reduce_ammo_percent_max, ini_reduce_ammo_percent_min, ini_reduce_ammo_percent_min, 100);
85+
load_range_from_ini(reduce_ammo_percent, 0, 0, 0, 100);
8786
load_num_from_ini(reduce_drugs_percent, 0, 0, 100);
8887
load_int_list_from_ini(reduce_drugs_pids);
8988

@@ -172,67 +171,30 @@ procedure reduce_loot(variable critter) begin
172171
variable
173172
item,
174173
list,
175-
count,
176-
newCount,
177-
packSize,
178-
pid,
179-
removeStats,
180-
weaponStats;
174+
removeStats;
181175

182176
list := inven_as_array(critter);
183177
removeStats := "";
184178
foreach item in list begin
185179
if (item == 0) then
186180
continue;
187-
pid := obj_pid(item);
188181
if (obj_item_subtype(item) == item_type_ammo) then begin
189-
if (ini_reduce_ammo_percent_min > 0) then begin
190-
// reduce ammo in measures of individual rounds, not packs
191-
packSize := get_proto_data(pid, PROTO_AM_PACK_SIZE);
192-
count := (obj_is_carrying_obj(critter, item) - 1) * packSize + get_weapon_ammo_count(item);
193-
newCount := round(count * (100 - random(ini_reduce_ammo_percent_min, ini_reduce_ammo_percent_max)) / 100.0);
194-
//display_msg("count: "+count+", pack: "+packSize+", new: "+newCount+" ("+ceil(1.0*newCount / packSize)+")");
195-
call reduce_item_count(critter, item, ceil(1.0*newCount / packSize));
196-
// if number of items reduced, object reference will be different
197-
item := obj_carrying_pid_obj(critter, pid);
198-
if (item and newCount % packSize > 0) then
199-
set_weapon_ammo_count(item, newCount % packSize);
200-
201-
removeStats += obj_name(item)+" ("+count+" -> "+newCount+"), ";
202-
end
182+
removeStats += reduce_ammo_in_stack(critter, item, ini_reduce_ammo_percent);
203183
end
204184
else if (obj_item_subtype(item) == item_type_drug) then begin
205-
if (ini_reduce_drugs_percent > 0 and is_in_array(pid, ini_reduce_drugs_pids)) then begin
206-
// reduce with probability formula
207-
count := obj_is_carrying_obj(critter, item);
208-
newCount := count * (100 - ini_reduce_drugs_percent) / 100.0;
209-
newCount := floor(newCount) + (random(0, 99) < (newCount - floor(newCount))*100);
210-
call reduce_item_count(critter, item, newCount);
211-
removeStats += obj_name(item)+" ("+count+" -> "+newCount+"), ";
212-
end
185+
removeStats += reduce_item_in_stack(critter, item, ini_reduce_drugs_pids, ini_reduce_drugs_percent);
213186
end
214187
else if (obj_item_subtype(item) == item_type_weapon) then begin
215-
if (ini_destroy_weapon_percent > 0 and is_in_array(pid, ini_destroy_weapon_list)) then
216-
if (try_destroy_weapon(critter, item)) then
188+
if (ini_destroy_weapon_percent > 0
189+
and is_in_array(obj_pid(item), ini_destroy_weapon_list)
190+
and try_destroy_weapon(critter, item)) then
217191
removeStats += obj_name(item)+", ";
192+
else
193+
removeStats += reduce_ammo_in_weapon(item, ini_reduce_ammo_percent);
218194
end
219195
end
220196
if (removeStats != "") then
221-
debug_log("removed loot for "+obj_name(critter)+": "+removeStats);
222-
end
223-
224-
225-
procedure reduce_item_count(variable invenobj, variable item, variable newCount) begin
226-
variable count := obj_is_carrying_obj(invenobj, item);
227-
if (newCount >= count) then return;
228-
229-
count := rm_mult_objs_from_inven(invenobj, item, count - newCount);
230-
destroy_object(item);
197+
debug_log("Removed loot for "+obj_name(critter)+": "+removeStats);
231198
end
232199

233200

234-
235-
236-
237-
238-

0 commit comments

Comments
 (0)