OSP Code Combat Script to guarantee all melee weapons (1hand, 2hand + polearms)

Users who are viewing this thread

Written for WB, SP and MP, unsure if it works with MB.

Don't know if this has been done before, but I keep seeing threads asking for "tf_guarantee_all" and "tf_guarantee_polearms" so I wrote this script.

As the subject say, this script ensures the troops have ALL 1hand 2hand and polearms mentioned in troops.py.

Add to Module_scripts,
Code:
  ("force_weapon",
   [(store_script_param, ":agent", 1),
    (try_begin),
      (this_or_next|multiplayer_is_server),
      (neg|game_in_multiplayer_mode),
      (agent_is_alive, ":agent"),
      (agent_is_non_player, ":agent"),
      (agent_get_troop_id, ":troop", ":agent"),
      (eq, ":troop", "trp_YOUR_TROOP"), 
      (troop_get_inventory_capacity, ":cap", ":troop"),
      (try_for_range, ":i", 0, ":cap"),
        (troop_get_inventory_slot, ":item", ":troop", ":i"),
        (ge, ":item", 0),
        (item_get_type, ":type", ":item"),
        (ge, ":type", itp_type_one_handed_wpn),
        (le, ":type", itp_type_polearm),
        (neg|agent_has_item_equipped, ":agent", ":item"),
        (agent_equip_item, ":agent", ":item"),
      (try_end), #try inventory
    (try_end),
    ]),
Remember, to replace : "YOUR_TROOP", with your troops id!
To enable this script for multiple troops,
replace: (eq, ":troop", "trp_YOUR_TROOP"),
with
Code:
(this_or_next|eq, ":troop", "trp_YOUR_TROOP"), 
(this_or_next|eq, ":troop", "trp_YOUR_TROOP2"),
(this_or_next|eq, ":troop", "trp_YOUR_TROO3"),
... ... ...
(eq, ":troop", "trp_YOUR_TROOP_last"),


And in the ti_on_agent_spawn triggers of the game modes you want to enable this for: 
Code:
(call_script, "script_force_weapon", ":agent_no"),

In all the agent_spawn triggers of the native game modes, the agent should already be stored in ":agent_no", but if you are making your own mission template for a game mode, start with something like this:
Code:
  (ti_on_agent_spawn, 0, 0, [],
   [(store_trigger_param_1, ":agent_no"),
    (call_script, "script_force_weapon", ":agent_no"),
    ]),
Screen shot:
scriptyv.jpg

(Armour by Njunja, from Eastern Armor OSP 1.0)

