Skip to content

Commit

Permalink
Override hardcoded logic of the alliance target #286
Browse files Browse the repository at this point in the history
Hardcoded function SetAllianceTarget overrides attackMove operations which in some cases we may not want to do e.g if we want to expand instead because we need money desperately.

So now we have our own control system.
  • Loading branch information
SMUnlimited committed May 19, 2024
1 parent 86d9ab0 commit a07dc2c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 46 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### 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.

### Fixed
- Fixed issue with boolean check of third mine timing.
- Fixed issue where mine required for ancient or item expansions could be nulled mid use which would break the logic. (jzy-chitong56)
Expand Down
101 changes: 55 additions & 46 deletions common.eai
Original file line number Diff line number Diff line change
Expand Up @@ -877,11 +877,13 @@ globals
constant integer USE_SPECIAL_RACES = 5
constant integer PROFILE_SELECTION = 6
constant integer NEUTRAL_GUARDS = 7
constant integer TYPECASTING = 8

gamecache amaiCache = InitGameCache("AMAI_AI.w3v")
constant integer PROFILE_USED = 0
constant integer GREETINGS_NUM = 1
constant integer CHAT_LOCK = 2
constant integer ALLIANCE_TARGET = 3

//gamecache settings = InitGameCache("AMAI_Set.w3v")

Expand Down Expand Up @@ -1082,6 +1084,11 @@ endglobals
// return 0
//endfunction

function I2U takes integer i returns unit
call SaveFogStateHandle(com, TYPECASTING, 0, ConvertFogState(i))
return LoadUnitHandle(com, TYPECASTING, 0)
endfunction

