OSP Code QoL Universal Troop Costumizing System (with Save Feature)

Users who are viewing this thread

KON_Air

Master Knight
Universal Troop Costumizing System (UTCS), is the solution to all your non-hero troop item modifications! This simple set of scripts are easy to understand and implement. It uses two troops Paper Doll and Paper Doll Equipped and simply copies items from Paper Doll and gives them to Paper Doll Equipped. UTCS also virtually has no limits to number of customizable troops.

Let's start with the scripts;

script_paper_doll_prep;
Changes requirement stats of the Paper Doll to the Paper Doll Equipped. So only the items Paper Doll Equipped can use are equipable by Paper Doll. This script also changes the Paper Dolls gender to Paper Doll Equipped's gender. I'm not really sure what would that be useful for...

Code:
  #script_paper_doll_prep
  # INPUT: arg1 = Troop which will be used as paper dool arg2 = Troop which will be equipped
  # OUTPUT: none
("paper_doll_prep", [
       (store_script_param_1, ":paper_doll"),
       (store_script_param_2, ":paper_doll_equipped"),
[color=red] #Clear Inventory
(troop_clear_inventory,":paper_doll"),[/color]
#Remove Stats and Skills
     (troop_raise_attribute, ":paper_doll", ca_strength, -1000),
(troop_raise_attribute, ":paper_doll", ca_agility, -1000),
     (troop_raise_skill, ":paper_doll", skl_shield, -1000),
     (troop_raise_skill, ":paper_doll", skl_riding, -1000),
     (troop_raise_skill, ":paper_doll", skl_power_throw, -1000),
     (troop_raise_skill, ":paper_doll", skl_power_draw, -1000),
#Get Stats and Skills
(store_attribute_level,":pe_str",":paper_doll_equipped",ca_strength),
(store_attribute_level,":pe_agi",":paper_doll_equipped",ca_agility),
(store_skill_level,":pe_skl1",skl_shield,":paper_doll_equipped"),
(store_skill_level,":pe_skl2",skl_riding,":paper_doll_equipped"),
(store_skill_level,":pe_skl3",skl_power_throw,":paper_doll_equipped"),
(store_skill_level,":pe_skl4",skl_power_draw,":paper_doll_equipped"),
#Replace Stats and Skills
     (troop_raise_attribute, ":paper_doll", ca_strength, ":pe_str"),
(troop_raise_attribute, ":paper_doll", ca_agility, ":pe_agi"),
     (troop_raise_skill, ":paper_doll", skl_shield, ":pe_skl1"),
     (troop_raise_skill, ":paper_doll", skl_riding, ":pe_skl2"),
     (troop_raise_skill, ":paper_doll", skl_power_throw, ":pe_skl3"),
     (troop_raise_skill, ":paper_doll", skl_power_draw, ":pe_skl4"),
#Change Gender
        (troop_get_type, ":is_female", ":paper_doll_equipped"),
        (try_begin),
          (eq, ":is_female", 1),
          (troop_set_type,":paper_doll",1),
        (else_try),
          (troop_set_type,":paper_doll",0),
        (try_end),
#Now equip what target troop has
(call_script, "script_paper_doll_execute", ":paper_doll_equipped", ":paper_doll"),


]),


script_paper_doll_price_get; If want to charge for equipped items this is the script you should call. It calculates $paper_doll_equipped_surlups which is the money you get back from selling replaced items as surlups, and $paper_doll_equipped_expense as the cost of new items. It is open of improvement such as including Trade skills to calculations.. etc. Default values are 50xitems value for expense, 25xitems value for surlups.

Code:
  #script_paper_doll_price_get
  # INPUT: arg1 = Troop which will be used as paper dool arg2 = Troop which will be equipped.
  # OUTPUT: $paper_doll_equipped_surlups = Money that will return from previous items $paper_doll_equipped_expense = Money required to equip new items.
