OSP Code Combat Agent Take Ammo Script

Users who are viewing this thread

Hello everyone! A few days ago I was toying with Shredzorz's autofire code and porting it to work with 1.151 and without WSE. IIRC, his script doesn't take ammo, so I wrote this one. For the script to work, you will need to uncomment "#agent_get_item_slot" in header_operations.py (Not sure why they commented it out).

This script is open source and free for anyone to use.

Credit is not necessary but it would be nice. :smile:

Notes: reg0 returns the max amount taken, so if you have 30 bolts, and you take 10, you end up with reg0=10, but if you have 9 bolts and take 10, reg0 = 9.

module_scripts.py
Code:
# script_agent_take_ammo
# Input: arg1 = agent_no, arg2 = amount, arg3 = ammo_type (itp_type_arrows, itp_type_bolts, itp_type_bullets)
# Output: reg0 = ammo taken

 ("agent_take_ammo", 
    [
	(store_script_param, ":agent", 1),
	(store_script_param, ":count", 2),
	(store_script_param, ":ammo_type", 3),
	
	(assign, reg0, 0),
	(assign, ":ammo_needed", ":count"),
	(assign, ":ammo_taken", 0),
	(assign, ":stop", ek_head), # or 4, if ek_head doesn't work

	(agent_get_ammo, ":total_ammo", ":agent", 1),

	(try_for_range, ":item_slot", 0, ":stop"),
		(neq, ":stop", 0),

		# Get the item and make sure it's the right type
	    	(agent_get_item_slot, ":item", ":agent", ":item_slot"),
	    	
	       # Make sure there is an item
	    	(gt, ":item", 0),
		(item_get_type, ":item_type", ":item"),
		(eq, ":item_type", ":ammo_type"),

		# Get ammo of slot
		(agent_get_ammo_for_slot, ":ammo", ":agent", ":item_slot"),

		(try_begin),
			# Make sure item has ammo, if not, we cycle to the next one
			(gt, ":ammo", 0),
			(try_begin),
				# If ammo >= needed ammo, take required ammo and stop
				(ge, ":ammo", ":ammo_needed"),
				(val_sub, ":ammo", ":ammo_needed"),
				(val_add, ":ammo_taken", ":ammo_needed"),
				(agent_set_ammo, ":agent", ":item", ":ammo"),
				(assign, ":stop", 0),
			(else_try),
				# If ammo < needed ammo, take all ammo
				(lt, ":ammo", ":ammo_needed"),
				(val_add, ":ammo_taken", ":ammo"),
				(agent_set_ammo, ":agent", ":item", 0),
			(try_end),				
		(try_end),
		(try_begin),
			(le, ":ammo_needed", 0),
			(assign, ":stop", 0),
		(try_end),
	(try_end),

	(assign, reg0, ":ammo_taken"),

    ]),

module_mission_templates.py
Code:
# Example Trigger
test1 = (0, 0, 0, [(key_clicked, key_z)], 
[
	(get_player_agent_no, ":agent"),
	(call_script, "script_agent_take_ammo", ":agent", 10, itp_type_arrows),
	(display_message, "@Arrows taken: {reg0}"),
	(call_script, "script_agent_take_ammo", ":agent", 10, itp_type_bolts),
	(display_message, "@Bolts taken: {reg0}"),
	(call_script, "script_agent_take_ammo", ":agent", 10, itp_type_bullets),
	(display_message, "@Bullets taken: {reg0}"),
])
 
You can break out of a loop by changing the boundary conditions. Although in this case it's only 4 iterations, which isn't that big of a deal. I would also start it from the bottom (since players are more likely to put weapons first), but more iterations might be with bots than players.
Code:
(assign, ":stop", ek_head),
(try_for_range, ":item_slot", 0, ":stop"),
...
(assign, ":stop", 0),
(try_end),
You can also directly use 0 as the last parameter without (assign, ":ammo", 0), and I suspect you'll want  (val_sub, ":ammo_needed", ":ammo"), instead of 0.
 
You can break out of a loop by changing the boundary conditions. Although in this case it's only 4 iterations, which isn't that big of a deal. I would also start it from the bottom (since players are more likely to put weapons first), but more iterations might be with bots than players.

By starting with the first item I think it mimics what the M&B engine does when you reload weapons, though it could probably be optimized by starting from the bottom to (hopefully) perform less loops. (I might add an alternate version).

Code:
(assign, ":stop", ek_head),
(try_for_range, ":item_slot", 0, ":stop"),
...
(assign, ":stop", 0),
(try_end),
OK, I'll try that. Thanks!

You can also directly use 0 as the last parameter without (assign, ":ammo", 0), and I suspect you'll want  (val_sub, ":ammo_needed", ":ammo"), instead of 0.
I need a little bit more info on this. :smile:
 
(val_sub, ":ammo_needed", 0), doesn't do anything at all
(assign, ":ammo", 0), does the same, and you can simply call (agent_set_ammo, ":agent", ":item", ":ammo"), on the next line.
 
Somebody said:
(val_sub, ":ammo_needed", 0), doesn't do anything at all
(assign, ":ammo", 0), does the same, and you can simply call (agent_set_ammo, ":agent", ":item", ":ammo"), on the next line.

Thanks a lot! Spotting those minor errors are really helpful. :smile:
 
Back
Top Bottom