OSP Code SP [WB] Combat Modifier Buildings

Users who are viewing this thread

What is this?
This code establishes a system overwriting Native's building slots whereby "upgrades" can be obtained by with the use of agent modifier operations applied from mission templates. Included in this package is also a number of auxiliary buildings which I have not bothered to remove - these can be elaborated on later by request. This is not a complete module, although placeholders values are included for native factions and towns. The effect of changing modifiers will depend on the individual factions. Also included is an initialization framework where the costs are made dynamic and the newer buildings can become upgraded - even by the AI if they are sufficiently wealthy. A number of capitals have some extant infrastructure, however the player can only upgrade them or build one in a conquered center due to their cumulative nature so as to not make a sufficiently motivated player too overpowered. Feel free to give feedback or discuss below, or tell me how awesome this is going to be and what mod you're going to add it in.

What are agent modifiers?
Agent modifiers are operations which make troops faster and stronger in battle. Although it can be used to weaken them instead, it is more interesting to see divergence between difference factions using different weaponry to varying degrees of effectiveness. The operations in use are agent_set_max_hit_points/agent_set_damage_modifier/agent_set_accuracy_modifier/agent_set_speed_modifier/agent_set_reload_speed_modifier/agent_set_ranged_damage_modifier/agent_set_horse_speed_factor, which were introduced in the more recent patches.
module_mission_templates said:
common_battle_init_banner = (
  ti_on_agent_spawn, 0, 0, [],
  [
    (store_trigger_param_1, ":agent_no"),
    (agent_get_troop_id, ":troop_no", ":agent_no"),
    (call_script, "script_troop_agent_set_banner", "tableau_game_troop_label_banner", ":agent_no", ":troop_no"),
    (call_script, "script_init_agent_modifiers", ":agent_no"),
  ])
Code:
  ("init_agent_modifiers",
    [
    (store_script_param_1, ":agent"),

    (agent_get_party_id, ":party_no", ":agent"),
    (agent_get_troop_id, ":troop_no", ":agent"),
    (try_begin),
      (eq, ":party_no", "p_main_party"),
      (assign,  ":party_faction", "$players_kingdom"),
      (val_max, ":party_faction", "fac_player_supporters_faction"),
    (else_try),
      (party_is_active, ":party_no"),
      (store_faction_of_party, ":party_faction", ":party_no"),
    (else_try), #spawned agents, bodyguards?
      (assign, ":party_faction", "fac_commoners"),
    (try_end),

    (try_begin), #heros already upgrade skill/items
      (troop_is_hero, ":troop_no"),
      (assign, ":troop_faction", -1),
    (else_try),
      (store_faction_of_troop, ":troop_faction", ":troop_no"),
    (try_end),
    
    #force triggering
    (try_begin),
      (eq, "$g_is_quick_battle", 1),
      (try_begin), #override previous hero restriction
        (get_player_agent_no, ":player_agent"),
        (agent_get_rider, ":rider", ":agent"),
        (this_or_next|eq, ":rider", ":player_agent"),
        (eq, ":player_agent", ":agent"),
        (assign, ":troop_faction", "$g_quick_battle_team_1_faction"),
      (try_end),
      (assign, ":party_faction", ":troop_faction"),
    (try_end),

    #do some conditionals for agent/party/faction checks
    #in general if agent/party mismatch, they are deserters
    (try_begin),
      # (this_or_next|eq, ":troop_faction", "fac_commoners"),
      (try_begin), #player's parties
        (eq, ":party_faction", "fac_player_supporters_faction"),
        (faction_slot_eq, "fac_player_supporters_faction", slot_faction_state, sfs_active),
        # (this_or_next|eq, ":troop_faction", "$g_player_culture"),
        (eq, ":troop_faction", "fac_commoners"), #arming mercenaries
        (assign, ":troop_faction", ":party_faction"),
      (try_end),
      (eq, ":troop_faction", ":party_faction"),
      (is_between, ":troop_faction", kingdoms_begin, kingdoms_end),
      (try_begin), #troops
        (agent_is_human, ":agent"),
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_foundrys),
        (val_add, ":num_buildings", 100),
        (agent_set_damage_modifier, ":agent", ":num_buildings"),
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_arsenals),
        (val_add, ":num_buildings", 100),
        (agent_set_ranged_damage_modifier, ":agent", ":num_buildings"),
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_ranges),
        (val_add, ":num_buildings", 100),
        (agent_set_accuracy_modifier, ":agent", ":num_buildings"),
        (agent_set_reload_speed_modifier, ":agent", ":num_buildings"),
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_barracks),
        (store_agent_hit_points, ":health", ":agent", 1),
        (val_add, ":health", ":num_buildings"),
        (agent_set_max_hit_points, ":agent", ":health", 1),
      (else_try), #horses
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_stables),
        (val_add, ":num_buildings", 100),
        # (agent_set_horse_speed_factor, ":agent", ":num_buildings"), #this gets modified with current health in CC
        # (agent_set_damage_modifier, ":agent", ":num_buildings"), #charge damage?
        (agent_set_speed_modifier, ":agent", ":num_buildings"), #this doesn't work well
        # (agent_set_damage_modifier, ":agent", ":num_buildings"), #this screws up charge damage - inflicting via operation still works
        #horse HP are large enough to warrant percentage increase
        (agent_set_max_hit_points, ":agent", ":num_buildings", 0),
        (agent_get_rider, ":rider", ":agent"), #surprisingly this works
        (agent_set_horse_speed_factor, ":rider", ":num_buildings"), #downside is the rider now gets the bonus, not the horse
        (agent_set_slot, ":agent", slot_agent_horse_modifier, ":num_buildings"), #which we can correct here with another trigger
      (try_end),
    (try_end),
    ]
  ),

What are these special buildings supposed to do?
  • Foundry - melee damage
  • Arsenal - ranged damage
  • Stables - horse hp/speed
  • Barracks - health (linear)
  • Shooting Range - accuracy/reload
