I made this for a super secret project, but someone else wanted it too, so I figured I would just release it as OSP for everyone to use. As the title of the thread says, it's a script that allows for automatic firearms in singleplayer. It works by holding down the right mouse button to aim and the left mouse button to fire. It also makes the AI fire automatic weapons in bursts. It doesn't use up ammunition, so you've got infinite ammo for the time being. I've still got a lot of work to do on it, but I'd like to get some feedback on it in its current state.
A few comments on code simplification, more than anything else...not sure if this is the detail you were after or not
For the player trigger:
1) I guess my personal taste--I'm not sure how much performance it does or doesn't save--is to move as much as possible into the conditions block, so all the stuff through (eq, ":wielded_type", itp_type_pistol), could be in the conditions block to prevent the consequence block from getting loaded into memory unnecessarily. In the same vein, I might put the cooldown stuff in the conditions block and then end the block with a key_is_down, key_right_mouse_button check. Again, not positive if this is better or not.
2) The try block to get the ek_slot of the wielded item can be removed in favor of the WSE operation:
(agent_get_wielded_item_slot_no, <destination>, <agent_no>, [<hand_no>]), #Stores <agent_no>'s wielded item slot for [<hand_no>] into <destination>
3) Using the (troop_has_item_equipped, ":troop", ":ammo"), for the player will check against the troop's equipment at the beginning of the mission, not what the player-agent currently has equipped. I think (agent_has_item_equipped,<agent_id>,<item_id>), is needed here
4) It looks like it uses ammo...is this not removing ammo??:
(val_sub, ":ammo_amount", 1),
(agent_set_item_slot_ammo, ":agent", ":item_slot", ":ammo_amount"),
5) Might gk_attack and gk_defend be better than key_right/left_mouse_button ?
6) A curiosity question more than anything else...these operations take the weapon's item slot, NOT the ammo's item slot? I'd thought they took the ammo's slot, while you use the wielded weapon's slot.
(agent_get_item_slot_ammo, <destination>, <agent_no>, <item_slot_no>), #Stores <agent_no>'s <item_slot_no> ammo count into <destination>
(agent_set_item_slot_ammo, <agent_no>, <item_slot_no>, <value>), #Sets <agent_no>'s <item_slot_no> ammo count to <value>
AI Trigger:
1) (troop_get_class, ":cur_agent_class", ":troop"), should probably be (agent_get_division, ":cur_agent_class", ":cur_agent"), and then you don't need to bother with getting the troop ID
2) See comments 2 and 3 (and 6) above--particularly for 3 since not all agents will have all the equipment of the troop template and the template might not have that specific item marked as equipped even though the agent does
3) (agent_get_team, ":target_team", ":target_agent"),
(teams_are_enemies, ":target_team", ":cur_agent_team"),
I believe can be simplified to (neg|agent_is_ally, ":target_agent"),
4) Curiosity question 2: what does moving the Z of the target position up 150 accomplish?
5) (team_get_hold_fire_order, ":fire_order", ":cur_agent_team"),
(neq, ":fire_order", aordr_hold_your_fire),
...you already got the hold fire order higher in the loop, and here you aren't specifying a division, so it will use division 0 and I don't think you necessarily care about grc_infantry's hold fire order. Particularly if the agent isn't in that division
6) You might also want to get the agent's simple behavior and/or combat state, before you get the target agent:
#Values for agent_get_combat_state
cs_free = 0
cs_target_in_sight = 1 # ranged units
cs_guard = 2 # no shield
cs_wield = 3 # reach out weapon, preparing to strike, melee units
cs_fire = 3 # ranged units
cs_swing = 4 # cut / thrust, melee units
cs_load = 4 # crossbow units
cs_still = 7 # melee units, happens, not always (seems to have something to do with the part of body hit), when hit
cs_no_visible_targets = 7 # ranged units or blocking iwth a shield
cs_target_on_right_hand_side = 8 # horse archers
# For the player or dead units it always returns 0.
# But for living human agents here are some of the values it can return and what each seems to mean:
# 0 = nothing active
# 1 = firing ranged
# 3 = preparing and holding attack (either melee or ranged)
# 4 = swinging with melee
# 7 = recovering from being hit
# 8 = ranged equipped, no target in field of view
and being sure that the combat state isn't higher than 4, for instance
In general--I haven't put a lot of thought into this--I'm wondering if it wouldn't be possible to toss the burst code into a ti_on_weapon_attack item trigger, allowing the engine to control more of this rather than the micromanagement, particularly for the bots.
6) A curiosity question more than anything else...these operations take the weapon's item slot, NOT the ammo's item slot? I'd thought they took the ammo's slot, while you use the wielded weapon's slot.
(agent_get_item_slot_ammo, <destination>, <agent_no>, <item_slot_no>), #Stores <agent_no>'s <item_slot_no> ammo count into <destination>
(agent_set_item_slot_ammo, <agent_no>, <item_slot_no>, <value>), #Sets <agent_no>'s <item_slot_no> ammo count to <value>
6) A curiosity question more than anything else...these operations take the weapon's item slot, NOT the ammo's item slot? I'd thought they took the ammo's slot, while you use the wielded weapon's slot.
(agent_get_item_slot_ammo, <destination>, <agent_no>, <item_slot_no>), #Stores <agent_no>'s <item_slot_no> ammo count into <destination>
(agent_set_item_slot_ammo, <agent_no>, <item_slot_no>, <value>), #Sets <agent_no>'s <item_slot_no> ammo count to <value>
A few comments on code simplification, more than anything else...not sure if this is the detail you were after or not
For the player trigger:
1) I guess my personal taste--I'm not sure how much performance it does or doesn't save--is to move as much as possible into the conditions block, so all the stuff through (eq, ":wielded_type", itp_type_pistol), could be in the conditions block to prevent the consequence block from getting loaded into memory unnecessarily. In the same vein, I might put the cooldown stuff in the conditions block and then end the block with a key_is_down, key_right_mouse_button check. Again, not positive if this is better or not.
2) The try block to get the ek_slot of the wielded item can be removed in favor of the WSE operation:
(agent_get_wielded_item_slot_no, <destination>, <agent_no>, [<hand_no>]), #Stores <agent_no>'s wielded item slot for [<hand_no>] into <destination>
3) Using the (troop_has_item_equipped, ":troop", ":ammo"), for the player will check against the troop's equipment at the beginning of the mission, not what the player-agent currently has equipped. I think (agent_has_item_equipped,<agent_id>,<item_id>), is needed here
4) It looks like it uses ammo...is this not removing ammo??:
(val_sub, ":ammo_amount", 1),
(agent_set_item_slot_ammo, ":agent", ":item_slot", ":ammo_amount"),
5) Might gk_attack and gk_defend be better than key_right/left_mouse_button ?
6) A curiosity question more than anything else...these operations take the weapon's item slot, NOT the ammo's item slot? I'd thought they took the ammo's slot, while you use the wielded weapon's slot.
(agent_get_item_slot_ammo, <destination>, <agent_no>, <item_slot_no>), #Stores <agent_no>'s <item_slot_no> ammo count into <destination>
(agent_set_item_slot_ammo, <agent_no>, <item_slot_no>, <value>), #Sets <agent_no>'s <item_slot_no> ammo count to <value>
AI Trigger:
1) (troop_get_class, ":cur_agent_class", ":troop"), should probably be (agent_get_division, ":cur_agent_class", ":cur_agent"), and then you don't need to bother with getting the troop ID
2) See comments 2 and 3 (and 6) above--particularly for 3 since not all agents will have all the equipment of the troop template and the template might not have that specific item marked as equipped even though the agent does
3) (agent_get_team, ":target_team", ":target_agent"),
(teams_are_enemies, ":target_team", ":cur_agent_team"),
I believe can be simplified to (neg|agent_is_ally, ":target_agent"),
4) Curiosity question 2: what does moving the Z of the target position up 150 accomplish?
5) (team_get_hold_fire_order, ":fire_order", ":cur_agent_team"),
(neq, ":fire_order", aordr_hold_your_fire),
...you already got the hold fire order higher in the loop, and here you aren't specifying a division, so it will use division 0 and I don't think you necessarily care about grc_infantry's hold fire order. Particularly if the agent isn't in that division
6) You might also want to get the agent's simple behavior and/or combat state, before you get the target agent:
#Values for agent_get_combat_state
cs_free = 0
cs_target_in_sight = 1 # ranged units
cs_guard = 2 # no shield
cs_wield = 3 # reach out weapon, preparing to strike, melee units
cs_fire = 3 # ranged units
cs_swing = 4 # cut / thrust, melee units
cs_load = 4 # crossbow units
cs_still = 7 # melee units, happens, not always (seems to have something to do with the part of body hit), when hit
cs_no_visible_targets = 7 # ranged units or blocking iwth a shield
cs_target_on_right_hand_side = 8 # horse archers
# For the player or dead units it always returns 0.
# But for living human agents here are some of the values it can return and what each seems to mean:
# 0 = nothing active
# 1 = firing ranged
# 3 = preparing and holding attack (either melee or ranged)
# 4 = swinging with melee
# 7 = recovering from being hit
# 8 = ranged equipped, no target in field of view
and being sure that the combat state isn't higher than 4, for instance
In general--I haven't put a lot of thought into this--I'm wondering if it wouldn't be possible to toss the burst code into a ti_on_weapon_attack item trigger, allowing the engine to control more of this rather than the micromanagement, particularly for the bots.
3) Oh yeah, I didn't even think about that. I'll do that.
4) I dunno. I haven't really delved into the ammo thing yet. I've been busy with other things. I hadn't even looked at this script for like a month until now.
5) Ah, yes. I always seem to forget about the gk_ things.
6) (cmp already replied to this one)
1) I do still need to get the troop ID so I can get its proficiency level, but I suppose I could do that.
2) Alrighty then.
3) Are you sure? Wouldn't that only check if the target is an enemy of the player?
4) Wouldn't it move the position up to the eye level of the agent? Maybe not, I haven't really tested it at all. (agent_get_look_position) has always seemed a little ambiguous to me.
5) Oops. That's embarrassing.
6) I'm not entirely sure what you mean by that. Would that really do anything?
Thanks for the feedback/help. I scripted this really fast, so there were a few stupid mistakes, but I was too used to looking at it to notice them. Always nice to have some fresh eyes look it over.
4) Wouldn't it move the position up to the eye level of the agent? Maybe not, I haven't really tested it at all. (agent_get_look_position) has always seemed a little ambiguous to me.
Checking the combat state or attack action or simple behavior earlier on might allow you to skip some of the distance/line of sight position checks that might be more onerous on the engine by failing if the agent isn't trying to fire anyway. But, with the WSE get target_agent operation (which I haven't played with yet), that might do the same thing--I'm not sure how good at is at fetching a -1 when there's not a target.
And zombies! Don't forget Zombies! Lmao
/spam
Amazing scripting work though. If you do optimize and release, it will definitely help a lot of people out. (PS: If you can just figure out how to make the AI reload weapons every X amount of shots, nobody will even realize that they have unlimited ammo)
(spawn_missile, <agent_no>, <position>, <velocity_fixed_point>, <weapon_item_no>, <missile_item_no>, [<weapon_item_modifier>], [<missile_item_modifier>]), #Spawns a <missile_item_no> shot by <agent_no> with <weapon_item_no> at <position> with <velocity_fixed_point>
Sorry for the necro, but did you end up updating the code or adding any new features? I'm in the process of trying to add my own way of reloading guns after X shots (by adding some random a** constants...not working too well)
Sorry, those models are for a mod I'm working on and aren't available for other people to use. At least not at the moment. Who knows what may happen in the future.
Also, I've started working on my Star Wars mod again after taking a short break, so that means I've started refining and improving this script again as well. There should be a better version of it available soon.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.