AMAI
AMAI copied to clipboard
CommonSleepUntilTargetDeadAM
when AI run to function GetIntervalCreep ,the game will get stuck I never found the reason I suspect causative is GetIntervalCreep returns GetIntervalCreep() will formed many times loop But it's have a judgment can avoid problems if sd < 0 then return null endif
Now I trace the code ,find there seems to be a problem here
the loop
local location unitloc = null
if target = null then
return
endif
if race_has_ghouls and race_ghouls_attack then
set attack_length_counter = 5000 // Force army to regroup to try and get ghouls to go along
endif
loop
......................
if GetOwningPlayer(target) == ai_player or not UnitAlive(target) or (UnitInvis(target) and not IsUnitDetected(target, ai_player)) then
.............
set target = XXXXX
exitwhen target == null
endif
..............
if c_ally_total > 0 and dist > 1300 and dist < 2500 then
if CheckAttackWait(target) then
call AttackMoveXY(R2I(GetLocationX(ally_loc)), R2I(GetLocationY(ally_loc)))
else
call **AttackMoveKill**(target)
endif
else
call **AttackMoveKill**(target)
endif
so when loop go back to the first line -- if Kill the target , then target is null now GetOwningPlayer(target) == ai_player never established but exitwhen target == null Included in the judgment here so the loop will used null unit run ?? maybe the exitwhen target == null cannot Included in the judgment here
**exitwhen target == null**
if GetOwningPlayer(target) == ai_player or not UnitAlive(target) or (UnitInvis(target) and not IsUnitDetected(target, ai_player)) then
.............
set target = XXXXX
endif
**exitwhen target == null**
function code
function CommonSleepUntilTargetDeadAM takes unit target, boolean iscreeping, boolean reform returns nothing
local real dist = 0
local integer attack_length_counter = 0
local integer combat_length_counter = 0
local group g = null
local location unitloc = null
//~~call DisplayTimedTextToPlayer(Player(0),0,0,15,"230")
if race_has_ghouls and race_ghouls_attack then
set attack_length_counter = 5000 // Force army to regroup to try and get ghouls to go along
endif
loop
exitwhen town_threat_break and town_threatened and town_threat[most_threatened_town] >= teleport_low_threat and not desperation_assault
exitwhen break_attack and not desperation_assault
//exitwhen captain_flee and CaptainRetreating()
exitwhen isfleeing and CaptainRetreating() and not desperation_assault
exitwhen CaptainIsEmpty() and not desperation_assault
//exitwhen not UnitAlive(target) and CaptainIsHome() // A fail safe mechanism if getlocationnoncreepstrength malfunctions: not needed as issue now fixed
if GetOwningPlayer(target) == ai_player or not UnitAlive(target) or (UnitInvis(target) and not IsUnitDetected(target, ai_player)) then
set g = CreateGroup()
call GroupEnumUnitsInRange(g,GetUnitX(target), GetUnitY(target),battle_radius,null)
set g = SelectByAlive(g,true)
set g = SelectByEnemy(g,ai_player, true)
if not UnitAlive(target) or UnitInvis(target) then
set g = SelectByVisible(g,ai_player,true)
endif
if iscreeping then
set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_AGGRESSIVE), true) // if creeping and unit invisible see if any other creeps targetable
endif
set target = FirstOfGroup(g)
call DestroyGroup(g)
exitwhen target == null
endif
//if not iscreeping then
// exitwhen GetLocationNonCreepStrength(unitx, unity, battle_radius) <= 0 and not UnitAlive(target) and GetLocationEnemyStructures(unitx, unity, battle_radius) <= 0 // enemies are dead and target dead
//else
//call Trace("Units, Creeps: " + Int2Str(GetLocationNonCreepStrength(unitx, unity, battle_radius)) + "," + Int2Str(GetLocationCreepStrength(unitx, unity, 500)))
// exitwhen GetLocationNonCreepStrength(unitx, unity, battle_radius) <= 0 and not UnitAlive(target) and GetLocationCreepStrength(unitx, unity, 500) <= 0
//endif
set unitloc = GetUnitLoc(target)
set dist = DistanceBetweenPoints(ally_loc, unitloc)
call RemoveLocation(unitloc)
if c_ally_total > 0 and dist > 1300 and dist < 2500 then
if CheckAttackWait(target) then
call AttackMoveXY(R2I(GetLocationX(ally_loc)), R2I(GetLocationY(ally_loc)))
else
call AttackMoveKill(target)
endif
else
call AttackMoveKill(target)
endif
call Sleep(2 * sleep_multiplier)
call CreateDebugTag("Reform until target dead", 10, target, 1.00, 0.80)
//set attack_length_counter = attack_length_counter + 1
//if reform and attack_length_counter > attack_reform_length then
// if CaptainInCombat(true) then
// set attack_length_counter = attack_length_counter - 2
// else
// set attack_length_counter = 0
// call FormGroupAM(2)
// endif
//endif
if desperation_assault and attack_length_counter > attack_reform_length * 5 then
call DesperationAssault()
set attack_length_counter = 0
else
set attack_length_counter = attack_length_counter + 1
endif
if not desperation_assault then // Do not bother reforming in desperation mode, full attack speed
if reform and CaptainInCombat(true) then
set combat_length_counter = combat_length_counter + 1
elseif reform then
set attack_length_counter = attack_length_counter + 1
set combat_length_counter = 0
endif
if reform and CaptainInCombat(true) and combat_length_counter > attack_reform_length * 3 then
set combat_length_counter = 0
call FormGroupAM(2)
elseif reform and not CaptainInCombat(true) and attack_length_counter > attack_reform_length then
set attack_length_counter = 0
set combat_length_counter = 0
call FormGroupAM(2)
endif
endif
endloop
set g = null
set unitloc = null
set target = null
endfunction