OSP Code SP [WB] Order: Weapon Type Switch

Users who are viewing this thread

Caba`drin said:
Dermeister said:
thats a long script is there a way to copy and past it so that it pasted exacly how you wrote it because me ity pastes it in 1 line O_O! even though i selected it all and did control C control V

That's odd. Have you tried editing the module_*.py files with Notepad++ ? That should ease your pain.

SonKidd said:
for single player only?
would it be possible for it to work for AI under command for multilayer by adding triggers to the appropriate mission templates?
thanks!
For single player only.
I've not ever dealt with multiplayer coding...I honestly don't know what (if anything) may be required  to make this work for bots.

I just tested adding this script to multiplayer battle.

The shield command works.
However, the other commands don't work.

Anyone have any idea wht modifications are needed?

EDIT

I deleted the "Check if Hero" part and it works fine. However, there is one problem, the code works for ALL troops of that class. Not only the ones you are commanding and I can't seem to find the operation for "check whether troop is under your command in multiplayer". Does anyone know it?

Code:
  # script_order_weapon_type_switch
  # Input: Order Type   
  # Output: Nothing
  # On key depression, try to switch division to appropriate weapon
("order_weapon_type_switch", [ 
     (store_script_param_1, ":ordertype"),
     (get_player_agent_no, ":player"),
     (agent_get_team, ":playerteam", ":player"),
     (try_for_agents, ":agent"),
         (agent_is_alive, ":agent"),
         (agent_is_human, ":agent"),
         (agent_is_non_player, ":agent"),
         (agent_get_team, ":team", ":agent"),
         (eq, ":team", ":playerteam"), #On Player's side?
         (agent_get_division, ":class", ":agent"),
         (try_begin), #Mark class as in battle
             (eq, ":class", 0),
             (assign, ":group0_in_battle", 1),
         (else_try),
             (eq, ":class", 1),
             (assign, ":group1_in_battle", 1),   
         (else_try),
             (eq, ":class", 2),
             (assign, ":group2_in_battle", 1),         
         (else_try),
             (eq, ":class", 3),
             (assign, ":group3_in_battle", 1),         
         (else_try),
             (eq, ":class", 4),
             (assign, ":group4_in_battle", 1),         
         (else_try),
             (eq, ":class", 5),
             (assign, ":group5_in_battle", 1),   
         (else_try),
             (eq, ":class", 6),
             (assign, ":group6_in_battle", 1),         
         (else_try),
             (eq, ":class", 7),
             (assign, ":group7_in_battle", 1),         
         (else_try),
             (eq, ":class", 8),
             (assign, ":group8_in_battle", 1),                       
         (try_end),
         (class_is_listening_order, ":team", ":class"), #Is the agent's team selected?
         (try_begin), #Mark class as selected
             (eq, ":class", 0),
             (assign, ":group0_is_selected", 1),
         (else_try),
             (eq, ":class", 1),
             (assign, ":group1_is_selected", 1),   
         (else_try),
             (eq, ":class", 2),
             (assign, ":group2_is_selected", 1),         
         (else_try),
             (eq, ":class", 3),
             (assign, ":group3_is_selected", 1),         
         (else_try),
             (eq, ":class", 4),
             (assign, ":group4_is_selected", 1),         
         (else_try),
             (eq, ":class", 5),
             (assign, ":group5_is_selected", 1),   
         (else_try),
             (eq, ":class", 6),
             (assign, ":group6_is_selected", 1),         
         (else_try),
             (eq, ":class", 7),
             (assign, ":group7_is_selected", 1),         
         (else_try),
             (eq, ":class", 8),
             (assign, ":group8_is_selected", 1),                       
         (try_end),
         (agent_get_troop_id, ":troop",":agent"),     
         #regular troops
		 (troop_get_inventory_capacity,":cap",":troop"),
		 (try_for_range, ":i", 0, ":cap"),#(slots < 10)?
			 (troop_get_inventory_slot,":item",":troop",":i"),
			 (gt, ":item", 0),
			 (item_get_type, ":weapontype", ":item"),
			 (try_begin),
				 (eq, ":ordertype", ranged),
				 (str_store_string, s1, "@ready bows and missiles"),
				 (this_or_next|eq, ":weapontype", itp_type_bow),
				 (this_or_next|eq, ":weapontype", itp_type_crossbow),
				 (eq, ":weapontype", itp_type_thrown),
				 (agent_has_item_equipped, ":agent", ":item"),
				 (agent_set_wielded_item, ":agent", ":item"),
				 (assign, ":cap", 0),#loop breaker
			 (else_try),
				 (eq, ":ordertype", onehand),
				 (str_store_string, s1, "@ready side arms"),
				 (eq, ":weapontype", itp_type_one_handed_wpn),
				 (agent_has_item_equipped, ":agent", ":item"),
				 (agent_set_wielded_item, ":agent", ":item"),
				 (assign, ":cap", 0),#loop breaker
			 (else_try),
				 (eq, ":ordertype", bothhands),
				 (str_store_string, s1, "@ready two-handers and polearms"),
				 (this_or_next|eq, ":weapontype", itp_type_two_handed_wpn),
				 (eq, ":weapontype", itp_type_polearm),
				 (agent_has_item_equipped, ":agent", ":item"),
				 (agent_set_wielded_item, ":agent", ":item"),
				 (assign, ":cap", 0),#loop breaker
			 (else_try),
				 (eq, ":ordertype", shield),
				 (agent_get_wielded_item, ":shield", ":agent", 1),
				 (try_begin),
					 (gt, ":shield", 0),
					 (agent_unequip_item, ":agent", ":shield"),
					 (agent_equip_item, ":agent", ":shield"), #Moves shield to back
					 (str_store_string, s1, "@doff your shields"),
					 (assign, ":cap", 0),#loop breaker
				 (else_try),
					 (eq, ":weapontype", itp_type_shield),
					 (agent_has_item_equipped, ":agent", ":item"),
					 (agent_set_wielded_item, ":agent", ":item"), #Moves shield from back to hand
					 (str_store_string, s1, "@brandish shields"),
					 (assign, ":cap", 0),#loop breaker
				 (try_end),
			 (try_end),
		 (try_end),
     (try_end), #Agent Loop
     (str_clear, s2),
     (str_clear, s3),
     (assign, ":count_possible", 0),
     (assign, ":count_selected", 0),
     (try_begin),
         (eq, ":group0_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group0_is_selected", 1),
         (val_add, ":count_selected", 1),
         (str_store_class_name, s2, 0),
     (try_end),
     (try_begin),
          (eq, ":group1_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group1_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 1),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 1),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group2_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group2_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 2),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 2),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group3_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group3_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 3),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 3),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group4_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group4_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 4),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 4),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group5_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group5_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 5),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 5),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group6_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group6_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 6),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 6),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group7_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group7_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),   
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 7),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 7),
         (try_end),
     (try_end),
     (try_begin),
          (eq, ":group8_in_battle", 1),
         (val_add, ":count_possible", 1),
         (eq, ":group8_is_selected", 1),
         (val_add, ":count_selected", 1),
         (try_begin),
             (neg|str_is_empty, s2),
             (str_store_class_name, s3, 8),
             (str_store_string, s2, "@{!}{s2}, {s3}"),
         (else_try),
             (str_store_class_name, s2, 8),
         (try_end),
     (try_end),
     (try_begin),
         (eq, ":count_selected", ":count_possible"),
         (str_store_string, s2, "@Everyone"),
     (try_end),
     (try_begin),
         (gt, ":count_selected", 0),
         (display_message, "@{!}{s2}, {s1}!", 0xFFDDDD66),
     (try_end),
     (str_clear, s2),
     (str_clear, s3),
    ]),

 
Would you be able to tell a non modder how to get this beauty working?

If I just take the mainpart, then it gives me not defined errors and the more I take of your things the more errors I get.
Then I add in the constants and some of those errors disappear, however I am unable to get it into the mission templates, because your explanation of what to do is not sufficent for me.

So I left that out do I need to do it? I just want it in normal battles on the field, sieges and maybe the city raiding scenario or will it work there anyway?



The resulting script.txt is like 11kb while the original is 1mb, so I guess that didn't work out so well :wink:
 
@Pappus,

First, none of the code parts are optional, so all of them need to get put into their correct files or you are going to get errors.

Second, a chunk of those are "warnings" about globals that even once we get it all workings, some will remain; don't worry about that.

Third, both the scripts and constants parts don't take anything special to get them in. With constants, go to the bottom of the file and paste them (I'm guessing you've done that without a problem). Scripts similarly can go at the beginning or end, so long as it gets pasted within the beginning scripts = [    and, if you're dropping them at the very end, before the final ] which is the last character in the file. When you paste them, make sure they aren't breaking up any code that is there already...you are sure you aren't if you put them at the very beginning  or end (as stated before) or if they go between the end of one script and the beginning of the next, which looks like this:
Code:
   //...ending code from a script...//
   ]),

-->THIS IS BETWEEN SCRIPTS<--

  # script_name_of_script:
  # Description of what the script does
  # INPUT: none
  ("name_of_script",

Fourth, if you don't include the stuff in mission_templates, even if everything else was in the right spot, the game would never know to look at it, so you wouldn't see it work anyhow. So, to get it into mission templates, paste everything in the mission_templates spoiler (those four/five lines) together toward the top of the file...where I described in the opening post works well, so long as it isn't in the middle of another bit of code...or right at the top of the file works too, so long as it is under these two lines:
pilgrim_disguise = [itm_pilgrim_hood,itm_pilgrim_disguise,itm_practice_staff, itm_throwing_daggers]
af_castle_lord = af_override_horse | af_override_weapons| af_require_civilian

Now that the code that looks for if you press the appropriate buttons is in, we need to tell it to use that code in the appropriate missions.
The first mission we'll do is for field battles. It is called "lead_charge". If you search for lead_charge you should find it's beginning, which looks like this:
Code:
(
    "lead_charge",mtf_battle_mode,charge,
    "You lead your men to battle.",
    [
Scroll to the end of it, which is about 200 lines down and looks like this:
Code:
      common_battle_order_panel,
      common_battle_order_panel_tick,

    ],
  ),

  (
    "village_attack_bandits",mtf_battle_mode,charge,
    "You lead your men to battle.",
    [
You'll note that the mission where you attack bandits in villages begins right after lead_charge. Regardless, what we care about is the closed bracket followed by a comma '],' at the end of lead_charge, before the attack_bandits bit begins. We need to add the order_weapon_type_triggers here by putting " + order_weapon_type_triggers" between the bracket and the comma, so it will look like "] + order_weapon_type_triggers,"  or in context:
Code:
      common_battle_order_panel,
      common_battle_order_panel_tick,

    ] + order_weapon_type_triggers,
  ),

  (
    "village_attack_bandits",mtf_battle_mode,charge,
    "You lead your men to battle.",
    [

And that's that. Now do the same in other missions you want it included in: go to the end of the mission, find the closing bracket, add the " + order_weapon_type_triggers" and you're set.

To find other battle missions, search for "mtf_battle_mode"
Add the triggers to whichever ones you want, skipping any that start with multiplayer_ or are commented out (marked with #)
 
Is it possible to attach .wav prompts to the rolling order outputs?

I was wondering this as I was driving home today.  I had been futzing around with your code a bit and started thinking it might be neat to add basic voice acting for the player in a mod.
 
ThunderClaw said:
Is it possible to attach .wav prompts to the rolling order outputs?

I was wondering this as I was driving home today.  I had been futzing around with your code a bit and started thinking it might be neat to add basic voice acting for the player in a mod.

You could either use (play_sound,<sound_id>,[options]), or (agent_play_sound, <agent_id>, <sound_id>),
The first is probably all that is needed if you are having the player give a command. The engine uses .ogg files, rather than .wav but that's minor really.

This would be easy to add to my code here, but a bit more difficult to track with Native orders, since the engine doesn't store what Native order is being given in a readily accessible way. You'd need a global variable to track those key presses within some (game_key_clicked, key),-based triggers. For this, see motomataru's formations code (specifically the mission_templates triggers) and how he tracks Native orders.
 
Caba`drin said:
You could either use (play_sound,<sound_id>,[options]), or (agent_play_sound, <agent_id>, <sound_id>),
The first is probably all that is needed if you are having the player give a command. The engine uses .ogg files, rather than .wav but that's minor really.