("paper_doll_price_get", [
       (store_script_param_1, ":paper_doll"),
       (store_script_param_2, ":paper_doll_equipped"),
(try_for_range, ":slot_no", 0, 9),#exclude food,
(troop_get_inventory_slot,":cur_item",":paper_doll",":slot_no"),
(neq, ":cur_item", -1),
(store_item_value, ":cur_item_value", ":cur_item"),
(store_mul, ":expense", ":cur_item_value", 50),
(val_add, "$paper_doll_equipped_expense", ":expense"),
(try_end),

(try_for_range, ":slot_no", 0, 9),#exclude food,
(troop_get_inventory_slot,":old_item",":paper_doll_equipped",":slot_no"),
(neq, ":old_item", -1),
(store_item_value, ":old_item_value", ":old_item"),
(store_mul, ":surlups", ":old_item_value", 25),
(val_add, "$paper_doll_equipped_surlups", ":surlups"),
(try_end),

#Debug... Might be useful...
# (assign, reg0, "$paper_doll_equipped_surlups"),
# (assign, reg1, "$paper_doll_equipped_expense"),
# (str_store_string, s33, "@Surplus: {reg0}"),
# (str_store_string, s34, "@Expense: {reg1}"),
# (display_message, "@{s33} {s34}"),
]),


script_paper_doll_execute; This the main trick, it copies items from ek_item0 to ek_item_food and gives them to target troop. It also keeps the modifiers (rust, reinforced... etc.) It can be expanded to copy entire inventory by simply chaning a value, (try_for_range, ":slot_no", 0, 9), this one

Code:
  #script_paper_doll_execute
  # INPUT: arg1 = Troop which will be used as paper dool arg2 = Troop which will be equipped.
  # OUTPUT: Equips target troop with items from Source Troop
("paper_doll_execute", [
       (store_script_param_1, ":paper_doll"),
       (store_script_param_2, ":paper_doll_equipped"),
(troop_clear_inventory,":paper_doll_equipped"),
(try_for_range, ":slot_no", 0, 9),#exclude food,
(troop_get_inventory_slot,":cur_item",":paper_doll",":slot_no"),
(troop_get_inventory_slot,":old_item",":paper_doll_equipped",":slot_no"),
(try_begin),
(neq, ":cur_item", -1),
(troop_get_inventory_slot_modifier, ":item_modifier", ":paper_doll", ":slot_no"),
(troop_add_item, ":paper_doll_equipped", ":cur_item", ":item_modifier"),
(else_try),
(neq, ":old_item", -1), #my first legacy code... Not that it functions or anything.
(troop_remove_item, ":paper_doll_equipped", ":old_item"),
(try_end),
(try_end),
(troop_equip_items, ":paper_doll_equipped"),
(call_script, "script_paper_doll_memorize", ":paper_doll_equipped"),
]),

script_paper_doll_memorize; This is the script for memorizing which item is in which slot and has which modifier. Can be applied to any troop, but main purpose is to memorize Paper Doll Equipped troops, who loose their inventory when a saved game is loaded.

Code:
  #script_paper_doll_memorize
  # INPUT: arg1 = Troop which is equipped via paper doll
  # OUTPUT: Stores equipped items and their modifiers in slots
("paper_doll_memorize", [
       (store_script_param_1, ":paper_doll_equipped"),
#Get items
(assign, ":slot_no", ek_item_0),
(try_for_range, ":mem_slot_no", slot_troop_item_memory_1, slot_troop_item_memory_1_mod),
(troop_get_inventory_slot,":cur_item",":paper_doll_equipped", ":slot_no"),
(troop_set_slot, ":paper_doll_equipped", ":mem_slot_no", ":cur_item"),
(val_add, ":slot_no", 1),
(try_end),
 
#Get modifiers
(try_for_range, ":mem_slot_no", slot_troop_item_memory_1_mod, slot_troop_item_memory_end),
(troop_get_inventory_slot_modifier, ":item_modifier", ":paper_doll_equipped", ":slot_no"),
(troop_set_slot, ":paper_doll_equipped", slot_troop_item_memory_1_mod, ":item_modifier"),
(val_add, ":slot_no", 1),
(try_end),
]),

