OSP Code Combat [WB][B] Alternate Weapon Modes

Somebody

Code Pope
Baron
WBWF&S
Best answers
1
This is a basic framework for toggling weapon modes, similar to bayonet scripts. It involves using another item entry to represent an alternate version of a weapon and catches user key presses to toggle between the two modes. The AI is also responsive to an extent - issuing the "use any weapon order" will allow any bots that have one of these weapons to toggle modes, while issuing "use blunt weapons" will cause them to check their equipment to see if an alternate version of their weapon is blunt.

Throughout the history of man people have always been bashing one another in the head. The ability to flip your weapon over in order to make use of another wedge in order to apply force so as to drive one's enemies before them has been a great advancement in warfare. I have no idea why you're reading this description instead of the code.

The following are are a bunch of Native items flipped. The resource can be downloaded here.
Code:
["h_alt", "Rock Pick", [("alt_iron_hammer_new",0),("iron_hammer_new",ixmesh_carry),], itp_type_one_handed_wpn|itp_merchandise|itp_primary|itp_wooden_parry, itc_scimitar,
7 , weight(2)|spd_rtng(100) | weapon_length(55)|swing_damage(20 , pierce) | thrust_damage(0 ,  pierce),imodbits_mace ],
["pick_alt", "Hammer", [("alt_rusty_pick",0),("rusty_pick",ixmesh_carry),], itp_type_one_handed_wpn|itp_merchandise|itp_primary|itp_wooden_parry, itc_scimitar|itcf_carry_axe_left_hip,
27 , weight(2)|spd_rtng(99) | weapon_length(69)|swing_damage(18 , blunt) | thrust_damage(0 ,  pierce),imodbits_pick ],
["fp_alt", "Fighting Hammer", [("alt_fighting_pick_new",0),("fighting_pick_new",ixmesh_carry),], itp_type_one_handed_wpn|itp_merchandise|itp_primary|itp_wooden_parry, itc_scimitar|itcf_carry_axe_left_hip,
108 , weight(1.0)|spd_rtng(98) | weapon_length(70)|swing_damage(22 , blunt) | thrust_damage(0 ,  pierce),imodbits_pick ],
["mp_alt", "Military Hammer", [("alt_steel_pick_new",0),("steel_pick_new",ixmesh_carry),], itp_type_one_handed_wpn|itp_merchandise|itp_primary, itc_scimitar|itcf_carry_axe_left_hip,
280 , weight(1.5)|spd_rtng(98) | weapon_length(70)|swing_damage(29 , blunt) | thrust_damage(0 ,  pierce),imodbits_pick ],
["ih_alt", "Battle Pick", [("alt_military_hammer",0),("military_hammer",ixmesh_carry),], itp_type_one_handed_wpn|itp_merchandise|itp_primary, itc_scimitar|itcf_carry_axe_left_hip,
173 , weight(2.5)| spd_rtng(97) | weapon_length(70)|swing_damage(25 , pierce) | thrust_damage(0 ,  pierce),imodbits_mace ],
["bec_de_corbin_alt", "War Hammer", [("alt_bec",0),("bec_de_corbin_a",ixmesh_carry),], itp_type_two_handed_wpn| itp_two_handed|itp_primary|itp_bonus_against_shield|itp_wooden_parry|itp_can_knock_down, itc_nodachi|itcf_carry_axe_back,
 251 , weight(3.0)|difficulty(10)|spd_rtng(80) | weapon_length(120)|swing_damage(40 , blunt) | thrust_damage(0 ,  pierce),imodbits_axe ],
["sarranid_two_handed_pick_b", "Exotic War Pick", [("alt_handed_battle_axe_h",0),("two_handed_battle_axe_h",ixmesh_carry),], itp_type_two_handed_wpn|itp_two_handed|itp_primary|itp_bonus_against_shield|itp_unbalanced, itc_nodachi|itcf_carry_axe_back,
 280 , weight(3.0)|difficulty(10)|spd_rtng(90) | weapon_length(90)|swing_damage(40 , pierce) | thrust_damage(0 ,  pierce),imodbits_pick ],
