This OSP introduces a number of dynamically retextured shield- including Native's norman shields which have not seen the light of day in ages. Compared to the original tableau shields, these often feature designs in the foreground instead of merely featuring whatever inappropriate banner the troop might field. The design is semi-randomized by modulating the banner offset for heroes, but a presentation is included to assign a fixed design for the player character & loyal companions. The goal of this project is, I suppose, to add variety without creating duplicates of item entries in troop inventories so as to not unbalance item loot ratios or merchandise quantities. There are some funky workarounds for , but performance should be acceptable.
Replace the first version of
with this to take advantage of slots.
Toss this in somewhere - reserve 2 slots after this as well (next used slot is slot_troop_first_encountered @59)
Drop this off in the usual camp menu options.
Download the BRF & Textures here
Credits & inspiration for the round shield retexture
goes to RobinHat and the rest are from AlphaDelta who contributed them to Lords and Realms but has since been banned.
You can also find a mirror for this OSP on NexusMods
Add this helper function at the top - dunde's 1 Liner Heraldic Code
This is necessary to pack additional info into the tableau parameters
Code:
def heraldic(item_tableau):
return (ti_on_init_item, [(store_trigger_param_1, ":agent_no"),(store_trigger_param_2, ":troop_no"),(call_script, "script_shield_item_set_banner", item_tableau, ":agent_no", ":troop_no")])
Code:
["round_shield_1a", "Nordic Round Shield", [("tableau_shield_round_1",0)], itp_merchandise|itp_type_shield|itp_wooden_parry, itcf_carry_round_shield,
210 , weight(4)|hit_points(350)|body_armor(15)|spd_rtng(84)|shield_width(50),imodbits_shield,
[heraldic("tableau_round_shield_1a")]],
["norman_shield_a", "Knightly Norman Shield", [("tab_shield_norman_a",0)], itp_type_shield|itp_wooden_parry, itcf_carry_kite_shield, 354, weight(2.75)|hit_points(420)|body_armor(8)|spd_rtng(82)|shield_width(35)|shield_height(70)|difficulty(2),imodbits_shield,
[heraldic("tableau_shield_norman_a")]],
["norman_shield_b", "Horseman's Norman Shield", [("tab_shield_norman_b",0)], itp_type_shield|itp_wooden_parry, itcf_carry_kite_shield, 236, weight(2.5)|hit_points(350)|body_armor(5)|spd_rtng(88)|shield_width(35)|shield_height(70)|difficulty(1),imodbits_shield,
[heraldic("tableau_shield_norman_b")]],
Code:
#embossed
("tableau_mesh_shield_norman_1", 0, "tableau_mesh_shield_norman_1", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_2", 0, "tableau_mesh_shield_norman_2", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_3", 0, "tableau_mesh_shield_norman_3", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_4", 0, "tableau_mesh_shield_norman_4", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_5", 0, "tableau_mesh_shield_norman_5", 0, 0, 0, 0, 0, 0, 10, 10, 10),
#no boss
("tableau_mesh_shield_norman_6", 0, "tableau_mesh_shield_norman_6", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_7", 0, "tableau_mesh_shield_norman_7", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_norman_8", 0, "tableau_mesh_shield_norman_8", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1a", 0, "tableau_mesh_shield_round_1a", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1b", 0, "tableau_mesh_shield_round_1b", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1c", 0, "tableau_mesh_shield_round_1c", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1d", 0, "tableau_mesh_shield_round_1d", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1e", 0, "tableau_mesh_shield_round_1e", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1f", 0, "tableau_mesh_shield_round_1f", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1g", 0, "tableau_mesh_shield_round_1g", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1h", 0, "tableau_mesh_shield_round_1h", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1i", 0, "tableau_mesh_shield_round_1i", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1j", 0, "tableau_mesh_shield_round_1j", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1k", 0, "tableau_mesh_shield_round_1k", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1l", 0, "tableau_mesh_shield_round_1l", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("tableau_mesh_shield_round_1m", 0, "tableau_mesh_shield_round_1m", 0, 0, 0, 0, 0, 0, 10, 10, 10),
("quest_window", 0, "quests_window", 0, 0, 0, 0, 0, 0, 1, 1, 1),
Code:
#metal boss
("shield_norman_a", 0, "sample_shield_norman_a", 512, 512, 0, 0, 0, 0,
[
(store_script_param, ":banner_mesh", 1),
(set_fixed_point_multiplier, 100),
(store_mod, ":background_slot", ":banner_mesh", 1000),
(val_sub, ":background_slot", arms_meshes_begin),
(troop_get_slot, ":background_color", "trp_banner_background_color_array", ":background_slot"),
(cur_tableau_set_background_color, ":background_color"),
(init_position, pos1),
(position_set_z, pos1, 10),
(val_div, ":banner_mesh", 1000),
(val_add, ":banner_mesh", "mesh_tableau_mesh_shield_norman_1"),
(assign, reg3, ":banner_mesh"),
(cur_tableau_add_mesh, ":banner_mesh", pos1, 0, 0),
(cur_tableau_set_camera_parameters, 0, 200, 200, 0, 100000),
]),
#leather + boss
("shield_norman_b", 0, "sample_shield_norman_b", 512, 512, 0, 0, 0, 0,
[
(store_script_param, ":banner_mesh", 1),
(set_fixed_point_multiplier, 100),
(store_mod, ":background_slot", ":banner_mesh", 1000),
(val_sub, ":background_slot", arms_meshes_begin),
(troop_get_slot, ":background_color", "trp_banner_background_color_array", ":background_slot"),
(cur_tableau_set_background_color, ":background_color"),
(init_position, pos1),
(position_set_z, pos1, 10),
(val_div, ":banner_mesh", 1000),
(val_add, ":banner_mesh", "mesh_tableau_mesh_shield_norman_6"),
(assign, reg3, ":banner_mesh"),
(cur_tableau_add_mesh, ":banner_mesh", pos1, 0, 0),
(cur_tableau_set_camera_parameters, 0, 200, 200, 0, 100000),
]),
("round_shield_1a", 0, "sample_shield_round_1", 512, 256, 0, 0, 0, 0,
[
(store_script_param, ":banner_mesh", 1),
(set_fixed_point_multiplier, 100),
(store_mod, ":background_slot", ":banner_mesh", 1000),
# (assign, reg1, ":background_slot"),
# (assign, reg2, ":banner_mesh"),
(val_sub, ":background_slot", arms_meshes_begin),
(troop_get_slot, ":background_color", "trp_banner_background_color_array", ":background_slot"),
(cur_tableau_set_background_color, ":background_color"),
(init_position, pos1),
(position_set_z, pos1, 10),
(val_div, ":banner_mesh", 1000),
(val_add, ":banner_mesh", "mesh_tableau_mesh_shield_round_1a"),
(assign, reg3, ":banner_mesh"),
(cur_tableau_add_mesh, ":banner_mesh", pos1, 0, 0),
(cur_tableau_set_camera_parameters, 0, 200, 100, 0, 100000),
# (display_message, "@{reg3}&{reg1} = {reg2}", ":background_color"),
]),
Code:
#script_shield_item_set_banner
# INPUT: agent_no
# OUTPUT: none
("shield_item_set_banner",
[
(store_script_param, ":tableau_no",1),
(store_script_param, ":agent_no", 2),
(store_script_param, ":troop_no", 3),
(call_script, "script_agent_troop_get_banner_mesh", ":agent_no", ":troop_no"),
(assign, ":banner_mesh", reg0),
(try_begin),
(ge, ":troop_no", 0),
(assign, ":random_no", 0),
(try_begin),
(eq, ":tableau_no", "tableau_round_shield_1a"),
(try_begin),
(troop_is_hero, ":troop_no"),
(store_mod, ":random_no", ":banner_mesh", 13),
(else_try),
(store_random_in_range, ":banner_mesh", arms_meshes_begin, arms_meshes_end_minus_one),
(store_random_in_range, ":random_no", 0, 13), # 13 other variants
(try_end),
(else_try),
(is_between, ":tableau_no", "tableau_shield_norman_a", "tableau_round_shield_1a"),
(try_begin),
(eq, ":tableau_no", "tableau_shield_norman_b"),
(assign, ":limit", 3),
(else_try),
(assign, ":limit", 5),
(try_end),
(try_begin),
(troop_is_hero, ":troop_no"),
(store_mod, ":random_no", ":banner_mesh", ":limit"),
(else_try),
(store_random_in_range, ":banner_mesh", arms_meshes_begin, arms_meshes_end_minus_one),
(store_random_in_range, ":random_no", 0, ":limit"),
(try_end),
(try_end),
(neq, ":random_no", 0),
(val_mul, ":random_no", 1000),
(store_add, reg0, ":banner_mesh", ":random_no"),
(try_end),
(cur_item_set_tableau_material, ":tableau_no", reg0),
]),
Code:
("shield_tableau", 0, mesh_quest_window, [
(ti_on_presentation_event_state_change,
[
(store_trigger_param_1, ":object"),
(store_trigger_param_2, ":value"),
(assign, ":continue", 0),
(try_begin),
(eq, ":object", "$g_presentation_obj_1"), # show towns
(party_get_num_companion_stacks, ":stack_max", "p_main_party"),
(try_for_range, ":stack_no", 0, ":stack_max"),
(party_stack_get_troop_id, ":troop_no", "p_main_party", ":stack_no"),
(troop_is_hero, ":troop_no"),
(try_begin),
(eq, ":value", 0),
(assign, "$lord_selected", ":troop_no"),
(assign, ":stack_max", -1),
(else_try),
(val_sub, ":value", 1),
(try_end),
(try_end),
(val_max, "$lord_selected", "trp_player"),
(else_try),
(eq, ":object", "$g_presentation_obj_2"), # round
(troop_set_slot, "$lord_selected", slot_troop_personal_tableau, ":value"),
(else_try),
(eq, ":object", "$g_presentation_obj_3"), # norman a
(troop_set_slot, "$lord_selected", slot_troop_personal_tableau + 1, ":value"),
(else_try),
(eq, ":object", "$g_presentation_obj_4"), #norman b
(troop_set_slot, "$lord_selected", slot_troop_personal_tableau + 2, ":value"),
(else_try),
(eq, ":object", "$g_close_equipment_selection"),
(assign, "$lord_selected", -1),
(assign, ":continue", -1),
(presentation_set_duration, 0),
(try_end),
(try_begin),
(eq, ":continue", 0),
(start_presentation, "prsnt_shield_tableau"),
(try_end),
]),
(ti_on_presentation_load,
[
(presentation_set_duration, 999999),
(set_fixed_point_multiplier, 1000),
(init_position, pos11),
(init_position, pos12),
(create_combo_label_overlay, "$g_presentation_obj_1"),
(party_get_num_companion_stacks, ":stack_max", "p_main_party"),
(assign, ":cur_stack", 0),
(try_for_range, ":stack_no", 0, ":stack_max"),
(party_stack_get_troop_id, ":troop_no", "p_main_party", ":stack_no"),
(troop_is_hero, ":troop_no"),
(str_store_troop_name, s1, ":troop_no"),
(overlay_add_item, "$g_presentation_obj_1", s1),
(try_begin),
(eq, "$lord_selected", ":troop_no"),
(overlay_set_val, "$g_presentation_obj_1", ":cur_stack"),
(try_end),
(val_add, ":cur_stack", 1),
(try_end),
(position_set_x, pos11, 250),
(position_set_y, pos11, 50),
(overlay_set_position, "$g_presentation_obj_1", pos11),
# (position_set_x, pos12, 1000),
# (position_set_y, pos12, 2000),
# (overlay_set_size, "$g_presentation_obj_1", pos12),
(create_mesh_overlay_with_tableau_material, reg1, -1, "tableau_troop_note_mesh", "$lord_selected"),
(position_set_x, pos11, 100),
(position_set_y, pos11, 250),
(overlay_set_position, reg1, pos11),
(position_set_x, pos11, 775),
(create_mesh_overlay_with_item_id, reg1, "itm_round_shield_1a"),
(troop_set_slot, active_npcs_including_player_begin, slot_troop_personal_tableau, reg1),
(position_set_y, pos11, 225),
(overlay_set_position, reg1, pos11),
(init_position, pos10),
(position_rotate_z, pos10, 45),
(overlay_set_mesh_rotation, reg1, pos10),
(create_slider_overlay, "$g_presentation_obj_2", 0, 12),
(position_set_y, pos11, 150),
(overlay_set_position, "$g_presentation_obj_2", pos11),
(call_script, "script_shield_tableau_slider", "$g_presentation_obj_2", slot_troop_personal_tableau),
(create_mesh_overlay_with_item_id, reg1, "itm_norman_shield_a"),
(troop_set_slot, active_npcs_including_player_begin, slot_troop_personal_tableau + 1, reg1),
(position_set_y, pos11, 375),
(overlay_set_position, reg1, pos11),
(create_slider_overlay, "$g_presentation_obj_3", 0, 4),
(position_set_y, pos11, 300),
(overlay_set_position, "$g_presentation_obj_3", pos11),
(call_script, "script_shield_tableau_slider", "$g_presentation_obj_3", slot_troop_personal_tableau + 1),
(create_mesh_overlay_with_item_id, reg1, "itm_norman_shield_b"),
(troop_set_slot, active_npcs_including_player_begin, slot_troop_personal_tableau + 2, reg1),
(position_set_y, pos11, 525),
(overlay_set_position, reg1, pos11),
(create_slider_overlay, "$g_presentation_obj_4", 0, 2),
(position_set_y, pos11, 450),
(overlay_set_position, "$g_presentation_obj_4", pos11),
(call_script, "script_shield_tableau_slider", "$g_presentation_obj_4", slot_troop_personal_tableau + 2),
(create_game_button_overlay, "$g_close_equipment_selection", "str_done"),
(position_set_x, pos11, 775),
(position_set_y, pos11, 50),
(overlay_set_position, "$g_close_equipment_selection", pos11),
]),
]),
Code:
shield_item_set_banner
Code:
#script_shield_item_set_banner
# INPUT: agent_no
# OUTPUT: none
("shield_item_set_banner",
[
(store_script_param, ":tableau_no",1),
(store_script_param, ":agent_no", 2),
(store_script_param, ":troop_no", 3),
(try_begin), #custom troop, custom banner
(is_presentation_active, "prsnt_shield_tableau"),
(assign, ":troop_no", "$lord_selected"),
(troop_get_slot, ":banner_spr", ":troop_no", slot_troop_banner_scene_prop),
(assign, reg1, ":banner_spr"),
(try_begin),
(le, ":banner_spr", 0),
(troop_get_slot, ":banner_spr", "trp_player", slot_troop_banner_scene_prop),
(le, ":banner_spr", 0),
(store_random_in_range, ":banner_spr", "mesh_arms_default_a", "mesh_troop_label_banner"),
(try_end),
(assign, reg2, ":banner_spr"),
(val_sub, ":banner_spr", banner_scene_props_begin),
(troop_get_slot, ":color", "trp_banner_background_color_array", ":banner_spr"),
(str_store_troop_name, s1, ":troop_no"),
(display_message, "@{s1} had {reg1}, resolved to {reg2}", ":color"),
(val_add, ":banner_spr", arms_meshes_begin),
(assign, reg0, ":banner_spr"),
(else_try),
(call_script, "script_agent_troop_get_banner_mesh", ":agent_no", ":troop_no"),
(try_end),
(assign, ":banner_mesh", reg0),
(try_begin),
(ge, ":troop_no", 0),
(assign, ":random_no", 0),
(try_begin),
(eq, ":tableau_no", "tableau_round_shield_1a"),
(assign, ":banner_mesh", reg0),
(try_begin),
(troop_is_hero, ":troop_no"),
(try_begin),
(troop_get_slot, ":random_no", ":troop_no", slot_troop_personal_tableau),
(eq, ":random_no", -1),
(store_mod, ":random_no", ":banner_mesh", 13),
(try_end),
(else_try),
(store_random_in_range, ":banner_mesh", arms_meshes_begin, arms_meshes_end_minus_one),
(store_random_in_range, ":random_no", 0, 13), # 13 other variants
(try_end),
(else_try),
(is_between, ":tableau_no", "tableau_shield_norman_a", "tableau_round_shield_1a"),
(try_begin),
(eq, ":tableau_no", "tableau_shield_norman_b"),
(assign, ":limit", 3),
(else_try),
(assign, ":limit", 5),
(try_end),
(try_begin),
(troop_is_hero, ":troop_no"),
(try_begin),
(store_sub, ":random_no", ":tableau_no", "tableau_shield_norman_a"),
(val_add, ":random_no", slot_troop_personal_tableau + 1),
(troop_get_slot, ":random_no", ":troop_no", ":random_no"),
(eq, ":random_no", -1),
(store_mod, ":random_no", ":banner_mesh", ":limit"),
(try_end),
(else_try),
(store_random_in_range, ":banner_mesh", arms_meshes_begin, arms_meshes_end_minus_one),
(store_random_in_range, ":random_no", 0, ":limit"),
(try_end),
(try_end),
(neq, ":random_no", 0),
(val_mul, ":random_no", 1000),
(store_add, reg0, ":banner_mesh", ":random_no"),
(try_end),
(cur_item_set_tableau_material, ":tableau_no", reg0),
]),
("shield_tableau_slider", [
(store_script_param_1, ":object_no"),
(store_script_param_2, ":slot_no"),
(troop_get_slot, ":value", "$lord_selected", ":slot_no"),
(try_begin),
(eq, ":value", -1),
(call_script, "script_agent_troop_get_banner_mesh", -1, "$lord_selected"),
(try_begin),
(eq, ":slot_no", slot_troop_personal_tableau),
(assign, ":limit", 13),
(else_try),
(eq, ":slot_no", slot_troop_personal_tableau + 1),
(assign, ":limit", 5),
(else_try),
(eq, ":slot_no", slot_troop_personal_tableau + 2),
(assign, ":limit", 3),
(try_end),
(store_mod, ":value", reg0, ":limit"),
(try_end),
# (val_clamp, ":value", 0, ":limit"),
(overlay_set_val, ":object_no", ":value"),
]),
Code:
slot_troop_personal_tableau = 56
Code:
("action_select_tableau",[
],"Embrace your Norman heritage.",
[
(assign, "$lord_selected", "trp_player"),
(start_presentation, "prsnt_shield_tableau"),
]
),
Download the BRF & Textures here
Credits & inspiration for the round shield retexture
Code:
tableau_shield_round_1a
You can also find a mirror for this OSP on NexusMods