dynamically switching weapon capabilities while in battle (basically working)

Users who are viewing this thread

HokieBT

Grandmaster Knight
I want to be able to have the ability to toggle a weapons capabilities during battle.  So I could switch a throwing axe or javelin into a regular axe or spear by pressing a button.  I did some testing with this in my star wars mod with the following code:

module_mission_templates.py
Code:
SW - toggle_weapon_capabilities
common_toggle_weapon_capabilities = (0, 0, 0, [
	(key_clicked, key_t)
	],
	[
		(get_player_agent_no, ":player_agent"),
		(agent_is_alive, ":player_agent"),
		
		(display_message, "@attempting to switch weapon capabilities..."),

		(try_begin),
			(agent_has_item_equipped, ":player_agent", "itm_lightsaber_green_pike"),
			#(agent_get_wielded_item, ":handone", ":player_agent", 0),      
			#(agent_get_wielded_item, ":handtwo", ":player_agent", 1),      			
			(try_for_range, ":slot_no", 0, 4),
				#(troop_get_inventory_slot, ":item", "trp_player",":slot_no"),
				(troop_get_inventory_slot, ":item", "$g_player_troop",":slot_no"),	#since custom commander is integrated
				(try_begin),
					(eq, ":item", "itm_lightsaber_green_pike"),
					(troop_set_inventory_slot, "trp_player", ":slot_no", "itm_force_throw_lightsaber_green_pike"),
					(display_message, "@weapon capabilities were switched."),
				(try_end),
			(try_end),
		(else_try),
			(agent_has_item_equipped, ":player_agent", "itm_force_throw_lightsaber_green_pike"),
			(try_for_range, ":slot_no", 0, 4),
				#(troop_get_inventory_slot, ":item", "trp_player",":slot_no"),
				(troop_get_inventory_slot, ":item", "$g_player_troop",":slot_no"),	#since custom commander is integrated
				(try_begin),
					(eq, ":item", "itm_force_throw_lightsaber_green_pike"),
					(troop_set_inventory_slot, "trp_player", ":slot_no", "itm_lightsaber_green_pike"),
					(display_message, "@weapon capabilities were switched."),
				(try_end),
			(try_end),
		(try_end),					
	])

Note:  I was only trying to test if this is possible, so the above code would need to be improved.  Most likely we'd only want to be able to toggle the weapon we were wielding and we wouldn't want to hard-code weapon names but would probably use another slot on each weapon (or something like that) to tell what the alternative one was.

This code ALMOST works, I can start with only a "lightsaber pike", press the T key to switch it, and now I have a "throwing lightsaber pike".  The problem is it ONLY seems to work if I go to my inventory screen...  It does not automatically switch the weapon I have equipped, if I un-equip and re-equip the weapon it doesn't change, if I switch a weapon that is not equipped it doesn't change, etc....  So does anybody have an idea how to fix this so you wouldn't have to go to the inventory screen every time?  Or at the minimum make it so you could toggle the weapon capabilities on the inventory screen itself ?

   
 
wow, good work hokiebt, nice idea and a useful thing with some improvements (usable with all items mainly )...
 
So,  in order to use that in battles, you have to run to your baggage first? If not, then you could only use it in battles, and map it to the inventory key or something.
 
Rize said:
So,  in order to use that in battles, you have to run to your baggage first? If not, then you could only use it in battles, and map it to the inventory key or something.

I think I removed the inventory key restriction in my mod, but yeah, it seems like it will only really switch if you open the inventory screen.  The idea would be to make it dynamically switch in battle, but so far I haven't been able to figure out how to do that...
 
I've been trying to do something like that as well. You know, a musket with bayonett for melee and ranged. I didn't find a way.
I've had your problem too. You either have to go to the inventory or start a conversation. Two problems:
1) Your ammo is also refilled.
2) It sucks that you have press the inventory key in addition to the switch key. A conversation works better. It can be opened with a script (start_mission_conversation). You could start a conversation with the player himself. Just put something like "close me" in the text. It's still not very nice to have to close it manually.

Problem 1 is why I didn't use it in 1866.

