advanced_ai = (
0, 0, 0, [
(eq, "$advanced_ai_open", 1),
# (neg|main_hero_fallen),
(neg|all_enemies_defeated),
], [
(get_player_agent_no, ":player"),
(agent_is_active, ":player"),
(agent_is_alive, ":player"),
# (store_mission_timer_a, ":timer"),
(store_mission_timer_b, ":timer_b"),
# (store_mission_timer_c, ":timer_c"),
# (store_mission_timer_a_msec, ":timer_mili"),
(try_for_agents, ":agents"),
# SOURCE CHECK
(neq, ":agents", ":player"), # Source Agent is not player
(agent_is_active, ":agents"), # Source Agent is present
(agent_is_alive, ":agents"), # Source Agent is alive
(agent_is_human, ":agents"), # Source Agent is not horse
(agent_slot_eq, ":agents", slot_agent_is_running_away, 0), # Source Agent is not fleeing
(agent_get_troop_id, ":troop_no", ":agents"), # Get troop reference of the source agent
(troop_get_slot, ":is_AI", ":troop_no", player_knows_how_to_play), # Source troop has AI
(eq, ":is_AI", 1), # Source troop has AI
(troop_get_slot, ":chance_AI", ":troop_no", player_skill_level), # # Source troop skill level
(agent_get_team, ":agent_team", ":agents"), # Get source team
(team_get_movement_order, ":cur_team_order", ":agent_team"),
(eq, ":cur_team_order", mordr_charge, grc_everyone),
(agent_ai_get_look_target, ":target", ":agents"), # Get the current enemy of the source agent
(gt, ":target", 0), # If there is a target
# TARGET CHECK
(agent_is_active, ":target"),
(agent_is_alive, ":target"),
(agent_is_human, ":target"),
(agent_get_team, ":target_team", ":target"),
(neq, ":target_team", ":agent_team"), #unfriendly teams
# WEAPONS
(try_begin),
(agent_get_wielded_item, ":left_item_source", ":agents", 1),
(gt, ":left_item_source", 0),
# (item_get_type, ":left_item_type_source", ":left_item_source"),
(try_end),
(try_begin),
(agent_get_wielded_item, ":right_item_source", ":agents", 0),
(gt, ":right_item_source", 0),
# (item_get_type, ":right_item_type_source", ":right_item_source"),
# (item_get_weapon_length, ":weapon_length_right_source", ":right_item_source"),
(try_end),
# HORSE
(agent_get_horse, ":horse", ":agents"),
(eq, ":horse", -1), # no horse
# (agent_get_animation, ":source_animation", ":agents"),
(agent_get_animation, ":target_animation", ":target"),
(agent_get_bone_position, pos55, ":agents", hb_foot_l, 1),
(agent_get_bone_position, pos56, ":agents", hb_head, 1),
# POSITION
(agent_get_position, pos11, ":target"),
(agent_get_position, pos12, ":agents"),
(neg|position_is_behind_position, pos11, pos12), #agents are not behind each other
(get_distance_between_positions, ":dist", pos11, pos12),
# COMBAT INFO
(agent_get_defend_action, ":pos_def", ":target"), #attack action
(agent_get_action_dir, ":pos_atkdir", ":target"),
(agent_get_attack_action, ":pos_atk", ":target"), #attack action
# (agent_get_combat_state, ":pos_state", ":target"),
# (agent_get_combat_state, ":source_state", ":agents"),
# (agent_get_defend_action, ":source_defend_action", ":agents"), #defend action
(agent_get_action_dir, ":source_attack_dir", ":agents"), # attack/block direction
(agent_get_attack_action, ":source_attack_action", ":agents"), #attack action
# (assign, reg5, ":source_attack_dir"),
# (display_message, "@{reg5}"),
(assign, ":continue", 0),
(try_begin),
(ge, ":chance_AI", 1),
(assign, ":continue", 1),
(else_try),
(store_random_in_range, ":chance_strength", 0, ":chance_AI"), #chance is based on troop
(eq, ":chance_strength", 0),
(assign, ":continue", 1),
(try_end),
(eq, ":continue", 1),
# switch between passive / agressive
# (try_begin),
# (eq, ":timer_b", 10),
# (try_begin),
# (agent_slot_eq, ":agents", play_passive, 0),
# (agent_set_slot, ":agents", play_passive, 1),
# (agent_ai_set_aggressiveness, ":agents", 30),
# (display_message, "@I am passive now."),
# (else_try),
# (agent_slot_eq, ":agents", play_passive, 1),
# (agent_set_slot, ":agents", play_passive, 0),
# (agent_ai_set_aggressiveness, ":agents", 100),
# (display_message, "@I am agressive now."),
# (try_end),
# (reset_mission_timer_b),
# (try_end),
# (store_random_in_range, ":decision", 1, 10),
# (agent_set_slot, ":agents", run_block, 1),
# (agent_set_slot, ":agents", run_feint, 1),
# (agent_set_slot, ":agents", run_footwork, 1),
# (agent_set_slot, ":agents", run_attack, 1),
# (agent_set_slot, ":agents", run_counter_attack, 1),
# (agent_set_slot, ":agents", run_chamber, 1),
# (try_begin),
# (troop_slot_ge, ":troop_no", this_guy_only_blocks, 1),
# (agent_set_slot, ":agents", run_feint, -1),
# (agent_set_slot, ":agents", run_footwork, -1),
# (agent_set_slot, ":agents", run_attack, -1),
# (agent_set_slot, ":agents", run_counter_attack, -1),
# (agent_set_slot, ":agents", run_chamber, -1),
# (try_end),
# (try_begin),
# (troop_slot_ge, ":troop_no", this_guy_only_s, 1),
# (agent_set_slot, ":agents", run_feint, -1),
# (agent_set_slot, ":agents", run_block, -1),
# (agent_set_slot, ":agents", run_footwork, -1),
# (agent_set_slot, ":agents", run_counter_attack, -1),
# (agent_set_slot, ":agents", run_chamber, -1),
# (try_end),
# make ai block more when their hp is low
# Chambering
(try_begin),
(store_random_in_range, ":dice_chamber", 0, 500),
(eq, ":dice_chamber", 250),
# (eq, ":source_attack_action", 0), # if free
# (agent_slot_ge, ":agents", run_chamber, 1), # troop constraints
(le, ":dist", 200), # IF close enough
(eq, ":pos_atk", 2), # release attack
# (eq, ":decision", 5), # decided to chamber
(try_begin),
(eq, ":pos_atkdir", 0), # enemy is attackin down
(agent_set_attack_action, ":agents", 0, 0), # attack down
(else_try),
(eq, ":pos_atkdir", 1), # enemy is attackin right
(agent_set_attack_action,":agents", 2, 0), # attack left
(else_try),
(eq, ":pos_atkdir", 2), # enemy is attackin left
(agent_set_attack_action, ":agents", 1, 0), # attack right
(else_try),
(eq, ":pos_atkdir", 3), # enemy is attacking up
(agent_set_attack_action, ":agents", 3, 0), # attack up
(try_end),
(try_end),
# Release swing if he is readying
(try_begin),
(store_random_in_range, ":dice_to_release", 0, 5),
(eq, ":dice_to_release", 3),
(eq, ":source_attack_action", 1),
(this_or_next|eq, ":pos_def", 1),
(this_or_next|eq, ":pos_def", 2),
(eq, ":pos_def", 0),
(this_or_next|eq, ":pos_atk", 3),
(this_or_next|eq, ":pos_atk", 4),
(this_or_next|eq, ":pos_atk", 6),
(this_or_next|eq, ":pos_atk", 7),
(eq, ":pos_atk", 0),
(agent_set_attack_action, ":agents", ":source_attack_dir", 0),
# (display_message, "@Release"),
(try_end),
# Make holds
(try_begin),
(eq, ":timer_b", 15),
(store_random_in_range, ":random_dir", 1, 3),
(agent_set_attack_action, ":agents", ":random_dir", 1),
(agent_set_slot, ":agents", agent_cur_action, action_hold),
(try_end),
(try_begin),
(agent_slot_eq, ":agents", agent_cur_action, action_hold),
(eq, ":timer_b", 16),
(agent_set_attack_action, ":agents", ":source_attack_dir", 0),
(agent_set_slot, ":agents", agent_cur_action, action_feint),
(reset_mission_timer_b),
(try_end),
#Counter-attack
(try_begin),
# (agent_slot_ge, ":agents", run_counter_attack, 1),
(le, ":dist", 200),
(store_random_in_range, ":dice_counter", 0, 20),
(eq, ":dice_counter", 15),
(this_or_next|eq, ":pos_def", 1),
(this_or_next|eq, ":pos_def", 2),
(eq, ":pos_def", 0),
(this_or_next|eq, ":pos_atk", 3),
(this_or_next|eq, ":pos_atk", 4),
(this_or_next|eq, ":pos_atk", 6),
(this_or_next|eq, ":pos_atk", 7),
(eq, ":pos_atk", 0),
(store_random_in_range, ":random_dir", 1, 3),
(store_random_in_range, ":random_action", 0, 1),
(agent_set_attack_action, ":agents", ":random_dir", ":random_action"),
# (display_message, "@Counter-attack"),
(try_end),
#Feinting
(try_begin),
# (ge, ":timer", 10), # ai starts feinting after 10 seconds into duel
# (neg|agent_slot_eq, ":agents", agent_cur_action, action_hold),
# (agent_slot_ge, ":agents", run_feint, 1),
# dice
# (is_between, ":decision", 6, 8),
# if distance is close enough
# (eq, ":pos_def", 2),
(le, ":dist", 225),
(this_or_next|eq, ":pos_def", 1),
(this_or_next|eq, ":pos_def", 2),
(eq, ":pos_def", 0),
(this_or_next|eq, ":pos_atk", 3),
(this_or_next|eq, ":pos_atk", 4),
(this_or_next|eq, ":pos_atk", 6),
(this_or_next|eq, ":pos_atk", 7),
(eq, ":pos_atk", 0),
# (display_message, "@Feinting."),
(store_random_in_range, ":feint_times", 3, 12),
(store_div, ":start_releasing", ":feint_times", 3),
# Feint to different directions
(try_for_range, ":feinting_amount", 0, ":feint_times"),
# (eq, ":pos_atkdir", ":source_attack_dir"),
(store_random_in_range, ":random_dir", 0, 4), # store direction
(neq, ":random_dir", "$last_direction"), # if it is not equal to last direction
# (assign, ":continue", 1),
# (try_begin),
# (eq, ":random_dir", 0),
# (le, ":dist", 100),
# (assign, ":continue", 0),
# (agent_force_rethink, ":agents"),
# (try_end),
# (eq, ":continue", 1),
# (agent_set_speed_modifier, ":agents", 50),
# (neq, ":pos_atkdir", ":source_attack_dir"),
(agent_force_rethink, ":agents"),
(try_begin),
(ge, ":feinting_amount", ":start_releasing"),
(agent_set_attack_action, ":agents", ":random_dir", 0), # attack
(else_try),
(agent_set_attack_action, ":agents", ":random_dir", 1),
(try_end),
(assign, "$last_direction", ":random_dir"), # store the last used direction
# (assign, ":feint_times", -1),
# (display_message, "@Feint"),
(eq, ":feinting_amount", ":feint_times"),
(assign, ":feinting_amount", -1),
(try_end),
(try_end),
# Track how many feints player do in a second and if its above 3, %100 hit
# Footwork
(try_begin),
# (agent_slot_ge, ":agents", run_footwork, 1),
# When distance is too far, come closer to target
(try_begin),
# (try_begin),
# (troop_slot_ge, ":troop_no", this_guy_only_s, 1),
# (val_mul, pos11, -1),
# (else_try),
(ge, ":dist", 225),
# (try_end),
(agent_force_rethink, ":agents"),
(agent_set_scripted_destination, ":agents", pos11, 0, 1),
# When close enough,
(else_try),
(store_random_in_range, ":right", -150, -450),
(store_random_in_range, ":left", 150, 350),
# (store_random_in_range, ":up", 25, 75),
(store_random_in_range, ":forward", 50, 150),
# (store_random_in_range, ":up_down", 150, -150),
# (store_random_in_range, ":blocking", -500, 500),
(agent_force_rethink, ":agents"),
# (copy_position, pos13, pos12),
# (store_random_in_range, ":dice_for_footwork", 0, 3),
# (eq, ":dice_for_footwork", 2),
(agent_clear_scripted_mode, ":agents"),
# ATTACKING / BLOCKING
(try_begin),
# # WITH SHIELD
# # ONLY BLOCK
# (gt, ":left_item_source", 0), # if he has item on left hand
# (eq, ":left_item_type_source", itp_type_shield), # if the item is shield
# (eq, ":source_animation", "anim_defend_shield"),
# # (eq, ":source_attack_action", 2), # guarding
# (position_move_x, pos12, ":shield"),
# (display_message, "@I have shield."),
# (else_try),
# NO SHIELD
# BY SOURCE POS
# ATTACK
(try_begin),
(eq, ":source_attack_dir", 0), #down
(position_move_x, pos12, ":right"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 6),
# (eq, ":dice_forward", 5),
(position_move_y, pos12, ":forward"),
# (try_end),
(else_try),
(eq, ":source_attack_dir", 1), #slashright
(position_move_x, pos12, ":right"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 6),
# (eq, ":dice_forward", 5),
(position_move_y, pos12, ":forward"),
# (try_end),
(else_try),
(eq, ":source_attack_dir", 2), #slashleft
(position_move_x, pos12, ":left"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 6),
# (eq, ":dice_forward", 5),
(position_move_y, pos12, ":forward"),
# (try_end),
(else_try),
(eq, ":source_attack_dir", 3), #overswing
(position_move_x, pos12, ":left"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 6),
# (eq, ":dice_forward", 5),
(position_move_y, pos12, ":forward"),
# (try_end),
(try_end),
# BY TARGET POS
# ATTACK
# (try_begin),
# (eq, ":source_attack_dir", 0), #down
# (position_move_x, pos11, ":right"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 10),
# (eq, ":dice_forward", 5),
# (position_move_y, pos11, ":forward"),
# (try_end),
# (else_try),
# (eq, ":source_attack_dir", 1), #slashright
# (position_move_x, pos11, ":right"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 10),
# (eq, ":dice_forward", 5),
# (position_move_y, pos11, ":forward"),
# (try_end),
# (position_move_y, pos11, ":up_down"),
# (else_try),
# (eq, ":source_attack_dir", 2), #slashleft
# (position_move_x, pos11, ":left"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 10),
# (eq, ":dice_forward", 5),
# (position_move_y, pos11, ":forward"),
# (try_end),
# (position_move_y, pos11, ":up_down"),
# (else_try),
# (eq, ":source_attack_dir", 3), #overswing
# (position_move_x, pos11, ":left"),
# (try_begin),
# (store_random_in_range, ":dice_forward", 0, 10),
# (eq, ":dice_forward", 5),
# (position_move_y, pos11, ":forward"),
# (try_end),
# (position_move_y, pos11, ":forward"),
# (try_end),
# (display_message, "@I have no shield."),
(try_end),
# (try_begin),
# (troop_slot_ge, ":troop_no", this_guy_only_s, 1),
# (agent_set_scripted_destination, ":agents", pos13, 0, 1),
# (else_try),
# (agent_set_speed_modifier, ":agents", 100),
# (agent_clear_scripted_mode, ":agents"),
(try_begin),
# (store_random_in_range, ":move_by_player", 0, 2),
# (try_begin),
# (eq, ":move_by_player", 0),
(agent_set_scripted_destination, ":agents", pos12, 0, 1),
# (else_try),
# (agent_set_scripted_destination, ":agents", pos11, 0, 1),
# (try_end),
(try_end),
(try_end),
(try_end),
# Move agent back after completing a release
# (try_begin),
# (this_or_next|eq, ":source_attack_action", 6),
# (eq, ":source_attack_action", 3),
# (position_move_y, pos12, -600),
# (agent_set_scripted_destination, ":agents", pos12, 0, 1),
# (try_end),
# make footwork inverse for allowed players
# Target Switching
# Make head of the source move up and down when is attacking
# (try_begin),
# (store_random_in_range, ":look", 0, 2),
# (try_begin),
# (eq, ":look", 0),
# (agent_set_look_target_position, ":agents", pos55),
# # (display_message, "@look at foot"),
# (else_try),
# (agent_set_look_target_position, ":agents", pos56),
# # (display_message, "@look at head"),
# (try_end),
# (try_end),
# Cavalry
# Bump-lance
# Archers
# Leg shot
# AI kick
# (try_begin),
# (neq, ":source_animation", "anim_prepare_kick_0"),
# (store_random_in_range, ":dice_kick", 0, 100),
# (eq, ":dice_kick", 50),
# (le, ":dist", 80),
# (eq, ":timer", 30),
# (agent_set_attack_action, ":agents", -2, -2),
# (agent_set_attack_action, ":target", -2, -2),
# (agent_set_defend_action, ":agents", -2, -2),
# (agent_set_defend_action, ":target", -2, -2),
# (agent_set_animation, ":agents", "anim_prepare_kick_0"),
# (agent_deliver_damage_to_agent, ":agents", ":target", 3),
# (agent_set_animation, ":target", -1),
# (agent_set_animation, ":target", "anim_strike3_abdomen_front"), # Get Kicked
# (store_random_in_range, ":random_dir", 0, 3), # store direction
# (agent_set_attack_action, ":agents", ":random_dir", 0), # attack
# (display_message, "@Agent kicks."),
# (try_end),
# AI kicks over jumps
(try_begin),
(le, ":dist", 200),
(eq, ":target_animation", "anim_prepare_kick_0"),
(agent_set_attack_action, ":agents", -2, -2),
(agent_set_attack_action, ":target", -2, -2),
(agent_set_defend_action, ":agents", -2, -2),
(agent_set_defend_action, ":target", -2, -2),
(agent_set_animation, ":agents", "anim_jump"),
(display_message, "@Agent avoids kicks."),
(try_end),
#Blocking
(try_begin),
# (agent_slot_ge, ":agents", run_block, 1),
# (try_begin),
# (troop_slot_ge, ":troop_no", this_guy_only_blocks, 1),
# (else_try),
# (this_or_next|eq, ":pos_atk", 3), # completing attack after hit
# (assign, ":continue", 0),
# (try_begin),
# (agent_slot_eq, ":agents", play_passive, 1),
# (assign, ":continue", 1),
# (else_try),
# (agent_slot_eq, ":agents", play_passive, 0),
# (store_random_in_range, ":dice_block", 0, 15),
# (try_begin),
# (eq, ":dice_block", 12),
(eq, ":pos_atk", 2), # releasing attack
# (else_try),
# (eq, ":pos_atk", 2), # readying attack
# (try_end),
# (eq, ":pos_def", 0),
# (assign, ":continue", 1),
# (try_end),
# (eq, ":continue", 1),
(le, ":dist", 400), # close enough
# (le, ":decision", 4), # decision made
# (try_end),
(agent_force_rethink, ":agents"),
#(store_random_in_range, ":random_chance", 1, 150),
(try_begin),
(eq, ":pos_atkdir", 0),
(agent_set_defend_action, ":agents", 0, 0),
(else_try),
(eq, ":pos_atkdir", 1),
(agent_set_defend_action, ":agents", 1, 0),
(else_try),
(eq, ":pos_atkdir", 2),
(agent_set_defend_action, ":agents", 2, 0),
(else_try),
(eq, ":pos_atkdir", 3),
(agent_set_defend_action, ":agents", 3, 0),
(try_end),
(try_end),
(try_end),
])