Each building adds 1% to their respective modifier - the effects of upgrading are linear but can be customized. The names and descriptions are fairly generic so as to fit into most M&B modules, but again you can customize those or remove them if so desired. The first two are likely the most powerful, whereas the last 3 are more about support. Obviously infantry factions do not need to build stables (other than holding their lords' parade ponies), and close-quarter factions don't need to be accurate when swinging, whereas a faction with firearms obviously want both precision and reload speed. As I have not run extensive playtesting, they are not guaranteed to be balanced (it's up to you to beta-test  these things). Not all the features in the description are included in this package, nor are they suited for mods of all culture.
Code:
improvement_limit = 12000
equipment_limit = 3000

slot_center_has_manor            = 130 #village
slot_center_has_mill             = 131
slot_center_has_watch_tower      = 132
slot_center_has_plantation       = 133
slot_center_has_lumber_yard      = 134
slot_center_has_school           = 135
slot_center_has_messenger_post   = 136 #town, castle, village
slot_center_has_prisoner_tower   = 137 #town, castle
slot_center_has_mercenary_hall   = 138 #town
slot_center_has_merchant_guild   = 139 #town
# slot_center_has_slaver_pit       = 138 #town, castle
slot_center_has_academy  = 140 #town, castle
slot_center_has_foundry  = 141 #towns
slot_center_has_arsenal  = 142 #towns
slot_center_has_stables  = 143 #towns
slot_center_has_barrack  = 144 #town, castle
slot_center_has_shrange  = 145 #town, castle

village_improvements_begin = slot_center_has_manor
village_improvements_end = slot_center_has_prisoner_tower

military_infra_begin = slot_center_has_foundry
military_infra_end = slot_center_has_shrange + 1
walled_center_improvements_begin = slot_center_has_messenger_post
walled_center_improvements_end   = slot_center_has_shrange + 1
initial_castle_improvements_end  = slot_center_has_mercenary_hall
num_improvements = walled_center_improvements_end - village_improvements_begin
Code:
  ("spt_castle", "castle"),
  ("spt_town", "town"),
  ("spt_village", "village"),
  
  ("manor", "Manor"),
  ("mill", "Mill"),
  ("watchtower", "Watch Tower"),
  ("plantation", "Plantation"),
  ("lumber_yard", "Lumber Yard"),
  ("school", "School"),
  ("messenger_post", "Messenger Post"),
  ("prison_tower", "Prisoner Tower"),
  ("mercenary_hall", "Mercenary Hall"),
  ("merchant_hall", "Merchant Guild"),
  ("military_hall", "Military Academy"),
  ("foundry", "Steelworks Furnace"),
  ("arsenal", "Great Arsenal"),
  ("stables", "Companion Range"),
  ("barracks", "Field Barrack"),
  ("shooting_range", "Marksmen Gallery"),
  
  ("manor_details", "A manor lets you rest at the village and pay your troops half wages while you rest. You will be able to review the garrison, which will become more disciplined."),
  ("fishpond_details", "A mill increases village prosperity by 5%."),
  ("watchtower_details", "A watch tower lets the villagers raise alarm earlier. The amount of cattle that can be driven off is halved. The time it takes for enemies to loot the village increases by 50%. The village will also be reinforced with additional watchmen."),
  ("plantation_details", "A plantation allows for conscription of troops. Workers from surrounding regions will gather here and defend it by force if necessary. In addition, there is a chance that colonial troops will be recruited from the new culture."),
  ("lumber_details", "A lumber yard deforests the surrounding countryside for a 5% increase in prosperity and results in a decrease in build time for nearby centers."),
  ("school_details", "A school increases the loyality of the inhabitants to you by +1 every month. The school's graduates will aid in the defense this village."),
  ("messenger_post_details", "A messenger post lets the inhabitants send you a message whenever enemies are nearby, even if you are far away from here. An officer will be on duty at all times to coordinate the defenses."),
  ("prison_tower_details", "A prison tower reduces the chance for special captives held here to escape."),
  #new stuff below
  ("merc_hall_details", "A mercenary hall attracts famed adventurers from Calradia and Georia across the sea, hosting up to twice the number of hired blades and reducing their cost in garrisons."),
  ("merchant_details", "A merchant guild expedites the flow of commerce in this town by increasing base prosperity gained per trade and the number of caravans that can be supported overall. If a mercenary hall is also build, caravans originating from this town will be better escorted."),
  ("academy_details", "A military academy increases the rate at which soldiers can be trained while in garrison, and also allows the promotion of veteran soldiers to champion status as well as civilizing certain bandit troops."),
  ("foundry_details", "A foundry produces high-quality weapons using the latest advances in ferrous metallurgy, increasing close-quarter damage done by 1%."),
  ("arsenal_details", "An arsenal create arms of exceptional quality and stockpiles of deadly ammunition, increasing ranged damage done by 1%."),
  ("stable_details", "A companion range provides an open pasture for horses to graze and tracks for equestrian exercise, and as such increases the endurance and speed of mounts by 1%."),
  ("barrack_details", "A barrack establishes permanent cantonments for drilling yards and field hospitals as well as imposing sanitation standards, increasing the health of common soldiers by 1%."),
  ("shooting_details", "A shooting gallery allows all skirmishers to practice in a variety of gauntlets while honing their precision, allow them to keep firing under any conditions, increasing their reload speed and accuracy by 1%."),

Will the AI use it?
As I have mentioned in the previous sections, the Native factions come pre-loaded with between 9-10 buildings distributed in their towns. In addition, each walled center owned by a lord gets a chance at building a random infrastructure at the start (based on wealth and renown), and over the span of the game. This calculation will succeed rarely, but if you promote the properly conditioned companion to the aristocracy it might be expedited.
script_game_start said:
      (try_for_range, ":center_no", walled_centers_begin, walled_centers_end),#add town garrisons
      ......
        #create lord parties
        (party_get_slot, ":center_lord", ":center_no", slot_town_lord),
        (ge, ":center_lord", 1),
        (troop_slot_eq, ":center_lord", slot_troop_leaded_party, 0),
        (assign, "$g_there_is_no_avaliable_centers", 0),
        (call_script, "script_create_kingdom_hero_party", ":center_lord", ":center_no"),
        (assign, ":lords_party", "$pout_party"),
        (party_attach_to_party, ":lords_party", ":center_no"),
        (party_set_slot, ":center_no", slot_town_player_odds, 1000),
       
        (troop_get_slot, ":renown", ":center_lord", slot_troop_renown),
        (val_add, ":renown", ":initial_wealth"),
        (call_script, "script_allocate_buildings", ":center_no", ":renown"),
script_troop_does_business_in_center said:
    ......
    (call_script, "script_npc_upgrade_buildings", ":troop_no", ":center_no"),

    #Recruit volunteers
    (try_begin),
      (is_between, ":center_no", villages_begin, villages_end),
Code:
  #script_allocate_buildings
  # This script is called to initialize nifty new buildings
  # INPUT: center, renown points for allocation
  # OUTPUT: s50 to be displayed
  ("allocate_buildings",
   [
    (store_script_param, ":center_no", 1),
    (store_script_param, ":renown", 2),

    (assign, reg0, ":renown"),
    (val_mul, ":renown", 10),
    (str_store_party_name, s51, ":center_no"),
    (str_store_string, s50, "@{s51} allocated {reg0} wealth for buildings"),
    
    (store_random_in_range, ":random", 0, 5),
    (try_begin), #not towns anymore
      (is_between, ":center_no", castles_begin, castles_end),
      (assign, ":range", initial_castle_improvements_end),
    (else_try),
      (assign, ":range", walled_center_improvements_end),
    (try_end),
    (try_for_range, ":unused", 0, ":random"),
      (store_random_in_range, ":improvements", walled_center_improvements_begin, ":range"),
      (try_begin), #reroll if existing, add base infrastructure bonus
        (party_slot_ge, ":center_no", ":improvements", 1),
        (val_add, ":renown", 1500),
      (else_try),
        (party_get_slot, ":cost", "p_zendar", ":improvements"),
        (ge, ":renown", ":cost"),
        (val_sub, ":renown", ":cost"),
        (party_set_slot, ":center_no", ":improvements", 1),
        (store_sub, ":string", ":improvements", village_improvements_begin),
        (val_add, ":string", "str_manor"),
        (str_store_string, s51, ":string"),
        (str_store_string, s50, "str_s50_comma_s51"),
      (try_end),
    (try_end),
    (display_log_message, "@{s50}"),
  ]),
  
  #script_npc_upgrade_buildings
  # This script is called to initialize nifty new buildings
  # INPUT: center, renown points for allocation
  # OUTPUT: s50 to be displayed
  ("npc_upgrade_buildings",
   [
    (assign, ":improvement_limit", improvement_limit),
    (assign, ":equipment_limit", equipment_limit),
    (store_script_param, ":troop_no", 1),
    (store_script_param, ":center_no", 2),

    (troop_get_slot, ":personality", ":troop_no", slot_lord_reputation_type),
    (troop_get_slot, ":troop_wealth", ":troop_no", slot_troop_wealth),
    
    (try_begin),
      (is_between, ":personality", lrep_martial, lrep_selfrighteous),
      (val_div, ":equipment_limit", 2),
    (else_try),
      (is_between, ":personality", lrep_selfrighteous, lrep_goodnatured),
      (val_mul, ":improvement_limit", ":personality"),
    (else_try),
      (is_between, ":personality", lrep_goodnatured, lrep_custodian),
      (try_begin), #exception
        (eq, ":personality", lrep_roguish),
        (val_sub, ":equipment_limit", 1000),
      (else_try),
        (store_mul, ":level", ":personality", 250),
        (val_sub, ":improvement_limit", ":level"),
      (try_end),
    (try_end),

    #upgrade centers
    (try_begin),
      (gt, ":troop_wealth", ":improvement_limit"), #surplus cash
      (party_slot_eq, ":center_no", slot_center_current_improvement, 0), #not already building
      (assign, ":continue", 1),
      #this randomization applies so that there is a chance of not building an improvement
      (store_random_in_range, ":improvement_no", village_improvements_begin, walled_center_improvements_end),
      (party_slot_eq, ":center_no", ":improvement_no", 0), #not already built
      (try_begin), #villages
        (party_slot_eq, ":center_no", slot_party_type, spt_village),
        (ge, ":improvement_no", village_improvements_end),
        (assign, ":continue", 0),
      (else_try), #towns, castles
        (lt, ":improvement_no", walled_center_improvements_begin),
        (assign, ":continue", 0),
      (try_end),
      (eq, ":continue", 1),
      (call_script, "script_get_improvement_details", ":improvement_no", 1, 1),
      (assign, ":improvement_cost", reg0),	# 4000-25000
      (store_attribute_level, ":level", ":troop_no", ca_intelligence), #10-70
      (store_skill_level, ":skill", "skl_engineer", ":troop_no"), #0 to 15
      (val_mul, ":skill", ":level"), # 0 to 105
      (store_character_level, ":level", ":troop_no"), #22-50
      (val_add, ":skill", ":level"),
      (val_sub, ":improvement_cost", ":level"),

      #get working strength
      (party_get_num_companions, ":divider", ":center_no"), #0~300, ignoring wounded
      (party_get_num_prisoners, ":level", ":center_no"), #possibly up to 100
      (gt, ":divider", ":level"),

      #calculate time - manpower, prosperity, and int/level-based
      (party_get_slot, ":multiplier", ":center_no", slot_town_prosperity), #-100 to 100
      (val_sub, ":multiplier", ":level"),
      (store_sub, ":multiplier", 200, ":multiplier"), #300 to 100
      # (val_div, ":level", 2),
      # (val_add, ":divider", ":level"), #25 - 400
      (store_character_level, ":level", ":troop_no"), #22-50
      (val_add, ":divider", ":level"),
      (store_attribute_level, ":level", ":troop_no", ca_intelligence), #10-70
      (store_skill_level, ":skill", "skl_engineer", ":troop_no"), #0 to 15
      (val_mul, ":level", ":skill"), # 0 to 105

      (val_add, ":divider", ":level"), #total 30~500

      (store_mul, ":improvement_time", ":improvement_cost", ":multiplier"), #400000 - 2700000
      (val_div, ":improvement_time", 100),
      (val_div, ":improvement_time", ":divider"), #18.18~800
      (lt, ":improvement_time", 160), #feasible
      (val_max, ":improvement_time", 3), #not instantaneous

      (val_sub, ":troop_wealth", ":improvement_cost"),
      (try_begin),
        (store_faction_of_troop, ":troop_faction", ":troop_no"),
        (this_or_next|eq, ":troop_faction", "$players_kingdom"),
        (eq, "$cheat_mode", 2),
        (assign, reg0, ":improvement_time"),
        (display_log_message, "@{s10} constructs a {s0} in {s4}, finish in {reg0} days"),
      (try_end),
      (assign, "$g_improvement_type", ":improvement_no"),
      (call_script, "script_improve_center", ":center_no", ":improvement_time"),
      (try_end),
    (try_end),
    (troop_set_slot, ":troop_no", slot_troop_wealth, ":troop_wealth"),
   ]
  ),

How can I use it?
Since the buildings are constructed along the native system of menus and triggers, the new buildings simply take up more slots and real estate. Just go through the menu and click on the new things, be sure to have enough money. If you are using diplomacy, the lines for building them via the chamberlain and tallying them through the constable can also be made available. Otherwise, one of the new benefits of joining a faction that fits your playing style is that you now have access to their existing improvements - as long as you are using their troops, of course.
Code:
  (
    "center_manage",0,
    "{s19}^{reg6?^^You are\
 currently building {s7}. The building will be completed after {reg8} day{reg9?s:}.:}",
    "none",
    [(call_script, "script_get_improvement_progress", "$current_town"),
    ],
    [
      ("center_build_manor",[(eq, reg6, 0),
                             (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                             (party_slot_eq, "$g_encountered_party", slot_center_has_manor, 0),
                                  ],
       "Build a manor.",[(assign, "$g_improvement_type", slot_center_has_manor),
                         (jump_to_menu, "mnu_center_improve"),]),
      ("center_build_fish_pond",[(eq, reg6, 0),
                                 (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                                 (party_slot_eq, "$g_encountered_party", slot_center_has_mill, 0),
                                  ],
       "Build a mill.",[(assign, "$g_improvement_type", slot_center_has_mill),
                             (jump_to_menu, "mnu_center_improve"),]),

      ("center_build_lumber_mill",[(eq, reg6, 0),
                                 (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                                 (party_slot_eq, "$g_encountered_party", slot_center_has_lumber_yard, 0),
                                  ],
       "Build a lumber mill and saw yard.",[(assign, "$g_improvement_type", slot_center_has_lumber_yard),
                             (jump_to_menu, "mnu_center_improve"),]),

      ("center_build_plantation",[(eq, reg6, 0),
                                 (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                                 (party_slot_eq, "$g_encountered_party", slot_center_has_plantation, 0),
                                 #requirement - culture different from conquerors
                                 (party_get_slot, ":original_faction", "$current_town", slot_center_original_faction),
                                 (party_get_slot, ":ex_faction", "$current_town", slot_center_ex_faction),
                                 (this_or_next|eq, "$g_encountered_party_faction", ":ex_faction"),
                                 (neq, "$g_encountered_party_faction", ":original_faction"),
                                  ],
       "Build a plantation.",[(assign, "$g_improvement_type", slot_center_has_plantation),
                             (jump_to_menu, "mnu_center_improve"),]),

      ("center_build_watch_tower",[(eq, reg6, 0),
                                   (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                                   (party_slot_eq, "$g_encountered_party", slot_center_has_watch_tower, 0),
                                  ],
       "Build a watch tower.",[(assign, "$g_improvement_type", slot_center_has_watch_tower),
                               (jump_to_menu, "mnu_center_improve"),]),
      ("center_build_school",[(eq, reg6, 0),
                              (party_slot_eq, "$g_encountered_party", slot_party_type, spt_village),
                              (party_slot_eq, "$g_encountered_party", slot_center_has_school, 0),
                                  ],
       "Build a school.",[(assign, "$g_improvement_type", slot_center_has_school),
                          (jump_to_menu, "mnu_center_improve"),]),
      ("center_build_messenger_post",[(eq, reg6, 0),
                                      (party_slot_eq, "$g_encountered_party", slot_center_has_messenger_post, 0),
                                       ],
       "Build a messenger post.",[(assign, "$g_improvement_type", slot_center_has_messenger_post),
                                  (jump_to_menu, "mnu_center_improve"),]),
      
        ("center_build_mercenary_hall",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (party_slot_eq, "$g_encountered_party", slot_center_has_mercenary_hall, 0),
           ],
        "Build a mercenary hall.",[(assign, "$g_improvement_type", slot_center_has_mercenary_hall),
        (jump_to_menu, "mnu_center_improve"),]),

        ("center_build_merchant_hall",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (party_slot_eq, "$g_encountered_party", slot_center_has_merchant_guild, 0),
           ],
        "Build a merchant guild house.",[(assign, "$g_improvement_type", slot_center_has_merchant_guild),
        (jump_to_menu, "mnu_center_improve"),]),

        ("center_build_academy",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (party_slot_eq, "$g_encountered_party", slot_center_has_academy, 0),
          (assign, ":end", villages_end),
          #store_distance_to_party_from_party, faction check?
          (try_for_range, ":centers", villages_begin, ":end"),
            (party_slot_eq, ":centers", slot_village_bound_center, "$g_encountered_party"),
            (party_slot_ge, ":centers", slot_center_has_school, 1),
            (assign, ":end", 0),
          (try_end),
          (eq, ":end", 0),
           ],
        "Build a military academy.",[(assign, "$g_improvement_type", slot_center_has_academy),
        (jump_to_menu, "mnu_center_improve"),]),

        ("center_build_academy_no",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (party_slot_eq, "$g_encountered_party", slot_center_has_academy, 0),
          (assign, ":end", villages_end),
          (try_for_range, ":centers", villages_begin, ":end"),
            (party_slot_eq, ":centers", slot_village_bound_center, "$g_encountered_party"),
            (party_slot_ge, ":centers", slot_center_has_school, 1),
            (assign, ":end", 0),
          (try_end),
          (eq, ":end", villages_end),
          (disable_menu_option),
           ],
        "Build a military academy (requires a nearby school).",[]),

        ("center_build_foundry",[(eq, reg6, 0),
          (this_or_next|party_slot_eq, "$g_encountered_party", slot_party_type, spt_castle),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (call_script, "script_cf_center_infrastructure", "$g_encountered_party"),
           ],
        "Build a steel forge.",[(assign, "$g_improvement_type", slot_center_has_foundry), (jump_to_menu, "mnu_center_improve"),]),
        
        ("center_build_arsenal",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (call_script, "script_cf_center_infrastructure", "$g_encountered_party"),
           ],
        "Build an arsenal.",[(assign, "$g_improvement_type", slot_center_has_arsenal), (jump_to_menu, "mnu_center_improve"),]),
        
        ("center_build_stable",[(eq, reg6, 0),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (call_script, "script_cf_center_infrastructure", "$g_encountered_party"),
           ],
        "Build a companion stable.",[(assign, "$g_improvement_type", slot_center_has_stables),(jump_to_menu, "mnu_center_improve"),]),
        
        ("center_build_barrack",[(eq, reg6, 0),
          (this_or_next|party_slot_eq, "$g_encountered_party", slot_party_type, spt_castle),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (call_script, "script_cf_center_infrastructure", "$g_encountered_party"),
           ],
        "Build a field barrack.",[(assign, "$g_improvement_type", slot_center_has_barrack),(jump_to_menu, "mnu_center_improve"),]),

        ("center_build_range",[(eq, reg6, 0),
          (this_or_next|party_slot_eq, "$g_encountered_party", slot_party_type, spt_castle),
          (party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
          (call_script, "script_cf_center_infrastructure", "$g_encountered_party"),
           ],
        "Build a shooting range.",[(assign, "$g_improvement_type", slot_center_has_shrange),(jump_to_menu, "mnu_center_improve"),]),


      ("center_build_prisoner_tower",[(eq, reg6, 0),
                                      (this_or_next|party_slot_eq, "$g_encountered_party", slot_party_type, spt_town),
                                      (party_slot_eq, "$g_encountered_party", slot_party_type, spt_castle),
                                      (party_slot_eq, "$g_encountered_party", slot_center_has_prisoner_tower, 0),
                                       ],
       "Build a prisoner tower.",[(assign, "$g_improvement_type", slot_center_has_prisoner_tower),
                                  (jump_to_menu, "mnu_center_improve"),]),

      ("go_back_dot",[],"Go back.",[(jump_to_menu, "$g_next_menu")]),
    ],
  ),

  (
    "center_improve",0,
    "{s19} As the party member with the highest engineer skill ({reg2}), {reg3?you reckon:{s3} reckons} that building the {s4} will cost you\
 {reg5} denars and will take {reg6} days.",
    "none",
    [(call_script, "script_get_improvement_details", "$g_improvement_type", 1, 2),
     (assign, ":improvement_cost", reg0),
     (str_store_string_reg, s4, s0),
     (str_store_string_reg, s19, s1),
     (call_script, "script_get_max_skill_of_player_party", "skl_engineer"),
     (assign, ":max_skill", reg0),
     (assign, ":max_skill_owner", reg1),
     (assign, reg2, ":max_skill"),

     (store_sub, ":multiplier", 21, ":max_skill"),
     (val_mul, ":improvement_cost", ":multiplier"),
     (val_div, ":improvement_cost", 20),

     (assign, ":rate", 100),
     #lumber yard bonus
     (try_for_range, ":centers", centers_begin, centers_end),
       (this_or_next|eq, ":centers", "$g_encountered_party"),
       (party_slot_eq, ":centers", slot_village_bound_center, "$g_encountered_party"),
       (party_slot_ge, ":centers", slot_center_has_lumber_yard, 1),
       (val_add, ":rate", 5),
     (try_end),

     (store_div, ":improvement_time", ":improvement_cost", ":rate"),
     (store_sqrt, ":base_time", ":improvement_cost"),
     (val_div, ":base_time", 2),
     (val_add, ":base_time", 3),
     (val_add, ":improvement_time", ":base_time"),

     (assign, reg5, ":improvement_cost"),
     (assign, reg6, ":improvement_time"),

     (try_begin),
       (eq, ":max_skill_owner", "trp_player"),
       (assign, reg3, 1),
     (else_try),
       (assign, reg3, 0),
       (str_store_troop_name, s3, ":max_skill_owner"),
     (try_end),
     (set_fixed_point_multiplier, 100),
     (position_set_x, pos0, 60),
     (position_set_y, pos0, 30),
     (position_set_z, pos0, 90), #scale
     (set_game_menu_tableau_mesh, "tableau_troop_note_mesh", ":max_skill_owner", pos0),
     (try_begin), #fast build
       (eq, "$cheat_mode", 1),
       (assign, reg6, 0),
     (try_end),
    ],
    [
      ("improve_cont",[(store_troop_gold, ":cur_gold", "trp_player"),
                       (store_troop_gold, ":cur_treasury", "trp_household_possessions"),
                       (val_max, ":cur_gold", ":cur_treasury"),
                       (ge, ":cur_gold", reg5)],
       "Go on.", [(troop_remove_gold, "trp_player", reg5),
                  (call_script, "script_improve_center", "$g_encountered_party", reg6),
                  # (party_set_slot, "$g_encountered_party", slot_center_current_improvement, "$g_improvement_type"),
                  # (store_current_hours, ":cur_hours"),
                  # (store_mul, ":hours_takes", reg6, 24),
                  # (val_add, ":hours_takes", ":cur_hours"),
                  # (party_set_slot, "$g_encountered_party", slot_center_improvement_end_hour, ":hours_takes"),
                  (jump_to_menu,"mnu_center_manage"),
                  ]),
      ("forget_it",[], "Forget it.", [(jump_to_menu,"mnu_center_manage")]),

    ],
  ),

Is that everything?
Nope, more stuff below
Code:
  #script_initialize_improvement_info
  ("initialize_improvement_info",
    [
      #these slots determine the cost of improvements
      (party_set_slot, "p_zendar", slot_center_has_manor, 8000),
      (party_set_slot, "p_zendar", slot_center_has_mill, 6000),
      (party_set_slot, "p_zendar", slot_center_has_watch_tower, 5000),
      (party_set_slot, "p_zendar", slot_center_has_plantation, 10000),
      (party_set_slot, "p_zendar", slot_center_has_lumber_yard, 12000),
      (party_set_slot, "p_zendar", slot_center_has_school, 9000),
      (party_set_slot, "p_zendar", slot_center_has_messenger_post, 4000),
      
      (party_set_slot, "p_zendar", slot_center_has_prisoner_tower, 7000),
      (party_set_slot, "p_zendar", slot_center_has_mercenary_hall, 10000),
      (party_set_slot, "p_zendar", slot_center_has_merchant_guild, 25000),
      (party_set_slot, "p_zendar", slot_center_has_academy, 60000),
      (party_set_slot, "p_zendar", slot_center_has_foundry, 42000),
      (party_set_slot, "p_zendar", slot_center_has_arsenal, 33000),
      (party_set_slot, "p_zendar", slot_center_has_stables, 25000),
      (party_set_slot, "p_zendar", slot_center_has_barrack, 27500),
      (party_set_slot, "p_zendar", slot_center_has_shrange, 15000),

      #string references are done via offsets





      #assign static improvements to capitals - every city gets something?


      #swadian
      (party_set_slot, "p_town_6", slot_center_has_barrack, 1),
      (party_set_slot, "p_town_7", slot_center_has_stables, 2),
      (party_set_slot, "p_town_4", slot_center_has_stables, 3),
      (party_set_slot, "p_town_16", slot_center_has_foundry, 3),
      
      #vaegir
      (party_set_slot, "p_town_2", slot_center_has_foundry, 2),
      (party_set_slot, "p_town_8", slot_center_has_shrange, 4),
      (party_set_slot, "p_town_9", slot_center_has_arsenal, 3),
      
      #khergit
      (party_set_slot, "p_town_10", slot_center_has_shrange, 3),
      (party_set_slot, "p_town_17", slot_center_has_stables, 5),
      (party_set_slot, "p_town_18", slot_center_has_arsenal, 2),
      
      #nord
      (party_set_slot, "p_town_1", slot_center_has_academy, 15),
      (party_set_slot, "p_town_1", slot_center_has_foundry, 5),
      (party_set_slot, "p_town_2", slot_center_has_barrack, 4),
      
      #rhodok
      (party_set_slot, "p_town_3", slot_center_has_barrack, 5),
      (party_set_slot, "p_town_5", slot_center_has_arsenal, 3),
      (party_set_slot, "p_town_5", slot_center_has_shrange, 4),
      (party_set_slot, "p_town_15", slot_center_has_merchant_guild, 1),

      #sarranid
      (party_set_slot, "p_town_19", slot_center_has_foundry, 2),
      (party_set_slot, "p_town_20", slot_center_has_arsenal, 2),
      (party_set_slot, "p_town_21", slot_center_has_stables, 2),
      (party_set_slot, "p_town_22", slot_center_has_barrack, 2),
      (party_set_slot, "p_town_22", slot_center_has_shrange, 2),
    
    ]
  ),
  ("cf_center_infrastructure",
    [
    (store_script_param_1, ":center_no"),
    (assign, ":end", military_infra_end),
    (try_for_range, ":improvements", military_infra_begin, ":end"),
      (party_slot_ge, ":center_no", ":improvements", 1),
      (assign, ":end", 0),
    (try_end),
    (eq, ":end", military_infra_end),
    ]
  ),

  #script_get_improvement_progress
  # INPUT: arg1 = center_no
  # OUTPUT: stuff and silly strings
  ("get_improvement_progress",
    [(store_script_param, ":center_no", 1),
    (try_begin),
      (party_slot_eq, ":center_no", slot_party_type, spt_village),
      (assign, ":begin", village_improvements_begin),
      (assign, ":end", village_improvements_end),
      (str_store_string, s17, "str_spt_village"),
    (else_try),
      (assign, ":begin", walled_center_improvements_begin),
      (assign, ":end", walled_center_improvements_end),
      (party_slot_eq, ":center_no", slot_party_type, spt_town),
      (str_store_string, s17, "str_spt_town"),
    (else_try),
      (str_store_string, s17, "str_spt_castle"),
    (try_end),

    (str_clear, s50),
    (str_clear, s51),
    (str_clear, s52),
    (assign, ":num_improvements", 0),
    (try_for_range, ":improvement_no", ":begin", ":end"),
      (party_get_slot, ":level", ":center_no", ":improvement_no"),
      (gt, ":level", 0),
      # (party_slot_ge, ":center_no", ":improvement_no", 1),
      (store_sub, ":string", ":improvement_no", village_improvements_begin),
      (val_add, ":string", "str_manor"),
      (str_store_string, s52, ":string"),
      (try_begin),
        (is_between, ":improvement_no", military_infra_begin, military_infra_end),
        (assign, reg9, ":level"),
        (str_store_string, s52, "@{s52} (Level {reg9})"),
      (try_end),
      
      # (call_script, "script_get_improvement_details", ":improvement_no", 0, 1),
      (try_begin),
        (eq, ":num_improvements", 0),
        (str_store_string_reg, s51, s52),
      (else_try),
        (str_store_string_reg, s50, s52),
        (str_store_string, s51, "str_s50_comma_s51"),
      (try_end),
      (val_add,  ":num_improvements", 1),
    (try_end),

    (assign, reg8, ":num_improvements"),
    (store_sub, reg9, reg8, 1),
    (str_store_party_name, s19, ":center_no"),
    (str_store_string, s19, "@The {s17} of {s19} has {reg8?{reg9?the following improvements - :built a} {s51}:no improvements}."),
    (assign, reg6, 0),
    (try_begin),
      (party_get_slot, ":cur_improvement", ":center_no", slot_center_current_improvement),
      (gt, ":cur_improvement", 0),
      # (call_script, "script_get_improvement_details", ":cur_improvement", 0, 1),
      (val_sub, ":cur_improvement", village_improvements_begin),
      (val_add, ":cur_improvement", "str_manor"),
      (str_store_string, s7, ":cur_improvement"),
      (assign, reg6, 1),
      (store_current_hours, ":cur_hours"),
      (party_get_slot, ":finish_time", ":center_no", slot_center_improvement_end_hour),
      (val_sub, ":finish_time", ":cur_hours"),
      (store_div, reg8, ":finish_time", 24),
      (val_max, reg8, 1),
      (store_sub, reg9, reg8, 1),
    (try_end),
  ]),
  ("improve_center", [
    (store_script_param_1, ":center_no"),
    (store_script_param_2, ":improvement_time"),
    (party_set_slot, ":center_no", slot_center_current_improvement, "$g_improvement_type"),
    (store_current_hours, ":cur_hours"),
    (store_mul, ":hours_takes", ":improvement_time", 24),
    (val_add, ":hours_takes", ":cur_hours"),
    (party_set_slot, ":center_no", slot_center_improvement_end_hour, ":hours_takes"),
  ]),
If anybody wants to package this with modmerger, feel free.
 
Auxiliary post due to overflow :arrow: some essential stuff follows
This collects the number of buildings built by the faction and feeds it into script_init_agent_modifiers
Code:
slot_faction_num_foundrys = 23
slot_faction_num_arsenals = 24
slot_faction_num_barracks = 25
slot_faction_num_stables  = 26
slot_faction_num_ranges   = 27
Code:
  # script_faction_recalculate_strength
  # Input: arg1 = faction_no
  # Output: reg0 = strength
  ("faction_recalculate_strength",
    [
    (store_script_param_1, ":faction_no"),

    (call_script, "script_faction_get_number_of_armies", ":faction_no"),
    (assign, ":num_armies", reg0),
    (assign, ":num_castles", 0),
    (assign, ":num_towns", 0),

    (assign, ":num_barrack", 0),
    (assign, ":num_arsenal", 0),
    (assign, ":num_stables", 0),
    (assign, ":num_foundry", 0),
    (assign, ":num_sranges", 0),

    (try_for_range, ":center_no", centers_begin, centers_end),
      (store_faction_of_party, ":center_faction", ":center_no"),
      (eq, ":center_faction", ":faction_no"),
      (try_begin),
        (party_slot_eq, ":center_no", slot_party_type, spt_castle),
        (val_add, ":num_castles", 1),
      (else_try),
        (party_slot_eq, ":center_no", slot_party_type, spt_town),
        (val_add, ":num_towns", 1),
      (try_end),
      (try_begin),
        (party_get_slot, ":num_building", ":center_no", slot_center_has_barrack),
        (val_add, ":num_barrack", ":num_building"),
        (party_get_slot, ":num_building", ":center_no", slot_center_has_arsenal),
        (val_add, ":num_arsenal", ":num_building"),
        (party_get_slot, ":num_building", ":center_no", slot_center_has_stables),
        (val_add, ":num_stables", ":num_building"),
        (party_get_slot, ":num_building", ":center_no", slot_center_has_foundry),
        (val_add, ":num_foundry", ":num_building"),
        (party_get_slot, ":num_building", ":center_no", slot_center_has_shrange),
        (val_add, ":num_sranges", ":num_building"),
      (try_end),
    (try_end),

    (faction_set_slot, ":faction_no", slot_faction_num_armies, ":num_armies"),
    (faction_set_slot, ":faction_no", slot_faction_num_castles, ":num_castles"),
    (faction_set_slot, ":faction_no", slot_faction_num_towns, ":num_towns"),
    
    (try_begin), #force multiplier to exaggerate effect of buildings
      (eq, "$cheat_mode", 1),
      (val_mul, ":num_barrack", 5),
      (val_mul, ":num_arsenal", 5),
      (val_mul, ":num_stables", 5),
      (val_mul, ":num_sranges", 5),
      (val_mul, ":num_foundry", 5),
    (try_end),

    (faction_set_slot, ":faction_no", slot_faction_num_barracks, ":num_barrack"),
    (faction_set_slot, ":faction_no", slot_faction_num_arsenals, ":num_arsenal"),
    (faction_set_slot, ":faction_no", slot_faction_num_stables, ":num_stables"),
    (faction_set_slot, ":faction_no", slot_faction_num_ranges, ":num_sranges"),
    (faction_set_slot, ":faction_no", slot_faction_num_foundrys, ":num_foundry"),

  ]),
Code:
# Checking center upgrades
  (12,
   [(try_for_range, ":center_no", centers_begin, centers_end),
      (party_get_slot, ":cur_improvement", ":center_no", slot_center_current_improvement),
      (gt, ":cur_improvement", 0),
      (party_get_slot, ":cur_improvement_end_time", ":center_no", slot_center_improvement_end_hour),
      (store_current_hours, ":cur_hours"),
      (ge, ":cur_hours", ":cur_improvement_end_time"),
      (party_set_slot, ":center_no", ":cur_improvement", 1),
      (party_set_slot, ":center_no", slot_center_current_improvement, 0),
      (call_script, "script_get_improvement_details", ":cur_improvement", 0, 1),
      (try_begin),
        (this_or_next|eq, "$cheat_mode", 1),
        (party_slot_eq, ":center_no", slot_town_lord, "trp_player"),
        (str_store_party_name_link, s4, ":center_no"),
        (display_log_message, "@Building of {s0} in {s4} has been completed."),
        (try_begin),
          (eq, ":cur_improvement", slot_center_has_manor),
          (party_set_flags, ":center_no", pf_hide_defenders, 0),
        (try_end),
      (try_end),

      (try_begin),
        (is_between, ":center_no", villages_begin, villages_end),
        (try_begin),
          (this_or_next|eq, ":cur_improvement", slot_center_has_mill),
          (eq, ":cur_improvement", slot_center_has_lumber_yard),
          (call_script, "script_change_center_prosperity", ":center_no", 5),
        (try_end),
      (try_end),
    (try_end),
    ]),
Non-essential elements of the extended building system follow - take a look because some of the earlier code might contain references here

The script in the first post stores the speed in slot_agent_horse_modifier - remove that call if you want the bonus to stay with the rider instead of the horse.
Code:
custom_commander_horse_speed = (
  1, 0, 0, [],
  [
  # (get_player_agent_no, ":player_no"),
  (try_for_agents, ":agent_no"),
    (agent_is_alive, ":agent_no"),
    (agent_is_human, ":agent_no"),
    (agent_get_horse, ":horse_agent", ":agent_no"),
    (try_begin),
      (ge, ":horse_agent", 0),
      (store_agent_hit_points, ":horse_hp",":horse_agent"),
      (store_sub, ":lost_hp", 100, ":horse_hp"),
      (try_begin), #minor wound
        (le, ":lost_hp", 15),
        (val_div, ":lost_hp", 3),
        (store_add, ":speed_factor", 100, ":lost_hp"),
      (else_try), #grevious injury - limp along
        (ge, ":lost_hp", 90),
        (store_sub, ":speed_factor", 150, ":lost_hp"),
      (else_try), #blooded, adrenaline increases speed slightly and falls off
        (val_div, ":lost_hp", 2),
        (store_sub, ":speed_factor", 110, ":lost_hp"),
      (try_end),
      (agent_get_troop_id, ":agent_troop", ":agent_no"),
      (store_skill_level, ":skl_level", "skl_riding", ":agent_troop"),
      # (store_mul, ":speed_multi", ":skl_level", 2),
      (agent_get_slot, ":base_speed", ":horse_agent", slot_agent_horse_modifier),
      (val_add, ":skl_level", ":base_speed"),
      (val_max, ":skl_level", 100), #some horses (spawned) might not have slot set
      (val_mul, ":speed_factor", ":skl_level"),
      (val_div, ":speed_factor", 100),
      (agent_set_horse_speed_factor, ":agent_no", ":speed_factor"),
      # (try_begin),
        # (eq, ":agent_no", ":player_no"),
        # (assign, reg1, ":speed_factor"),
        ## horse speedometer
        # (display_message, "@travelling at {reg1} %"),
      # (try_end),
    (try_end),
  (try_end),
  ])
Code:
slot_agent_horse_modifier = 23
slot_agent_bonus_ammo = 24
This trigger should be added into whatever mission template (lead_charge) that has horses and other beasties. It is modified from Custom Commander and takes into account the horse's new buffed speed, instead of making the rider into a superbly trained jockey due to agent_set_horse_speed_factor at spawn.

The following gives exaggerated modifier values to custom battles
Code:
      (faction_set_slot, "fac_kingdom_1", slot_faction_num_foundrys, 75),
      (faction_set_slot, "fac_kingdom_1", slot_faction_num_stables, 10),
      
      (faction_set_slot, "fac_kingdom_2", slot_faction_num_arsenals, 125),
      (faction_set_slot, "fac_kingdom_2", slot_faction_num_barracks, 5),

      (faction_set_slot, "fac_kingdom_3", slot_faction_num_ranges, 10),
      (faction_set_slot, "fac_kingdom_3", slot_faction_num_stables, 130),

      (faction_set_slot, "fac_kingdom_4", slot_faction_num_foundrys, 25),
      (faction_set_slot, "fac_kingdom_4", slot_faction_num_arsenals, 10),
      
      (faction_set_slot, "fac_kingdom_5", slot_faction_num_ranges, 100),
      (faction_set_slot, "fac_kingdom_5", slot_faction_num_barracks, 15),

      (faction_set_slot, "fac_kingdom_6", slot_faction_num_foundrys, 10),
      (faction_set_slot, "fac_kingdom_6", slot_faction_num_barracks, 10),
      (faction_set_slot, "fac_kingdom_6", slot_faction_num_arsenals, 10),

The following gives some economical bonus for having built them inside centers, it also comes with a merchant item passing system and prosperity-based gold adder.
Code:
  # script_refresh_center_inventories
  ("refresh_center_inventories",
  [
    (reset_item_probabilities,100),
    (set_merchandise_modifier_quality,150),

    (try_for_range,":cur_center",towns_begin,towns_end),
      (party_get_slot,":cur_merchant",":cur_center",slot_town_merchant),
      (party_get_slot, ":prosperity", ":cur_center", slot_town_prosperity),
      (val_div, ":prosperity", 2), #-50 to 50
      (val_add, ":prosperity", 125), #
      # (set_merchandise_modifier_quality
      (reset_item_probabilities, ":prosperity"),
      (assign, ":total_production", 0),
      (try_for_range, ":cur_goods", trade_goods_begin, trade_goods_end),
        (call_script, "script_center_get_production", ":cur_center", ":cur_goods"),
        (assign, ":production", reg0),

        (try_for_range, ":cur_village", villages_begin, villages_end),
          (party_slot_eq, ":cur_village", slot_village_bound_center, ":cur_center"),
          (call_script, "script_center_get_production", ":cur_village", ":cur_goods"),
          (val_div, reg0, 3),
          (val_add, ":production", reg0),
        (try_end),

        (val_max, ":production", 1),
        (val_mul, ":production", 400),

        (val_add, ":total_production", ":production"),
        (item_set_slot, ":cur_goods", slot_item_is_checked, ":production"),
      (try_end),

      (party_get_slot, ":prosperity", ":cur_center", slot_town_prosperity),
      (assign, ":number_of_items_in_town", 25),
      (store_sub, ":ratio", ":prosperity", 50),

      (try_begin), #1.0x - 2.0x (50 - 100 prosperity)
        (ge, ":ratio", 0),
        (val_mul, ":ratio", 2),
      (try_end),
      (val_add, ":ratio", 100),
      (val_mul, ":number_of_items_in_town", ":ratio"),
      (val_div, ":number_of_items_in_town", 100),
      (val_clamp, ":number_of_items_in_town", 10, 40),
      (try_begin),
        (is_between, ":cur_center", castles_begin, castles_end),
        (val_div, ":number_of_items_in_town", 2),
      (try_end),
      (try_for_range, ":cur_goods", trade_goods_begin, trade_goods_end),
        (item_get_slot, ":production", ":cur_goods", slot_item_is_checked),
        (val_mul, ":production", ":number_of_items_in_town"),
        # (val_mul, ":cur_production", 100), #pre-multiplied
        (val_div, ":production", ":total_production"),
        (set_item_probability_in_merchandise, ":cur_goods", ":production"),
      (try_end),
      (troop_add_merchandise, ":cur_merchant", itp_type_goods, ":number_of_items_in_town"),
      (troop_ensure_inventory_space,":cur_merchant",merchant_inventory_space),
      (call_script, "script_add_merchant_gold", ":cur_merchant", 2500, ":prosperity", 50, 150),
      (call_script, "script_sort_merchant_inventory", ":cur_merchant", ":cur_center"),
      (val_add, ":prosperity", 10), #10 inv management
    (try_end),
  ]),
  

 # script_refresh_center_armories
  ("refresh_center_armories",
  [
    (assign, ":cur_town", towns_begin),
    (try_for_range,":cur_merchant",armor_merchants_begin,armor_merchants_end),
      (party_get_slot, ":prosperity", ":cur_town", slot_town_prosperity),
      (val_div, ":prosperity", 2), #-50 to 50
      (val_add, ":prosperity", 125), #75 to 175
      (try_begin),
        (party_get_slot, ":num_buildings", ":cur_town", slot_center_has_barrack),
        (gt, ":num_buildings", 0),
        (val_mul, ":num_buildings", 25),
        (val_add, ":prosperity", ":num_buildings"),
      (try_end),
      (set_merchandise_modifier_quality, ":prosperity"),
      (party_get_slot, ":cur_faction", ":cur_town", slot_center_original_faction),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_body_armor,16),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_head_armor,16),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_foot_armor,8),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_hand_armor,4),
      (troop_ensure_inventory_space,":cur_merchant",merchant_inventory_space),

      (call_script, "script_add_merchant_gold", ":cur_merchant", 1000, ":prosperity", 3, 5),

      (call_script, "script_sort_merchant_inventory", ":cur_merchant", ":cur_town"),
      (troop_sort_inventory, ":cur_merchant"),
      (val_add, ":cur_town", 1),
    (try_end),
  ]),
  # script_refresh_center_weaponsmiths
  ("refresh_center_weaponsmiths",
  [
    (assign, ":cur_town", towns_begin),
    (try_for_range,":cur_merchant",weapon_merchants_begin,weapon_merchants_end),
      (party_get_slot, ":prosperity", ":cur_town", slot_town_prosperity),
      (val_div, ":prosperity", 2), #-50 to 50
      (val_add, ":prosperity", 125), #
      (try_begin),
        (party_get_slot, ":num_buildings", ":cur_town", slot_center_has_foundry),
        (gt, ":num_buildings", 0),
        (val_mul, ":num_buildings", 20),
        (val_add, ":prosperity", ":num_buildings"),
      (try_end),
      (try_begin),
        (party_get_slot, ":num_buildings", ":cur_town", slot_center_has_arsenal),
        (gt, ":num_buildings", 0),
        (val_mul, ":num_buildings", 20),
        (val_add, ":prosperity", ":num_buildings"),
      (try_end),
      (set_merchandise_modifier_quality, ":prosperity"),
      (party_get_slot, ":cur_faction", ":cur_town", slot_center_original_faction),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_one_handed_wpn,5),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_two_handed_wpn,5),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_polearm,5),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_shield,6),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_bow,4),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_crossbow,3),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_thrown,5),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_arrows,2),
      (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_bolts,2),

      (troop_ensure_inventory_space, ":cur_merchant", merchant_inventory_space),

      (call_script, "script_add_merchant_gold", ":cur_merchant", 1000, ":prosperity", 5, 10),
      (call_script, "script_sort_merchant_inventory", ":cur_merchant", ":cur_town"),
      (troop_sort_inventory, ":cur_merchant"),
      (val_add, ":cur_town", 1), #increment
    (try_end),
  ]),

  # script_refresh_center_stables
  ("refresh_center_stables",
  [
  (assign, ":cur_town", towns_begin),
  (try_for_range,":cur_merchant",horse_merchants_begin,horse_merchants_end),

    (party_get_slot, ":prosperity", ":cur_town", slot_town_prosperity),
    (store_div, ":probability", ":prosperity", 2), #-50 to 50
    (val_add, ":probability", 125),
    (try_begin),
      (party_get_slot, ":num_buildings", ":cur_town", slot_center_has_stables),
      (gt, ":num_buildings", 0),
      (val_mul, ":num_buildings", 25),
      (val_add, ":prosperity", ":num_buildings"),
    (try_end),
    (set_merchandise_modifier_quality, ":probability"),
    (reset_item_probabilities, ":probability"),
    (party_get_slot, ":cur_faction", ":cur_town", slot_center_original_faction),
    (troop_add_merchandise_with_faction,":cur_merchant", ":cur_faction",itp_type_horse,5),
    (troop_ensure_inventory_space,":cur_merchant",65),
    (call_script, "script_add_merchant_gold", ":cur_merchant", 600, ":prosperity", 3, 5),
    (call_script, "script_sort_merchant_inventory", ":cur_merchant", ":cur_town"),
    (troop_sort_inventory, ":cur_merchant"),
    (val_add, ":cur_town", 1), #increment
  (try_end),
  ]),

  ("add_merchant_gold",
  [
  (store_script_param, ":cur_merchant", 1),
  (store_script_param, ":minimum", 2),

  (try_begin),
    (store_troop_gold, ":cur_gold",":cur_merchant"),
    (lt,":cur_gold",":minimum"),
    (store_script_param, ":multiplier", 3),
    (store_script_param, ":min", 4),
    (store_script_param, ":max", 5),
    (store_random_in_range,":new_gold", ":min", ":max"),
    (val_mul, ":new_gold", ":multiplier"),
    (store_random_in_range, ":cur_gold", 100, 200),#half of native
    (val_add, ":new_gold", ":cur_gold"),
    (troop_add_gold, ":cur_merchant", ":new_gold"),
  (try_end),
  ]),

