OSP Kit Combat [B] Bannerless Tableau Shields

Users who are viewing this thread

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.

5_tdU.jpg

3yXkT.jpg
d3JKB.jpg

Add this helper function at the top - dunde's 1 Liner Heraldic Code
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"),
  ]),
This is necessary to pack additional info into the tableau parameters
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),
    ]),
  ]),
Replace the first version of
Code:
shield_item_set_banner
with this to take advantage of slots.
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"),
  ]),
Toss this in somewhere - reserve 2 slots after this as well (next used slot is slot_troop_first_encountered @59)
Code:
slot_troop_personal_tableau = 56
Drop this off in the usual camp menu options.
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
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
 
Excellent! I'm definitely making use of this. :smile:

And the presentation looks like a godsend, I was going to experiment using tableaus in presentations anyway, and now I have a working example doing something pretty similar to what I want. Great!
 
Lav said:
And the presentation looks like a godsend, I was going to experiment using tableaus in presentations anyway, and now I have a working example doing something pretty similar to what I want. Great!
Thanks, but in the future I would probably add placeholder items specifically for tableaus instead of mucking about with
Code:
is_presentation_active
overrides in script_shield_item_set_banner (which I'd imagine impacts performance quite a bit). That way you can reposition the items (so they face different directions I suppose instead of the usual 45°. For sake of brevity I rolled up all of them into one and positioned them inside the presentation manually. You can always define a range of different shields in this way and cut some of the placeholder code.
 
My goal is repositioning not items in the presentation, but rather the heraldic texture on the item tableau. I'm currently fine-tuning heraldry for items using several keyboard triggers, checking on the results in inventory/character screen, with a test mission template for the final revision before writing down the coordinates/scale. Doing that in a presentation with a large character image would be much easier.

Though with the rate I'm converting game items to their heraldic versions I suspect that I'll have everything ready long before I finally manage to examine your presentation. In fact I only have to convert two more items before I'm done, with 15-20 already completed. :smile:
 
I've found that updating a position inside a trigger inside the mission template and re-using that particular register inside the tableau entry allows you to fine-tune the position more easily. To refresh the item I've used the usual agent equip operations (or even pressing escape and return). Another thing I've thought about doing is setting up the planar mesh as a scene prop (or item) and applying the item's tableau on it to better show where the meshes are layered in relation to one another.
 
Somebody said:
I've found that updating a position inside a trigger inside the mission template and re-using that particular register inside the tableau entry allows you to fine-tune the position more easily. To refresh the item I've used the usual agent equip operations (or even pressing escape and return). Another thing I've thought about doing is setting up the planar mesh as a scene prop (or item) and applying the item's tableau on it to better show where the meshes are layered in relation to one another.
I tried doing the same, but banner did not refresh for some reason, and since I was too lazy to debug I'm still using the global map triggers. :smile:

Still, the results look more or less decent... mostly. Oh allright, some items still need work. :smile:

i26hif.jpg


itm_hera_shirt_a
itm_hera_arena_tunicW
itm_hera_rich_tunic_a
itm_hera_tabard_b
itm_hera_padded_cloth_a
itm_hera_padded_cloth_b
itm_hera_archers_vest
itm_hera_leather_vest_a
itm_hera_sarranid_leather_armor
itm_hera_tribal_outfit
itm_hera_light_mail_and_plate
itm_hera_mail_and_plate
itm_hera_cuir_bouilli_a
itm_hera_brigandine_b
itm_hera_arena_armorW
itm_hera_mail_long_surcoat
itm_hera_plate_armor
And it also seems I suck at picking appropriate background color to match my banner texture, so there are visible rectangles on some items. Shouldn't be the case with Native textures.

At least I've finished with heraldry for now. But there are still 20+ clothing textures, as well as hats/boots/gloves which need some love too. :cry:
 
Back
Top Bottom