The following changes should also be made so that damage type and appearance correspond properly.
Code:
["pickaxe",         "Pickaxe", [("rusty_pick",0)], itp_type_one_handed_wpn|itp_merchandise|itp_primary|itp_wooden_parry, itc_scimitar|itcf_carry_mace_left_hip, 
27 , weight(3)|difficulty(0)|spd_rtng(99) | weapon_length(70)|swing_damage(19 , pierce) | thrust_damage(0 ,  pierce),imodbits_pick ],

["bec_de_corbin_a",  "War Hammer", [("bec_de_corbin_a",0)], itp_type_polearm|itp_merchandise| itp_cant_use_on_horseback|itp_primary|itp_penalty_with_shield|itp_wooden_parry|itp_two_handed, itc_staff|itcf_carry_spear,
 125 , weight(3.0)|difficulty(0)|spd_rtng(81) | weapon_length(120)|swing_damage(38, pierce) | thrust_damage(38 ,  pierce),imodbits_polearm ],
By making these two changes, pickaxes will look different from fighting picks and the business end of the bec-de-corbin should do pierce damage by default now.
This sets up the item relationships and reciprocates the slot setting so that you can toggle between them. Note that while it is possible to do this automatically (using python trickery), for a small item set it is simpler to do so manually. One disadvantage of this is that by not using itp_next_item_as_melee, the stats on the alternate version will not display. This can be fixed by either changing the item order so that the engine recognizes they are next to one another, or by fetching item damage values (populated by python) from game_get_item_extra_text.
Code:
    (item_set_slot, "itm_sarranid_two_handed_pick_b", slot_item_alternate, "itm_sarranid_two_handed_axe_b"),
    (item_set_slot, "itm_sarranid_two_handed_axe_b", slot_item_alternate, "itm_sarranid_two_handed_pick_b"),
    (item_set_slot, "itm_bec_de_corbin_a", slot_item_alternate, "itm_bec_de_corbin_alt"),
    (item_set_slot, "itm_bec_de_corbin_alt", slot_item_alternate, "itm_bec_de_corbin_a"),
    
    (item_set_slot, "itm_pick_alt", slot_item_alternate, "itm_pickaxe"),
    (item_set_slot, "itm_pickaxe", slot_item_alternate, "itm_pick_alt"),
    (item_set_slot, "itm_fp_alt", slot_item_alternate, "itm_fighting_pick"),
    (item_set_slot, "itm_fighting_pick", slot_item_alternate, "itm_fp_alt"),
    (item_set_slot, "itm_mp_alt", slot_item_alternate, "itm_military_pick"),    
    (item_set_slot, "itm_military_pick", slot_item_alternate, "itm_mp_alt"),
    
    (item_set_slot, "itm_hammer", slot_item_alternate, "itm_h_alt"),
    (item_set_slot, "itm_h_alt", slot_item_alternate, "itm_hammer"),
    (item_set_slot, "itm_military_hammer", slot_item_alternate, "itm_ih_alt"),
    (item_set_slot, "itm_ih_alt", slot_item_alternate, "itm_military_hammer"),
Code:
common_player_weapon_toggle = (0,0,1, [
    (neg|main_hero_fallen),
    (game_key_clicked, gk_toggle_weapon_mode),
    (get_player_agent_no, ":player_agent"),
    (agent_get_wielded_item, ":item", ":player_agent", 0),
    (gt, ":item", 0),
    (item_slot_ge, ":item", slot_item_alternate, 1),
  ],
  [
    (get_player_agent_no, ":player_agent"),
    (agent_get_wielded_item, ":item", ":player_agent", 0),
    (item_get_slot, ":alternate", ":item", slot_item_alternate),
    (gt, ":alternate", 1),
    (agent_unequip_item, ":player_agent", ":item"),
    (agent_equip_item, ":player_agent", ":alternate"),
    (agent_set_wielded_item, ":player_agent", ":alternate"),
  ],
)
common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
  (store_trigger_param_1, ":order_no"),
  (this_or_next|eq, ":order_no", mordr_use_any_weapon),
  (eq, ":order_no", mordr_use_blunt_weapons),
  ],
