Pretty simple really, press the attack controll while holding the defend controll. Ai will do it automatically when applicable with some degree of randomization.
To install, just paste the following in to module scripts:
("cf_agent_shield_bash",
[(store_script_param, ":agent",1),
(agent_get_position,pos1,":agent"),
(agent_set_animation, ":agent", "anim_release_bash"),
(agent_play_sound,":agent","snd_man_grunt"),
(assign,":victim",-1),
(try_for_agents,":possible_victim"),
(agent_is_alive,":possible_victim"),
(agent_is_human,":possible_victim"),
(neq,":possible_victim",":agent"),
(agent_get_class ,":class", ":possible_victim"),
(neq,":class",grc_cavalry),
(agent_get_position,pos2,":possible_victim"),
(get_distance_between_positions,":dist",pos1,pos2),
(lt,":dist",150),
(neg|position_is_behind_position,pos2,pos1),
(assign,":victim",":possible_victim"),
(end_try),
(gt,":victim",-1),
(store_random_in_range,":rand",1,20),
(store_agent_hit_points,":hp",":victim",1),
(val_sub,":hp",":rand"),
(try_begin),
(gt,":hp",0),
(agent_set_hit_points,":victim",":hp",1),
(agent_play_sound,":agent","snd_shield_hit_wood_wood"),
(agent_play_sound,":victim","snd_blunt_hit"),
(agent_set_animation, ":victim", "anim_strike_fall_back_rise_after_bashed"),
(else_try),
(agent_play_sound,":agent","snd_shield_hit_wood_wood"),
(agent_play_sound,":victim","snd_blunt_hit"),
(agent_deliver_damage_to_agent,":agent",":victim"),
(end_try),
]),
The following into any applicable mission template:
(0, 0, 0, [(game_key_is_down, gk_defend),(game_key_clicked, gk_attack),],
[(assign,":continue",0),
(get_player_agent_no,":player"),
(try_for_range,":shield","
itm_wooden_shield","
itm_heraldic_mail_with_surcoat"),
(agent_has_item_equipped,":player",":shield"),
(assign,":continue",1),
(end_try),
(eq,":continue",1),
(agent_get_horse,":horse",":player"),
(neg|gt,":horse",0),
(call_script,"script_cf_agent_shield_bash",":player"),
]),
(1.0, 0, 0, [],
[(get_player_agent_no,":player"),
(try_for_agents,":agent"),
(agent_is_alive,":agent"),
(agent_is_human,":agent"),
(neq,":agent",":player"),
(agent_get_class ,":class", ":agent"),
(neq,":class",grc_cavalry),
(assign,":continue",0),
(try_for_range,":shield","
itm_wooden_shield","
itm_heraldic_mail_with_surcoat"),
(agent_has_item_equipped,":agent",":shield"),
(assign,":continue",1),
(end_try),
(eq,":continue",1),
(assign,":chances",0),
(agent_get_team,":team",":agent"),
(agent_get_position,pos1,":agent"),
(try_for_agents,"
ther"),
(agent_is_alive,"
ther"),
(agent_is_human,"
ther"),
(agent_get_class ,":class", "
ther"),
(neq,":class",grc_cavalry),
(agent_get_team,"
therteam","
ther"),
(neq,":team","
therteam"),
(agent_get_position,pos2,"
ther"),
(get_distance_between_positions,":dist",pos1,pos2),
(neg|position_is_behind_position,pos2,pos1),
(lt,":dist",200),
(val_add,":chances",1),
(end_try),
(store_agent_hit_points,":health",":agent",0),
(val_mul,":health",-1),
(val_add,":health",100),
(val_div,":health",10),
(val_mul,":chances",":health"),
(store_random_in_range,":rand",1,25),
(lt,":rand",":chances"),
(call_script,"script_cf_agent_shield_bash",":agent"),
(end_try),]),
And the following into module animations (note that these must be pasted over two unused animations, not at the end of the file):
["strike_fall_back_rise_after_bashed", acf_enforce_all|acf_align_with_ground,
[2.0, "anim_human", blow+5400, blow+5453, arf_blend_in_2],
],
["release_bash", acf_enforce_all|acf_right_cut|acf_parallels_for_look_slope,
[0.62, "anim_human", combat+5710, combat+5740, blend_in_release],
],
Things to take note of: bashing is only for and only against footmen., thus cavalry will not bash or be bashed. Also, only shields in the range referenced in red above will be bash usable. If you want to bash with a shield, put it in that range.
Enjoy.