Works best with Caba`drin 's weapon switching script!
http://forums.taleworlds.com/index.php/topic,134031.0.html

Thanks Vornne for providing all the amendments!

Cheers.
 
 
Just a couple of small things: shouldn't the later "trp_YOUR_TROOP" strings (in troop_get_inventory_capacity and troop_get_inventory_slot) be replaced with ":troop", so your if_or_next suggestion would work? And also, why use the constants 2 and 4 with comments, when you could replace with itp_type_one_handed_wpn and itp_type_polearm, and not need it to be commented?

As for optimizing, you could change it to work on only one agent, and call the script from the ti_on_agent_spawn trigger of each game type mission template. I'm not sure why the solution you have for deathmatch doesn't work for battle mode, as I vaguely remember something like that all MP modes use some of the same spawning code, which you found - but at least you could change the trigger to fire only every second, rather than as often as possible ("1, 0, 0," rather than "0, 0, 0,"); it might not make much difference though, as I don't think checking a slot for all agents would be very intensive. You could also use "(agent_slot_eq, ":agent", slot_agent_forced, 0)" for a possible minuscule speed difference; I don't know.
 
Thanks for you suggestions! I implemented them.

This is actually my first script, so I'm rather unfamiliar with the tiggers. Calling the script from "ti_on_agent_spawn" just works perfectly fine!

Thanks,
 
I probably didn't explain myself very well... you don't need to have a separate method for deathmatch and battle, using ti_on_agent_spawn should work for any game mode; and also, if you change the script to deal with only one agent at a time, slot_agent_force shouldn't be necessary. The constants itp_type_one_handed_wpn are handled directly as python variables, not converted by the module system, so they should not be enclosed in quotes. Something like this - I haven't tested if it works, or even if it builds:
Code:
  ("force_weapon",
   [(store_script_param, ":agent", 1),
    (try_begin),
      (multiplayer_is_server),
      (agent_is_alive, ":agent"),
      (agent_is_non_player, ":agent"),
      (agent_get_troop_id, ":troop", ":agent"),
      (troop_get_inventory_capacity, ":cap", ":troop"),
      (try_for_range, ":i", 0, ":cap"),
        (troop_get_inventory_slot, ":item", ":troop", ":i"),
        (item_get_type, ":type", ":item"),
        (ge, ":type", itp_type_one_handed_wpn),
        (le, ":type", itp_type_polearm),
        (neg|agent_has_item_equipped, ":agent", ":item"),
        (agent_equip_item, ":agent", ":item"),
      (try_end), #try inventory
    (try_end),
    ]),
And in the ti_on_agent_spawn triggers of the game modes you want to enable this for:
Code:
(call_script, "script_force_weapon", ":agent_no"),
In all the agent_spawn triggers of the native game modes, the agent should already be stored in ":agent_no", but if you are making your own mission template for a game mode, start with something like this:
Code:
  (ti_on_agent_spawn, 0, 0, [],
   [(store_trigger_param_1, ":agent_no"),
    (call_script, "script_force_weapon", ":agent_no"),
    ]),
 
Thanks again.
It works!

I just added back one line:
(eq, ":troop", "trp_YOUR_TROOP"),
since some people might want some randomness of weapons for some troops.

Ah... I have so much to learn about the module system.
1 Question, what does "(store_trigger_param_1, ":agent_no")," in "ti_on_agent_spawn" do?
 
I haven't tested this out, but how does it work if a troop has more than one alternate weapon? Say, two polearms, a sword and two axes? Will it randomly choose between the pairs of polearms and axes?
 
The store_trigger_param_1 operation just stores the first parameter passed when the trigger is activated: in this case it happens to be the id of the newly spawned agent; sometimes there is more than one parameter - accessed with store_trigger_param_2 and _3. Some of the parameters are documented in header_triggers.py, but for the rest you can search them in the native scripts and copy how they are used. It's similar with scripts and store_script_param: the (call_script, "script_force_weapon", ":agent_no") operation passes one parameter, which is acessed in the called script with (store_script_param, ":agent", 1) - store the first parameter (":agent_no") in ":agent".


Lew2: I haven't been able to figure out how the hard coded system works (in multiplayer mode) but it seems to pick exactly the same equipment each time; I think agent_equip_item doesn't do anything if there are no free slots, so the equipment would probably not be random - probably the same default equip the game picks (for whatever reason), then the first non equipped items in the list until all slots are taken.
 
@OP: Excellent work for your first foray! Hope to see more code-dabblings from you.

Vornne said:
I think agent_equip_item doesn't do anything if there are no free slots, so the equipment would probably not be random - probably the same default equip the game picks (for whatever reason), then the first non equipped items in the list until all slots are taken.
This is true.

To ensure a balance of weapon types, some sort of "counter" variables would need to be added to the inventory loop, checking for equipped items of each target type. Once one is equipped, the appropriate variable value could be changed so the next vacant slot (if there are any) would go to a weapon of a different type.

 
Because the script doesn't check if the item in the inventory slot is valid before attempting to check for type - although the inventory cap is correct, the items in the equipment slots (from 0 to 10, especially the food slot) will most likely be empty.

(troop_get_inventory_slot, ":item", ":troop", ":i"),
(ge, ":item", 0), #add this
(item_get_type, ":type", ":item"),
 
Well that's very embarassing..  :oops: I really did load a different module to the one I edited; so sorry.

Sorry to bump the thread but, in case it's of any use to anyone, Caba`drin mentioned a small modification in another thread that applies the script to all non-hero troops, without needing to specify them individually. I know there are a lot of cases in which that's far from ideal but it does mean the entry written to scripts.txt can be copied out and applied to any module without use of the module system, ideal for txt-file modders.

