AMAI
AMAI copied to clipboard
BuyNeutral buy
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