script_paper_doll_recall; This script recalls the memorized items and gives them to the troops, the only down side you still need to call this manually and for each troop.

Code:
  #script_paper_doll_recall
  # INPUT: arg1 = Troop to be re-equipped
  # OUTPUT: none
("paper_doll_recall", [
	(store_script_param_1, ":paper_doll_equipped"),
#Clearing all
(troop_clear_inventory,":paper_doll_equipped"),
(try_for_range, ":slot_no", slot_troop_item_memory_1, slot_troop_item_memory_1_mod),
(troop_get_slot,":cur_item",":paper_doll_equipped",":slot_no"),

#Do Not Want A Loop Inside A Loop... I'd Rather Copy/Pasta
(try_begin),
(eq, ":slot_no", slot_troop_item_memory_1),
(assign, ":cur_modifier", slot_troop_item_memory_1_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_2),
(assign, ":cur_modifier", slot_troop_item_memory_2_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_3),
(assign, ":cur_modifier", slot_troop_item_memory_3_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_4),
(assign, ":cur_modifier", slot_troop_item_memory_4_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_5),
(assign, ":cur_modifier", slot_troop_item_memory_5_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_6),
(assign, ":cur_modifier", slot_troop_item_memory_6_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_7),
(assign, ":cur_modifier", slot_troop_item_memory_7_mod),
(else_try),
(eq, ":slot_no", slot_troop_item_memory_8),
(assign, ":cur_modifier", slot_troop_item_memory_8_mod),
(else_try),#you will never know
(assign, ":cur_modifier", 0),
(try_end),

(troop_add_item, ":paper_doll_equipped", ":cur_item", ":cur_modifier"),
(try_end),
(troop_equip_items, ":paper_doll_equipped"),]),

script_paper_doll_manual; allow you to write a call_script with 19 input values... yep...
9 items, a modifier for each and the troop to equip. Not tested... and I will need that one though... in distant future.

sample; (call_script, "script_paper_doll_manual", "itm_axe", imod_imodbit_heavy, "itm_nordic_shield" imodbit_thick, "itm_nordic_helmet", 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, "trp_nord_dude_without_boots"),

Code:
  #script_paper_doll_manual
  # INPUT: gee... item1, mod, item2, mod, item3, mod.... itm4, mod,  troop_no to equip -1 is empty see ek_item0 etc... table to equip troops
  # OUTPUT: wipes :troop_no's inventory and replaces it with the input and recalls it.
  ("paper_doll_manual",
    [(store_script_param, ":itm_0", 1),
     (store_script_param, ":itm_0_mod", 2),
	 (store_script_param, ":itm_1", 3),
     (store_script_param, ":itm_1_mod", 4),
	 (store_script_param, ":itm_2", 5),
     (store_script_param, ":itm_2_mod", 6),
	 (store_script_param, ":itm_3", 7),
     (store_script_param, ":itm_3_mod", 8),
	 (store_script_param, ":itm_4", 9),
     (store_script_param, ":itm_4_mod", 10),
	 (store_script_param, ":itm_5", 11),
     (store_script_param, ":itm_5_mod", 12),
	 (store_script_param, ":itm_6", 13),
     (store_script_param, ":itm_6_mod", 14),
	 (store_script_param, ":itm_7", 15),
     (store_script_param, ":itm_7_mod", 16),
	 (store_script_param, ":itm_8", 17),
     (store_script_param, ":itm_8_mod", 18),
     (store_script_param, ":paper_doll_equipped", 19),
	 
(troop_clear_inventory,":paper_doll_equipped"),
(try_begin),
(neq, ":itm_0", -1),
(neq, ":itm_0_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_0", ":itm_0_mod"),
(else_try),
(neq, ":itm_1", -1),
(neq, ":itm_1_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_1", ":itm_1_mod"),
(else_try),
(neq, ":itm_2", -1),
(neq, ":itm_2_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_2", ":itm_2_mod"),
(else_try),
(neq, ":itm_3", -1),
(neq, ":itm_3_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_3", ":itm_3_mod"),
(else_try),
(neq, ":itm_4", -1),
(neq, ":itm_4_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_4", ":itm_4_mod"),
(else_try),
(neq, ":itm_5", -1),
(neq, ":itm_5_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_5", ":itm_5_mod"),
(else_try),
(neq, ":itm_6", -1),
(neq, ":itm_6_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_6", ":itm_6_mod"),
(else_try),
(neq, ":itm_7", -1),
(neq, ":itm_7_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_7", ":itm_7_mod"),
(else_try),
(neq, ":itm_8", -1),
(neq, ":itm_8_mod", -1),
(troop_add_item, ":paper_doll_equipped", ":itm_8", ":itm_8_mod"),
(try_end),

(troop_equip_items, ":paper_doll_equipped"),
(call_script, "script_paper_doll_memorize", ":paper_doll_equipped"),
	 ]),