This gives improvements increased power in auto-calc in both field battles and sieges.
Replace calls to the original script with another parameter wherever possible
Code:
  #script_party_calculate_strength:
  # INPUT: arg1 = party_id, arg2 = exclude leader
  # OUTPUT: reg0 = strength

  ("party_calculate_strength",
    [
      (store_script_param, ":party", 1), #Party_id
      (store_script_param, ":exclude_leader", 2), #whether or not the first stack (leader) is included
      # (store_script_param, ":party_faction", 3), #calculated from calling context, re-calculated if invalid here
      (try_begin),
        (eq, ":party", -1),
        (assign, ":party_faction", -1),
      (else_try),
        (store_faction_of_party, ":party_faction", ":party"),
      (try_end),

      #bonus from buildings - arsenals only outfit arms for current faction
      (try_begin), #if an invalid input is given
        (neg|is_between, ":party_faction", kingdoms_begin, kingdoms_end),
        (try_begin),
          (this_or_next|eq, ":party", "p_main_party"),
          (eq, ":party", "p_main_party_backup"),
          (assign, ":party_faction", "$players_kingdom"),
        (else_try), #because the collective party is passed in, faction info is lost
          (eq, ":party", "p_collective_enemy"),
          (party_is_active, "$g_enemy_party"),
          (store_faction_of_party, ":party_faction", "$g_enemy_party"),
        (else_try),
          (this_or_next|eq, ":party", "p_collective_ally"),
          (eq, ":party", "p_collective_friends"),
          (party_is_active, "$g_ally_party"),
          (store_faction_of_party, ":party_faction", "$g_ally_party"),
        # (else_try),
          # (store_faction_of_party, ":party_faction", ":party"),
        (try_end),
        #do exclusion/assignment range for bandit/deserters
      (else_try), #deliberately empty
        (eq, ":party_faction", -1),
      (try_end),
      (assign, ":party_strength",0),
      (assign, ":party_strength_old",0),
      (party_get_num_companion_stacks, ":num_stacks", ":party"),
      (try_for_range, ":i_stack", ":exclude_leader", ":num_stacks"),
        (party_stack_get_troop_id, ":stack_troop",":party", ":i_stack"),
        (store_character_level, ":stack_strength", ":stack_troop"),
        (val_add, ":stack_strength", 4), #new was 12 (patch 1.125)
        (val_mul, ":stack_strength", ":stack_strength"),
        (store_div, ":stack_strength_old", ":stack_strength", 50), #debug
        
        (store_troop_faction, ":troop_faction", ":stack_troop"),
        #building calculation before divisor
        (try_begin), #arsenal check for matching factions
          (eq, ":troop_faction", ":party_faction"),
          #all troops benefit from melee weapon upgrades
          (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_foundrys),
          (val_add, ":num_buildings", 100),
          (val_mul, ":stack_strength", ":num_buildings"),
          (val_div, ":stack_strength", 100),
          (try_begin), #mounted skirmisher power (putting this outside means less power stacking
            (troop_is_guarantee_horse, ":stack_troop"),
            (troop_is_guarantee_ranged, ":stack_troop"),
            (faction_get_slot, ":num_buildings", ":party_faction", slot_center_has_shrange),
            (val_add, ":num_buildings", 100),
            (val_mul, ":stack_strength", ":num_buildings"),
            (val_div, ":stack_strength", 100),
          (else_try), #cavalry power
            (troop_is_guarantee_horse, ":stack_troop"),
            (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_stables),
            (val_add, ":num_buildings", 100),
            (val_mul, ":stack_strength", ":num_buildings"),
            (val_div, ":stack_strength", 100),
          (else_try), #ranged power
            (troop_is_guarantee_ranged, ":stack_troop"),
            (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_arsenals),
            (val_add, ":num_buildings", 100),
            (val_mul, ":stack_strength", ":num_buildings"),
            (val_div, ":stack_strength", 100),
          (else_try),
          (try_end),
        (try_end),
        
        (val_div, ":stack_strength", 50),
        (val_max, ":stack_strength", 1), #new (patch 1.125)
        (try_begin),
          (neg|troop_is_hero, ":stack_troop"),
          (party_stack_get_size, ":stack_size",":party",":i_stack"),
          (party_stack_get_num_wounded, ":num_wounded",":party",":i_stack"),
          (val_sub, ":stack_size", ":num_wounded"),
          (val_mul, ":stack_strength", ":stack_size"),
          (val_mul, ":stack_strength_old", ":stack_size"), #debug
        (else_try),
          (troop_is_wounded, ":stack_troop"), #hero & wounded
          (assign, ":stack_strength", 0),
          (assign, ":stack_size", 0),
        (try_end),
        (val_add, ":party_strength_old", ":stack_strength_old"), #debug
        (val_add, ":party_strength", ":stack_strength"),
      (try_end),
      (party_get_skill_level, ":cur_party_tactics", ":party", "skl_tactics"),
      # (val_mul, ":cur_party_tactics", 5), #way too OP
      (val_add, ":cur_party_tactics", 100),
      #bonus from buildings (tactics calc from CC)
      (try_begin), #barracks apply globally regardless of party composition from different factions
        (is_between, ":party_faction", kingdoms_begin, kingdoms_end),
        (faction_get_slot, ":num_buildings", ":party_faction", slot_faction_num_barracks),
        (val_add, ":cur_party_tactics", ":num_buildings"),
      (try_end),
      (val_mul, ":party_strength", ":cur_party_tactics"),
      (val_div, ":party_strength", 100),
      #(str_store_party_name, s61, ":party"), #debug
      #(assign, reg61, ":party_strength_old"), #debug
      (party_set_slot, ":party", slot_party_cached_strength, ":party_strength"),
      (assign, reg0, ":party_strength"),
      #(str_store_faction_name_link, s60, ":party_faction"),
      #(display_message, "@{s61} from {s60} has {reg61} strength {reg0} boosted"), #debug
  ]),
