AMAI icon indicating copy to clipboard operation
AMAI copied to clipboard

BuyNeutral buy

Open jzy-chitong56 opened this issue 1 year ago • 0 comments

I found that AI would not buy mercenaries

on race.ai buy mercenaries is call BuildUpgr(1, merc_rush, 65)

function BuildUpgr takes integer qty, integer unitid, integer prio returns nothing
    call SetBuildAllAM(BUILD_UPGRADE,qty,unitid,-1, BLOC_STD, prio)
endfunction

see, here no call RefreshNeeded , and buy mercenaries code on function RefreshNeeded (2.54DE the code on SetBuildAllAM also a copy)

this fix

function SetBuildAllAM takes integer t, integer mqty, integer unitid, integer town, integer bloc, integer prio returns nothing
  if buy_type[unitid] == BT_UPGRADE or buy_type[unitid] == BT_ML_UPGRADE then
    call SetBuildAllAM(BUILD_UPGRADE,qty,unitid,-1, BLOC_STD, prio)
  else
    call RefreshNeeded(BUILD_UNIT, qty, unitid, -1, BLOC_STD, prio)
  endif
endfunction

but I don't know why buy neutral heroes is normal ......................

this optimization , the loop merge into one

function AttackGroupAddNeutrals takes nothing returns nothing
  local integer i = 0
  local integer b = merc_number
  if merc_number < dragon_number then
    set b = dragon_number
  endif
  if b < ohter_race_number then
    set b = ohter_race_number
  endif
  loop
    exitwhen i > b
    if i <= merc_number and TownCountDone(merc_unit[i]) > 0 then
      call SetMeleeGroupAM(merc_unit[i])
    endif
    if i + 1 <= dragon_number and TownCountDone(dragons[i+1]) > 0 then
      call SetMeleeGroupAM(dragons[i+1])
    endif
    if TownCountDone(ohter_race_unit[i]) > 0 then 
      call SetMeleeGroupAM(ohter_race_unit[i])
    endif
    set i = i + 1
  endloop
endfunction

ohter race unit, but ohter_race_unit like already contains dragons and merc_unit , so AttackGroupAddNeutrals no need call SetMeleeGroupAM(dragons[i+1]) and call SetMeleeGroupAM(merc_unit[i])......

function GetPlayerHeroStrengthMod takes player p returns integer
  local group g = CreateGroup()
  local unit u = null
  local integer sum = 0
  local integer i = 0
  local boolean b = true
  call GroupEnumUnitsOfPlayer(g, p, null)
  set g = SelectUnittype(g, UNIT_TYPE_HERO, true)
  set g = SelectByAlive(g, true)
  loop
    set u = FirstOfGroup(g)
    exitwhen u == null
    set sum = sum + R2I(GetHeroStrength(u) * GetPlayerStrengthHandicap(GetOwningPlayer(u)) * (GetUnitState(u, UNIT_STATE_LIFE) / GetUnitState(u, UNIT_STATE_MAX_LIFE)))
    set i = 0
    if GetUnitTypeId(u) != hero[1] and GetUnitTypeId(u) != hero[2] and GetUnitTypeId(u) != hero[3] then  //other hero
      loop
        exitwhen i > ohter_race_number or b == false
        if GetUnitTypeId(u) == ohter_race_unit[i] then  //prevent repetition
          set b = false
        endif
        set i = i + 1
      endloop
      if b == true then
        set ohter_race_unit[ohter_race_number] = GetUnitTypeId(u)
        set ohter_race_number = ohter_race_number + 1
      endif
    endif
    call GroupRemoveUnit(g,u)
  endloop
  set sum = sum + GetPlayerHeroBonusStrength(ai_player)
  call DestroyGroup(g)
  set g = null
  return sum 
endfunction


