﻿# AI-vs-AI checks.

# Cheap first check. Full setup happens after a producer wins.
bdp_ai_vs_ai_phase_candidate_possible_trigger = {
	NOT = { has_game_rule = agot_battlefield_duel_ai_vs_ai_disabled }
	is_ai = yes
	is_alive = yes
	is_imprisoned = no
	is_in_army = yes
	age >= 16
	prowess >= 10
	is_current_dragonrider_warfare = no
	NOT = { has_trait = incapable }
	NOT = { has_trait = wounded_3 }
	NOT = { has_character_flag = already_fighting }
	NOT = { has_variable = engaged_in_single_combat }
	NOT = { has_character_flag = battlefiel_duel_recipient_spare }
	NOT = { has_character_flag = agot_battlefield_duel_cooldown }
	NOT = { has_character_flag = battlefield_duel_seek_combat_target_reserved }
	NOT = { has_character_flag = bdp_ai_vs_ai_human_participant_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_used_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_personal_cooldown }
	battlefield_duel_agot_not_war_decider_trigger = yes
}

# Dragons go first. Foot fighters can duel after the dragon event finishes.
bdp_ai_vs_ai_active_dragon_handling_pending_trigger = {
	scope:combat_side = {
		OR = {
			any_side_commander = {
				is_current_dragonrider_warfare = yes
				var:current_dragon = { NOT = { has_character_flag = recently_joined_battle } }
			}
			any_side_knight = {
				is_current_dragonrider_warfare = yes
				var:current_dragon = { NOT = { has_character_flag = recently_joined_battle } }
			}
			enemy_side = {
				OR = {
					any_side_commander = {
						is_current_dragonrider_warfare = yes
						var:current_dragon = { NOT = { has_character_flag = recently_joined_battle } }
					}
					any_side_knight = {
						is_current_dragonrider_warfare = yes
						var:current_dragon = { NOT = { has_character_flag = recently_joined_battle } }
					}
				}
			}
		}
	}
}

# Commander route waits for dragons and player duels, then checks both sides.
bdp_ai_vs_ai_phase_ready_trigger = {
	exists = scope:combat_side
	is_alive = yes
	is_commanding_army = yes
	scope:combat_side = {
		exists = side_commander
		side_commander = {
			this = root
			has_character_flag = calculated_dragon_modifier
			NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
		}
		enemy_side = {
			exists = side_commander
			side_commander = {
				has_character_flag = calculated_dragon_modifier
				NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
			}
			OR = {
				any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
				any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			}
		}
		OR = {
			any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
		}
	}
	NOT = { bdp_ai_vs_ai_active_dragon_handling_pending_trigger = yes }
	NOT = { bdp_ai_vs_ai_human_route_active_trigger = yes }
}

# Knight fallback follows the same dragon and player-duel rules.
bdp_ai_vs_ai_knight_phase_ready_trigger = {
	exists = scope:combat_side
	bdp_ai_vs_ai_phase_candidate_possible_trigger = yes
	scope:combat_side = {
		# Only the strongest eligible knight gets to offer this fallback.
		NOT = {
			any_side_knight = {
				bdp_ai_vs_ai_phase_candidate_possible_trigger = yes
				prowess > root.prowess
			}
		}
		exists = side_commander
		side_commander = {
			has_character_flag = calculated_dragon_modifier
			NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
		}
		enemy_side = {
			exists = side_commander
			side_commander = {
				has_character_flag = calculated_dragon_modifier
				NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
			}
			OR = {
				any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
				any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			}
		}
		OR = {
			any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
		}
	}
	NOT = { bdp_ai_vs_ai_active_dragon_handling_pending_trigger = yes }
	NOT = { bdp_ai_vs_ai_human_route_active_trigger = yes }
}

# Last chance after a dragon event ends the battle.
bdp_ai_vs_ai_dragon_combat_end_ready_trigger = {
	exists = scope:combat_side
	is_alive = yes
	this = scope:combat_side.side_commander
	scope:combat_side = {
		exists = combat
		exists = side_commander
		side_commander = {
			has_character_flag = calculated_dragon_modifier
			NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
		}
		enemy_side = {
			exists = side_commander
			side_commander = {
				has_character_flag = calculated_dragon_modifier
				NOT = { has_character_flag = bdp_ai_vs_ai_resolved_current_battle }
			}
			OR = {
				any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
				any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			}
		}
		OR = {
			any_side_knight = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
			any_side_commander = { bdp_ai_vs_ai_phase_candidate_possible_trigger = yes }
		}
		# Riders stay out. Surviving foot fighters stay eligible.
		OR = {
			any_side_knight = { is_current_dragonrider_warfare = yes }
			any_side_commander = { is_current_dragonrider_warfare = yes }
			enemy_side = {
				OR = {
					any_side_knight = { is_current_dragonrider_warfare = yes }
					any_side_commander = { is_current_dragonrider_warfare = yes }
				}
			}
		}
	}
	NOT = { bdp_ai_vs_ai_human_route_active_trigger = yes }
}