script_game_event_simulate_battle said:
          (try_begin),
            #For sieges increase attacker casualties and reduce defender casualties.
            (this_or_next|party_slot_eq, ":root_defender_party", slot_party_type, spt_castle),
            (party_slot_eq, ":root_defender_party", slot_party_type, spt_town),
            (assign, ":defender_percent", 123),
            (try_begin), #special bonus
              (party_get_slot, ":num_buildings", ":root_defender_party", slot_center_has_shrange),
              (gt, ":num_buildings", 0),
              (val_mul, ":num_buildings", 3),
              (val_add, ":defender_percent", ":num_buildings"),
            (try_end),
            (try_begin), #special bonus (normally greater than other bonus)
              (party_slot_ge, ":root_defender_party", slot_center_has_barrack, 1),
              (val_add, ":defender_percent", 5),
            (try_end),
            (val_mul, ":defender_strength", ":defender_percent"),
#it was 1.5 in old version, now it is only 1.23
            (val_div, ":defender_strength", 100),

            (party_get_skill_level, ":attacker_percent", ":root_attacker_party", "skl_engineer"),
            (val_add, ":attacker_percent", 100),
            (val_mul, ":attacker_strength", ":attacker"percent), #it was 0.5 in old version, now it is only 1 / 1.23

            (val_div, ":attacker_strength", 123),
          (try_end),