//function SetHandleHandle takes handle subject, string name, handle value returns nothing
// if value==null then
// call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
Expand Down Expand Up @@ -11580,55 +11587,48 @@ function CommonSleepUntilTargetDeadAM takes unit target, boolean iscreeping, boo
//exitwhen captain_flee and CaptainRetreating()
exitwhen isfleeing and (CaptainRetreating() or CaptainIsHome()) and not desperation_assault
exitwhen CaptainIsEmpty() and not desperation_assault
if (c_ally_total > 0 and GetAllianceTarget() != null) then // If alliance target exists this overrides hardcoded attack controls regardless of unit you pass, so reconfigure attack to be aware of this
set target = GetAllianceTarget()
endif
//if (c_ally_total > 0 and GetAllianceTarget() != null) then // If alliance target exists this overrides hardcoded attack controls regardless of unit you pass, so reconfigure attack to be aware of this
// set target = GetAllianceTarget()
//endif
exitwhen target == null // Fail safe
//exitwhen not UnitAlive(target) and CaptainIsHome() // A fail safe mechanism if getlocationnoncreepstrength malfunctions: not needed as issue now fixed
if IsPlayerAlly(ai_player, GetOwningPlayer(target)) 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) // to find enemies that ai has noticed
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)
endif
exitwhen target == null
exitwhen IsPlayerAlly(ai_player, GetOwningPlayer(target)) or not UnitAlive(target) or (UnitInvis(target) and not IsUnitDetected(target, ai_player))
//if IsPlayerAlly(ai_player, GetOwningPlayer(target)) 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) // to find enemies that ai has noticed
// 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)
//endif
//exitwhen target == null
//if not iscreeping then
// exitwhen GetLocationNonCreepStrength(unitx, unity, battle_radius) <= 0 and not UnitAlive(target) and GetLocationEnemyStrength(unitx, unity, battle_radius, true) <= 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 dist = DistanceBetweenPoints_kd(ally_loc, GetUnitLoc(target))
if c_ally_total > 0 and dist > 1300 and dist < 2500 then
if CheckAttackWait(target) then
set lastcaptainx = GetLocationX(ally_loc)
set lastcaptainy = GetLocationY(ally_loc)
//call SetCaptainHome(, lastcaptainx, lastcaptainy)
call AttackMoveXY(R2I(GetLocationX(ally_loc)), R2I(GetLocationY(ally_loc)))
call CreateDebugTagLoc("Reform until ally target dead", 10, GetLocationX(ally_loc), GetLocationY(ally_loc), 1.00, 0.80)
else
call AttackMoveKill(target)
set lastcaptainx = GetUnitX(target)
set lastcaptainy = GetUnitY(target)
if (GetAllianceTarget() == target) then
call CreateDebugTag("Reform until ally dead", 10, target, 1.00, 0.80)
else
call CreateDebugTag("Reform until target dead", 10, target, 1.00, 0.80)
endif
endif
if c_ally_total > 0 and dist > 1300 and dist < 2500 and CheckAttackWait(target) then
set lastcaptainx = GetLocationX(ally_loc)
set lastcaptainy = GetLocationY(ally_loc)
//call SetCaptainHome(, lastcaptainx, lastcaptainy)
call AttackMoveXY(R2I(GetLocationX(ally_loc)), R2I(GetLocationY(ally_loc))) // Override and help nearby ally
call CreateDebugTagLoc("Reform near ally", 10, GetLocationX(ally_loc), GetLocationY(ally_loc), 1.00, 0.80)
else
call AttackMoveKill(target)
set lastcaptainx = GetUnitX(target)
set lastcaptainy = GetUnitY(target)
if (c_ally_total > 0 and GetAllianceTarget() == target) then
//if (GetAllianceTarget() == target) then
call AttackMoveKill(target)
//else
// call AttackMoveXY(R2I(lastcaptainx), R2I(lastcaptainy)) // Override and ignore the alliance target
//endif
if (c_ally_total > 0 and I2U(GetStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0")) == target) then
call CreateDebugTag("Reform until ally dead", 10, target, 1.00, 0.80)
else
call CreateDebugTag("Reform until target dead", 10, target, 1.00, 0.80)
Expand Down Expand Up @@ -11713,18 +11713,24 @@ function SetChatVarsAttack takes unit u returns nothing
endfunction

function SetAllianceTargetIfLead takes unit u returns nothing
if (GetAllianceTarget() == null or u == null) then // if leadally
call SetAllianceTarget(u)
if (not HaveStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0") and u != null) then // if leadally
call StoreInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0", GetHandleId(u))
//call SetAllianceTarget(u)
endif
if (HaveStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0") and u == null) then
call FlushStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0")
endif
endfunction

function SetAllianceTargetIfLeadAndChat takes unit u, integer chat returns nothing
if (GetAllianceTarget() == null) then // if leadally
call SetAllianceTarget(u)
if (not HaveStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0") and u != null) then // if leadally
call StoreInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0", GetHandleId(u))
//call SetAllianceTarget(u)
call SetChatVarsAttack(u)
call Chat(chat)
elseif (u == null) then
call SetAllianceTarget(u)
elseif (HaveStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0") and u == null) then
//call SetAllianceTarget(u)
call FlushStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0")
endif
endfunction

Expand Down Expand Up @@ -12474,7 +12480,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean
if c_ally_total > 0 then
call SetLeadAlly()
if difficulty != EASY then
set common = GetAllianceTarget()
set common = I2U(GetStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0")) //GetAllianceTarget()
if common != null then
call Trace("===Desperation Attack Alliance Target===")
//call Chat(C_Ally)
Expand Down Expand Up @@ -12704,10 +12710,13 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean

// coordinate with allies
//



if c_ally_total > 0 then
call SetLeadAlly()
if difficulty != EASY then
set common = GetAllianceTarget()
set common = I2U(GetStoredInteger(amaiCache, Int2Str(ALLIANCE_TARGET), "0")) //GetAllianceTarget()
if common != null then
call Trace("Attack Alliance Target")
//call Chat(C_Ally)
Expand Down

2 comments on commit a07dc2c

@jzy-chitong56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

com, TYPECASTING it seems that the unit has never been stored, won't the extraction always be null
Storing a Fog State may require checking if ConvertFog State can be used in AI scripts

In my experience, not all functions in J can be used in AI
After changing the skin, I originally intended to change the name back, but the function to get name did not work

jzy-chitong56@a32fc87

@jzy-chitong56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple testing
6V6V6V5
Still being occupied by allies and targets, unable to enter their own attack logic, making it difficult to expand. The starting point of Mine has been null and has not yet expanded

Please sign in to comment.