From 4f538c81bd5a7e1622177ac3f99c4ffebca0dcd4 Mon Sep 17 00:00:00 2001 From: SMUnlimited Date: Mon, 20 May 2024 17:00:40 +0100 Subject: [PATCH] Retreat Control fixes and improvements #305 Another case of hardcoded AI conflicting with AMAI logic. Retreat Control will now protect own towns first over allied towns. --- CHANGELOG.md | 3 +++ Jobs/ARMY_TRACK.eai | 19 ++++++++++++++----- Jobs/RETREAT_CONTROL.eai | 5 +++-- REFORGED/StandardAiSettings.txt | 2 +- ROC/StandardAiSettings.txt | 2 +- TFT/StandardAiSettings.txt | 2 +- common.eai | 18 ++++++++++-------- 7 files changed, 33 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95af1cf55..d205e87d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Added - AMAI now takes direct control of alliance targets instead of using the hardcoded logic. This will enable better control and allow us to ignore the alliance target in some situations. +### Changed +- Retreat Control will now protect own towns first over allied towns. + ### Fixed - Fixed factory rate to build extra buildings was always too low as didn't take account of building cost vs income correctly. - Fixed issue with boolean check of third mine timing. diff --git a/Jobs/ARMY_TRACK.eai b/Jobs/ARMY_TRACK.eai index 2659d1d49..1ac6066e3 100644 --- a/Jobs/ARMY_TRACK.eai +++ b/Jobs/ARMY_TRACK.eai @@ -14,6 +14,7 @@ integer lastArmyNum = 0 integer lastFreeNum = 0 integer mode = 0 + integer most_threatened_player_town = 0 #ELSE // Army Tracker @@ -206,9 +207,14 @@ function UpdateSpecificTownThreat takes integer num returns nothing endif set i = i + 1 endloop - if IsPlayerAlly(Player(town_owner[num]), ai_player) or Player(town_owner[num]) == ai_player then + if Player(town_owner[num]) == ai_player then + if (most_threatened_player_town == -1 or town_threat[most_threatened_player_town] < town_threat[num]) and town_count[num] > 0 then + set most_threatened_player_town = num + endif + set most_threatened_player_town = num + elseif IsPlayerAlly(Player(town_owner[num]), ai_player) then if (most_threatened_town == -1 or town_threat[most_threatened_town] < town_threat[num]) and town_count[num] > 0 then - if (town_can_tp[num] == true or Player(town_owner[num]) == ai_player) then + if (town_can_tp[num] == true) then set most_threatened_town = num endif endif @@ -228,6 +234,7 @@ function UpdateTownThreat takes nothing returns nothing set town_threatened = false //call Trace("ARMY_TRACK: Town threat update") set most_threatened_town = -1 + set most_threatened_player_town = -1 set most_threatened_enemy_town = -1 endif loop @@ -240,10 +247,12 @@ function UpdateTownThreat takes nothing returns nothing set mode = 3 set lastFreeNum = 0 call Trace ("ThreatenedTownThreat:" + Real2Str(town_threat[most_threatened_town]) + " AcceptedThreatLevel:" + Real2Str(accepted_threat_level)) - if town_threat[most_threatened_town] > accepted_threat_level then //and town_threat[most_threatened_town] > (I2R(c_ally_total + 1) / c_enemy_total) * town_threat[most_threatened_enemy_town] then + if town_threat[most_threatened_player_town] > accepted_threat_level then //and town_threat[most_threatened_town] > (I2R(c_ally_total + 1) / c_enemy_total) * town_threat[most_threatened_enemy_town] then + set town_threatened = true + set most_threatened_town = most_threatened_player_town + call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(town_loc[most_threatened_player_town]), GetLocationY(town_loc[most_threatened_player_town])) + elseif town_threat[most_threatened_town] > accepted_threat_level * 1.2 then set town_threatened = true - endif - if town_threatened then call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(town_loc[most_threatened_town]), GetLocationY(town_loc[most_threatened_town])) endif else diff --git a/Jobs/RETREAT_CONTROL.eai b/Jobs/RETREAT_CONTROL.eai index 7c2f4a222..0b8c2e81c 100644 --- a/Jobs/RETREAT_CONTROL.eai +++ b/Jobs/RETREAT_CONTROL.eai @@ -110,13 +110,14 @@ function RetreatControlJob takes nothing returns nothing - if not desperation_assault and ((CaptainRetreating() and isfleeing) or town_threatened) then //((major_hero == null or not UnitAlive(major_hero)) and ver_heroes) or then //attack_running and + if not desperation_assault and ((CaptainRetreating() and isfleeing) or town_threatened or CaptainIsHome()) then //((major_hero == null or not UnitAlive(major_hero)) and ver_heroes) or then //attack_running and call Trace("===Retreat control ended===") set break_attack = attack_running set retreat_controlled = false call SetGroupsFlee(true) - if major_hero != null and UnitAlive(major_hero) and DistanceBetweenPoints_kd(home_location, GetUnitLoc(major_hero)) < 1250 then + if CaptainIsHome() or (major_hero != null and UnitAlive(major_hero) and DistanceBetweenPoints_kd(home_location, GetUnitLoc(major_hero)) < 1250) then set isfleeing = false // home so no need to be retreating. Also prevents bug in the captainretreating condition + call SetGroupsFlee(false) endif return endif diff --git a/REFORGED/StandardAiSettings.txt b/REFORGED/StandardAiSettings.txt index bae374959..10187420c 100644 --- a/REFORGED/StandardAiSettings.txt +++ b/REFORGED/StandardAiSettings.txt @@ -1,5 +1,5 @@ AiCommand Value Comment -SetDefendPlayer true //ai will attempt to aid allied controlled players +SetDefendPlayer false //{REDUNDENT FROM AMAI as otherwise overrides AMAI attack logic}ai will attempt to aid allied controlled players SetRandomPaths true //ai will choose destinations in more random fashion SetTargetHeroes not isNewbie //{REDUNDENT FROM AMAI}ai places higher prority on attacking heros SetPeonsRepair true //{REDUNDENT FROM AMAI}workers automatically repair structures diff --git a/ROC/StandardAiSettings.txt b/ROC/StandardAiSettings.txt index a8d2117ff..49cda5df6 100644 --- a/ROC/StandardAiSettings.txt +++ b/ROC/StandardAiSettings.txt @@ -1,5 +1,5 @@ AiCommand Value Comment -SetDefendPlayer true //ai will attempt to aid allied controlled players +SetDefendPlayer false //ai will attempt to aid allied controlled players SetRandomPaths true //ai will choose destinations in more random fashion SetTargetHeroes not isNewbie //{REDUNDENT FROM AMAI}ai places higher prority on attacking heros SetPeonsRepair true //{REDUNDENT FROM AMAI}workers automatically repair structures diff --git a/TFT/StandardAiSettings.txt b/TFT/StandardAiSettings.txt index bae374959..996020972 100644 --- a/TFT/StandardAiSettings.txt +++ b/TFT/StandardAiSettings.txt @@ -1,5 +1,5 @@ AiCommand Value Comment -SetDefendPlayer true //ai will attempt to aid allied controlled players +SetDefendPlayer false //ai will attempt to aid allied controlled players SetRandomPaths true //ai will choose destinations in more random fashion SetTargetHeroes not isNewbie //{REDUNDENT FROM AMAI}ai places higher prority on attacking heros SetPeonsRepair true //{REDUNDENT FROM AMAI}workers automatically repair structures diff --git a/common.eai b/common.eai index 266439a1a..6c3ce6413 100644 --- a/common.eai +++ b/common.eai @@ -12411,6 +12411,7 @@ function SleepUntilTownDefended takes integer ai_strength returns nothing local integer defense_length_counter = 0 set own_strength = ai_strength call Trace("==Sleep Defend Town==" ) + loop if town_loc[most_threatened_town] != null and LinearInterpolation(ver_low_aggression,ver_high_aggression,ver_flee_multiple1,ver_flee_multiple2,attacking_aggression)*own_strength > army_strength[town_threat_army[most_threatened_town]] then if town_threat[most_threatened_town] >= teleport_low_threat then @@ -12418,24 +12419,25 @@ function SleepUntilTownDefended takes integer ai_strength returns nothing //call AttackMoveXY(R2I(GetLocationX(town_loc[most_threatened_town])), R2I(GetLocationY(town_loc[most_threatened_town]))) endif endif - call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(town_loc[most_threatened_town]), GetLocationY(town_loc[most_threatened_town])) + //call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(town_loc[most_threatened_town]), GetLocationY(town_loc[most_threatened_town])) else //call Trace("Town threatened - retreat" ) //if town_threat[most_threatened_town] >= teleport_low_threat then if not teleporting then //call AttackMoveXY(R2I(GetLocationX(home_location)), R2I(GetLocationY(home_location))) endif - set defense_length_counter = defense_length_counter + 1 - if defense_length_counter > attack_reform_length then - set defense_length_counter = 0 - call FormGroupAM(2) - endif + //endif - call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(home_location), GetLocationY(home_location)) + //call SetCaptainHome(DEFENSE_CAPTAIN, GetLocationX(home_location), GetLocationY(home_location)) //call ClearCaptainTargets() //call CaptainGoHome() endif - if not CaptainIsHome() then + set defense_length_counter = defense_length_counter + 1 + if defense_length_counter > attack_reform_length then + set defense_length_counter = 0 + call FormGroupAM(2) + endif + if not CaptainIsHome() and not CaptainRetreating() then call CaptainGoHome() endif exitwhen not town_threatened and not TownThreatened() and not CaptainInCombat(false)