This is the upgrade menu depicted in screenshots and the update - overwrite some of the menu in the original post
Modify the following to the list of buildings
mnu_center_manage said:
  (
    "center_manage",0,
    "{s19}^{reg6?^^You are\
currently building {s7}. The building will be completed after {reg8} day{reg9?s:}.:}",
    "none",
    [(call_script, "script_get_improvement_progress", "$current_town"),
    (assign, "$enterprise_cost", -1),
    ],
...
      ("center_upgrade_infra",[(eq, reg6, 0),
        (assign, ":end", military_infra_end),
        (try_for_range, ":improvements", military_infra_begin, ":end"),
          (party_slot_ge, "$g_encountered_party", ":improvements", 1),
          (assign, ":end", 0),
        (try_end),
        (eq, ":end", 0),
        ],
      "Upgrade military buildings.",[(jump_to_menu, "mnu_center_upgrade"),]),

      ("center_cancel_build",[(eq, reg6, 1),],
      "Cancel building the {s7}.",[
        (call_script, "script_change_center_prosperity", "$current_town", -3),
        (call_script, "script_change_player_relation_with_center", "$current_town", -3),
        (party_set_slot, "$current_town", slot_center_current_improvement, 0),
        (party_set_slot, "$current_town", slot_village_recover_progress, 0),
        (party_get_slot, ":hours_left", "$current_town", slot_center_improvement_end_hour),

        #reinvest in economy
        # (party_get_slot, ":cur_wealth", "$current_town", slot_town_wealth),
        (try_begin),
          (is_between, "$current_town", towns_begin, towns_end),
          (party_get_slot, ":merchant_troop", "$current_town", slot_town_merchant),
          (troop_add_gold, ":merchant_troop", ":hours_left"),
        (else_try),
          (is_between, "$current_town", villages_begin, villages_end),
          (party_get_slot, ":merchant_troop", "$current_town", slot_town_elder),
        (try_end),
       
        (store_current_hours, ":cur_hours"),
        (val_sub, ":hours_left", ":cur_hours"),
        (val_mul, ":hours_left", 10), #a paltry sum
        (try_begin),
          (gt, ":merchant_troop", 0),
          (troop_add_gold, ":merchant_troop", ":hours_left"),
        (else_try), #castle has no seneschal
          (party_get_slot, ":cur_gold", "$current_town", slot_center_accumulated_tariffs),
          (val_add, ":cur_gold", ":hours_left"),
          (party_set_slot, "$current_town", slot_center_accumulated_tariffs, ":cur_gold"),
        (try_end),
        (jump_to_menu, "$g_next_menu"),
        ]),

      ("go_back_dot",[],"Go back.",[(jump_to_menu, "$g_next_menu")]),
    ],
  ),
