Autoloot Source Code with Merging Instructions for other mods

Users who are viewing this thread

fisheye

Grandmaster Knight
NOTE: This version is no longer supported, the upgraded version by rubik is highly recommended:
http://forums.taleworlds.com/index.php/topic,60097.0.html


https://www.mbrepository.com/file.php?cid=1&id=951

Band of Warriors has some code where you can click one button and have all your heroes upgrade their gear from your loot pool. This is the new and improved code for it. It is a straight cut-and-paste into your mod source, very easy, no customization required.

List of changes (you only need to add code in 11 places):

module_constants:
* Some new constants, mostly slot definitions. Make sure these do not clash with your slot definitions

module_dialogs:
* A "start" option for talking to your heroes, this has to be near the top of the dialogs file.
* A chunk of item management conversation for selecting hero upgrade options, this has to be in "member_talk"
* A small conditional making sure you cannot separate a party member while talking to them inside the camp

module_game_menus:
* An additional option to access loot management from the camp menu
* "mnu_total_victory": Instead of just displaying the loot screen (change_screen_loot), we display a loot management menu instead
* Autoloot menus are at the bottom, you can put them anywhere.

module_items:
* An "itm_items_end" item at the end of the list to mark the end of the list

module_scripts:
* A call to "script_init_item_difficulties" at the top in "game_start"
* The autoloot scripts are at the bottom of the file, you can put them anywhere

module_strings:
* Some new strings, you can put them anywhere

process_items.py: (NOTE! this is process_items.py, the actual PYTHON processing code)
* A small snippet of code to be placed inside the "for item in items:" loop. Most modders don't change the process_xxx files so you can just copy this file.


That's all!

Note: the current version only supports items with a STR requirement of 5-14. So if you got an item of strength requirement 15, it won't work correctly (you just have to add in an additional line of code for each of these high-requirement items).

 
Updated to fix issue where items with requirement 0 and the heavy or masterwork modifier are perceived to have difficulty 1 and 4 respectively instead of 0.
 
fisheye said:
Updated to fix issue where items with requirement 0 and the heavy or masterwork modifier are perceived to have difficulty 1 and 4 respectively instead of 0.

Great code fisheye, I might include this in future versions of my mod if it is ok with you.

s/g
 
Hi guys, could someone please tell me what to do with the files in the rar package. Thx for posting this. I've done some tweaks to the game, but only in the text files, plus added unique armory (items). I have no idea how to merge this with my game. Many thanks.
 
Search for the tag "autoloot", find the chunk of code, cut and paste in the correct location in your own code.

It is impossible to get more specific than that, sorry.

My feeling is that you need at least a nonzero level of skill in modding to incorporate this, so you will have to learn the module system to really make use of this. This is a modder's resource, not a magelord tweak.
 
I didn't download the most recent version with the "Masterwork Hunting Bow" fix yet, but I've noticed that bastard swords aren't considered one-handed as before. Is this by design, or in the newest release, or needs looking at?
 
What's the itp_xxx on the bastardsword? That's what it is classified as, because that's what item_get_type returns. There's no workaround on this issue for this version. That's the price to pay for making the code vastly simpler for other modders to incorporate.
 
Ah, okay. It's itp_type_two_handed_wpn. So it won't equip unless telling the Hero to equip two-handed weapons. I wonder what would happen if declaring a new itp_ and using the logical OR operators that Fugiwara was happy to see in the mod system now. Maybe it could be worked out to check something declared with "itp_type_two_handed_wpn|itp_my_new_bastard_sword_type".
 
Thanks for porting the autoloot code!

I have a problem though:

New items I've added disappear through autolooting. They are removed from the party inventory, but none of
the heroes use them. Any idea why?

 
Did you initialize them if they have minimum requirements (like Strength or Power Draw)? There is a place in module_scripts that initializes items with requirements.
 
I did nothing but add the source in.
What do you mean by initialize? I see that the top of the autoloot-code in module_scripts deals with difficulty, but why would added items be treated any different than native items with a strenght requirement?
 
Could you post an example, e.g. the item listing