As far as I know it should work anywhere in the file; just copy the following into scripts.txt and add one to the total at the top.1

Code:
force_weapon -1
 19 23 2 1224979098644774912 1 4 0 1073742241 0 2147484067 0 1702 1 1224979098644774912 1707 1 1224979098644774912 1718 2 1224979098644774913 1224979098644774912 2147485155 1 1224979098644774913 1540 2 1224979098644774914 1224979098644774913 6 3 1224979098644774915 0 1224979098644774914 1541 3 1224979098644774916 1224979098644774913 1224979098644774915 30 2 1224979098644774916 0 1570 2 1224979098644774917 1224979098644774916 30 2 1224979098644774917 2 2147483680 2 1224979098644774917 4 2147485377 2 1224979098644774912 1224979098644774916 1779 2 1224979098644774912 1224979098644774916 3 0 3 0

So
Code:
scriptsfile version 1
631
would become
Code:
scriptsfile version 1
632
 
@Thorberg, you would also need to add the text for the "call script" line that comes during the trigger "ti_agent_spawn" within various mission templates. It won't be able to do anything sitting in scripts if it isn't called in the mission.
 
Oops. Interesting, but oops. I suppose I must've muddled mods somewhere along the line because I've managed to get it (apparently) working in a mod just messing about with txt files. Sorry, I'll see if I can figure out what I've done tomorrow after some sleep.

Sorry again for all the nonsensical babble I dumped in here.. I'm very gradually dragging my way towards some understanding.
 
OK so to confirm,  cuz I thinik there's a bit of the actual instructions on how to install this little bastard that people are presuming that everyone who wants this script already understands, and it could use to be fleshed out for the sake of total noobs like me.

This is something I need to put into module_scripts.py and... what other file?  Cuz your agent_spawn thingee isn't in module_scripts.py.  There's one for multiplayer, but none for singleplayer  So which file is it in?  Checked Module_mission_templates.py before posting this, also didn't find your agent_spawn trigger, so I need info at this point.  Or does the multiplayer trigger handle both?  But then why label it 'multiplayer?'
 
The ti_on_agent_spawn triggers should be in module_mission_templates.py somewhere. The way I eventually got it working (with the neg|troop_is_hero or whatever it was) was to insert it into the common_battle_init_banner function near the top of the file, so
Code:
common_battle_init_banner = (
  ti_on_agent_spawn, 0, 0, [],
  [
    (store_trigger_param_1, ":agent_no"),

    (agent_get_troop_id, ":troop_no", ":agent_no"),
    (call_script, "script_troop_agent_set_banner", "tableau_game_troop_label_banner", ":agent_no", ":troop_no"),
  ])
became
Code:
common_battle_init_banner = (
  ti_on_agent_spawn, 0, 0, [],
  [
    (store_trigger_param_1, ":agent_no"),
    (call_script, "script_force_weapon", ":agent_no"),
    (agent_get_troop_id, ":troop_no", ":agent_no"),
    (call_script, "script_troop_agent_set_banner", "tableau_game_troop_label_banner", ":agent_no", ":troop_no"),
  ])

Note that if you just add the force weapon script to the call already in there it'll return an error after trying to use the troop_no as the agent_id or something similar; doesn't work and spews errors in damned weird places.

Doing it this way saves adding it individually for every game mode you want it in but it'll affect the item_kinds1.txt entries for heraldic items, so you'll have to use the file it produces or copy the shields and heraldic mails over.
 
OK.

Hmm...

On a whim, I want to try putting the new line at the end, after script_troop_agent_set_banner but before the close bracket, to see if that deals with the "heraldic" problem.  I don't know if Python is one, but there are definitely programming languages where order of operations matter

Let's see it if works.  Probably barking up the wrong tree.,
 
Well I don't know what the bug was supposed to look like with the heraldic items but I haven't run into it.  Everything seems reasonably stable after a quick test run.
 
Back
Top Bottom