This would be easy to add to my code here, but a bit more difficult to track with Native orders, since the engine doesn't store what Native order is being given in a readily accessible way. You'd need a global variable to track those key presses within some (game_key_clicked, key),-based triggers. For this, see motomataru's formations code (specifically the mission_templates triggers) and how he tracks Native orders.
Interesting.  I'll have to look into this later down the road, I'm still sorting out a couple other things with my own mod.  If/when I work up a solution to this I'll pass it along.
 
I'm seeking a bit of input. I'm going a little batty trying to figure out how to improve the functionality of the weapon/shield orders, particularly for the combination of orders surrounding using a polearm and a shield. I'm looking for a functional combination that will allow the player to have a wide range of control when dealing with, say, a spearman equipped with a shield, spear, and sword. The player should be able to order the Spearmen to "turtle up" and force the use of their shields (preferably with the polearm, but with the sword if necessary), OR to wield the spear without a shield, OR to try and use the spear with a shield (depending on the type of polearm it is) and if the shield can't be used then keep using the polearm.

First I'll explain how it currently works with different states of orders being given and what happens when certain keys are pressed...then I'll float an alternative possibility...but I'd very much appreciate any other ideas folk might have. For some reason this is really wracking my brain.

In all cases, assume a division/group/class of spear-type agents, and I'm trying to achieve what I've described above.