["zathan_sword", etc etc]

and the how it is problematic, e.g.

Borcha discards zathan's sword but picks up the dagger, so zathan's sword is left in the loot pile.

PS did you add them after "itm_items_end" in module_items.py? That item is the end marker and MUST be at the end.
 
Below is the end of my module_items file.
These helmets do show up as loot after battle. But when giving the heroes the chance to autoloot, the helmets disappear from the loot but isn't being used by the heroes.
So in essence, after the autloot, these helmets are gone - they somehow vanish in the process as it were. :lol:
I've gone through  your code fisheye, but can't find anything that would exclude new items.
Is there an ID_items cap involved?

Thanks for your help. :smile:

#FROM COMMUNITYHELMS

["crown_great_helmet", "Crown Great Helmet", [("crown_helm",0)], itp_merchandise| itp_type_head_armor|itp_covers_head,0,
4250 , weight(3)|abundance(10)|head_armor(60)|body_armor(0)|leg_armor(0)|difficulty(10) ,imodbits_plate ],
["flat_topped_helmet_faceplate", "Flat Topped Helmet", [("faceplate",0)], itp_merchandise| itp_type_head_armor,0,
569 , weight(2.5)|abundance(100)|head_armor(46)|body_armor(0)|leg_armor(0)|difficulty(:cool: ,imodbits_plate ],
["flat_topped_helmet_b", "Flat Topped Helmet", [("flattop",0)], itp_merchandise| itp_type_head_armor  ,0,
411 , weight(2)|abundance(100)|head_armor(40)|body_armor(0)|leg_armor(0)|difficulty(:cool: ,imodbits_plate ],
["mail_coif_b", "Mail Coif", [("full_mail_coif",0)], itp_merchandise| itp_type_head_armor  ,0,
156 , weight(1.50)|abundance(100)|head_armor(29)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_armor ],
["ghulam_helmet", "Ghulam Helmet", [("ghulam_helm2",0)], itp_merchandise| itp_type_head_armor  ,0,
555 , weight(2.0)|abundance(100)|head_armor(43)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["nordic_helmet_b", "Nordic Helmet", [("helmet_w_eyeguard_new_alt",0)], itp_merchandise| itp_type_head_armor  ,0,
450 , weight(2.25)|abundance(100)|head_armor(42)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["kettle_hat_paddedcoif", "Kettle Hat", [("kettlehat_paddedcoif",0)], itp_merchandise| itp_type_head_armor,0,
109 , weight(1.5)|abundance(100)|head_armor(25)|body_armor(0)|leg_armor(0)|difficulty(6) ,imodbits_plate ],
["kettle_hat_b", "Kettle Hat", [("kettlehelm",0)], itp_merchandise| itp_type_head_armor,0,
167 , weight(1.5)|abundance(100)|head_armor(30)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["great_helmet_b", "Great Helmet", [("maciejowskihelm",0)], itp_merchandise| itp_type_head_armor|itp_covers_head,0,
1180 , weight(3)|abundance(100)|head_armor(54)|body_armor(0)|leg_armor(0)|difficulty(10) ,imodbits_plate ],
["mamluk_helmet", "Mamluk Helmet", [("mamluk_helm",0)], itp_merchandise| itp_type_head_armor  ,0,
755 , weight(2.5)|abundance(100)|head_armor(44)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["mamluk_helmet_b", "Mamluk Helmet", [("metropolian_helm",0)], itp_merchandise| itp_type_head_armor  ,0,
755 , weight(2.5)|abundance(100)|head_armor(44)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["nasal_helmet_b", "Nasal Helmet", [("nasal_helmet_new",0)], itp_merchandise| itp_type_head_armor  ,0,
66 , weight(1)|abundance(100)|head_armor(21)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["nasal_helmet_c", "Nasal Helmet", [("nasal_helmet_new_alt",0)], itp_merchandise| itp_type_head_armor  ,0,
83 , weight(1.25)|abundance(100)|head_armor(23)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["nasal_helmet_d", "Nasal Helmet", [("nasalhelm_coif",0)], itp_merchandise| itp_type_head_armor  ,0,
83 , weight(1.25)|abundance(100)|head_armor(27)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["nordic_helmet_c", "Nordic Helmet", [("nordhelm_coif",0)], itp_merchandise| itp_type_head_armor  ,0,
480 , weight(2)|abundance(100)|head_armor(43)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["guard_helmet_b", "Guard Helmet", [("normanhelmwithcoif",0)], itp_merchandise| itp_type_head_armor  ,0,
555 , weight(2.5)|abundance(100)|head_armor(47)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["bascinet_b", "Bascinet", [("realbascinetb",0)], itp_merchandise| itp_type_head_armor  ,0,
555 , weight(2.5)|abundance(100)|head_armor(45)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["bascinet_c", "Bascinet", [("realbascinetc",0)], itp_merchandise| itp_type_head_armor  ,0,
555 , weight(2.5)|abundance(100)|head_armor(45)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["skullcap_with_coif", "Skullcap with Coif", [("skullcap_coif",0)], itp_merchandise| itp_type_head_armor  ,0,
258 , weight(1.75)|abundance(100)|head_armor(36)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["suttonhoo_helm", "Sutton Hoo Helmet", [("suttonhoo",0)], itp_merchandise| itp_type_head_armor  ,0,
555 , weight(2.5)|abundance(100)|head_armor(44)|body_armor(0)|leg_armor(0)|difficulty(9) ,imodbits_plate ],
["valsgarde_helmet", "Valsgarde Helmet", [("valsgarde",0)], itp_merchandise| itp_type_head_armor  ,0,
631 , weight(2.25)|abundance(100)|head_armor(4:cool:|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["vendel_helmet", "Vendel Helmet", [("vendel",0)], itp_merchandise| itp_type_head_armor  ,0,
570 , weight(2)|abundance(100)|head_armor(45)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["manhunter_helmet", "Manhunter Helmet", [("orcmaskcheeks",0)], itp_merchandise| itp_type_head_armor  ,0,
277 , weight(2)|abundance(100)|head_armor(37)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],
["manhunter_helmet_b", "Manhunter Helmet", [("orcromanhelm",0)], itp_merchandise| itp_type_head_armor  ,0,
237 , weight(1.75)|abundance(100)|head_armor(34)|body_armor(0)|leg_armor(0)|difficulty(7) ,imodbits_plate ],

######################################################################################
# Autoloot: Need this dummy item here to mark end of file
######################################################################################
["items_end","INVALID ITEM", [("practice_sword",0)], itp_type_one_handed_wpn|itp_primary|itp_secondary, itc_longsword, 3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),imodbits_none],


]
 
I had some problems with light plate and mail  and a few others disappearing. The solution was to place the items with others of the same type

from module_constants

weapons_begin = "itm_wooden_stick"
weapons_end = "itm_wooden_shield"
ranged_weapons_begin = "itm_jarid"
ranged_weapons_end = "itm_torch"
armors_begin = "itm_leather_gloves"
armors_end = "itm_wooden_stick"
shields_begin = "itm_wooden_shield"
shields_end = "itm_jarid"

Putting my items between other items of the same type allowed for autolooting to work with those items.

mfberg
 
OH ****! I'm an ass. Kick me. Thanks mfberg, you showed me the bug. Holy crap your bug reports are always the absolute best.

New version uploaded to repository. Now autoloot will work no matter where you put your items.

For those of you with the code already incorporated, replace your auto_loot_troop script in module_scripts with the following.

By the way regardless of the autoloot scripts it's still a good idea to respect the item order in the items file, because some old outdated code from native (loot_player_items) uses those constants. If you really want to be able to put your items anywhere you need to fix that routine too.

Code:
("auto_loot_troop", [  
	(try_begin),
		(store_script_param, ":troop", 1),
		(store_script_param, ":pool", 2),	
		
		(troop_get_slot,":upg_armor", ":troop",slot_upgrade_armor),
		(troop_get_slot,":upg_horses",":troop",slot_upgrade_horse),
			
		# dump whatever rubbish is in the main inventory
		(troop_get_inventory_capacity, ":inv_cap", ":troop"),
		(try_for_range, ":i_slot", 10, ":inv_cap"),
			(troop_get_inventory_slot, ":item", ":troop", ":i_slot"),
			(ge, ":item", 0),
			(troop_get_inventory_slot_modifier, ":imod", ":troop", ":i_slot"),
			(troop_add_item, ":pool", ":item", ":imod"), #put it back in the pool			
			(troop_set_inventory_slot, ":troop", ":i_slot", -1), # delete it
		(try_end),
		
		# dispose of the troop's equipped items if necessary
		(try_begin),
			(troop_slot_ge, ":troop", slot_upgrade_wpn_0, 1),
			(troop_get_inventory_slot, ":item", ":troop", 0),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":troop", 0),
			(troop_set_inventory_slot, ":troop", 0, -1), #delete it
			(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
		(try_end),
		
		(try_begin),
			(troop_slot_ge, ":troop", slot_upgrade_wpn_1, 1),
			(troop_get_inventory_slot, ":item", ":troop", 1),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":troop", 1),
			(troop_set_inventory_slot, ":troop", 1, -1), #delete it
			(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
		(try_end),
		
		(try_begin),
			(troop_slot_ge, ":troop", slot_upgrade_wpn_2, 1),
			(troop_get_inventory_slot, ":item", ":troop", 2),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":troop", 2),
			(troop_set_inventory_slot, ":troop", 2, -1), #delete it
			(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
		(try_end),
		
		(try_begin),
			(troop_slot_ge, ":troop", slot_upgrade_wpn_3, 1),
			(troop_get_inventory_slot, ":item", ":troop", 3),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":troop", 3),
			(troop_set_inventory_slot, ":troop", 3, -1), #delete it
			(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
		(try_end),

		(try_for_range, ":i_slot", 4, 9),
			(troop_get_inventory_slot, ":item", ":troop", ":i_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":troop", ":i_slot"),
			(try_begin),
				(neq, ":upg_armor", 0), # we're uprgrading armors
				(is_between, ":i_slot", ek_head, ek_horse), # it's an armor slot
				(troop_set_inventory_slot, ":troop", ":i_slot", -1), #delete it
				(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
			(else_try),
				(neq, ":upg_horses", 0), # we're uprgrading horses
				(eq, ":i_slot", ek_horse), # it's a horse slot
				(troop_set_inventory_slot, ":troop", ":i_slot", -1), #delete it
				(troop_add_item, ":pool", ":item", ":imod"), # chuck it in the pool
			(try_end),
		(try_end),
		
		# clear best matches
		(assign, ":best_helmet_slot", -1),
		(assign, ":best_helmet_val", 0),
		(assign, ":best_body_slot", -1),
		(assign, ":best_body_val", 0),
		(assign, ":best_boots_slot", -1),
		(assign, ":best_boots_val", 0),
		(assign, ":best_gloves_slot", -1),
		(assign, ":best_gloves_val", 0),
		(assign, ":best_horse_slot", -1),
		(assign, ":best_horse_val", 0),
		
		# Now search through the pool for the best items
		(troop_get_inventory_capacity, ":inv_cap", ":pool"),
		(try_for_range, ":i_slot", 0, ":inv_cap"),
			(troop_get_inventory_slot, ":item", ":pool", ":i_slot"),
			(ge, ":item", 0),
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":i_slot"),
			(call_script, "script_troop_can_use_item", ":troop", ":item", ":imod"),
			(eq, reg0, 1), # can use
			(call_script, "script_get_item_value_with_imod", ":item", ":imod"),
			(assign, ":score", reg0),
			
			(item_get_type, ":item_type", ":item"),
			
			(try_begin),
				(eq, ":item_type", itp_type_horse), #it's a horse
				(eq, ":upg_horses", 1), # we're uprgrading horses
				(gt, ":score", ":best_horse_val"),
				(assign, ":best_horse_slot", ":i_slot"),
				(assign, ":best_horse_val", ":score"),
			(else_try),
				(try_begin),
					(eq, ":item_type", itp_type_head_armor), 
					(eq, ":upg_armor", 1), # we're uprgrading armor
					(gt, ":score", ":best_helmet_val"),
					(assign, ":best_helmet_slot", ":i_slot"),
					(assign, ":best_helmet_val", ":score"),
				(else_try),
					(eq, ":item_type", itp_type_body_armor), 
					(eq, ":upg_armor", 1), # we're uprgrading armor
					(gt, ":score", ":best_body_val"),
					(assign, ":best_body_slot", ":i_slot"),
					(assign, ":best_body_val", ":score"),
				(else_try),
					(eq, ":item_type", itp_type_foot_armor),		
					(eq, ":upg_armor", 1), # we're uprgrading armor
					(gt, ":score", ":best_boots_val"),
					(assign, ":best_boots_slot", ":i_slot"),
					(assign, ":best_boots_val", ":score"),
				(else_try),
					(eq, ":item_type", itp_type_hand_armor),			
					(eq, ":upg_armor", 1), # we're uprgrading armor
					(gt, ":score", ":best_gloves_val"),
					(assign, ":best_gloves_slot", ":i_slot"),
					(assign, ":best_gloves_val", ":score"),
				(try_end),
			(try_end),
		(try_end),
		
		# Now we know which ones are the best. Give them to the troop.		
		(try_begin),
			(assign, ":best_slot", ":best_helmet_slot"),
			(ge, ":best_slot", 0),
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":troop", ek_head, ":item"),
			(troop_set_inventory_slot_modifier, ":troop", ek_head, ":imod"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1),
		(try_end),
		
		(try_begin),
			(assign, ":best_slot", ":best_body_slot"),
			(ge, ":best_slot", 0),
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":troop", ek_body, ":item"),
			(troop_set_inventory_slot_modifier, ":troop", ek_body, ":imod"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1),
		(try_end),
		
		(try_begin),
			(assign, ":best_slot", ":best_boots_slot"),
			(ge, ":best_slot", 0),
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":troop", ek_foot, ":item"),
			(troop_set_inventory_slot_modifier, ":troop", ek_foot, ":imod"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1),
		(try_end),
		
		(try_begin),
			(assign, ":best_slot", ":best_gloves_slot"),
			(ge, ":best_slot", 0),
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":troop", ek_gloves, ":item"),
			(troop_set_inventory_slot_modifier, ":troop", ek_gloves, ":imod"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1),
		(try_end),
		
		(try_begin),
			(assign, ":best_slot", ":best_horse_slot"),
			(ge, ":best_slot", 0),
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"),
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":troop", ek_horse, ":item"),
			(troop_set_inventory_slot_modifier, ":troop", ek_horse, ":imod"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1),
		(try_end),

		(try_for_range, ":i_slot", 0,4),
			(store_add, ":trp_slot", ":i_slot", slot_upgrade_wpn_0),
			(troop_get_slot, ":type", ":troop", ":trp_slot"),
			(gt, ":type", 0), #we're upgrading for this slot
			(call_script, "script_scan_for_best_item_of_type", ":pool", ":type", ":troop"), #search for the best
			(assign, ":best_slot", reg0),
			(neq, ":best_slot", -1), #got something
			(troop_get_inventory_slot, ":item", ":pool", ":best_slot"), #get it
			(ge, ":item", 0),			
			(troop_get_inventory_slot_modifier, ":imod", ":pool", ":best_slot"),
			(troop_set_inventory_slot, ":pool", ":best_slot", -1), #remove from pool
			(troop_set_inventory_slot, ":troop", ":i_slot", ":item"), #add to slot
			(troop_set_inventory_slot_modifier, ":troop", ":i_slot", ":imod"),
		(try_end),
		
	(try_end),	
]),



 
Thanks so much both of you, you're awesome!
Will give it another go tomorrow and report back how it works.

edit: yup, works a treat now, thanks!
 
Thanks for making this so easily available fisheye, I'm going to include it in my gameplay mod. 
 
Back
Top Bottom