I've also tryed another idea: When you press Ctrl+F an item is spawned in front of the player. As F is pressed, the item is being equipped right away. It doesn't work very well either:
1) Sometimes the item is not being equipped. Then it flies in the air.
2) Of course when you equip a new item, an old one is unequipped. Unfortunatelly not always the one you have in your hands, but just one of the 4 you have equipped. I don't know whether it is random or anything. The problem is that it goes like this:
before: lightsaber, blaster, ammo, axe
switching: lighsaber, blaster, lightsaber thrown, axe
switching again: lightsaber, blaster, lightsaber thrown, lightsaber.
I guess you see the problem.
 
thanks very much for the feedback, that is helpful to know that a conversation also works, so I may play around with that.  It would be great to get something like this working, but its not looking good so far...  :sad:
 
Well, you could make a script that turns your weapon into a throwing one and throws it right away, but then comes my problem with the attack code.
And as for rifles with bayonets, Highlander, you could map a function that makes the agent stab with his bayonet, though if you use something like (agent_has_item_equipped,":player",":rifle"),...................(call_script,"script_cf_bayonet_stab",":player"), you can stab with anything as long as you have a bayonet rifle equipped... And NPC's won't use it either way.
 
Rize said:
Well, you could make a script that turns your weapon into a throwing one and throws it right away, but then comes my problem with the attack code.
And as for rifles with bayonets, Highlander, you could map a function that makes the agent stab with his bayonet, though if you use something like (agent_has_item_equipped,":player",":rifle"),...................(call_script,"script_cf_bayonet_stab",":player"), you can stab with anything as long as you have a bayonet rifle equipped... And NPC's won't use it either way.
Ermmm... no.
 
Highlander said:
2) A conversation works better. It can be opened with a script (start_mission_conversation). You could start a conversation with the player himself. Just put something like "close me" in the text. It's still not very nice to have to close it manually.

Alternatively, one could use a message like "you have begun using your [whatever] as a [missile/melee] weapon." Still awkward, but at least it somewhat gives the appearance of.. er, well, trying to maintain immersion. Gotta be a better way though.



This is an interesting topic. I think I'll take a look into this myself this evening.
 
I've been playing around with this, and Highlander had the best suggestion of using start_mission_conversation.  for example:

1) I have a "lightsaber pike" in one of my 4 weapon slots
2) while in a scene I press the T key and the code toggles any of the 4 weapon slots to an alternate weapon (if available) and display a conversation summary
3)  I can now equip a "throwing lightsaber pike" in the scene, if I view my inventory it has been switched and the item modifier was kept
4) if I press the T key again then these weapons switch back

NOTE:  the limitations are that you have to display this conversation, your weapons will be sheathed after the conversation, and ammo will be refilled

       

I'm still working on this code, but if anybody wants to test or try and improve it they are more them welcome to....

module_constants.py
Code:
slot_item_alternate_weapon    	  = 6	#SW - for the common_toggle_weapon_capabilities code

game_start in module_scripts.py
Code:
	 #SW - settng alternative weapon capabilities for common_toggle_weapon_capabilities code
	 (item_set_slot, "itm_lightsaber_green_pike", slot_item_alternate_weapon, "itm_force_throw_lightsaber_green_pike"),
	 (item_set_slot, "itm_force_throw_lightsaber_green_pike", slot_item_alternate_weapon, "itm_lightsaber_green_pike"),
	 (item_set_slot, "itm_lightsaber_green", slot_item_alternate_weapon, "itm_force_throw_lightsaber_green_merch"),
	 (item_set_slot, "itm_force_throw_lightsaber_green", slot_item_alternate_weapon, "itm_lightsaber_green"),