Code:
  ("upgrade_infrastructure", [
    (store_script_param_1, ":center_no"),
    (store_script_param_2, "$g_improvement_type"),
    (party_get_slot, ":total", ":center_no", "$g_improvement_type"),
    (store_mul, ":deficit", ":total", -1),
    (store_random_in_range, ":deficit", ":deficit", -7),
    (call_script, "script_change_center_prosperity", ":center_no", ":deficit"),
    (party_get_slot, "$enterprise_cost", "p_zendar", "$g_improvement_type"),
    (val_mul, "$enterprise_cost", ":total"),
    (val_div, "$enterprise_cost", 4),
    #current building is twice as expensive cumulatively
    (try_for_range, ":slots", military_infra_begin, military_infra_end),
      (party_get_slot, ":num_buildings", ":center_no", ":slots"),
      (val_add, ":total", ":num_buildings"),
    (try_end),
    (val_mul, ":total", 5000),
    (val_add, "$enterprise_cost", ":total"),
    
    (jump_to_menu, "mnu_center_improve"),
  ]),
Code:
  (
    "center_upgrade",0,
    "Overhauling the infrastructure in {s6} requires the allocation of additional land and resources.\
 Each successive undertaking consumes more manpower and may cause a drop in the economy while renovations are ongoing.\
 Consider leaving a larger garrison and conscripted labour force to ensure the timely completion of this project.",
    "none",
    [(str_store_party_name, s6, "$current_town"),
     (call_script, "script_set_town_picture"),],
    [
        ("center_upgrade_foundry",[
          (party_get_slot, reg6, "$g_encountered_party", slot_center_has_foundry),
          (is_between, reg6, 1, 5),
           ],
        "Upgrade the level {reg6} forge.",[(call_script, "script_upgrade_infrastructure", "$current_town", slot_center_has_foundry),]),
        
        ("center_upgrade_arsenal",[
          (party_get_slot, reg6, "$g_encountered_party", slot_center_has_arsenal),
          (is_between, reg6, 1, 5),
           ],
        "Upgrade the level {reg6} arsenal.",[(call_script, "script_upgrade_infrastructure", "$current_town", slot_center_has_arsenal),]),
        
        ("center_upgrade_stable",[
          (party_get_slot, reg6, "$g_encountered_party", slot_center_has_stables),
          (is_between, reg6, 1, 5),
           ],
        "Upgrade the level {reg6} stable.",[(call_script, "script_upgrade_infrastructure", "$current_town", slot_center_has_stables),]),
        
        ("center_upgrade_barrack",[
          (party_get_slot, reg6, "$g_encountered_party", slot_center_has_barrack),
          (is_between, reg6, 1, 5),
           ],
        "Upgrade the level {reg6} barrack.",[(call_script, "script_upgrade_infrastructure", "$current_town", slot_center_has_barrack),]),

        ("center_upgrade_range",[
          (party_get_slot, reg6, "$g_encountered_party", slot_center_has_shrange),
          (is_between, reg6, 1, 5),
           ],
        "Upgrade the level {reg6} shooting range.",[(call_script, "script_upgrade_infrastructure", "$current_town", slot_center_has_shrange),]),

      ("cancel_upgrade",[],"Nevermind.",[(jump_to_menu, "$g_next_menu")]),
    ],
  ),

  (
    "center_improve",0,
    "{s19} As the party member with the highest engineer skill ({reg2}), {reg3?you reckon:{s3} reckons} that building the {s4} will cost you\
 {reg5} denars and will take {reg6} days.",
    "none",
    [(call_script, "script_get_improvement_details", "$g_improvement_type", 1, 2),
     (try_begin), #not specified
       (eq, "$enterprise_cost", -1), 
       (assign, ":improvement_cost", reg0),
     (else_try),
       (assign, ":improvement_cost", "$enterprise_cost"),
     (try_end),
     (str_store_string_reg, s4, s0),
     (str_store_string_reg, s19, s1),
     (call_script, "script_get_max_skill_of_player_party", "skl_engineer"),
     (assign, ":max_skill", reg0),
     (assign, ":max_skill_owner", reg1),
     (assign, reg2, ":max_skill"),

     (store_sub, ":multiplier", 21, ":max_skill"),
     (val_mul, ":improvement_cost", ":multiplier"),
     (val_div, ":improvement_cost", 20),

     (assign, ":rate", 100),
     #lumber yard bonus
     (try_for_range, ":centers", centers_begin, centers_end),
       (this_or_next|eq, ":centers", "$g_encountered_party"),
       (party_slot_eq, ":centers", slot_village_bound_center, "$g_encountered_party"),
       (party_slot_ge, ":centers", slot_center_has_lumber_yard, 1),
       (val_add, ":rate", 5),
     (try_end),

     (store_div, ":improvement_time", ":improvement_cost", ":rate"),
     (store_sqrt, ":base_time", ":improvement_cost"),
     (val_div, ":base_time", 10),
     (try_begin), #upgrading for decreased duration (cost still pretty high)
       (gt, "$enterprise_cost", 0),
       #assuming a high average of 150+50 per castle, 300+100 per town
       (party_get_num_companions, ":size", "$g_encountered_party"),
       (party_get_num_prisoners, ":prisoners", "$g_encountered_party"),
       (val_mul, ":prisoners", 2), #could do faction/level/strength check as well
       (val_add, ":size", ":prisoners"),
       (val_max, ":size", 75),
       #current level between 1 and 5
       (party_get_slot, ":total", "$g_encountered_party", "$g_improvement_type"),
       (val_mul, ":total", 60), #aproximate work-days - 100 to 500
       (val_mul, ":base_time", ":total"),
       (val_div, ":base_time", ":size"),
     (try_end),
     (val_add, ":base_time", 3),
     (val_add, ":improvement_time", ":base_time"),

     (assign, reg5, ":improvement_cost"),
     (assign, reg6, ":improvement_time"),

     (try_begin),
       (eq, ":max_skill_owner", "trp_player"),
       (assign, reg3, 1),
     (else_try),
       (assign, reg3, 0),
       (str_store_troop_name, s3, ":max_skill_owner"),
     (try_end),
     (set_fixed_point_multiplier, 100),
     (position_set_x, pos0, 60),
     (position_set_y, pos0, 30),
     (position_set_z, pos0, 90), #scale
     (set_game_menu_tableau_mesh, "tableau_troop_note_mesh", ":max_skill_owner", pos0),
     (try_begin), #fast build
       (eq, "$cheat_mode", 1),
       (troop_add_gold, "trp_player", reg5),
     (try_end),

    ],
    [
      ("improve_cont",[(store_troop_gold, ":cur_gold", "trp_player"),
                       (store_troop_gold, ":cur_treasury", "trp_household_possessions"),
                       (val_max, ":cur_gold", ":cur_treasury"),
                       (ge, ":cur_gold", reg5)],
       "Go on.", [
                 (try_begin), #fast build
                   (eq, "$cheat_mode", 1),
                   (assign, reg6, 0),
                 (else_try),
                   (troop_remove_gold, "trp_player", reg5),
                 (try_end),
                  (call_script, "script_improve_center", "$g_encountered_party", reg6),
                  # (party_set_slot, "$g_encountered_party", slot_center_current_improvement, "$g_improvement_type"),
                  # (store_current_hours, ":cur_hours"),
                  # (store_mul, ":hours_takes", reg6, 24),
                  # (val_add, ":hours_takes", ":cur_hours"),
                  # (party_set_slot, "$g_encountered_party", slot_center_improvement_end_hour, ":hours_takes"),
                  (jump_to_menu,"mnu_center_manage"),
                  ]),
      ("forget_it",[], "Forget it.", [(jump_to_menu,"mnu_center_manage")]),

    ],
  ),

