This is code to replace script_party_calculate_loot in module_scripts. It's short, sweet and simple. In fact, after testing it, I haven't the foggiest why I didn't do this months ago; the looting code has always been one of the more problematic things in Warband.
Why am I sharing this one out? If you've ever looked at that script in Native, you know that it's anything but short, sweet and simple; it relies on the calculation of party shares, which is prone to various issues, and because it uses troop_loot_troop, it doesn't give access to the full range of equipment that should be available. This uses a very different method to iterate through the Troop items, using a random chance based on Looting skill. No more pile of 20 worthless Rocks when you've just fought 40 Looters fighting alongside some well-equipped Deserters- that problem is fixed, amongst others.
This code could very easily be extended to allow for special treasures held by enemy Heroes and other fun things, and it allows horses to be looted just like anything else.
Why am I sharing this one out? If you've ever looked at that script in Native, you know that it's anything but short, sweet and simple; it relies on the calculation of party shares, which is prone to various issues, and because it uses troop_loot_troop, it doesn't give access to the full range of equipment that should be available. This uses a very different method to iterate through the Troop items, using a random chance based on Looting skill. No more pile of 20 worthless Rocks when you've just fought 40 Looters fighting alongside some well-equipped Deserters- that problem is fixed, amongst others.
This code could very easily be extended to allow for special treasures held by enemy Heroes and other fun things, and it allows horses to be looted just like anything else.
Code:
#script_party_calculate_loot:
# INPUT:
# param1: Party-id
# Returns num looted items in reg(0)
("party_calculate_loot",
[
(store_script_param_1, ":enemy_party"), #Enemy Party_id
(troop_clear_inventory,"trp_temp_troop"),#Clear the temp troop inventory
(assign, ":num_looted_items",0),
(assign, ":loot_slot", 10),
#Get looting skill
(party_get_skill_level, ":player_party_looting", "p_main_party", "skl_looting"),
(val_mul, ":player_party_looting", 3),
(party_get_num_companion_stacks, ":num_stacks",":enemy_party"),
(try_for_range, ":i_stack", 0, ":num_stacks"),
(lt, ":loot_slot", 40),#Don't overfill loot
(party_stack_get_troop_id, ":stack_troop",":enemy_party",":i_stack"),
(try_for_range, ":current_inv", 0, 30),
(troop_get_inventory_slot,":my_inv",":stack_troop",":current_inv"),#Search for items
(gt, ":my_inv", 0),#We have a valid item
(store_random_in_range, ":rand", 1, 135),
(val_add, ":rand", ":player_party_looting"),
(try_begin),
(ge, ":rand", 100),
(troop_set_inventory_slot, "trp_temp_troop", ":loot_slot", ":my_inv"),
(val_add, ":loot_slot", 1),#Bump the slot upwards, so that we don't overwrite
(val_add, ":num_looted_items", 1),
(try_end),
(try_end),
(try_end),
#Add random trade goods where appropriate
(try_begin),
(this_or_next|party_slot_eq, "$g_enemy_party", slot_party_type, spt_kingdom_caravan),
(this_or_next|party_slot_eq, "$g_enemy_party", slot_party_type, spt_bandit_lair),
(party_slot_eq, "$g_enemy_party", slot_party_type, spt_village_farmer),
(party_get_skill_level, ":player_looting", "p_main_party", "skl_looting"),
(store_random_in_range, ":plunder_amount", 1, 5),
(val_add, ":plunder_amount", ":player_looting"),
(troop_add_merchandise, "trp_temp_troop", itp_type_goods, ":plunder_amount"),
(val_add, ":num_looted_items", ":plunder_amount"),
(try_end),
(assign, reg0, ":num_looted_items"),
]),