Possible change #1: polearm and shield order slightly depend on one another...I've tried it and it is not producing optimal behavior.
-No orders given
--Shield Key: Force use shields
--Pole/2Hander Key: Use 2hand/polearm. Force unequip shield.
-Use 2H/Polearm already given; no shield order given
--Shield Key: Use shields if troop can, but prefer to continue wielding polearm
--Pole/2Hander key: does nothing
-No weapon order; USE Shields already given
--Shield Key: Force unequip shields
--Pole/2Hander Key:  Use shields if troop can, but prefer wielding polearm to using shield
-Pole/2Hander weapon order; USE Shields already given
--Shield Key: Force unequip shields
--Pole/2Hander Key:  does nothing

Possible change #2: shield key always forces equip/unequip of shields, and polearm/2hander key behavior changes
-No orders given
--Shield Key: Force use shields
--Pole/2Hander Key: Use 2hand/polearm. Force unequip shield.
-Use 2H/Polearm already given; no shield order given
--Shield Key: Force use shields
--Pole/2Hander key: Use shields if troop can, but prefer wielding polearm to using shield
-No weapon order; USE Shields already given
--Shield Key: Force unequip shields
--Pole/2Hander Key:  Try wielding polearm, but prefer to keeping shield to switching weapon
-Pole/2Hander weapon order; USE Shields already given
--Shield Key: Force unequip shields
--Pole/2Hander Key:  Use shields if troop can, but prefer wielding polearm to using shield

