diff --git a/CHANGELOG.md b/CHANGELOG.md index 1902715e7..2d1eecf8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +## Unreleased + +### Fixed + +- Fix to avoid rare crashes in job thread. +- Fix to avoid a case where AMAI tries to buy more than one hero in tier 1 and when using the recalculate heros ai command. + ## [3.4.0] - 2024-11-19 ### Added diff --git a/Jobs/BUY_NEUTRAL_HERO.eai b/Jobs/BUY_NEUTRAL_HERO.eai index 9d19712ed..0265cd89d 100644 --- a/Jobs/BUY_NEUTRAL_HERO.eai +++ b/Jobs/BUY_NEUTRAL_HERO.eai @@ -15,7 +15,7 @@ function BuyNeutralHero takes integer id returns nothing //call Trace("Get Tavern Hero Job") - if TownCountDone(id) >= neutral_wanted[nn] then + if TownCountDone(id) >= neutral_wanted[nn] or tavern == null or not neutral_available[nn] then call RecycleGuardPosition(neutral_sent[nn]) call GroupRemoveUnit(unit_buying_tavern, neutral_sent[nn]) set neutral_sent[nn] = null @@ -27,6 +27,13 @@ function BuyNeutralHero takes integer id returns nothing return endif + if not IsStandardUnit(buying_unit) then + call RecycleGuardPosition(buying_unit) + call GroupRemoveUnit(unit_buying_tavern, buying_unit) + set neutral_sent[nn] = null + set buying_unit = null + endif + if place_guarded and daytime >= 5 and daytime < 18 then set time_next_try = (18 - daytime)*20 else diff --git a/common.eai b/common.eai index fa708900d..986461a4c 100644 --- a/common.eai +++ b/common.eai @@ -9103,11 +9103,18 @@ endfunction //============================================================================ function ChooseFirstHero takes nothing returns integer - //if ver_neutral_heroes_available and neutral_available[NEUTRAL_TAVERN] and neutral_guarded[NEUTRAL_TAVERN] then - //call remove_hero(7) - //set first_choosable_hero = ver_neutral_hero_number - //endif - if IsMapFlagSet(MAP_RANDOM_HERO) then + local integer i = 0 + if hero_built[1] and recalculate_heros then + loop + exitwhen i >= hero_number + if hero[1] == all_heroes[i] then + set chosen = i + return chosen + endif + set i = i + 1 + endloop + endif + if IsMapFlagSet(MAP_RANDOM_HERO) and hero[1] == null then // call DisplayToAll("Map flag set") set hero[1] = GetExistingHero() else @@ -9120,16 +9127,38 @@ endfunction //============================================================================ function ChooseSecondHero takes nothing returns nothing + local integer i = 0 call make_hero_rp_positive() call remove_hero(chosen) + if hero_built[2] and recalculate_heros then + loop + exitwhen i >= hero_number + if hero[2] == all_heroes[i] then + set chosen = i + return + endif + set i = i + 1 + endloop + endif set chosen = ChooseHero() set hero[2] = all_heroes[chosen] endfunction //============================================================================ function ChooseRestHeroes takes nothing returns nothing + local integer i = 0 call make_hero_rp_positive() call remove_hero(chosen) + if hero_built[3] and recalculate_heros then + loop + exitwhen i >= hero_number + if hero[3] == all_heroes[i] then + set chosen = i + return + endif + set i = i + 1 + endloop + endif set hero[3] = all_heroes[ChooseHero()] endfunction @@ -10113,12 +10142,16 @@ function GetNeutralHero takes integer unitid returns integer if (unitid == hero[1] and hero_built[1]) or (unitid == hero[2] and hero_built[2]) or (unitid == hero[3] and hero_built[3]) then call Trace("Try To Resurrect Tavern Hero") - if SetProduce(1,old_id[unitid],-1) then + if SetProduce(1,old_id[unitid],-1) then return BUILT_ALL else return CANNOT_BUILD endif endif + + if (unitid != hero[1] and unitid != hero[2] and unitid != hero[3]) then + return CANNOT_BUILD // Mismatch we somehow trying to build a hero that isn't the chosen hero we now want to build + endif // if neutral_sent[NEUTRAL_TAVERN] == null then // set neutral_sent[NEUTRAL_TAVERN] = GetUnitToBuy(nearest_neutral[NEUTRAL_TAVERN])