function GetOwnStrength takes nothing returns integer
  local real sum = 0
  local group g = CreateGroup()
  local unit u = null
  local integer max_ghouls = attacking_ghouls
  local integer ghoul_num = 0
  local integer i = 0
  local real airsum = 0
  local race r = null
  local boolean b = true
  call GroupEnumUnitsOfPlayer(g, ai_player, null)
  loop
    set u = FirstOfGroup(g)
    exitwhen u == null
    if UnitAlive(u) and not IsUnitType(u, UNIT_TYPE_PEON) and not IsUnitType(u, UNIT_TYPE_HERO) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitInGroup(u, unit_healing) and not IsUnitHidden(u) then
      if GetUnitTypeId(u) == old_id[racial_ghoul] then
        if ghoul_num < max_ghouls then
          set sum = sum + GetUnitStrength(u)
          set ghoul_num = ghoul_num + 1
        endif
      else
        set sum = sum + GetUnitStrength(u)
      endif
      if IsUnitType(u, UNIT_TYPE_ATTACKS_FLYING) then
        set airsum = airsum + GetUnitStrength(u)
      endif
      set i = 0
      set r = GetUnitRace(u)
      if r != GetPlayerRace(ai_player) then
        if GetUnitTypeId(u) != 'ngir' and GetUnitTypeId(u) != 'nzep' and not IsUnitType(u, UNIT_TYPE_SUMMONED) then
          loop
            exitwhen i > ohter_race_number or b == false
            if GetUnitTypeId(u) == ohter_race_unit[i] then  //prevent repetition
              set b = false
            endif
            set i = i + 1
          endloop
          if b == true then
            set ohter_race_unit[ohter_race_number] = GetUnitTypeId(u)
            set ohter_race_number = ohter_race_number + 1
          endif
        endif
      endif
    endif
    call GroupRemoveUnit(g, u)
  endloop
  if i > 1 and ohter_race_unit[i-1] != 0 and ohter_race_unit[i-1] != null and TownCountDone(ohter_race_unit[i-1]) == 0 then  //prevent infinite increase
    set ohter_race_unit[i-1] = 0
    set ohter_race_number = ohter_race_number - 1
  endif
  call DestroyGroup(g)
  set g = null
  set r = null
  set air_strength = R2I(airsum + 0.5)
  return R2I(sum) + GetPlayerHeroStrengthMod(ai_player)
endfunction


and Another question , if one map has multiple mercenary camps or dragon perches , then only the last one will take effect maybe the array should continue set merc_unit[7] .....

  if not mercfound then
  elseif i == 1 then
    set merc_unit[0] = SATYR_SHADOWDANCER
    set merc_unit[1] = DARK_TROLL_BERSERKER
    set merc_unit[2] = DARK_TROLL_SHADOW_PRIEST
    set merc_unit[3] = GIANT_WOLF
    set merc_types[1] = DARK_TROLL_SHADOW_PRIEST
    set merc_types[2] = SATYR_SHADOWDANCER
    set merc_types[3] = GIANT_WOLF
    set merc_types[4] = DARK_TROLL_BERSERKER
    set merc_types[5] = SATYR_SHADOWDANCER
    set merc_types[6] = GIANT_WOLF
  elseif i == 2 then
    set merc_unit[0] = CENTAUR_OUTRUNNER
    set merc_unit[1] = QUILLBOAR_HUNTER
    set merc_unit[2] = CENTAUR_ARCHER
    set merc_unit[3] = HARPY_WINDWITCH
    set merc_types[1] = 0
    set merc_types[2] = HARPY_WINDWITCH
    set merc_types[3] = CENTAUR_OUTRUNNER
    set merc_types[4] = CENTAUR_ARCHER
    set merc_types[5] = QUILLBOAR_HUNTER
    set merc_types[6] = CENTAUR_OUTRUNNER

if roostfound then
  if not roostfound then
  elseif k == 1 then
    set dragons[1] = BLACK_DRAGON_1
    set dragons[2] = BLACK_DRAGON_2
    set dragons[3] = BLACK_DRAGON_3
  elseif k == 2 then
    set dragons[1] = BLUE_DRAGON_1
    set dragons[2] = BLUE_DRAGON_2
    set dragons[3] = BLUE_DRAGON_3

jzy-chitong56 avatar Oct 18 '22 14:10 jzy-chitong56