• The forum has been updated. For an explanation of some of the changes, head over here.

OSP Code Combat Updated: Tournament lancers: Use the right weapon.

Currently viewing this thread:

Hatonastick

Some pretty quick and simple code that wasn't quick or simple for me to write.  I spent many hours experimenting and testing to see whether or not information I'd read was still current with regards to item flags, whether you could add your own, whether there were ways around it without hacking anything etc.  I discovered all I'd read was still current and that there was no simple way of adding your own flags to items (if there is any at all).  So in the end this script ended up being more specific than I wanted as I refer to item names directly.  Pity, being able to access 'itp_couchable' or similar would have made this much easier.  Plus for some reason my previous script that was meant to run through all items in an NPCs inventory, didn't.  Well it did with some, didn't with others and for some reason accessed their normal combat inventory rather than the items assigned to them (by force) for the tournament.  In the end this change is rather simple and relies rather heavily upon the behaviour of (agent_set_wielded_item) which I noticed only changes an NPCs item if the item you ask them to change to is in their inventory (or at least the inventory that I couldn't seem to find :smile:).  Well either the result is due to this function, or it's due to normal NPC AI behaviour I guess.  Either way it works out fine and is now somewhat shorter than the original version that I wrote.

Actually I did wonder if the weird behaviour I got while attempting to look through an NPCs inventory (barring code bugs on my part) had anything to do with the scripts that force the various normal troops to fight as NPCs in tournaments with a different weapon layout to what they normally have.  Be interested to see if my original script works better in normal combat situations (I get annoyed about companion NPCs sticking with their lance after being dismounted only to be easily overwhelmed on foot because they didn't switch to their backup weapon).

Add back-up sword for lancers in tournaments.
In 'module_scripts.py':
In 'set_items_for_tournament':
After:
          (mission_tpl_entry_add_override_item, "mt_arena_melee_fight", ":i_ep", "itm_practice_lance"),
          (mission_tpl_entry_add_override_item, "mt_arena_melee_fight", ":i_ep", ":cur_shield_item"),
Add:
          (mission_tpl_entry_add_override_item, "mt_arena_melee_fight", ":i_ep", "itm_practice_sword"),

Note: I also allow the archer to use a sword instead of the rather pointless dagger.  Only change that if you want to.  It's not important for this script.

Force a lancer to use their lance while on horse back (as per Native), but force them to change to the backup weapon the instant they lose their horse.
In 'module_mission_templates.py':
Inside the 'tournament_triggers' tuple add this trigger:
Code:
   # Force mounted NPCs to use the lance (if they have it), and to switch
   # automatically to their backup weapon if dismounted. 
   (0, 0, 1, [(eq, "$g_mt_mode", abm_tournament),],
   [
      # Run through all active NPCs on the tournament battle field.
      (try_for_agents, ":agent"),
        # Isn't a player.
        (agent_is_non_player, ":agent"),
        # Isn't a horse.
        (agent_is_human, ":agent"),
        # Hasn't been defeated.
        (agent_is_alive, ":agent"),
        # They riding a horse?
        (agent_get_horse, ":horse", ":agent"),
        # Force choice of secondary weapon while dismounted.
        (try_begin),
          # Isn't riding a horse.
          (le, ":horse", 0),
          # Get wielded item.
          (agent_get_wielded_item, ":wielded_item", ":agent", 0),
          # Is it a practice lance?
          (eq, ":wielded_item", "itm_practice_lance"),
          # Equip their backup weapon.  We've preset this to be a sword.
          (agent_set_wielded_item, ":agent", "itm_practice_sword"),
        # Force them to use the lance while mounted.
        (else_try),
          # Is riding a horse.
          (gt, ":horse", 0),
          # Get wielded item.
          (agent_get_wielded_item, ":wielded", ":agent", 0),
          # Is it a practice lance? 
          (neq, ":wielded", "itm_practice_lance"),
          # Force the NPC to wield the lance, but this will only happen if they
          # actually have a lance in their inventory.  Otherwise this does
          # nothing.  So those armed normally with sword/shield, two-handed
          # swords, axe/shield, bow/sword, bow/crossbow etc. wont be affected.
          (agent_set_wielded_item, ":agent", "itm_practice_lance"),
        (try_end),        
      (try_end),
   ]),

From all my testing this works well (I tested extensively with large numbers of debug output I'd added).  Lancers switch to their backup weapon even as they are busy falling off of their now unconscious horse.  This means that lancers are no longer easy pickings after being dismounted (which is my favourite tactic versus lancers in tournaments with Native).

Note:  This works under v1.113 Warband.  No idea if it will behave the same with any other version.  This is free for all use and no credit required.  Am hoping one day soon that this NPC AI fix/kludge will no longer be required too. :smile:

Edit: I just changed something in the script.  Only just realised the totally superfluous condition block was still in the script.  Sorry about that.  Totally unnecessary since the whole thing sits inside the tournament code block already.

Edit:  Version 2 of this script (still the tournament version, sorry).  This version has two scripts, cut down from the original.  One script constantly checks to see if there are any soldiers on foot trying to use a lance, and forces them to use their sword.  The other version is called once at the start of the tournament battle and forces any mounted units who have a lance, to switch to them.  I had a reason for doing this at some stage, but hey it has been a long day and I forget what it was.  :mrgreen:
Code:
   # For lancers in tournaments (who've been equipped with a backup weapon).

   # Note:  It appears that (agent_set_wielded_item, <agent_id>, <item_id>),
   # will only change the wielded weapon if the one you request that they
   # switch to is in their inventory somewhere.  So it's safe to ask all NPCs
   # in a battle to switch items to a particular one as only the ones that have
   # said item will switch.  This is very handy.
   
   # Force mounted NPCs to switch to their lance.  This is called once at the
   # start of the battle.
   (0, 1, ti_once, [(eq, "$g_mt_mode", abm_tournament),],
   [
      # Run through all active NPCs on the tournament battle field.
      (try_for_agents, ":agent"),
        # Isn't a player.
        (agent_is_non_player, ":agent"),
        # Isn't a horse.
        (agent_is_human, ":agent"),
        # Hasn't been defeated.
        (agent_is_alive, ":agent"),
        # They riding a horse?
        (agent_get_horse, ":horse", ":agent"),
        # Is riding a horse.
        (gt, ":horse", 0),
        # Get wielded item.
        (agent_get_wielded_item, ":wielded", ":agent", 0),
        # Is it a practice lance? 
        (neq, ":wielded", "itm_practice_lance"),
        # Force the NPC to wield the lance, but this will only happen if they
        # actually have a lance in their inventory.  Otherwise this does
        # nothing.  So those armed normally with sword/shield, two-handed
        # swords, axe/shield, bow/sword, bow/crossbow etc. wont be affected.
        (agent_set_wielded_item, ":agent", "itm_practice_lance"),
      (try_end),   
   ]),
   
   # Check to make sure there are no lance users on foot, if so force them to
   # switch to their sword.
   (0, 0, 1, [(eq, "$g_mt_mode", abm_tournament),],
   [
      # Run through all active NPCs on the tournament battle field.
      (try_for_agents, ":agent"),
        # Isn't a player.
        (agent_is_non_player, ":agent"),
        # Isn't a horse.
        (agent_is_human, ":agent"),
        # Hasn't been defeated.
        (agent_is_alive, ":agent"),
        # They riding a horse?
        (agent_get_horse, ":horse", ":agent"),
        # Isn't riding a horse.
        (le, ":horse", 0),
        # Get wielded item.
        (agent_get_wielded_item, ":wielded_item", ":agent", 0),
        # Is it a practice lance?
        (eq, ":wielded_item", "itm_practice_lance"),
        # Equip their backup weapon.  We've preset this to be a sword.
        (agent_set_wielded_item, ":agent", "itm_practice_sword"),
      (try_end),
   ]),
 

Drachen

Regular
WBWF&S
Is there a way I could use this to apply to normal troops on the battlefield? I was asking earlier about how I could make my Swadian Lancers use their lance until they dismount, or if they spawn dismounted like in a seige.

Thanks for your hard work!

Drachen
 

Hatonastick

The short answer should be yes (heavily modified), but I think I'd want the script to be a bit more general than this version is.  My original script probably would be better suited, once I iron the bugs out.  That's going to be my next project anyway (as part of my Mod, but I'm releasing bits like this separately for general use).  Really it needs to go through a units inventory and look for a more appropriate weapon -- this can be done, just for some reason wasn't working as per normal in tournaments, but as I said above I think that's more to do with the scripts that force tournament gear upon NPCs etc.  Either that or my code had a bug that I could not see.  Either way this simpler code is preferable for tournaments as the complexity wasn't needed.
 

Arch3r

Count
M&BWBNW
This is quite a good idea, it allows you to assign weapons to troop slots and than forcing them to wield it with a command button (like the current Use Blunt Weapons), t'is a nice idea.
 
Warband only, as I can see from agent_set_wielded_item usage

Interesting, can 1.011 relate at all to numerical IDs which are not defined in a header_operations yet.. hmm. Need to try it when I'll be back home. I know that MB can relate to flags, which became available only in WB, e.g. ti_on_missile_hit
 

Hatonastick

GetAssista said:
Warband only, as I can see from agent_set_wielded_item usage

Interesting, can 1.011 relate at all to numerical IDs which are not defined in a header_operations yet.. hmm. Need to try it when I'll be back home. I know that MB can relate to flags, which became available only in WB, e.g. ti_on_missile_hit
Yeah sorry about that.  I code mainly for Warband (I still play other peoples mods in MB though!) as I'm making my own mod.

Anyway, would be interested to know if there's a possible work around for MB though.

Edit:  Hmm where would I need to add this trigger for normal battles?  I've found ' "lead_charge",mtf_battle_mode,charge,' in 'module_mission_templates.py' but am not 100% sure that's the right place.  I did have some notes I'd made on where battles of each sort were controlled from (single player only) but its managed to disappear into the ether.  :roll:

Edit: Ok it's mostly written except for one major stumbling block that current doesn't make sense (but I need sleep, so probably something simple I've overlooked) in that '(try_for_agents, ":agent"),' isn't returning any valid agents (except maybe the companion NPC, but also in his case sometimes it works and sometimes it doesnt, very odd).  Will work on this tomorrow.  Chances are one of the other bods will have something better up by then anyway.
 

LocNlol

Regular
Hey, that's really neat. This opens up a lot of possibilities such as troops using one handed weapons in sieges but 2handed/polearms in open field battle, or switching on player command. Thanks ! :smile:
 

Hatonastick

Well...  It works in Tournament battles, but not (so far) in any others.  For some reason '(try_for_agents, :agent)' doesn't seem to be cycling through the battlefield properly.  I've definitely got the script in the right place and I've added the inventory search side of things, but it seems to bomb out towards the top.  In any case today is another day and I'll have a fresh crack at it.

Edit: Ok the Tournament script works fine as is, but my battle one is going to be different.  Currently Im adding one new command for units and one new trigger.

Edit: I've fixed a minor bug in the original that probably wouldn't have affected anyone and provided a new version.  In reality the new version doesn't add anything or alter anything.  It is potentially more friendly should AI be changed in the future in that it only forces a weapon change for mounted lance users right at the start of the battle rather than every second or so.  It may use a little less unnecessary processor power too if you had a round which featured lots of mounted troops without lances, but some how I doubt it matters either way.  Just use the one you prefer.  :mrgreen:

Edit: I'm hoping that something will be done to fix the weapon selection issue.  We shouldn't have to write scripts to plug holes in the AI..  Well.. Not unless the AI itself was shifted completely to scripts. :smile:

Either way not a wasted effort as I'm now working on some new commands for the battle command system.

Can a moderator please lock this thread?  I'm not going to add anything else here.  This is done and dusted, thanks. :smile:
 
Top Bottom