bdp_ai_vs_ai_human_route_active_trigger = {
	# Keep CK3's live combat side. Do not rebuild it from a knight.
	scope:combat_side = {
		OR = {
			any_side_commander = {
				is_ai = no
				OR = {
					has_character_flag = battlefield_duel_ai_challenge_auto_window
					has_character_flag = battlefield_duel_ai_challenge_prompt
					has_character_flag = battlefield_duel_opportunity_window
					has_character_flag = battlefield_duel_opportunity_prompt
					has_character_flag = battlefield_duel_pending_prompt
					has_character_flag = battlefield_duel_prompt_lock
					has_character_flag = battlefield_duel_seek_combat_manual_prompt
					has_character_flag = battlefield_duel_seek_combat_bodyguard_gate
					has_character_flag = battlefield_duel_ai_bodyguard_player_reserved
					has_character_flag = battlefield_duel_ai_bodyguard_followup_pending
					AND = {
						is_current_dragonrider_warfare = no
						OR = {
							has_character_flag = already_fighting
							has_variable = engaged_in_single_combat
						}
					}
				}
			}
			enemy_side = {
				any_side_commander = {
					is_ai = no
					OR = {
						has_character_flag = battlefield_duel_ai_challenge_auto_window
						has_character_flag = battlefield_duel_ai_challenge_prompt
						has_character_flag = battlefield_duel_opportunity_window
						has_character_flag = battlefield_duel_opportunity_prompt
						has_character_flag = battlefield_duel_pending_prompt
						has_character_flag = battlefield_duel_prompt_lock
						has_character_flag = battlefield_duel_seek_combat_manual_prompt
						has_character_flag = battlefield_duel_seek_combat_bodyguard_gate
						has_character_flag = battlefield_duel_ai_bodyguard_player_reserved
						has_character_flag = battlefield_duel_ai_bodyguard_followup_pending
						AND = {
							is_current_dragonrider_warfare = no
							OR = {
								has_character_flag = already_fighting
								has_variable = engaged_in_single_combat
							}
						}
					}
				}
			}
		}
	}
}

# War exposure stays on the war. Raids use the battle limits.
bdp_ai_vs_ai_war_exposure_available_trigger = {
	save_temporary_scope_as = bdp_ai_vs_ai_exposure_candidate
	OR = {
		NOT = { exists = scope:combat_side.combat.combat_war }
		scope:combat_side.combat.combat_war = {
			NOT = {
				is_target_in_variable_list = {
					name = bdp_ai_vs_ai_third_exposure
					target = scope:bdp_ai_vs_ai_exposure_candidate
				}
			}
		}
	}
}

bdp_ai_vs_ai_candidate_eligible_trigger = {
	is_ai = yes
	is_alive = yes
	is_imprisoned = no
	is_in_army = yes
	age >= 16
	prowess >= 10
	is_current_dragonrider_warfare = no
	NOT = { has_trait = incapable }
	NOT = { has_trait = wounded_3 }
	NOT = { has_character_flag = already_fighting }
	NOT = { has_variable = engaged_in_single_combat }
	NOT = { has_character_flag = battlefiel_duel_recipient_spare }
	NOT = { has_character_flag = agot_battlefield_duel_cooldown }
	NOT = { has_character_flag = battlefield_duel_seek_combat_target_reserved }
	NOT = { has_character_flag = bdp_ai_vs_ai_human_participant_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_used_current_battle }
	NOT = { is_in_list = bdp_ai_vs_ai_manual_reserved }
	battlefield_duel_agot_not_war_decider_trigger = yes
	has_variable = bdp_ai_vs_ai_career_ceiling
	has_variable = bdp_ai_vs_ai_lifetime_duels
	bdp_ai_vs_ai_war_exposure_available_trigger = yes
	NOT = { has_character_flag = bdp_ai_vs_ai_personal_cooldown }
}