Another possible change:
Re-do the shield toggle by using two keys for shields, rather than just one...though I'm not sure that would help the confusion.

What would make the most sense for use as a player?
 
Caba, could you perhaps be so kind to specify which txt files are changed by these module files? Obviously scripts.txt and mission_templates.txt are changed, but the constants got me a little confused...

I already have a full customized install, and even though I added your code in the Diplomacy source code (which I use as my base), I'd rather not overwrite my customized txt's if it's not necessary.

Thanks in advance!
 
Captain_Octavius said:
Caba, could you perhaps be so kind to specify which txt files are changed by these module files? Obviously scripts.txt and mission_templates.txt are changed, but the constants got me a little confused...

I already have a full customized install, and even though I added your code in the Diplomacy source code (which I use as my base), I'd rather not overwrite my customized txt's if it's not necessary.

Thanks in advance!

If you use your previous variables.txt in your Module System folder, it should just be mission_templates, scripts, quick strings and variable uses, but I'll double check. Constants is used at compile-time to turn words into numbers. It isn't stored elsewhere.
 
Hmmm... I suddenly thought of something:

Instead of checking if class is selected for every troop
Code:
INSIDE AGENT LOOP:
(class_is_listening_order, ":team", ":class"), #Is the agent's team selected?
         (try_begin), #Mark class as selected
             (eq, ":class", 0),
             (assign, ":group0_is_selected", 1),
         (else_try),
             (eq, ":class", 1),
             (assign, ":group1_is_selected", 1),   
         (else_try),
             (eq, ":class", 2),
             (assign, ":group2_is_selected", 1),         
         (else_try),
             (eq, ":class", 3),
             (assign, ":group3_is_selected", 1),         
         (else_try),
             (eq, ":class", 4),
             (assign, ":group4_is_selected", 1),         
         (else_try),
             (eq, ":class", 5),
             (assign, ":group5_is_selected", 1),   
         (else_try),
             (eq, ":class", 6),
             (assign, ":group6_is_selected", 1),         
         (else_try),
             (eq, ":class", 7),
             (assign, ":group7_is_selected", 1),         
         (else_try),
             (eq, ":class", 8),
             (assign, ":group8_is_selected", 1),                       
         (try_end),