Those are constants;
Code:
slot_troop_item_memory_1		= 59
slot_troop_item_memory_2		= 60
slot_troop_item_memory_3		= 61
slot_troop_item_memory_4		= 62
slot_troop_item_memory_5		= 63
slot_troop_item_memory_6		= 64
slot_troop_item_memory_7		= 65
slot_troop_item_memory_8		= 66
slot_troop_item_memory_9		= 67

slot_troop_item_memory_1_mod		= 68
slot_troop_item_memory_2_mod		= 69
slot_troop_item_memory_3_mod		= 70
slot_troop_item_memory_4_mod		= 71
slot_troop_item_memory_5_mod		= 72
slot_troop_item_memory_6_mod		= 73
slot_troop_item_memory_7_mod		= 74
slot_troop_item_memory_8_mod		= 75
slot_troop_item_memory_9_mod		= 76
slot_troop_item_memory_end			= 77 #ninja slot, I think I have a use for it...


For sample use see; http://mbx.streetofeyes.com/index.php/topic,872.msg29256.html#msg29256


Final Note; No, I didn't peek at Expanded Gameplay 2, as a matter of fact I'm downloading it now :razz:
 
Ooh, I was thinking of doing something very similar to this in Liberty or Death.  I'll definately be studying this code.
 
Great, thank you. Got to try it sometime.

But I want to know, if, say, player disbands his customized troops, then hires some troops of the same type as were the disbanded ones, but with default equipment, will that recall script give new troops customised stuff?
Or, if you hire 1 peasant, buy him a full plate, then hire 99 more peasants, will they also have the plate?
 
It directly costumizes/recalls the troops inventory.

So, if you give "trp_peasant" full plate, then hire 99 more peasants, they will all have same items. Disbanding or wheter you have "trp_peasant" in your party or not is irrevelant.
 
Oh, by the way, if you don't do that in troops;

guarantee_all = tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_helmet|tf_guarantee_gloves|tf_guarantee_horse|tf_guarantee_ranged|tf_guarantee_ranged


  ["custom_a","custom_a","custom_a",guarantee_all,no_scene,reserved,fac_commoners,
  [itm_hide_boots],
  str_6|agi_6|level(7),wp(60),knows_common,mercenary_face_1, mercenary_face_2],

Unguaranteed items will be eaten by the script. (ie. Bow and arrow on a troop without tf_guarantee_ranged will eat arrows).
 
Can you be more descriptive by what you mean by "eaten?"  Does it mean that even if you assign a troop type to have a certain item, if you haven't assigned the guarantee flag, they won't end up having it? 
 