bdp_ai_vs_ai_normal_rank_trigger = {
	OR = {
		is_landed = no
		AND = {
			is_landed = yes
			highest_held_title_tier <= tier_county
		}
	}
}

# A protector has to be fighting on the ward's side.
bdp_ai_vs_ai_present_substitute_eligible_trigger = {
	bdp_ai_vs_ai_candidate_eligible_trigger = yes
	NOT = { this = scope:bdp_ai_vs_ai_substitution_ward }
	OR = {
		AND = {
			exists = knight_army
			knight_army = {
				is_army_in_combat = yes
				involved_combat_side = { this = scope:bdp_ai_vs_ai_substitution_side }
			}
		}
		AND = {
			exists = commanding_army
			commanding_army = {
				is_army_in_combat = yes
				involved_combat_side = { this = scope:bdp_ai_vs_ai_substitution_side }
			}
		}
	}
}

# Prodigy squires follow the same rules as the player-facing route.
bdp_ai_vs_ai_prodigy_substitute_eligible_trigger = {
	is_ai = yes
	is_alive = yes
	is_imprisoned = no
	is_hostage = no
	is_travelling = no
	NOT = { exists = involved_activity }
	is_in_the_same_court_as = scope:bdp_ai_vs_ai_substitution_ward
	is_current_dragonrider_warfare = no
	NOT = { has_trait = incapable }
	NOT = { has_trait = wounded_3 }
	NOT = { has_character_flag = already_fighting }
	NOT = { has_variable = engaged_in_single_combat }
	NOT = { has_character_flag = bdp_ai_vs_ai_human_participant_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_used_current_battle }
	NOT = { is_in_list = bdp_ai_vs_ai_manual_reserved }
	has_trait = squire
	age >= 12
	age < 16
	prowess >= extremely_high_skill_rating
	has_variable = bdp_ai_vs_ai_career_ceiling
	has_variable = bdp_ai_vs_ai_lifetime_duels
	bdp_ai_vs_ai_war_exposure_available_trigger = yes
	NOT = { has_character_flag = bdp_ai_vs_ai_personal_cooldown }
}

# Recheck the substitute after they step in.
bdp_ai_vs_ai_actual_fighter_ready_trigger = {
	is_ai = yes
	is_alive = yes
	is_imprisoned = no
	NOT = { has_trait = incapable }
	NOT = { has_trait = wounded_3 }
	NOT = { has_character_flag = already_fighting }
	NOT = { has_variable = engaged_in_single_combat }
	NOT = { has_character_flag = bdp_ai_vs_ai_human_participant_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_used_current_battle }
	NOT = { has_character_flag = bdp_ai_vs_ai_personal_cooldown }
	has_variable = bdp_ai_vs_ai_career_ceiling
	has_variable = bdp_ai_vs_ai_lifetime_duels
	bdp_ai_vs_ai_war_exposure_available_trigger = yes
}

# Normal notifications stay local. Realm-famous popups ignore this.
bdp_ai_vs_ai_player_relevance_trigger = {
	is_ai = no
	OR = {
		AND = {
			is_commanding_army = yes
			commanding_army = {
				is_army_in_combat = yes
				involved_combat_side = {
					OR = {
						this = scope:bdp_ai_vs_ai_side_a
						this = scope:bdp_ai_vs_ai_side_b
					}
				}
			}
		}
		is_close_family_of = scope:bdp_ai_vs_ai_winner
		is_close_family_of = scope:bdp_ai_vs_ai_loser
		is_spouse_of = scope:bdp_ai_vs_ai_winner
		is_spouse_of = scope:bdp_ai_vs_ai_loser
		has_relation_friend = scope:bdp_ai_vs_ai_winner
		has_relation_best_friend = scope:bdp_ai_vs_ai_winner
		has_relation_rival = scope:bdp_ai_vs_ai_winner
		has_relation_nemesis = scope:bdp_ai_vs_ai_winner
		has_relation_friend = scope:bdp_ai_vs_ai_loser
		has_relation_best_friend = scope:bdp_ai_vs_ai_loser
		has_relation_rival = scope:bdp_ai_vs_ai_loser
		has_relation_nemesis = scope:bdp_ai_vs_ai_loser
		scope:bdp_ai_vs_ai_winner.liege ?= this
		scope:bdp_ai_vs_ai_loser.liege ?= this
	}
}