And, finally, here's a kitbashed upload of my Native folder, where I was also testing stupid things like overhead stabs and dual-wielding. Again, play custom battle to test these features, and apologies if your stuff is in there somehow.
 
Outstanding presentation and fantastic concept. Should be pretty easy to integrate in a existing codebase
without much fuss while adding strategic complexity which is visible in both modes, not just in menus and screens.

I know that it almost takes more time to prepare and release it than developing it in first place.
A nice work kind of falls short for this kind of effort. Thanks for sharing, mate.
 
If you do get it working, try giving some feedback as to how unbalanced it gets in the long run, when a faction takes over a number of centers that have these built. Editing the second post to add some auto-calc and additional effects mentioned in the description string.
 
Well well, an OSP by Somebody.
Neat idea. I would've never even thought of linking buildings directly to agent modifiers. Interesting. :smile:
The execution is probably brilliant as well, though I've got to go to bed an unfortunately have got no time for code now. :sad:
 
MickDick said:
This is nothing short of extremely impressive.

I need for more osp scripts  :neutral: especially by "Somebody" ,and it's a good and difficult script here, interesting.
Thanks !
 
A quick update since this got moved to the right board, with a presentation layer that provides read-only overview of faction modifiers that can be adjusted during debug or quick-battle. The link to the dropbox will be updated eventually, but until then here's a few teasers.
presentation.jpg

Invoke it by passing in $faction_selected before starting the presentation like so
prsnt_game_custom_battle_designer said:
      (assign, ":cur_y", 330),
      (assign, ":cur_y", 350),
      (assign, ":cur_y_adder", 40),
      #do interface here instead of tableau above
      (create_button_overlay, "$g_presentation_obj_profile_banner_selection_1", "str_faction", tf_center_justify),
      (create_text_overlay, reg0, "str_faction", tf_center_justify),
      (position_set_x, pos1, 175),
      (position_set_y, pos1, ":cur_y"),
      (overlay_set_position, "$g_presentation_obj_profile_banner_selection_1", pos1),
      (overlay_set_position, reg0, pos1),
      (overlay_set_alpha, reg0, 0x80),
      (overlay_set_tooltip, "$g_presentation_obj_profile_banner_selection_1", "@Click here to adjust faction modifiers"),
      (faction_get_color, ":color", "$g_quick_battle_team_1_faction"),
      (overlay_set_color, "$g_presentation_obj_profile_banner_selection_1", ":color"),

      (create_button_overlay, "$g_presentation_obj_profile_banner_selection_2", "str_faction", tf_center_justify),
      (position_set_x, pos1, 820),
      (position_set_y, pos1, ":cur_y"),
      (create_text_overlay, reg0, "str_faction", tf_center_justify),
      (overlay_set_position, reg0, pos1),
      (overlay_set_alpha, reg0, 0x80),
      (overlay_set_position, "$g_presentation_obj_profile_banner_selection_2", pos1),
      (overlay_set_tooltip, "$g_presentation_obj_profile_banner_selection_2", "@Click here to adjust faction modifiers"),
      (faction_get_color, ":color", "$g_quick_battle_team_2_faction"),
      (overlay_set_color, "$g_presentation_obj_profile_banner_selection_2", ":color"),