Why not pull that part out for optimization?

Code:
(agent_get_team, ":playerteam", ":playeragent"),
         (try_begin), #Mark class as selected
             (class_is_listening_order, ":playerteam", 0),
             (assign, ":group0_is_selected", 1),
         (else_try),
             (class_is_listening_order, ":playerteam", 1),
             (assign, ":group1_is_selected", 1),   
         (else_try),
             (class_is_listening_order, ":playerteam", 2),
             (assign, ":group2_is_selected", 1),         
         (else_try),
             (class_is_listening_order, ":playerteam", 3),
             (assign, ":group3_is_selected", 1),         
         (else_try),
             (class_is_listening_order, ":playerteam", 4),
             (assign, ":group4_is_selected", 1),         
         (else_try),
             (class_is_listening_order, ":playerteam", 5),
             (assign, ":group5_is_selected", 1),   
         (else_try),
             (class_is_listening_order, ":playerteam", 6),
             (assign, ":group6_is_selected", 1),         
         (else_try),
             (class_is_listening_order, ":playerteam", 7),
             (assign, ":group7_is_selected", 1),         
         (else_try),
             (class_is_listening_order, ":playerteam", 8),
             (assign, ":group8_is_selected", 1),                       
         (try_end),
     (try_for_agents, ":agent"), 
...
 
JuicyDeath said:
Caba`drin said:
two-handed or polearm
and if they have both?
As is, the script will equip which ever one is found first as it cycles through the agent's equipped items.
This works well enough for most units as there are very few that are equipped with both two handers and polearms...and I needed to find some place to use fewer function keys.

However, in the very near future I'll be posting an updated version of this code (merged with my skirmish order) that separates these commands and reorganizes how they are given to be more similar to the way Native orders are selected.

@SonKidd...
Not a bad idea at all. The new version, mentioned above, uses something like this.
 
JuicyDeath said:
Caba`drin said:
merged with my skirmish order
sounds interesting. So you can make AI keep distance? can you do this for 2h and pole soldiers?

See here. It's rough, but it has ranged troops at least attempt to withdraw from impending melee.

With the method I've used, it is more accurate to describe it as avoiding melee/withdrawing from melee than maintaining distance. As such, fine tuning it to polearm-users and 2 handers to maintain optimal distance is not possible. We'd need a different level of control over bot decision making for that, I'm afraid. The best I've done with polearm users is to force them to use their polearm until they are swamped in melee, then they switch to whatever side arm they have equipped.
 
I am not sure, wether this still is supposed to work, but I keep getting invalid syntax of this part:
order_weapon_type_triggers = [   
(0, 0, 1, [(key_clicked, key_for_onehand)], [(call_script, "script_order_weapon_type_switch", onehand)]),
(0, 0, 1, [(key_clicked, key_for_bothhands)], [(call_script, "script_order_weapon_type_switch", bothhands)]),
(0, 0, 1, [(key_clicked, key_for_ranged)], [(call_script, "script_order_weapon_type_switch", ranged)]),
(0, 0, 1, [(key_clicked, key_for_shield)], [(call_script, "script_order_weapon_type_switch", shield)]),
]
 
Back
Top Bottom