module_mission_templates.py
Code:
#SW - toggle_weapon_capabilities
common_toggle_weapon_capabilities = (0, 0, 0, [
	(key_clicked, key_t)
	],
	[
		(get_player_agent_no, ":player_agent"),
		(agent_is_alive, ":player_agent"),
		#clear the strings
		(str_clear, s1),(str_clear, s2),(str_clear, s10),(str_clear, s11),(str_clear, s12),(str_clear, s13),
		(try_for_range, ":slot_no", 0, 4),
			(troop_get_inventory_slot, ":item", "$g_player_troop",":slot_no"),	#since custom commander is integrated
			(try_begin),
				(ge, ":item", 0),	#don't check empty item slots
				(item_slot_ge, ":item", slot_item_alternate_weapon, 1),	#see if the item has an alternate weapon slot defined
				(item_get_slot, ":alternate_weapon", ":item", slot_item_alternate_weapon),	#get the alternate weapon
				(troop_get_inventory_slot_modifier, ":modifier", "$g_player_troop", ":slot_no"),	#get the modifier
				(troop_set_inventory_slot, "$g_player_troop", ":slot_no", ":alternate_weapon"),	#set the alternate weapon
				(troop_set_inventory_slot_modifier, "$g_player_troop", ":slot_no", ":modifier"),	#set the modifier
				#record the names to display in the dialog later
				(str_store_item_name, s1, ":item"),	
				(str_store_item_name, s2, ":alternate_weapon"),
				(try_begin),
					(eq, ":slot_no", 0),
					(str_store_string, s10, "@{s1} switched to {s2}"),
				(else_try),
					(eq, ":slot_no", 1),
					(str_store_string, s11, "@{s1} switched to {s2}"),
				(else_try),
					(eq, ":slot_no", 2),
					(str_store_string, s12, "@{s1} switched to {s2}"),
				(else_try),
					(eq, ":slot_no", 3),
					(str_store_string, s13, "@{s1} switched to {s2}"),
				(try_end),
				(assign, "$show_switch_weapon_dialog", 1),
			(try_end),
		(try_end),
		(try_begin),
			(eq, "$show_switch_weapon_dialog", 1),
			(start_mission_conversation, "$g_player_troop"),	#workaround since weapons don't automatically switch
		(try_end),
	])

put near the top of module_dialogs.py
Code:
  #SW - added player dialog for weapon switch functionality
  [anyone,"start", 
	[
		(eq, "$show_switch_weapon_dialog", 1),
		(assign, "$show_switch_weapon_dialog", 0),
	], 
	"^{s10}^{s11}^{s12}^{s13}^^^Note: displaying this dialog is necessary due to a M&B game engine limitation.","close_window",[]
  ], 
 
hi, did you guys ever think about the dialogs that has sentance like this: Warning: This line should never display.
those dialogs should never be seen by the player, I dont know what makes that yet, maybe it is anyone|auto_proceed, but we could really use it here, if the developers dont make that toggle weapon flag perfect.
 
Yeah, as you saw there are a lot of issues with the current toggle weapon flag in Warband
http://forums.taleworlds.com/index.php/topic,101073.msg2530287.html#msg2530287

I've never tried using the auto_proceed command, do you know if you still have to click the Mouse to move the dialog forward?  I'm guessing its something like that?

Highlander actually found a better implementation then my code above.  He actually stores all the weapons in a variables, then kills and re-spawns the player in their current position.  This is a little tough in M&B 1.x since there isn't a remove_agent we had to move them to the edge of the screen, but in warband they did add a remove_agent so it should work much smoother.  However, I still wish the developers just fixed the toggle weapon code to work correctly instead of us having to code our own....  :sad:
 
there are big problems with highlander's old way and new way:
the blood and arrows on the agent will disappear, the current animation will be interrupted.

I am trying my method. if it work I will reply here.
 
Well, I tested this and WilliamBerne had a good suggestion with using the auto_proceed command, but unfortunately it doesn't seem to work combined with a close_window type of command.  :sad:  I can use auto_proceed to automatically skip one dialog and go to a different one, but I can't automatically close that next one either....    I tried some other stuff like putting a (eq, 1, 0) in the top of the second window so it wouldn't be displayed but that didn't work either or just caused issues.  So I don't think its possible to skip displaying the dialog, but maybe somebody else can think of a better way...  Also, Highlander's method of re-spawning the player had another disadvantage, because after battle the summary screen shows that X number of Players have been injured because the code has to kill all the old player agents.  So for now I've just gone back to always display the conversation popup.
 
I tested it too, didnt work. :sad:

"because after battle the summary screen shows that X number of Players have been injured".
you can use (set_show_messages,"value"),

(set_show_messages,0),
kill player agent
respawn player agent
(set_show_messages,1),

but I still dont like that way, cause the look of the agent will change.
 
Back
Top Bottom