[
  (store_trigger_param_1, ":order_no"),
  (store_trigger_param_2, ":agent_id"), #probably the player
  (agent_get_team, ":team_id", ":agent_id"),
  
  (try_for_agents, ":agent_no"),
    (agent_is_active, ":agent_no"),
    (agent_is_human, ":agent_no"),
    (agent_is_non_player, ":agent_no"),
    (agent_is_alive, ":agent_no"),
    (agent_get_team, ":team_no", ":agent_no"),
    (eq, ":team_no", ":team_id"),
    (agent_get_class, ":class_no", ":agent_no"),
    (class_is_listening_order, ":team_no", ":class_no"),
    (agent_get_wielded_item, ":item_no", ":agent_no", 0),
    (try_begin), #could be using fists
      (gt, ":item_no", 0),
      (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
    (else_try),
      (assign, ":swap_no", 0),
    (try_end),
    
    (try_begin), #none found on wielded item
      (eq, ":swap_no", 0), #
      (assign, ":end", ek_head),
      (try_for_range, ":item_slot", ek_item_0, ":end"),
        (agent_get_item_slot, ":item_no", ":agent_no", ":item_slot"),
        (gt, ":item_no", 0),
        (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
        (gt, ":swap_no", 0),
        (assign, ":end", -1),
      (try_end),
    (try_end),
    (gt, ":swap_no", 0),
    (try_begin), #make use of the other item slots
      (eq, ":order_no", mordr_use_any_weapon), #too lazy to re-set, just plain swapping
    (else_try),
      (eq, ":order_no", mordr_use_blunt_weapons), #switching to blunt modes only
      #check inventory to see if weapon can be toggled
      (try_begin),
        
        (try_for_range, ":item_slot", ek_item_0, ":end"),
          (agent_get_item_slot, ":item_id", ":agent_no", ":item_slot"),
          (this_or_next|eq, ":item_id", "itm_h_alt"),
          (this_or_next|eq, ":item_id", "itm_ih_alt"),
          (this_or_next|eq, ":item_id", "itm_bec_de_corbin_a"),
          (this_or_next|eq, ":item_id", "itm_pickaxe"),
          (is_between, ":item_id", "itm_fighting_pick", "itm_morningstar"),
          (assign, ":item_no", ":item_id"),
          (assign, ":end", ek_item_0),
          (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
          
        (try_end),
      (try_end),
      #these are piercing weapons
      (this_or_next|eq, ":item_no", "itm_h_alt"),
      (this_or_next|eq, ":item_no", "itm_ih_alt"),
      (this_or_next|eq, ":item_no", "itm_bec_de_corbin_a"),
      (this_or_next|eq, ":item_no", "itm_pickaxe"),
      (is_between, ":item_no", "itm_fighting_pick", "itm_morningstar"),
    (else_try), #exclude them
      (assign, ":swap_no", 0),
    (try_end),
    (gt, ":swap_no", 0),
    (agent_unequip_item, ":agent_no", ":item_no"),
    (agent_equip_item, ":agent_no", ":swap_no"),
    (agent_set_wielded_item, ":agent_no", ":swap_no"),
  (try_end),
])
Note that the item damage type check for blunt weapons is done manually - this can be automated, again, if damage values are pre-cached to slots.
Finally, define slot_item_alternate somewhere nice in module_constants. Please remember to download the resources (or click on the image) before adding the triggers to the appropriate mission template. An updated post with adding alternate weapons procedurally along with other functionalities can be found here. And an updated Native module can be found here (use the dropbox link in description if workshop is still broken).
 

Slate024

Master Knight
M&BWBWF&S
Best answers
0
This is really neat, I think its a great idea and thanks for sharing Somebody.  I want to incorporate this into Silverstag.
 

Windyplains

Grandmaster Knight
WB
Best answers
0
Nice work and well presented, Somebody.  We will definitely make use of it in Silverstag.
 
Best answers
0
Could "Somebody" make a short display of it in game because it would be wonderful to see how it actually works. And this is just suggestion so don't need to do anything if you don't see it to be necessary.
 

Mad Skillz

Baron
WBM&BVC
Best answers
0
Knight of calradia said:
Could "Somebody" make a short display of it in game because it would be wonderful to see how it actually works. And this is just suggestion so don't need to do anything if you don't see it to be necessary.
Sure.

:razz:
 

Kentucky James VII

BioAfrikaner
Duke
Best answers
1
Amazing work!  Q: are there no retraints to this? E.g. a bow could become a firearm when toggled? Either way, this opens up endless possibilities
 

mercury19

Sergeant at Arms
Best answers
0
Sorry if I'm resurrecting this thread, but I didn't see anyone else with this error and hoped you could maybe help. I'm getting an invalid syntax error on common_ai_order_toggle in mission_templates.

Here is the error:
Code:
Traceback (most recent call last):
  File "process_init.py", line 2, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_global_variables.py", line 12, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting strings...
Exporting skills...
Exporting tracks...
Exporting animations...
Exporting meshes...
Exporting sounds...
Exporting skins...
Traceback (most recent call last):
  File "process_map_icons.py", line 6, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting faction data...
Exporting item data...
Traceback (most recent call last):
  File "process_items.py", line 66, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting scene data...
Traceback (most recent call last):
  File "process_scenes.py", line 15, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting troops data
Exporting particle data...
Traceback (most recent call last):
  File "process_scene_props.py", line 7, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_tableau_materials.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_presentations.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting party_template data...
Traceback (most recent call last):
  File "process_parties.py", line 6, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting quest data...
Exporting info_page data...
Traceback (most recent call last):
  File "process_scripts.py", line 7, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_mission_tmps.py", line 5, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_game_menus.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_simple_triggers.py", line 5, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_dialogs.py", line 9, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Traceback (most recent call last):
  File "process_global_variables_unused.py", line 3, in <module>
    from process_operations import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\process_operat
ions.py", line 21, in <module>
    from module_mission_templates import *
  File "C:\Users\President\Desktop\M&B MODSYS\Module_system 1.158\module_mission
_templates.py", line 14896
    common_ai_order_toggle (ti_on_order_issued, 0, 0, [
                         ^
SyntaxError: invalid syntax
Exporting postfx_params...

______________________________

Script processing has ended.
Press any key to exit. . .

It's probably some bonehead mistake, but I am new to this. Any help would be appreciated.

EDIT: I have imported slot_item_alternate, I ran into that error already and it seems fixed.


Thanks, M19
 

mercury19

Sergeant at Arms
Best answers
0
That was part of the original problem. I forgot to mention that earlier, sorry.  :oops: 

I copied the text exactly as is, and compiled. It gave me an invalid syntax on the = after common_player_weapon_toggle, and deleting that fixed it. But then it gave the same error on the = after common_ai_order_toggle. deleting that led to this newest error. Iv'e so far assumed that by having a new error, it means I have solved the previous error properly. I would now assume that was wrong.

I think that is the whole story now, again sorry I forgot the details before.

Thanks, M19
 

Somebody

Code Pope
Baron
WBWF&S
Best answers
1
Revisiting this code, since I've added some new (optional) features as follows. Code is commented, should be easy to figure out.

Basically code from Custom Commander, if you're using any sort of kit as a base instead of Native just modify whatever's there.
Code:
def set_item_score():
  item_score = []
  for i_item in xrange(len(items)):    
    type = items[i_item][3] & 0x000000ff
    if (type >= itp_type_one_handed_wpn and type <= itp_type_thrown and type != itp_type_shield) or (type >= itp_type_pistol and type <= itp_type_bullets):
      item_score.append((item_set_slot, i_item, slot_item_thrust_damage, get_thrust_damage(items[i_item][6])))
      item_score.append((item_set_slot, i_item, slot_item_swing_damage, get_swing_damage(items[i_item][6])))
      if (items[i_item][3] & itp_next_item_as_melee == itp_next_item_as_melee) and type != itp_type_thrown: #toggleable weapons
        item_score.append((item_set_slot, i_item, slot_item_alternate, i_item + 1))
        item_score.append((item_set_slot, i_item + 1, slot_item_alternate, i_item))
        # print items[i_item][0] + str(i_item) + " has alternate " + str(i_item+1)
  return item_score[:]

scripts = [
...
("init_item_score", set_item_score()),
...
Combine this with the code snippet on the first page to link weapon pairs that have a gap between them - remember to call it in the right order so slots aren't clobbered.
Code:
    (call_script, "script_init_item_score"),

    (item_set_slot, "itm_sarranid_two_handed_pick_b", slot_item_alternate, "itm_sarranid_two_handed_axe_b"),
    (item_set_slot, "itm_sarranid_two_handed_axe_b", slot_item_alternate, "itm_sarranid_two_handed_pick_b"),
    (item_set_slot, "itm_bec_de_corbin_a", slot_item_alternate, "itm_bec_de_corbin_alt"),
    (item_set_slot, "itm_bec_de_corbin_alt", slot_item_alternate, "itm_bec_de_corbin_a"),
    .....
Again, these recommended slots might already be defined in your module.
Code:
slot_item_alternate = 75
slot_item_swing_damage = 76
slot_item_thrust_damage = 77
Every second an agent loop runs, and after finding an agent wielding an appropriate item in the correct combat states we run some calculations and force weapon switching if the combat state is valid. A delay is added after successfully switching weapon modes.
Code:
common_ai_random_toggle = (1, 0, 0, 
  [],
  [
    (store_mission_timer_a, ":timer_a"),
    (try_for_agents, ":agent_no"),
      #check valid agent candidates
      (agent_is_active, ":agent_no"),
      (agent_is_human, ":agent_no"),
      (agent_is_non_player, ":agent_no"),
      (agent_is_alive, ":agent_no"),
      (agent_get_combat_state, ":cs", ":agent_no"),
      (this_or_next|eq, ":cs", 0), #cs_free
      (this_or_next|eq, ":cs", 7), #cs_still
      (eq, ":cs", 3), #cs_wield
      
      (agent_get_team, ":agent_team", ":agent_no"),
      (agent_get_class, ":agent_class", ":agent_no"),
      #should probably cache this inside team slots
      (team_get_weapon_usage_order, ":order_no", ":agent_team",  ":agent_class"),
      (neq, ":order_no", wordr_use_blunt_weapons),
      #check validity of weapon
      (agent_get_wielded_item, ":item_no", ":agent_no", 0),
      (gt, ":item_no", 0),
      (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
      (item_get_type, ":itp", ":item_no"),
      (is_between, ":itp", itp_type_one_handed_wpn, itp_type_arrows),
      (gt, ":swap_no", 0),
      
      #weapon mastery increases chance of toggling
      (agent_get_troop_id, ":troop_no", ":agent_no"),
      (store_skill_level, ":skill", "skl_weapon_master", ":troop_no"),
      (store_random_in_range, ":random_no", 0, 100),

      #most native troops do NOT have weapon mastery - adjust as needed
      (ge, ":skill", ":random_no"),
      
      #check timing
      (agent_get_slot, ":last_switched", ":agent_no", slot_agent_last_weapon_toggled),
      (lt, ":last_switched", ":timer_a"),
      
      (store_sub, ":wpt", ":itp", 2),
      (store_proficiency_level, ":prof", ":troop_no", ":wpt"),
      (assign, reg9, ":prof"),
      #proficiency decreases time between toggle
      (val_mul, ":random_no", 8), #from 0 to 160
      (val_add, ":random_no", 1600), #delay
      (store_sub, ":prof", ":random_no", ":prof"), #between 1500 to 600 usually
      (val_div, ":prof", 80), #between 12s to 7.5s
      
      #store timing
      (store_add, ":last_switched", ":timer_a", ":prof"),
      (agent_set_slot, ":agent_no", slot_agent_last_weapon_toggled, ":last_switched"),
      
      #actual switching
      (agent_unequip_item, ":agent_no", ":item_no"),
      (agent_equip_item, ":agent_no", ":swap_no"),
      (agent_set_wielded_item, ":agent_no", ":swap_no"),

      # (assign, reg10, ":last_switched"),
      # (str_store_item_name, s3, ":item_no"),
      # (str_store_item_name, s2, ":swap_no"),
      # (str_store_agent_name, s1, ":agent_no"),
      # (display_message, "@{reg10}:{s1} with {reg9} wpx switching to {s2} from {s3}"),
    (try_end),
  ]
)
Since Native doesn't give weapon mastery to normal troops, they have a low chance of triggering this. Adjust the number as appropriate, keeping in mind that higher weapon mastery skill increases the chances of actually switching and higher weapon proficiency reduces time between switches.
Code:
slot_agent_last_weapon_toggled = 26
This basically gets rid of the coded in weapon checks in favour of looking in the inventory for suitable items when prompted.
Code:
common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
  (store_trigger_param_1, ":order_no"),
  (this_or_next|eq, ":order_no", mordr_use_any_weapon),
  (eq, ":order_no", mordr_use_blunt_weapons),
  ],
  [
  (store_trigger_param_1, ":order_no"),
  (store_trigger_param_2, ":agent_id"), #probably the player
  (agent_get_team, ":team_id", ":agent_id"),
  
  (try_for_agents, ":agent_no"),

    (agent_is_active, ":agent_no"),
    (agent_is_human, ":agent_no"),
    (agent_is_non_player, ":agent_no"),
    (agent_is_alive, ":agent_no"),
    (agent_get_team, ":team_no", ":agent_no"),
    (eq, ":team_no", ":team_id"),
    (agent_get_class, ":class_no", ":agent_no"),
    (class_is_listening_order, ":team_no", ":class_no"),
    (agent_get_wielded_item, ":item_no", ":agent_no", 0),
    # (assign, reg10, ":agent_no"),
    # (str_store_agent_name, s1, ":agent_no"),
    # (try_begin),
      # (le, ":item_no", 0),
      # (str_store_string, s2, "@nothing"),
    # (else_try),
      # (str_store_item_name, s2, ":item_no"),
    # (try_end),
    # (str_store_string, s1, "@{reg10}:{s1} holding {s2}:"),
    # (try_for_range, ":item_slot", ek_item_0, ek_head),
      # (agent_get_item_slot, ":item_id", ":agent_no", ":item_slot"),
      # (gt, ":item_id", 0),
      # (neq, ":item_id", ":item_no"),
      # (str_store_item_name, s0, ":item_id"),
      # (str_store_string, s1, "@{s1}, {s0}"),
    # (try_end),
    # (display_message, s1),
    

    (gt, ":item_no", 0),
    (assign, ":swap_no", 0),

    #here we assume a weapon with alternate mode has been found already - it is rare that two item types will be equipped that can be swapped with different damage modes
    (try_begin), #make use of the other item slots
      (eq, ":order_no", mordr_use_any_weapon), #just plain swapping
      (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
      (neq, ":swap_no", 0),
      (agent_unequip_item, ":agent_no", ":item_no"),
      (agent_equip_item, ":agent_no", ":swap_no"),
      (agent_set_wielded_item, ":agent_no", ":swap_no", 0),
    (else_try),
      (eq, ":order_no", mordr_use_blunt_weapons), #switching to blunt modes only
      (neg|item_slot_ge, ":item_no", slot_item_swing_damage, 512), #not already holding blunt
      #check inventory to see if weapon can be toggled
      (assign, ":end", ek_head),
      # (str_store_agent_name, s10, ":agent_no"),
      # (assign, reg10, ":agent_no"),
      # (str_store_string, s10, "@{reg10}={s10}:blunt"),
      (try_for_range, ":item_slot", ek_item_0, ":end"),
        (agent_get_item_slot, ":item_id", ":agent_no", ":item_slot"),
        (gt, ":item_id", 0),
        
        (item_get_type, ":item_itp", ":item_id"),
        (is_between, ":item_itp", itp_type_one_handed_wpn, itp_type_arrows),
        # (neg|item_slot_ge, ":item_id", slot_item_swing_damage, 512), #let engine set wielded
        # (str_store_item_name, s1, ":item_id"),
        # (item_get_slot, reg9, ":item_id", slot_item_swing_damage),
        # (str_store_string, s10, "@{s10},checking {s1} with {reg9} dmg"),
        # (item_get_slot, ":swap_id", ":item_id", slot_item_alternate),
        # (gt, ":swap_id", 1),
        # (str_store_string, s10, "@{s10} and alt"),
        
        (try_begin),
          # (item_get_slot, ":damage", ":swap_id", slot_item_swing_damage),
          # (gt, ":damage", 512),
          (item_slot_ge, ":swap_id", slot_item_swing_damage, 513),
          (item_get_slot, ":damage", ":item_id", slot_item_thrust_damage),
          (this_or_next|eq, ":damage", 0), #no thrust capability
          (this_or_next|eq, ":damage", 256), #defined as (0, flag)
          (gt, ":damage", 512),

          # (assign, ":item_no", ":item_id"),
          (assign, ":end", -1),
          (agent_unequip_item, ":agent_no", ":item_id"),
          (agent_equip_item, ":agent_no", ":swap_id"),
          (agent_force_rethink, ":agent_no"),
        (try_end),
      (try_end),
      # (try_begin),
        # (eq, ":end", ek_head),
        # (assign, ":swap_no", -1),
        # (assign, ":item_no", -1),
        # (assign, ":color", 0xFF0000),
        # (display_message, "@{reg10}: switch to nothing", ":color"),
      # (else_try),
        # (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
        # (assign, ":color", 0x00FF00),
        # (str_store_item_name, s2, ":swap_no"),
        # (display_message, "@{reg10}: switch to {s2}", ":color"),
      # (try_end),
    # (else_try), #exclude them
      # (assign, ":swap_no", 0),
    (try_end),
    # (gt, ":item_no", 0),
    # (gt, ":swap_no", 0),
    # (agent_unequip_item, ":agent_no", ":item_no"),
    # (agent_unequip_item, ":agent_no", ":swap_no"),
    # (agent_equip_item, ":agent_no", ":swap_no"),
    # #(agent_set_wielded_item, ":agent_no", ":swap_no"),
    # (str_store_item_name, s3, ":item_no"),
    # (str_store_item_name, s2, ":swap_no"),
    # (str_store_agent_name, s1, ":agent_no"),
    # (display_message, "@{reg10}:{s1} switching to {s2} from {s3}", ":color"),
    # (agent_force_rethink, ":agent_no"),
  (try_end),
  ]
)
The following trigger should also be included as agents like to randomly equip invalid items (or rather, THE invalid item) when prompted
Code:
common_ai_sanity_check = (
  ti_on_item_wielded, 0, 0, [
  (store_trigger_param_2, ":item_no"),
  (eq, ":item_no", 0),
  ],
  [
  (store_trigger_param_1, ":agent_no"),
  # (str_store_agent_name, s11, ":agent_no"),
  # (assign, reg11, ":agent_no"),
  # (str_store_string, s11, "@{reg11}+{s11}"),
  # (try_for_range, ":item_slot", 0, ek_head),
    # (agent_get_item_slot, reg11, ":agent_no", ":item_slot"),
    # (str_store_string, s11, "@{s11}; {reg11}"),
  # (try_end),
  # (display_message, s11),
  (agent_unequip_item, ":agent_no", 0),
  (agent_force_rethink, ":agent_no"),
  
  ]
)
Unfortunately, native's itp_next_item_as_melee it doesn't display extra text on the alternate version, which isn't treated as a real item. If you add those items to a troop's inventory or mark them as merchandise, it is advisable to reduce their abundance modifier. Append this to the end of script_game_get_extra_text to display the relevant information.

Code:
  ("game_get_item_extra_text",
    [
...
      (else_try),
        (is_between, ":item_no", reference_books_begin, reference_books_end),
        (try_begin),
          (eq, ":extra_text_id", 0),
          (try_begin),
            (eq, ":item_no", "itm_book_wound_treatment_reference"),
            (str_store_string, s1, "@wound treament"),
          (else_try),
            (eq, ":item_no", "itm_book_training_reference"),
            (str_store_string, s1, "@trainer"),
          (else_try),
            (eq, ":item_no", "itm_book_surgery_reference"),
            (str_store_string, s1, "@surgery"),
          (try_end),
          (set_result_string, "@+1 to {s1} while in inventory"),
          (set_trigger_result, 0xFFEEDD),
        (try_end),
      (else_try),
        (item_get_slot, ":swap_no", ":item_no", slot_item_alternate),
        (gt, ":swap_no", 0),
        #this condition checks if it's already displayed engine-side
        (store_sub, ":damage", ":swap_no", ":item_no"),
        (neq, ":damage", 1),
        (try_begin),
          (eq, ":extra_text_id", 0),
          (str_store_item_name, s1, ":swap_no"),
          (set_result_string, "@Alternate version: {s1}"),
          (set_trigger_result, 0xADA2C2),
        (else_try),
          (eq, ":extra_text_id", 1),
          (item_get_slot, ":damage", ":swap_no", slot_item_swing_damage),
          #add damage from item modifiers here
          (try_begin),
            (is_between, ":damage", 0, 256),
            (assign, reg1, ":damage"),
            (str_store_string, s1, "@{reg1}c"),
          (else_try),
            (is_between, ":damage", 256, 512),
            (store_sub, reg1, ":damage", 256),
            (str_store_string, s1, "@{reg1}p"),
          (else_try),
            (ge, ":damage", 512),
            (store_sub, reg1, ":damage", 512),
            (str_store_string, s1, "@{reg1}b"),
          (try_end),
          (str_store_string, s1, "@Swing: {s1}"),
          (item_get_slot, ":damage", ":swap_no", slot_item_thrust_damage),
          (try_begin), #some weapons do not have thrust, most should have swing
            (neq, ":damage", 0),
            (neq, ":damage", 256),
            (neq, ":damage", 512),
            (try_begin),
              (is_between, ":damage", 0, 256),
              (assign, reg1, ":damage"),
              (str_store_string, s2, "@{reg1}c"),
            (else_try),
              (is_between, ":damage", 256, 512),
              (store_sub, reg1, ":damage", 256),
              (str_store_string, s2, "@{reg1}p"),
            (else_try),
              (ge, ":damage", 512),
              (store_sub, reg1, ":damage", 512),
              (str_store_string, s2, "@{reg1}b"),
            (try_end),
            (str_store_string, s1, "@{s1}^Thrust {s2}"),
          (try_end),
          (set_result_string, s1),
          (set_trigger_result, 0xEBC8C8),
        (try_end),
      (try_end),
  ]),
Please let me know if you actually make use of this somewhere so I can get some actual feedback.
 

GunFred

Squire
Best answers
0
Hello, I got a problem which I was hoping somebody(Somebody?) could help me with.
NameError: name 'ti_on_order_issued' is not defined
I have tried with both WB and WFaS and get the same error.
Traceback (most recent call last):
  File "process_init.py", line 2, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_global_variables.py", line 12, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting strings...
Exporting skills...
Exporting tracks...
Exporting animations...
Exporting meshes...
Exporting sounds...
Exporting skins...
Traceback (most recent call last):
  File "process_map_icons.py", line 6, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting faction data...
Exporting item data...
Traceback (most recent call last):
  File "process_items.py", line 66, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting scene data...
Traceback (most recent call last):
  File "process_scenes.py", line 15, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting troops data
Exporting particle data...
Traceback (most recent call last):
  File "process_scene_props.py", line 7, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_tableau_materials.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_presentations.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting party_template data...
Traceback (most recent call last):
  File "process_parties.py", line 6, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting quest data...
Exporting info_page data...
Traceback (most recent call last):
  File "process_scripts.py", line 7, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_mission_tmps.py", line 5, in <module>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_game_menus.py", line 8, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_simple_triggers.py", line 5, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_dialogs.py", line 9, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Traceback (most recent call last):
  File "process_global_variables_unused.py", line 3, in <module>
    from process_operations import *
  File "C:\Users\GunFred\Desktop\S - MS\process_operations.py", line 21, in <mod
ule>
    from module_mission_templates import *
  File "C:\Users\GunFred\Desktop\S - MS\module_mission_templates.py", line 78, i
n <module>
    common_ai_order_toggle = (ti_on_order_issued, 0, 0, [
NameError: name 'ti_on_order_issued' is not defined
Exporting postfx_params...

______________________________

Script processing has ended.
Press any key to exit. . .
What I have done is...

Constants:
slot_item_multiplayer_availability_linked_list_begin = 61 #temporary, can be moved to higher values

slot_item_alternate = 62 # Somebody's Alternate Weapon Modes


Scripts: (tested with and without the red parts, same error anyway)
# Somebody's Alternate Weapon Modes
  ("alternate_weapon_modes",
    [

(item_set_slot, "itm_???", slot_item_alternate, "itm_???_alt"),
(item_set_slot, "itm_???_alt", slot_item_alternate, "itm_???"),
    ]),

Mission_template: Just added the whole thing without changing it.

Resource: I did NOT use the downloadable resource because I got other models and items.
 

Somebody

Code Pope
Baron
WBWF&S
Best answers
1
Did you update your header_triggers?
Code:
ti_on_order_issued					  = -71.0 #can only be used in module_mission_templates triggers
# Trigger Param 1: order no
# Trigger Param 2: agent id