...
      (else_try),
        (eq, ":eek:bject", "$g_presentation_obj_custom_battle_designer_23"),
        (assign, "$g_quick_battle_game_type", ":value"),
        (presentation_set_duration, 0),
        (start_presentation, "prsnt_game_custom_battle_designer"),
      (else_try),
        (eq, ":eek:bject", "$g_presentation_obj_custom_battle_designer_23"),
        (assign, "$g_quick_battle_game_type", ":value"),
        (presentation_set_duration, 0),
        (start_presentation, "prsnt_game_custom_battle_designer"),
      (else_try), #player faction
        (eq, ":eek:bject", "$g_presentation_obj_profile_banner_selection_1"),
        (assign, "$g_presentation_next_presentation", "prsnt_game_custom_battle_designer"),
        (assign, "$faction_selected", "$g_quick_battle_team_1_faction"),
        (presentation_set_duration, 0),
        (start_presentation, "prsnt_faction_modifiers"),
      (else_try), #other faction
        (eq, ":eek:bject", "$g_presentation_obj_profile_banner_selection_2"),
        (assign, "$g_presentation_next_presentation", "prsnt_game_custom_battle_designer"),
        (assign, "$faction_selected", "$g_quick_battle_team_2_faction"),
        (presentation_set_duration, 0),
        (start_presentation, "prsnt_faction_modifiers"),
If you don't have those placeholder khergit factions anymore, change them to something else
Code:
  ("faction_modifiers", prsntf_manual_end_only, mesh_cb_ui_main, [
    (ti_on_presentation_load,
      [
        (presentation_set_duration, 999999),
        (set_fixed_point_multiplier, 1000),

        #display names
        (try_begin),
          (is_between, "$faction_selected", npc_kingdoms_begin, npc_kingdoms_end),
          (str_store_faction_name, s0, "$faction_selected"),
          (faction_get_color, ":color", "$faction_selected"),
          
          (create_text_overlay, reg0, s0, tf_center_justify),
          (overlay_set_color, reg0, ":color"),
          (position_set_x, pos1, 1500),
          (position_set_y, pos1, 1500),
          (overlay_set_size, reg0, pos1),
          (position_set_x, pos1, 500),
          (position_set_y, pos1, 100),
          (overlay_set_position, reg0, pos1),

          (store_sub, ":mesh", "$faction_selected", npc_kingdoms_begin),
          (val_add, ":mesh", "mesh_pic_arms_swadian"),
          (create_mesh_overlay, reg0, ":mesh"),
          (position_set_x, pos1, 500),
          (position_set_y, pos1, 600),
          (overlay_set_position, reg0, pos1),
          (position_set_x, pos1, 750),
          (position_set_y, pos1, 750),
          (overlay_set_size, reg0, pos1),
        (try_end),

        (str_clear, s0),
        (init_position, pos1),
        (str_store_string, s0, "str_shooting_details"),
        (str_clear, s1),
        (try_for_range_backwards, ":string", "str_foundry_details", "str_shooting_details"),
          (str_store_string, s1, ":string"),
          (str_store_string, s0, "@{s0}^^{s1}"),
        (try_end),
        (create_text_overlay, reg0, s0, tf_scrollable),
        (position_set_x, pos1, 15),
        (position_set_y, pos1, 50),
        (overlay_set_position, reg0, pos1),
        (position_set_x, pos1, 800),
        (position_set_y, pos1, 800),
        (overlay_set_size, reg0, pos1),
        (position_set_x, pos1, 300),
        (position_set_y, pos1, 500),
        (overlay_set_area_size, reg0, pos1),
          
        (assign, ":cur_y", 200),
        (assign, ":string", "str_foundry"),
        (try_for_range, ":slots", slot_faction_num_foundrys, slot_faction_num_ranges + 1),
          (faction_get_slot, ":value", "$faction_selected", ":slots"),
          #slider
          (create_slider_overlay, ":slider", 0, 200),
          (overlay_set_val, ":slider", ":value"),
          (init_position, pos1),
          (position_set_x, pos1, 495),
          (position_set_y, pos1, ":cur_y"),
          (overlay_set_position, ":slider", pos1),
          (faction_set_slot, "fac_khergits", ":slots", ":slider"),
          
          #label
          (assign, reg0, ":value"),
          (str_store_string, s0, ":string"),
          (create_text_overlay, ":label", "str_s0_dd_reg0", tf_single_line|tf_right_align|tf_with_outline),
          (position_set_x, pos1, 960),
          (overlay_set_position, ":label", pos1),
          (overlay_set_color, ":label", 0xFFFFFF),
          (faction_set_slot, "fac_black_khergits", ":slots", ":label"),
          
          # (store_add, ":description", ":string", 16),
          # (position_set_x, pos1, 100),
          # (position_set_x, pos1, ":cur_y"),
          # (create_text_overlay, reg0, ":description", tf_left_align),
          # (overlay_set_position, reg0, pos1),      
          (val_add, ":cur_y", 75),
          (val_add, ":string", 1),
        (try_end),


        # done
        (create_game_button_overlay, "$g_close_equipment_selection", "str_done"),
        (position_set_x, pos1, 850),
        (position_set_y, pos1, 100),
        (overlay_set_position, "$g_close_equipment_selection", pos1),

      ]),

    (ti_on_presentation_event_state_change,
      [
        (store_trigger_param_1, ":object"),
        (store_trigger_param_2, ":value"),

        (set_fixed_point_multiplier, 1000),
        (try_begin),#done/reset
          (eq, ":object", "$g_close_equipment_selection"),
          (try_begin),
            (gt, "$g_presentation_next_presentation", 0),
            (presentation_set_duration, 0),
            (start_presentation, "$g_presentation_next_presentation"),
          (else_try),
            (presentation_set_duration, 0),
          (try_end),
        (else_try), #read-only presentation unless otherwise stated
          (this_or_next|ge, "$cheat_mode", 1),
          (eq, "$g_is_quick_battle", 1),
          (try_for_range, ":slots", slot_faction_num_foundrys, slot_faction_num_ranges + 1),
            (faction_get_slot, ":slider", "fac_khergits", ":slots"),
            (eq, ":object", ":slider"),
            (faction_set_slot, "$faction_selected", ":slots", ":value"),
            (faction_get_slot, ":label", "fac_black_khergits", ":slots"),
            (assign, reg0, ":value"),
            (store_sub, ":string", ":slots", slot_faction_num_foundrys),
            (val_add, ":string", "str_foundry"),
            (str_store_string, s0, ":string"),
            (overlay_set_text, ":label", "str_s0_dd_reg0"),
          (try_end),
        (try_end),
    ]),
  ]),
Another few screenshots, although this is more of a quantitative mod than visual.
rvs2.jpg

Figure 1 shows ironclad Rhodoks storming a Sarranid castle and getting predictably stuck.
mb8.jpg

Figure 2 shows Khergits suffering heavy casualties from Nordic Furor added by combat modifiers. See the received damage? That's WITH 1/4 damage to player.
And finally here's a bunch of screenshots of the modified menu interface - note the inclusion of a troop tableau and cancellation option. As you can see, the expense and time investment scales up quite a bit, but can be reduced by using the garrison as a labour force. The cost is calculated as follows:
( Base Cost * Current Level ) / 4 + ( Cumulative Level of all military buildings * 5000 )
menu.jpg

The days-to-completion is 1 since I was still testing in cheat mode
 
Sory for post but I have this problem in module system.Just red lines.
Initializing...
Compiling all global variables...
Exporting strings...
Exporting skills...
Exporting tracks...
Exporting animations...
Exporting meshes...
Exporting sounds...
Exporting skins...
Exporting map icons...
Creating new tag_uses.txt file...
Creating new quick_strings.txt file...
Exporting faction data...
Exporting item data...
Exporting scene data...
Exporting troops data
Exporting particle data...
Exporting scene props...
Exporting tableau materials data...
Exporting presentations...
Exporting party_template data...
Exporting parties
Exporting quest data...
Exporting info_page data...
Exporting scripts...
ERROR: Usage of unassigned local variable: :troop_no
ERROR: Usage of unassigned local variable: :center_no
Error: Unable to find object:script_sort_merchant_inventory
ERROR: Illegal Identifier:script_sort_merchant_inventory
Error: Unable to find object:script_sort_merchant_inventory
ERROR: Illegal Identifier:script_sort_merchant_inventory
Error: Unable to find object:script_sort_merchant_inventory
ERROR: Illegal Identifier:script_sort_merchant_inventory
Error: Unable to find object:script_sort_merchant_inventory
ERROR: Illegal Identifier:script_sort_merchant_inventory

Exporting mission_template data...
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: player_agent, at: 0
WARNING: Local variable never used: jumpchance, at: 0
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: player_agent, at: 0
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: player_agent, at: 0
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: player_agent, at: 0
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: jumpchance, at: 0
ERROR: Usage of unassigned local variable: :player_agent
ERROR: Usage of unassigned local variable: :player_agent
WARNING: Local variable never used: jumpchance, at: 0
Exporting game menus data...
exporting simple triggers...
exporting triggers...
exporting dialogs...
WARNING: Local variable never used: cur_faction, at: 0
Checking global variable usages...
Exporting postfx_params...

______________________________

Script processing has ended.
Press any key to exit. . .
I can't find this script in thread
script_sort_merchant_inventory
Must I delete this in module_scrips?
get_improvement_details
And all building completed in 1 day.


And in game I have this errors:
0lyQzZ.jpg
 
sort_merchant_inventory can be commented out, it just does arbitrary rearrangement of items for merchants. Improvements auto-complete in one day with cheat mode enabled. Your in-game logs from party_set_ai_state suggests something went wrong and you're calling it with an invalid commander/troop_no parameter.
 
Back
Top Bottom