seems interesting!

Fancy to release the module system or the mod so even those with no scripting skills can test it?
 
Can you be more descriptive by what you mean by "eaten?"  Does it mean that even if you assign a troop type to have a certain item, if you haven't assigned the guarantee flag, they won't end up having it?

I figured it out without guarantee, troop may decide to unequip it later in between execute and prepare scripts. So that goes into inventory, and all inventroy is destroyed in execute script.

Oh and guarantee all should be;
Code:
guarantee_all = tf_guarantee_boots|tf_guarantee_armor|tf_guarantee_helmet|tf_guarantee_gloves|tf_guarantee_horse|tf_guarantee_ranged|tf_guarantee_ranged|tf_mounted|tf_guarantee_shield

The main usage idea was not continuous troop edit, it was for tiering faction troops, like Nord Warrior Circa 1257 (Axe, Leather armor) changing to Nord Warrior Circa 1300 (Super Axe, Super Chainmail). And I guess you should use a paper_doll_troop, per customizable troop.
 
is the fact that 'tf_guarantee_ranged' is listed twice intentional or a typo?  I'm assuming a typo but just want to make sure the 2nd one isn't required for arrows, etc...
 
afsaf yes its, and the #script_paper_doll_prep was buggered, we didn't clear the paper_doll's inventory, orginial fixed too.


Code:
  #script_paper_doll_prep
  # INPUT: arg1 = Troop which will be used as paper dool arg2 = Troop which will be equipped
  # OUTPUT: none
("paper_doll_prep", [
       (store_script_param_1, ":paper_doll"),
       (store_script_param_2, ":paper_doll_equipped"),
[color=red]	 #Clear Inventory 
	(troop_clear_inventory,":paper_doll"),[/color]
	 #Remove Stats and Skills
     (troop_raise_attribute, ":paper_doll", ca_strength, -1000),
	 (troop_raise_attribute, ":paper_doll", ca_agility, -1000),
     (troop_raise_skill, ":paper_doll", skl_shield, -1000),
     (troop_raise_skill, ":paper_doll", skl_riding, -1000),
     (troop_raise_skill, ":paper_doll", skl_power_throw, -1000),
     (troop_raise_skill, ":paper_doll", skl_power_draw, -1000),
	 #Get Stats and Skills
	(store_attribute_level,":pe_str",":paper_doll_equipped",ca_strength),
	(store_attribute_level,":pe_agi",":paper_doll_equipped",ca_agility),
	(store_skill_level,":pe_skl1",skl_shield,":paper_doll_equipped"),
	(store_skill_level,":pe_skl2",skl_riding,":paper_doll_equipped"),
	(store_skill_level,":pe_skl3",skl_power_throw,":paper_doll_equipped"),
	(store_skill_level,":pe_skl4",skl_power_draw,":paper_doll_equipped"),
	#Replace Stats and Skills
     (troop_raise_attribute, ":paper_doll", ca_strength, ":pe_str"),
	 (troop_raise_attribute, ":paper_doll", ca_agility, ":pe_agi"),
     (troop_raise_skill, ":paper_doll", skl_shield, ":pe_skl1"),
     (troop_raise_skill, ":paper_doll", skl_riding, ":pe_skl2"),
     (troop_raise_skill, ":paper_doll", skl_power_throw, ":pe_skl3"),
     (troop_raise_skill, ":paper_doll", skl_power_draw, ":pe_skl4"),
	#Change Gender
        (troop_get_type, ":is_female", ":paper_doll_equipped"),
        (try_begin),
          (eq, ":is_female", 1),
          (troop_set_type,":paper_doll",1),
        (else_try),
          (troop_set_type,":paper_doll",0),
        (try_end),
	 #Now equip what target troop has
	(call_script, "script_paper_doll_execute", ":paper_doll_equipped", ":paper_doll"),

	 
]),
 
Back
Top Bottom