- Joined
- Aug 3, 2004
- Messages
- 2,906
The Justify More Workers condition below is being ignored. It is also ignored if I use (Number of Mines Owned).
call DisplayTextToPlayer (p,0,0,"t")
// Where p is your player slot (if you're player one then type PlayerEx(1), if you're player 2 type PlayerEx (2) and so on)
// And t is whatever message you want between "double quotes"
//===========================================================================
//
// Shellgan
//
// Warcraft III AI script
// Generated by the Warcraft III World Editor
// Date: Fri Nov 17 01:16:57 2017
//
//===========================================================================
//***************************************************************************
//*
//* Global Variables
//*
//***************************************************************************
globals
integer attackWave = 1
integer nextDelay = 0
integer awGold = 0
integer awWood = 0
// Conditions
boolean gCond_Food_A = false
boolean gCond_Food_B = false
boolean gCond_Food_C = false
boolean gCond_Food_D = false
boolean gCond_Food_E = false
boolean gCond_Food_F = false
boolean gCond_Food_G = false
boolean gCond_Justify_Expansion = false
boolean gCond_Justify_More_Workers = false
boolean gCond_Hero_A = false
// Debug condition
boolean gCond_Debug = false
endglobals
//***************************************************************************
//*
//* Debug Functions
//*
//***************************************************************************
//===========================================================================
function B2S takes boolean b returns string
if b then
return "true"
else
return "false"
endif
endfunction
//===========================================================================
function Dig2Str takes integer i returns string
if i == 1 then
return "1"
elseif i == 2 then
return "2"
elseif i == 3 then
return "3"
elseif i == 4 then
return "4"
elseif i == 5 then
return "5"
elseif i == 6 then
return "6"
elseif i == 7 then
return "7"
elseif i == 8 then
return "8"
elseif i == 9 then
return "9"
else
return "0"
endif
endfunction
//===========================================================================
// Courtesy of AIAndy and Tommi. See source:
// http://www.hiveworkshop.com/threads/two-custom-campaign-ais-examples.8939/
function Int2Str takes integer ic returns string
local string s = ""
local integer i = ic
local integer ialt = 0
local boolean neg = false
if i == 0 then
return "0"
endif
if i < 0 then
set neg = true
set i = (-1)*i
endif
loop
exitwhen i == 0
set ialt = i
set i = i / 10
set s = Dig2Str( ialt - 10*i ) + s
endloop
if neg then
set s = "-"+s
endif
return s
endfunction
//===========================================================================
function Msg takes string message returns nothing
local integer slot = 0
loop
call DisplayTextToPlayer(Player(slot),0,0,message)
set slot = slot + 1
exitwhen slot >= 12
endloop
endfunction
//***************************************************************************
//*
//* Utility Functions
//*
//***************************************************************************
//===========================================================================
function CheckLastCommand takes boolean pop returns integer
local integer cmd = GetLastCommand()
if (pop) then
call PopLastCommand( )
endif
return cmd
endfunction
//===========================================================================
function CheckLastCommandData takes boolean pop returns integer
local integer data = GetLastData()
if (pop) then
call PopLastCommand( )
endif
return data
endfunction
//===========================================================================
function TotalFoodProduced takes nothing returns integer
return GetPlayerState(ai_player,PLAYER_STATE_RESOURCE_FOOD_CAP)
endfunction
//===========================================================================
function ExpansionNeeded takes nothing returns boolean
return take_exp
endfunction
//===========================================================================
function BuildExpansion takes integer hallID, integer mineID returns nothing
if (HallsCompleted(hallID)) then
call SetBuildExpa( TownCount(hallID) + 1, mineID )
endif
endfunction
//===========================================================================
function CurrentAttackWave takes nothing returns integer
return attackWave
endfunction
//===========================================================================
function ResetAttackUnits takes nothing returns nothing
set awGold = 0
set awWood = 0
call InitAssaultGroup( )
endfunction
//===========================================================================
function AddAttackUnit takes integer minQty, integer maxQty, integer unitID returns nothing
// Track attacking gold workers
if (unitID == 'ewsp') then
set awGold = awGold + minQty
endif
// Track attacking wood workers
if (unitID == 'ewsp') then
set awWood = awWood + minQty
endif
call SetAssaultGroup( minQty, maxQty, unitID )
endfunction
//***************************************************************************
//*
//* Basic Options
//*
//***************************************************************************
//===========================================================================
function InitOptions takes nothing returns nothing
call SetMeleeAI( )
call SetDefendPlayer( true )
call SetRandomPaths( true )
call SetTargetHeroes( true )
call SetPeonsRepair( true )
call SetHeroesFlee( true )
call SetHeroesBuyItems( true )
call SetUnitsFlee( false )
call SetGroupsFlee( true )
call SetWatchMegaTargets( true )
call SetIgnoreInjured( false )
call SetHeroesTakeItems( true )
call SetSlowChopping( false )
call SetCaptainChanges( true )
call SetSmartArtillery( true )
endfunction
//***************************************************************************
//*
//* Conditions
//*
//***************************************************************************
//===========================================================================
// Updates the values of all preset conditions
//===========================================================================
function UpdateConditions takes nothing returns nothing
set gCond_Food_A = ( FoodUsed( ) >= 14 )
set gCond_Food_B = ( FoodUsed( ) >= 28 )
set gCond_Food_C = ( FoodUsed( ) >= 42 )
set gCond_Food_D = ( FoodUsed( ) >= 86 )
set gCond_Food_E = ( FoodUsed( ) >= 100 )
set gCond_Food_F = ( FoodUsed( ) >= 114 )
set gCond_Food_G = ( FoodUsed( ) >= 122 )
set gCond_Justify_Expansion = ( GetMinesOwned( ) == 1 )
set gCond_Justify_More_Workers = ( GetUnitCount( 'egol' ) > 1 )
set gCond_Hero_A = ( GetUnitCountDone( 'nnad' ) >= 1 )
if gCond_Debug then
call Msg("==========================")
call Msg(("Justify more workers: " + B2S(gCond_Justify_More_Workers)))
call Msg(("Number of mine units: " + Int2Str(GetUnitCount( 'egol' )) + " || Number of done mine units: " + Int2Str(GetUnitCountDone( 'egol' ))))
call Msg("==========================")
endif
endfunction
//***************************************************************************
//*
//* Heroes
//*
//***************************************************************************
//===========================================================================
// Stores hero ID and skills
//===========================================================================
function SetHero takes integer order, integer heroid returns nothing
if (order == 1) then
set hero_id = heroid
if (heroid == 'O009') then
set skills1[ 1] = 'A033'
set skills1[ 2] = 'A04V'
set skills1[ 3] = 'A029'
set skills1[ 4] = 'A033'
set skills1[ 5] = 'A04V'
set skills1[ 6] = 'A00S'
set skills1[ 7] = 'A029'
set skills1[ 8] = 'A033'
set skills1[ 9] = 'A04V'
set skills1[10] = 'A029'
elseif (heroid == 'E006') then
set skills1[ 1] = 'A04Z'
set skills1[ 2] = 'A0A9'
set skills1[ 3] = 'A09B'
set skills1[ 4] = 'A04Z'
set skills1[ 5] = 'A0A9'
set skills1[ 6] = 'A09R'
set skills1[ 7] = 'A09B'
set skills1[ 8] = 'A04Z'
set skills1[ 9] = 'A0A9'
set skills1[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills1[ 1] = 'A02V'
set skills1[ 2] = 'A08K'
set skills1[ 3] = 'A05B'
set skills1[ 4] = 'A02V'
set skills1[ 5] = 'A08K'
set skills1[ 6] = 'A038'
set skills1[ 7] = 'A05B'
set skills1[ 8] = 'A02V'
set skills1[ 9] = 'A08K'
set skills1[10] = 'A05B'
endif
elseif (order == 2) then
set hero_id2 = heroid
if (heroid == 'O009') then
set skills2[ 1] = 'A033'
set skills2[ 2] = 'A04V'
set skills2[ 3] = 'A029'
set skills2[ 4] = 'A033'
set skills2[ 5] = 'A04V'
set skills2[ 6] = 'A00S'
set skills2[ 7] = 'A029'
set skills2[ 8] = 'A033'
set skills2[ 9] = 'A04V'
set skills2[10] = 'A029'
elseif (heroid == 'E006') then
set skills2[ 1] = 'A04Z'
set skills2[ 2] = 'A0A9'
set skills2[ 3] = 'A09B'
set skills2[ 4] = 'A04Z'
set skills2[ 5] = 'A0A9'
set skills2[ 6] = 'A09R'
set skills2[ 7] = 'A09B'
set skills2[ 8] = 'A04Z'
set skills2[ 9] = 'A0A9'
set skills2[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills2[ 1] = 'A02V'
set skills2[ 2] = 'A08K'
set skills2[ 3] = 'A05B'
set skills2[ 4] = 'A02V'
set skills2[ 5] = 'A08K'
set skills2[ 6] = 'A038'
set skills2[ 7] = 'A05B'
set skills2[ 8] = 'A02V'
set skills2[ 9] = 'A08K'
set skills2[10] = 'A05B'
endif
elseif (order == 3) then
set hero_id3 = heroid
if (heroid == 'O009') then
set skills3[ 1] = 'A033'
set skills3[ 2] = 'A04V'
set skills3[ 3] = 'A029'
set skills3[ 4] = 'A033'
set skills3[ 5] = 'A04V'
set skills3[ 6] = 'A00S'
set skills3[ 7] = 'A029'
set skills3[ 8] = 'A033'
set skills3[ 9] = 'A04V'
set skills3[10] = 'A029'
elseif (heroid == 'E006') then
set skills3[ 1] = 'A04Z'
set skills3[ 2] = 'A0A9'
set skills3[ 3] = 'A09B'
set skills3[ 4] = 'A04Z'
set skills3[ 5] = 'A0A9'
set skills3[ 6] = 'A09R'
set skills3[ 7] = 'A09B'
set skills3[ 8] = 'A04Z'
set skills3[ 9] = 'A0A9'
set skills3[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills3[ 1] = 'A02V'
set skills3[ 2] = 'A08K'
set skills3[ 3] = 'A05B'
set skills3[ 4] = 'A02V'
set skills3[ 5] = 'A08K'
set skills3[ 6] = 'A038'
set skills3[ 7] = 'A05B'
set skills3[ 8] = 'A02V'
set skills3[ 9] = 'A08K'
set skills3[10] = 'A05B'
endif
endif
endfunction
//===========================================================================
// Selects hero IDs for three possible heroes
//===========================================================================
function SelectHeroes takes nothing returns nothing
local integer roll = GetRandomInt(1,100)
if (roll <= 17) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'H00N' )
elseif (roll <= 34) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'E006' )
elseif (roll <= 50) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'H00N' )
elseif (roll <= 67) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'O009' )
elseif (roll <= 84) then
call SetHero( 1, 'H00N' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'E006' )
else
call SetHero( 1, 'H00N' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'O009' )
endif
endfunction
//===========================================================================
// Returns the hero skill for the given hero and level
//===========================================================================
function ChooseHeroSkill takes nothing returns integer
local integer curHero = GetHeroId()
local integer level = GetHeroLevelAI()
if (level > max_hero_level) then
set max_hero_level = level
endif
if (curHero == hero_id) then
return skills1[level]
elseif (curHero == hero_id2) then
return skills2[level]
elseif (curHero == hero_id3) then
return skills3[level]
endif
return 0
endfunction
//***************************************************************************
//*
//* Building and Harvesting
//*
//***************************************************************************
//===========================================================================
// Specifies building priorities for workers
//===========================================================================
function BuildPriorities takes nothing returns nothing
local integer mine = TownWithMine()
if (gCond_Food_A) then
call SetBuildAll( BUILD_UNIT, 1, 'nntg', -1 )
endif
if (gCond_Food_B) then
call SetBuildAll( BUILD_UNIT, 2, 'nntg', -1 )
endif
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 3, 'nntg', -1 )
endif
if (gCond_Food_D) then
call SetBuildAll( BUILD_UNIT, 4, 'nntg', -1 )
endif
if (gCond_Food_E) then
call SetBuildAll( BUILD_UNIT, 5, 'nntg', -1 )
endif
if (gCond_Hero_A) then
call SetBuildAll( BUILD_UNIT, 1, hero_id, -1 )
endif
call SetBuildAll( BUILD_UNIT, 1, 'etol', -1 )
if (gCond_Justify_More_Workers) then
call SetBuildAll( BUILD_UNIT, 1, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 3, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 4, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 5, 'ewsp', -1 )
if gCond_Debug then
call Msg("==========================")
call Msg("Build loop: making extra workers.")
call Msg("==========================")
endif
endif
call SetBuildAll( BUILD_UNIT, 6, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 7, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 8, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 9, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 10, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'nnad', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'nnsg', -1 )
call SetBuildAll( BUILD_UNIT, 11, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 12, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 13, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'n005', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'nnsg', -1 )
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnam', -1 )
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 1, 'etoa', -1 )
endif
if (gCond_Justify_Expansion) then
call BuildExpansion( 'etol', 'etol' )
endif
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnat', -1 )
endfunction
//===========================================================================
// Specifies harvesting priorities for workers
//===========================================================================
function HarvestPriorities takes nothing returns nothing
local integer mine = TownWithMine()
local integer allGold = GetUnitCountDone('ewsp')
local integer allWood = GetUnitCountDone('ewsp')
local integer numWorkers
set numWorkers = 5
call HarvestGold( mine + 0, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 1, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 2, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 3, numWorkers )
set numWorkers = allWood - awWood
if (numWorkers > 0) then
call HarvestWood( mine, numWorkers )
endif
endfunction
//===========================================================================
// Determines all building and harvesting assignments for workers
//===========================================================================
function WorkerAssignment takes nothing returns nothing
loop
call UpdateConditions( )
// Harvesting
call ClearHarvestAI( )
call HarvestPriorities( )
// Building
call InitBuildArray( )
call BuildPriorities( )
call Sleep( 2 )
endloop
endfunction
//***************************************************************************
//*
//* Attacking
//*
//***************************************************************************
//===========================================================================
// Returns true if the minimum forces for an attack exist
//===========================================================================
function HaveMinimumAttackers takes nothing returns boolean
local integer count
// Check for attack wave limit
if (attackWave > 20) then
return false
endif
// Attack Group: All Units
// No specific minimums exist, checking for at least one unit
set count = 0
set count = count + GetUnitCountDone(hero_id)
set count = count + GetUnitCountDone(hero_id2)
set count = count + GetUnitCountDone(hero_id3)
set count = count + GetUnitCountDone('efdr')
set count = count + GetUnitCountDone('h00D')
set count = count + GetUnitCountDone('nsnp')
set count = count + GetUnitCountDone('n00Q')
set count = count + GetUnitCountDone('nwgs')
set count = count + GetUnitCountDone('n01E')
set count = count + GetUnitCountDone('nmyr')
set count = count + GetUnitCountDone('nnsw')
set count = count + GetUnitCountDone('nhyc')
set count = count + GetUnitCountDone('n00E')
set count = count + GetUnitCountDone('n00T')
set count = count + GetUnitCountDone('n01D')
set count = count + GetUnitCountDone('n007')
if (count < 1) then
return false
endif
return true
endfunction
//===========================================================================
// Assigns units to attack based on the given attack group
//===========================================================================
function PrepareAttackGroup takes integer groupID returns nothing
local integer all
// Attack Group #1: All Units
if (groupID == 1) then
set all = GetUnitCountDone( hero_id )
call AddAttackUnit( all, all, hero_id )
set all = GetUnitCountDone( hero_id2 )
call AddAttackUnit( all, all, hero_id2 )
set all = GetUnitCountDone( hero_id3 )
call AddAttackUnit( all, all, hero_id3 )
set all = GetUnitCountDone( 'efdr' )
call AddAttackUnit( all, all, 'efdr' )
set all = GetUnitCountDone( 'h00D' )
call AddAttackUnit( all, all, 'h00D' )
set all = GetUnitCountDone( 'nsnp' )
call AddAttackUnit( all, all, 'nsnp' )
set all = GetUnitCountDone( 'n00Q' )
call AddAttackUnit( all, all, 'n00Q' )
set all = GetUnitCountDone( 'nwgs' )
call AddAttackUnit( all, all, 'nwgs' )
set all = GetUnitCountDone( 'n01E' )
call AddAttackUnit( all, all, 'n01E' )
set all = GetUnitCountDone( 'nmyr' )
call AddAttackUnit( all, all, 'nmyr' )
set all = GetUnitCountDone( 'nnsw' )
call AddAttackUnit( all, all, 'nnsw' )
set all = GetUnitCountDone( 'nhyc' )
call AddAttackUnit( all, all, 'nhyc' )
set all = GetUnitCountDone( 'n00E' )
call AddAttackUnit( all, all, 'n00E' )
set all = GetUnitCountDone( 'n00T' )
call AddAttackUnit( all, all, 'n00T' )
set all = GetUnitCountDone( 'n01D' )
call AddAttackUnit( all, all, 'n01D' )
set all = GetUnitCountDone( 'n007' )
call AddAttackUnit( all, all, 'n007' )
endif
endfunction
//===========================================================================
// Prepares an attack group based on the current attack wave
//===========================================================================
function PrepareForces takes nothing returns nothing
if (attackWave == 1) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 2) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 3) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 4) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 5) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 6) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 7) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 8) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 9) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 10) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 11) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 12) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 13) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 14) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 15) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 16) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 17) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 18) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 19) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 20) then
call PrepareAttackGroup( 1 )
endif
endfunction
//===========================================================================
// Sleep delays for each attack wave
//===========================================================================
function AttackWaveDelay takes integer inWave returns nothing
if (inWave < nextDelay) then
return
endif
if (inWave == 0) then
call Sleep( 200 )
elseif (inWave == 1) then
call Sleep( 80 )
elseif (inWave == 2) then
call Sleep( 80 )
elseif (inWave == 3) then
call Sleep( 80 )
elseif (inWave == 4) then
call Sleep( 80 )
elseif (inWave == 5) then
call Sleep( 80 )
elseif (inWave == 6) then
call Sleep( 80 )
elseif (inWave == 7) then
call Sleep( 80 )
elseif (inWave == 8) then
call Sleep( 80 )
elseif (inWave == 9) then
call Sleep( 80 )
elseif (inWave == 10) then
call Sleep( 80 )
elseif (inWave == 11) then
call Sleep( 80 )
elseif (inWave == 12) then
call Sleep( 80 )
elseif (inWave == 13) then
call Sleep( 80 )
elseif (inWave == 14) then
call Sleep( 80 )
elseif (inWave == 15) then
call Sleep( 80 )
elseif (inWave == 16) then
call Sleep( 80 )
elseif (inWave == 17) then
call Sleep( 80 )
elseif (inWave == 18) then
call Sleep( 80 )
elseif (inWave == 19) then
call Sleep( 80 )
elseif (inWave == 20) then
call Sleep( 80 )
endif
set nextDelay = inWave + 1
endfunction
//===========================================================================
// Advances attack wave counter
//===========================================================================
function AttackWaveUpdate takes nothing returns nothing
call AttackWaveDelay( attackWave )
set attackWave = attackWave + 1
if (attackWave > 20) then
set attackWave = 1
set nextDelay = attackWave + 1
endif
endfunction
//===========================================================================
// Basic attack functionality
//===========================================================================
function AttackTarget takes unit target, boolean addAlliance returns nothing
if (target == null) then
return
endif
if (addAlliance) then
call SetAllianceTarget( target )
endif
call FormGroup( 3, true )
call AttackMoveKillA( target )
if (not addAlliance) then
call SetAllianceTarget( null )
endif
endfunction
//===========================================================================
// Initiates an attack based on target priorities
//===========================================================================
function LaunchAttack takes nothing returns nothing
local unit target = null
local boolean setAlly = true
// Don't launch any attack while town is threatened
if (TownThreatened()) then
call Sleep( 2 )
return
endif
// Target Priority #1
if (target == null) then
set target = GetAllianceTarget()
if (target != null) then
set setAlly = false
endif
endif
// Target Priority #2
if (gCond_Food_C) then
if (target == null) then
set target = GetExpansionFoe()
if (target != null) then
set take_exp = false
endif
endif
// Target Priority #3
endif
if (target == null) then
set target = GetMegaTarget()
endif
// Target Priority #4
if (target == null) then
set target = GetEnemyExpansion()
endif
// Target Priority #5
if (target == null) then
set target = GetEnemyExpansion()
if (target == null) then
call StartGetEnemyBase( )
loop
exitwhen (not WaitGetEnemyBase())
call SuicideSleep( 1 )
endloop
set target = GetEnemyBase()
endif
endif
// Target Priority #6
if (target == null) then
set target = GetCreepCamp( 0, 9, false )
endif
// Target Priority #7
if (gCond_Food_C) then
if (target == null) then
set target = GetCreepCamp( 10, 100, true )
endif
endif
// Attack the target and increment attack wave
if (target != null) then
call AttackTarget( target, setAlly )
call AttackWaveUpdate( )
else
// If no target was found, sleep a bit before trying again
call Sleep( 20 )
endif
endfunction
//===========================================================================
// Determines all attacking assignments
//===========================================================================
function AttackAssignment takes nothing returns nothing
call StaggerSleep( 0, 2 )
if (attackWave == 1) then
call AttackWaveDelay( 0 )
endif
loop
loop
call UpdateConditions( )
exitwhen (HaveMinimumAttackers() and not CaptainRetreating())
call Sleep( 2 )
endloop
call ResetAttackUnits( )
call PrepareForces( )
call LaunchAttack( )
endloop
endfunction
//===========================================================================
// Debug loop
//===========================================================================
function DebugLoop takes nothing returns nothing
loop
call WaitForSignal()
set gCond_Debug = not gCond_Debug
endloop
endfunction
//***************************************************************************
//*
//* Main Entry Point
//*
//***************************************************************************
//===========================================================================
function main takes nothing returns nothing
call InitAI( )
call SetPlayerName( ai_player, "Shellgan" )
call InitOptions( )
call SelectHeroes( )
call CreateCaptains( )
call SetHeroLevels( function ChooseHeroSkill )
call Sleep( 0.1 )
call StartThread( function WorkerAssignment )
call StartThread( function AttackAssignment )
call StartThread( function DebugLoop )
call PlayGame( )
endfunction
//===========================================================================
//
// Shellgan
//
// Warcraft III AI script
// Generated by the Warcraft III World Editor
// Date: Fri Nov 17 01:16:57 2017
//
//===========================================================================
//***************************************************************************
//*
//* Global Variables
//*
//***************************************************************************
globals
integer attackWave = 1
integer nextDelay = 0
integer awGold = 0
integer awWood = 0
// Conditions
boolean gCond_Food_A = false
boolean gCond_Food_B = false
boolean gCond_Food_C = false
boolean gCond_Food_D = false
boolean gCond_Food_E = false
boolean gCond_Food_F = false
boolean gCond_Food_G = false
boolean gCond_Justify_Expansion = false
boolean gCond_Justify_More_Workers = false
boolean gCond_Hero_A = false
// Debug condition
boolean gCond_Debug = false
endglobals
//***************************************************************************
//*
//* Debug Functions
//*
//***************************************************************************
//===========================================================================
function B2S takes boolean b returns string
if b then
return "true"
else
return "false"
endif
endfunction
//===========================================================================
function Dig2Str takes integer i returns string
if i == 1 then
return "1"
elseif i == 2 then
return "2"
elseif i == 3 then
return "3"
elseif i == 4 then
return "4"
elseif i == 5 then
return "5"
elseif i == 6 then
return "6"
elseif i == 7 then
return "7"
elseif i == 8 then
return "8"
elseif i == 9 then
return "9"
else
return "0"
endif
endfunction
//===========================================================================
// Courtesy of AIAndy and Tommi. See source:
// http://www.hiveworkshop.com/threads/two-custom-campaign-ais-examples.8939/
function Int2Str takes integer ic returns string
local string s = ""
local integer i = ic
local integer ialt = 0
local boolean neg = false
if i == 0 then
return "0"
endif
if i < 0 then
set neg = true
set i = (-1)*i
endif
loop
exitwhen i == 0
set ialt = i
set i = i / 10
set s = Dig2Str( ialt - 10*i ) + s
endloop
if neg then
set s = "-"+s
endif
return s
endfunction
//===========================================================================
function Msg takes string message returns nothing
local integer slot = 0
loop
call DisplayTextToPlayer(Player(slot),0,0,message)
set slot = slot + 1
exitwhen slot >= 12
endloop
endfunction
//***************************************************************************
//*
//* Utility Functions
//*
//***************************************************************************
//===========================================================================
function CheckLastCommand takes boolean pop returns integer
local integer cmd = GetLastCommand()
if (pop) then
call PopLastCommand( )
endif
return cmd
endfunction
//===========================================================================
function CheckLastCommandData takes boolean pop returns integer
local integer data = GetLastData()
if (pop) then
call PopLastCommand( )
endif
return data
endfunction
//===========================================================================
function TotalFoodProduced takes nothing returns integer
return GetPlayerState(ai_player,PLAYER_STATE_RESOURCE_FOOD_CAP)
endfunction
//===========================================================================
function ExpansionNeeded takes nothing returns boolean
return take_exp
endfunction
//===========================================================================
function BuildExpansion takes integer hallID, integer mineID returns nothing
if (HallsCompleted(hallID)) then
call SetBuildExpa( TownCount(hallID) + 1, mineID )
endif
endfunction
//===========================================================================
function CurrentAttackWave takes nothing returns integer
return attackWave
endfunction
//===========================================================================
function ResetAttackUnits takes nothing returns nothing
set awGold = 0
set awWood = 0
call InitAssaultGroup( )
endfunction
//===========================================================================
function AddAttackUnit takes integer minQty, integer maxQty, integer unitID returns nothing
// Track attacking gold workers
if (unitID == 'ewsp') then
set awGold = awGold + minQty
endif
// Track attacking wood workers
if (unitID == 'ewsp') then
set awWood = awWood + minQty
endif
call SetAssaultGroup( minQty, maxQty, unitID )
endfunction
//***************************************************************************
//*
//* Basic Options
//*
//***************************************************************************
//===========================================================================
function InitOptions takes nothing returns nothing
call SetMeleeAI( )
call SetDefendPlayer( true )
call SetRandomPaths( true )
call SetTargetHeroes( true )
call SetPeonsRepair( true )
call SetHeroesFlee( true )
call SetHeroesBuyItems( true )
call SetUnitsFlee( false )
call SetGroupsFlee( true )
call SetWatchMegaTargets( true )
call SetIgnoreInjured( false )
call SetHeroesTakeItems( true )
call SetSlowChopping( false )
call SetCaptainChanges( true )
call SetSmartArtillery( true )
endfunction
//***************************************************************************
//*
//* Conditions
//*
//***************************************************************************
//===========================================================================
// Updates the values of all preset conditions
//===========================================================================
function UpdateConditions takes nothing returns nothing
set gCond_Food_A = ( FoodUsed( ) >= 14 )
set gCond_Food_B = ( FoodUsed( ) >= 28 )
set gCond_Food_C = ( FoodUsed( ) >= 42 )
set gCond_Food_D = ( FoodUsed( ) >= 86 )
set gCond_Food_E = ( FoodUsed( ) >= 100 )
set gCond_Food_F = ( FoodUsed( ) >= 114 )
set gCond_Food_G = ( FoodUsed( ) >= 122 )
set gCond_Justify_Expansion = ( GetMinesOwned( ) == 1 )
set gCond_Justify_More_Workers = ( GetUnitCount( 'egol' ) > 1 )
set gCond_Hero_A = ( GetUnitCountDone( 'nnad' ) >= 1 )
if gCond_Debug then
call Msg("==========================")
call Msg(("Justify more workers: " + B2S(gCond_Justify_More_Workers)))
call Msg(("Number of mine units: " + Int2Str(GetUnitCount( 'egol' )) + " || Number of done mine units: " + Int2Str(GetUnitCountDone( 'egol' ))))
call Msg("==========================")
endif
endfunction
//***************************************************************************
//*
//* Heroes
//*
//***************************************************************************
//===========================================================================
// Stores hero ID and skills
//===========================================================================
function SetHero takes integer order, integer heroid returns nothing
if (order == 1) then
set hero_id = heroid
if (heroid == 'O009') then
set skills1[ 1] = 'A033'
set skills1[ 2] = 'A04V'
set skills1[ 3] = 'A029'
set skills1[ 4] = 'A033'
set skills1[ 5] = 'A04V'
set skills1[ 6] = 'A00S'
set skills1[ 7] = 'A029'
set skills1[ 8] = 'A033'
set skills1[ 9] = 'A04V'
set skills1[10] = 'A029'
elseif (heroid == 'E006') then
set skills1[ 1] = 'A04Z'
set skills1[ 2] = 'A0A9'
set skills1[ 3] = 'A09B'
set skills1[ 4] = 'A04Z'
set skills1[ 5] = 'A0A9'
set skills1[ 6] = 'A09R'
set skills1[ 7] = 'A09B'
set skills1[ 8] = 'A04Z'
set skills1[ 9] = 'A0A9'
set skills1[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills1[ 1] = 'A02V'
set skills1[ 2] = 'A08K'
set skills1[ 3] = 'A05B'
set skills1[ 4] = 'A02V'
set skills1[ 5] = 'A08K'
set skills1[ 6] = 'A038'
set skills1[ 7] = 'A05B'
set skills1[ 8] = 'A02V'
set skills1[ 9] = 'A08K'
set skills1[10] = 'A05B'
endif
elseif (order == 2) then
set hero_id2 = heroid
if (heroid == 'O009') then
set skills2[ 1] = 'A033'
set skills2[ 2] = 'A04V'
set skills2[ 3] = 'A029'
set skills2[ 4] = 'A033'
set skills2[ 5] = 'A04V'
set skills2[ 6] = 'A00S'
set skills2[ 7] = 'A029'
set skills2[ 8] = 'A033'
set skills2[ 9] = 'A04V'
set skills2[10] = 'A029'
elseif (heroid == 'E006') then
set skills2[ 1] = 'A04Z'
set skills2[ 2] = 'A0A9'
set skills2[ 3] = 'A09B'
set skills2[ 4] = 'A04Z'
set skills2[ 5] = 'A0A9'
set skills2[ 6] = 'A09R'
set skills2[ 7] = 'A09B'
set skills2[ 8] = 'A04Z'
set skills2[ 9] = 'A0A9'
set skills2[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills2[ 1] = 'A02V'
set skills2[ 2] = 'A08K'
set skills2[ 3] = 'A05B'
set skills2[ 4] = 'A02V'
set skills2[ 5] = 'A08K'
set skills2[ 6] = 'A038'
set skills2[ 7] = 'A05B'
set skills2[ 8] = 'A02V'
set skills2[ 9] = 'A08K'
set skills2[10] = 'A05B'
endif
elseif (order == 3) then
set hero_id3 = heroid
if (heroid == 'O009') then
set skills3[ 1] = 'A033'
set skills3[ 2] = 'A04V'
set skills3[ 3] = 'A029'
set skills3[ 4] = 'A033'
set skills3[ 5] = 'A04V'
set skills3[ 6] = 'A00S'
set skills3[ 7] = 'A029'
set skills3[ 8] = 'A033'
set skills3[ 9] = 'A04V'
set skills3[10] = 'A029'
elseif (heroid == 'E006') then
set skills3[ 1] = 'A04Z'
set skills3[ 2] = 'A0A9'
set skills3[ 3] = 'A09B'
set skills3[ 4] = 'A04Z'
set skills3[ 5] = 'A0A9'
set skills3[ 6] = 'A09R'
set skills3[ 7] = 'A09B'
set skills3[ 8] = 'A04Z'
set skills3[ 9] = 'A0A9'
set skills3[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills3[ 1] = 'A02V'
set skills3[ 2] = 'A08K'
set skills3[ 3] = 'A05B'
set skills3[ 4] = 'A02V'
set skills3[ 5] = 'A08K'
set skills3[ 6] = 'A038'
set skills3[ 7] = 'A05B'
set skills3[ 8] = 'A02V'
set skills3[ 9] = 'A08K'
set skills3[10] = 'A05B'
endif
endif
endfunction
//===========================================================================
// Selects hero IDs for three possible heroes
//===========================================================================
function SelectHeroes takes nothing returns nothing
local integer roll = GetRandomInt(1,100)
if (roll <= 17) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'H00N' )
elseif (roll <= 34) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'E006' )
elseif (roll <= 50) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'H00N' )
elseif (roll <= 67) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'O009' )
elseif (roll <= 84) then
call SetHero( 1, 'H00N' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'E006' )
else
call SetHero( 1, 'H00N' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'O009' )
endif
endfunction
//===========================================================================
// Returns the hero skill for the given hero and level
//===========================================================================
function ChooseHeroSkill takes nothing returns integer
local integer curHero = GetHeroId()
local integer level = GetHeroLevelAI()
if (level > max_hero_level) then
set max_hero_level = level
endif
if (curHero == hero_id) then
return skills1[level]
elseif (curHero == hero_id2) then
return skills2[level]
elseif (curHero == hero_id3) then
return skills3[level]
endif
return 0
endfunction
//***************************************************************************
//*
//* Building and Harvesting
//*
//***************************************************************************
//===========================================================================
// Specifies building priorities for workers
//===========================================================================
function BuildPriorities takes nothing returns nothing
local integer mine = TownWithMine()
if (gCond_Food_A) then
call SetBuildAll( BUILD_UNIT, 1, 'nntg', -1 )
endif
if (gCond_Food_B) then
call SetBuildAll( BUILD_UNIT, 2, 'nntg', -1 )
endif
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 3, 'nntg', -1 )
endif
if (gCond_Food_D) then
call SetBuildAll( BUILD_UNIT, 4, 'nntg', -1 )
endif
if (gCond_Food_E) then
call SetBuildAll( BUILD_UNIT, 5, 'nntg', -1 )
endif
if (gCond_Hero_A) then
call SetBuildAll( BUILD_UNIT, 1, hero_id, -1 )
endif
call SetBuildAll( BUILD_UNIT, 1, 'etol', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 3, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 4, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 5, 'ewsp', -1 )
if (gCond_Justify_More_Workers) then
call SetBuildAll( BUILD_UNIT, 6, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 7, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 8, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 9, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 10, 'ewsp', -1 )
if gCond_Debug then
call Msg("==========================")
call Msg("Build loop: making extra workers.")
call Msg("==========================")
endif
endif
call SetBuildAll( BUILD_UNIT, 1, 'nnad', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'nnsg', -1 )
call SetBuildAll( BUILD_UNIT, 11, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 12, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 13, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'n005', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'nnsg', -1 )
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnam', -1 )
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 1, 'etoa', -1 )
endif
if (gCond_Justify_Expansion) then
call BuildExpansion( 'etol', 'etol' )
endif
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnat', -1 )
endfunction
//===========================================================================
// Specifies harvesting priorities for workers
//===========================================================================
function HarvestPriorities takes nothing returns nothing
local integer mine = TownWithMine()
local integer allGold = GetUnitCountDone('ewsp')
local integer allWood = GetUnitCountDone('ewsp')
local integer numWorkers
set numWorkers = 5
call HarvestGold( mine + 0, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 1, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 2, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 3, numWorkers )
set numWorkers = allWood - awWood
if (numWorkers > 0) then
call HarvestWood( mine, numWorkers )
endif
endfunction
//===========================================================================
// Determines all building and harvesting assignments for workers
//===========================================================================
function WorkerAssignment takes nothing returns nothing
loop
call UpdateConditions( )
// Harvesting
call ClearHarvestAI( )
call HarvestPriorities( )
// Building
call InitBuildArray( )
call BuildPriorities( )
call Sleep( 2 )
endloop
endfunction
//***************************************************************************
//*
//* Attacking
//*
//***************************************************************************
//===========================================================================
// Returns true if the minimum forces for an attack exist
//===========================================================================
function HaveMinimumAttackers takes nothing returns boolean
local integer count
// Check for attack wave limit
if (attackWave > 20) then
return false
endif
// Attack Group: All Units
// No specific minimums exist, checking for at least one unit
set count = 0
set count = count + GetUnitCountDone(hero_id)
set count = count + GetUnitCountDone(hero_id2)
set count = count + GetUnitCountDone(hero_id3)
set count = count + GetUnitCountDone('efdr')
set count = count + GetUnitCountDone('h00D')
set count = count + GetUnitCountDone('nsnp')
set count = count + GetUnitCountDone('n00Q')
set count = count + GetUnitCountDone('nwgs')
set count = count + GetUnitCountDone('n01E')
set count = count + GetUnitCountDone('nmyr')
set count = count + GetUnitCountDone('nnsw')
set count = count + GetUnitCountDone('nhyc')
set count = count + GetUnitCountDone('n00E')
set count = count + GetUnitCountDone('n00T')
set count = count + GetUnitCountDone('n01D')
set count = count + GetUnitCountDone('n007')
if (count < 1) then
return false
endif
return true
endfunction
//===========================================================================
// Assigns units to attack based on the given attack group
//===========================================================================
function PrepareAttackGroup takes integer groupID returns nothing
local integer all
// Attack Group #1: All Units
if (groupID == 1) then
set all = GetUnitCountDone( hero_id )
call AddAttackUnit( all, all, hero_id )
set all = GetUnitCountDone( hero_id2 )
call AddAttackUnit( all, all, hero_id2 )
set all = GetUnitCountDone( hero_id3 )
call AddAttackUnit( all, all, hero_id3 )
set all = GetUnitCountDone( 'efdr' )
call AddAttackUnit( all, all, 'efdr' )
set all = GetUnitCountDone( 'h00D' )
call AddAttackUnit( all, all, 'h00D' )
set all = GetUnitCountDone( 'nsnp' )
call AddAttackUnit( all, all, 'nsnp' )
set all = GetUnitCountDone( 'n00Q' )
call AddAttackUnit( all, all, 'n00Q' )
set all = GetUnitCountDone( 'nwgs' )
call AddAttackUnit( all, all, 'nwgs' )
set all = GetUnitCountDone( 'n01E' )
call AddAttackUnit( all, all, 'n01E' )
set all = GetUnitCountDone( 'nmyr' )
call AddAttackUnit( all, all, 'nmyr' )
set all = GetUnitCountDone( 'nnsw' )
call AddAttackUnit( all, all, 'nnsw' )
set all = GetUnitCountDone( 'nhyc' )
call AddAttackUnit( all, all, 'nhyc' )
set all = GetUnitCountDone( 'n00E' )
call AddAttackUnit( all, all, 'n00E' )
set all = GetUnitCountDone( 'n00T' )
call AddAttackUnit( all, all, 'n00T' )
set all = GetUnitCountDone( 'n01D' )
call AddAttackUnit( all, all, 'n01D' )
set all = GetUnitCountDone( 'n007' )
call AddAttackUnit( all, all, 'n007' )
endif
endfunction
//===========================================================================
// Prepares an attack group based on the current attack wave
//===========================================================================
function PrepareForces takes nothing returns nothing
if (attackWave == 1) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 2) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 3) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 4) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 5) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 6) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 7) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 8) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 9) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 10) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 11) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 12) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 13) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 14) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 15) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 16) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 17) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 18) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 19) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 20) then
call PrepareAttackGroup( 1 )
endif
endfunction
//===========================================================================
// Sleep delays for each attack wave
//===========================================================================
function AttackWaveDelay takes integer inWave returns nothing
if (inWave < nextDelay) then
return
endif
if (inWave == 0) then
call Sleep( 200 )
elseif (inWave == 1) then
call Sleep( 80 )
elseif (inWave == 2) then
call Sleep( 80 )
elseif (inWave == 3) then
call Sleep( 80 )
elseif (inWave == 4) then
call Sleep( 80 )
elseif (inWave == 5) then
call Sleep( 80 )
elseif (inWave == 6) then
call Sleep( 80 )
elseif (inWave == 7) then
call Sleep( 80 )
elseif (inWave == 8) then
call Sleep( 80 )
elseif (inWave == 9) then
call Sleep( 80 )
elseif (inWave == 10) then
call Sleep( 80 )
elseif (inWave == 11) then
call Sleep( 80 )
elseif (inWave == 12) then
call Sleep( 80 )
elseif (inWave == 13) then
call Sleep( 80 )
elseif (inWave == 14) then
call Sleep( 80 )
elseif (inWave == 15) then
call Sleep( 80 )
elseif (inWave == 16) then
call Sleep( 80 )
elseif (inWave == 17) then
call Sleep( 80 )
elseif (inWave == 18) then
call Sleep( 80 )
elseif (inWave == 19) then
call Sleep( 80 )
elseif (inWave == 20) then
call Sleep( 80 )
endif
set nextDelay = inWave + 1
endfunction
//===========================================================================
// Advances attack wave counter
//===========================================================================
function AttackWaveUpdate takes nothing returns nothing
call AttackWaveDelay( attackWave )
set attackWave = attackWave + 1
if (attackWave > 20) then
set attackWave = 1
set nextDelay = attackWave + 1
endif
endfunction
//===========================================================================
// Basic attack functionality
//===========================================================================
function AttackTarget takes unit target, boolean addAlliance returns nothing
if (target == null) then
return
endif
if (addAlliance) then
call SetAllianceTarget( target )
endif
call FormGroup( 3, true )
call AttackMoveKillA( target )
if (not addAlliance) then
call SetAllianceTarget( null )
endif
endfunction
//===========================================================================
// Initiates an attack based on target priorities
//===========================================================================
function LaunchAttack takes nothing returns nothing
local unit target = null
local boolean setAlly = true
// Don't launch any attack while town is threatened
if (TownThreatened()) then
call Sleep( 2 )
return
endif
// Target Priority #1
if (target == null) then
set target = GetAllianceTarget()
if (target != null) then
set setAlly = false
endif
endif
// Target Priority #2
if (gCond_Food_C) then
if (target == null) then
set target = GetExpansionFoe()
if (target != null) then
set take_exp = false
endif
endif
// Target Priority #3
endif
if (target == null) then
set target = GetMegaTarget()
endif
// Target Priority #4
if (target == null) then
set target = GetEnemyExpansion()
endif
// Target Priority #5
if (target == null) then
set target = GetEnemyExpansion()
if (target == null) then
call StartGetEnemyBase( )
loop
exitwhen (not WaitGetEnemyBase())
call SuicideSleep( 1 )
endloop
set target = GetEnemyBase()
endif
endif
// Target Priority #6
if (target == null) then
set target = GetCreepCamp( 0, 9, false )
endif
// Target Priority #7
if (gCond_Food_C) then
if (target == null) then
set target = GetCreepCamp( 10, 100, true )
endif
endif
// Attack the target and increment attack wave
if (target != null) then
call AttackTarget( target, setAlly )
call AttackWaveUpdate( )
else
// If no target was found, sleep a bit before trying again
call Sleep( 20 )
endif
endfunction
//===========================================================================
// Determines all attacking assignments
//===========================================================================
function AttackAssignment takes nothing returns nothing
call StaggerSleep( 0, 2 )
if (attackWave == 1) then
call AttackWaveDelay( 0 )
endif
loop
loop
call UpdateConditions( )
exitwhen (HaveMinimumAttackers() and not CaptainRetreating())
call Sleep( 2 )
endloop
call ResetAttackUnits( )
call PrepareForces( )
call LaunchAttack( )
endloop
endfunction
//===========================================================================
// Debug loop
//===========================================================================
function DebugLoop takes nothing returns nothing
loop
call WaitForSignal()
set gCond_Debug = not gCond_Debug
endloop
endfunction
//***************************************************************************
//*
//* Main Entry Point
//*
//***************************************************************************
//===========================================================================
function main takes nothing returns nothing
call InitAI( )
call SetPlayerName( ai_player, "Shellgan" )
call InitOptions( )
call SelectHeroes( )
call CreateCaptains( )
call SetHeroLevels( function ChooseHeroSkill )
call Sleep( 0.1 )
call StartThread( function WorkerAssignment )
call StartThread( function AttackAssignment )
call StartThread( function DebugLoop )
call PlayGame( )
endfunction
//===========================================================================
//
// Shellgan
//
// Warcraft III AI script
// Generated by the Warcraft III World Editor
// Date: Fri Nov 17 01:16:57 2017
//
//===========================================================================
//***************************************************************************
//*
//* Global Variables
//*
//***************************************************************************
globals
integer attackWave = 1
integer nextDelay = 0
integer awGold = 0
integer awWood = 0
// Conditions
boolean gCond_Food_A = false
boolean gCond_Food_B = false
boolean gCond_Food_C = false
boolean gCond_Food_D = false
boolean gCond_Food_E = false
boolean gCond_Food_F = false
boolean gCond_Food_G = false
boolean gCond_Justify_Expansion = false
boolean gCond_Justify_More_Workers = false
boolean gCond_Hero_A = false
// Debug condition
boolean gCond_Debug = false
endglobals
//***************************************************************************
//*
//* Debug Functions
//*
//***************************************************************************
//===========================================================================
function B2S takes boolean b returns string
if b then
return "true"
else
return "false"
endif
endfunction
//===========================================================================
function Dig2Str takes integer i returns string
if i == 1 then
return "1"
elseif i == 2 then
return "2"
elseif i == 3 then
return "3"
elseif i == 4 then
return "4"
elseif i == 5 then
return "5"
elseif i == 6 then
return "6"
elseif i == 7 then
return "7"
elseif i == 8 then
return "8"
elseif i == 9 then
return "9"
else
return "0"
endif
endfunction
//===========================================================================
// Courtesy of AIAndy and Tommi. See source:
// http://www.hiveworkshop.com/threads/two-custom-campaign-ais-examples.8939/
function Int2Str takes integer ic returns string
local string s = ""
local integer i = ic
local integer ialt = 0
local boolean neg = false
if i == 0 then
return "0"
endif
if i < 0 then
set neg = true
set i = (-1)*i
endif
loop
exitwhen i == 0
set ialt = i
set i = i / 10
set s = Dig2Str( ialt - 10*i ) + s
endloop
if neg then
set s = "-"+s
endif
return s
endfunction
//===========================================================================
function Msg takes string message returns nothing
local integer slot = 0
loop
call DisplayTextToPlayer(Player(slot),0,0,message)
set slot = slot + 1
exitwhen slot >= 12
endloop
endfunction
//***************************************************************************
//*
//* Utility Functions
//*
//***************************************************************************
//===========================================================================
function CheckLastCommand takes boolean pop returns integer
local integer cmd = GetLastCommand()
if (pop) then
call PopLastCommand( )
endif
return cmd
endfunction
//===========================================================================
function CheckLastCommandData takes boolean pop returns integer
local integer data = GetLastData()
if (pop) then
call PopLastCommand( )
endif
return data
endfunction
//===========================================================================
function TotalFoodProduced takes nothing returns integer
return GetPlayerState(ai_player,PLAYER_STATE_RESOURCE_FOOD_CAP)
endfunction
//===========================================================================
function ExpansionNeeded takes nothing returns boolean
return take_exp
endfunction
//===========================================================================
function BuildExpansion takes integer hallID, integer mineID returns nothing
if (HallsCompleted(hallID)) then
call SetBuildExpa( TownCount(hallID) + 1, mineID )
endif
endfunction
//===========================================================================
function CurrentAttackWave takes nothing returns integer
return attackWave
endfunction
//===========================================================================
function ResetAttackUnits takes nothing returns nothing
set awGold = 0
set awWood = 0
call InitAssaultGroup( )
endfunction
//===========================================================================
function AddAttackUnit takes integer minQty, integer maxQty, integer unitID returns nothing
// Track attacking gold workers
if (unitID == 'ewsp') then
set awGold = awGold + minQty
endif
// Track attacking wood workers
if (unitID == 'ewsp') then
set awWood = awWood + minQty
endif
call SetAssaultGroup( minQty, maxQty, unitID )
endfunction
//***************************************************************************
//*
//* Basic Options
//*
//***************************************************************************
//===========================================================================
function InitOptions takes nothing returns nothing
call SetMeleeAI( )
call SetDefendPlayer( true )
call SetRandomPaths( true )
call SetTargetHeroes( true )
call SetPeonsRepair( true )
call SetHeroesFlee( true )
call SetHeroesBuyItems( true )
call SetUnitsFlee( false )
call SetGroupsFlee( true )
call SetWatchMegaTargets( true )
call SetIgnoreInjured( false )
call SetHeroesTakeItems( true )
call SetSlowChopping( false )
call SetCaptainChanges( true )
call SetSmartArtillery( true )
endfunction
//***************************************************************************
//*
//* Conditions
//*
//***************************************************************************
//===========================================================================
// Updates the values of all preset conditions
//===========================================================================
function UpdateConditions takes nothing returns nothing
set gCond_Food_A = ( FoodUsed( ) >= 14 )
set gCond_Food_B = ( FoodUsed( ) >= 28 )
set gCond_Food_C = ( FoodUsed( ) >= 42 )
set gCond_Food_D = ( FoodUsed( ) >= 86 )
set gCond_Food_E = ( FoodUsed( ) >= 100 )
set gCond_Food_F = ( FoodUsed( ) >= 114 )
set gCond_Food_G = ( FoodUsed( ) >= 122 )
set gCond_Justify_Expansion = ( GetMinesOwned( ) == 1 )
set gCond_Justify_More_Workers = ( GetUnitCount( 'egol' ) > 1 )
set gCond_Hero_A = ( GetUnitCountDone( 'nnad' ) >= 1 )
if gCond_Debug then
call Msg("==========================")
call Msg(("Justify more workers: " + B2S(gCond_Justify_More_Workers)))
call Msg(("Number of mine units: " + Int2Str(GetUnitCount( 'egol' )) + " || Number of done mine units: " + Int2Str(GetUnitCountDone( 'egol' ))))
call Msg("==========================")
endif
endfunction
//***************************************************************************
//*
//* Heroes
//*
//***************************************************************************
//===========================================================================
// Stores hero ID and skills
//===========================================================================
function SetHero takes integer order, integer heroid returns nothing
if (order == 1) then
set hero_id = heroid
if (heroid == 'O009') then
set skills1[ 1] = 'A033'
set skills1[ 2] = 'A04V'
set skills1[ 3] = 'A029'
set skills1[ 4] = 'A033'
set skills1[ 5] = 'A04V'
set skills1[ 6] = 'A00S'
set skills1[ 7] = 'A029'
set skills1[ 8] = 'A033'
set skills1[ 9] = 'A04V'
set skills1[10] = 'A029'
elseif (heroid == 'E006') then
set skills1[ 1] = 'A04Z'
set skills1[ 2] = 'A0A9'
set skills1[ 3] = 'A09B'
set skills1[ 4] = 'A04Z'
set skills1[ 5] = 'A0A9'
set skills1[ 6] = 'A09R'
set skills1[ 7] = 'A09B'
set skills1[ 8] = 'A04Z'
set skills1[ 9] = 'A0A9'
set skills1[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills1[ 1] = 'A02V'
set skills1[ 2] = 'A08K'
set skills1[ 3] = 'A05B'
set skills1[ 4] = 'A02V'
set skills1[ 5] = 'A08K'
set skills1[ 6] = 'A038'
set skills1[ 7] = 'A05B'
set skills1[ 8] = 'A02V'
set skills1[ 9] = 'A08K'
set skills1[10] = 'A05B'
endif
elseif (order == 2) then
set hero_id2 = heroid
if (heroid == 'O009') then
set skills2[ 1] = 'A033'
set skills2[ 2] = 'A04V'
set skills2[ 3] = 'A029'
set skills2[ 4] = 'A033'
set skills2[ 5] = 'A04V'
set skills2[ 6] = 'A00S'
set skills2[ 7] = 'A029'
set skills2[ 8] = 'A033'
set skills2[ 9] = 'A04V'
set skills2[10] = 'A029'
elseif (heroid == 'E006') then
set skills2[ 1] = 'A04Z'
set skills2[ 2] = 'A0A9'
set skills2[ 3] = 'A09B'
set skills2[ 4] = 'A04Z'
set skills2[ 5] = 'A0A9'
set skills2[ 6] = 'A09R'
set skills2[ 7] = 'A09B'
set skills2[ 8] = 'A04Z'
set skills2[ 9] = 'A0A9'
set skills2[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills2[ 1] = 'A02V'
set skills2[ 2] = 'A08K'
set skills2[ 3] = 'A05B'
set skills2[ 4] = 'A02V'
set skills2[ 5] = 'A08K'
set skills2[ 6] = 'A038'
set skills2[ 7] = 'A05B'
set skills2[ 8] = 'A02V'
set skills2[ 9] = 'A08K'
set skills2[10] = 'A05B'
endif
elseif (order == 3) then
set hero_id3 = heroid
if (heroid == 'O009') then
set skills3[ 1] = 'A033'
set skills3[ 2] = 'A04V'
set skills3[ 3] = 'A029'
set skills3[ 4] = 'A033'
set skills3[ 5] = 'A04V'
set skills3[ 6] = 'A00S'
set skills3[ 7] = 'A029'
set skills3[ 8] = 'A033'
set skills3[ 9] = 'A04V'
set skills3[10] = 'A029'
elseif (heroid == 'E006') then
set skills3[ 1] = 'A04Z'
set skills3[ 2] = 'A0A9'
set skills3[ 3] = 'A09B'
set skills3[ 4] = 'A04Z'
set skills3[ 5] = 'A0A9'
set skills3[ 6] = 'A09R'
set skills3[ 7] = 'A09B'
set skills3[ 8] = 'A04Z'
set skills3[ 9] = 'A0A9'
set skills3[10] = 'A09B'
elseif (heroid == 'H00N') then
set skills3[ 1] = 'A02V'
set skills3[ 2] = 'A08K'
set skills3[ 3] = 'A05B'
set skills3[ 4] = 'A02V'
set skills3[ 5] = 'A08K'
set skills3[ 6] = 'A038'
set skills3[ 7] = 'A05B'
set skills3[ 8] = 'A02V'
set skills3[ 9] = 'A08K'
set skills3[10] = 'A05B'
endif
endif
endfunction
//===========================================================================
// Selects hero IDs for three possible heroes
//===========================================================================
function SelectHeroes takes nothing returns nothing
local integer roll = GetRandomInt(1,100)
if (roll <= 17) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'H00N' )
elseif (roll <= 34) then
call SetHero( 1, 'O009' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'E006' )
elseif (roll <= 50) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'H00N' )
elseif (roll <= 67) then
call SetHero( 1, 'E006' )
call SetHero( 2, 'H00N' )
call SetHero( 3, 'O009' )
elseif (roll <= 84) then
call SetHero( 1, 'H00N' )
call SetHero( 2, 'O009' )
call SetHero( 3, 'E006' )
else
call SetHero( 1, 'H00N' )
call SetHero( 2, 'E006' )
call SetHero( 3, 'O009' )
endif
endfunction
//===========================================================================
// Returns the hero skill for the given hero and level
//===========================================================================
function ChooseHeroSkill takes nothing returns integer
local integer curHero = GetHeroId()
local integer level = GetHeroLevelAI()
if (level > max_hero_level) then
set max_hero_level = level
endif
if (curHero == hero_id) then
return skills1[level]
elseif (curHero == hero_id2) then
return skills2[level]
elseif (curHero == hero_id3) then
return skills3[level]
endif
return 0
endfunction
//***************************************************************************
//*
//* Building and Harvesting
//*
//***************************************************************************
//===========================================================================
// Specifies building priorities for workers
//===========================================================================
function BuildPriorities takes nothing returns nothing
local integer mine = TownWithMine()
if (gCond_Food_A) then
call SetBuildAll( BUILD_UNIT, 1, 'nntg', -1 )
endif
if (gCond_Food_B) then
call SetBuildAll( BUILD_UNIT, 2, 'nntg', -1 )
endif
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 3, 'nntg', -1 )
endif
if (gCond_Food_D) then
call SetBuildAll( BUILD_UNIT, 4, 'nntg', -1 )
endif
if (gCond_Food_E) then
call SetBuildAll( BUILD_UNIT, 5, 'nntg', -1 )
endif
if (gCond_Hero_A) then
call SetBuildAll( BUILD_UNIT, 1, hero_id, -1 )
endif
call SetBuildAll( BUILD_UNIT, 1, 'etol', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 3, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 4, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 5, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 6, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 7, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 8, 'ewsp', -1 )
if (gCond_Justify_More_Workers) then
call SetBuildAll( BUILD_UNIT, 9, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 10, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 11, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 12, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 13, 'ewsp', -1 )
if gCond_Debug then
call Msg("==========================")
call Msg("Build loop: making extra workers.")
call Msg("==========================")
endif
endif
call SetBuildAll( BUILD_UNIT, 1, 'nnad', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'nnsg', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'n005', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'nnsg', -1 )
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnam', -1 )
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 1, 'etoa', -1 )
endif
if (gCond_Justify_Expansion) then
call BuildExpansion( 'etol', 'etol' )
endif
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnat', -1 )
endfunction
//===========================================================================
// Specifies harvesting priorities for workers
//===========================================================================
function HarvestPriorities takes nothing returns nothing
local integer mine = TownWithMine()
local integer allGold = GetUnitCountDone('ewsp')
local integer allWood = GetUnitCountDone('ewsp')
local integer numWorkers
set numWorkers = 5
call HarvestGold( mine + 0, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 1, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 2, numWorkers )
set numWorkers = 5
call HarvestGold( mine + 3, numWorkers )
set numWorkers = allWood - awWood
if (numWorkers > 0) then
call HarvestWood( mine, numWorkers )
endif
endfunction
//===========================================================================
// Determines all building and harvesting assignments for workers
//===========================================================================
function WorkerAssignment takes nothing returns nothing
loop
call UpdateConditions( )
// Harvesting
call ClearHarvestAI( )
call HarvestPriorities( )
// Building
call InitBuildArray( )
call BuildPriorities( )
call Sleep( 2 )
endloop
endfunction
//***************************************************************************
//*
//* Attacking
//*
//***************************************************************************
//===========================================================================
// Returns true if the minimum forces for an attack exist
//===========================================================================
function HaveMinimumAttackers takes nothing returns boolean
local integer count
// Check for attack wave limit
if (attackWave > 20) then
return false
endif
// Attack Group: All Units
// No specific minimums exist, checking for at least one unit
set count = 0
set count = count + GetUnitCountDone(hero_id)
set count = count + GetUnitCountDone(hero_id2)
set count = count + GetUnitCountDone(hero_id3)
set count = count + GetUnitCountDone('efdr')
set count = count + GetUnitCountDone('h00D')
set count = count + GetUnitCountDone('nsnp')
set count = count + GetUnitCountDone('n00Q')
set count = count + GetUnitCountDone('nwgs')
set count = count + GetUnitCountDone('n01E')
set count = count + GetUnitCountDone('nmyr')
set count = count + GetUnitCountDone('nnsw')
set count = count + GetUnitCountDone('nhyc')
set count = count + GetUnitCountDone('n00E')
set count = count + GetUnitCountDone('n00T')
set count = count + GetUnitCountDone('n01D')
set count = count + GetUnitCountDone('n007')
if (count < 1) then
return false
endif
return true
endfunction
//===========================================================================
// Assigns units to attack based on the given attack group
//===========================================================================
function PrepareAttackGroup takes integer groupID returns nothing
local integer all
// Attack Group #1: All Units
if (groupID == 1) then
set all = GetUnitCountDone( hero_id )
call AddAttackUnit( all, all, hero_id )
set all = GetUnitCountDone( hero_id2 )
call AddAttackUnit( all, all, hero_id2 )
set all = GetUnitCountDone( hero_id3 )
call AddAttackUnit( all, all, hero_id3 )
set all = GetUnitCountDone( 'efdr' )
call AddAttackUnit( all, all, 'efdr' )
set all = GetUnitCountDone( 'h00D' )
call AddAttackUnit( all, all, 'h00D' )
set all = GetUnitCountDone( 'nsnp' )
call AddAttackUnit( all, all, 'nsnp' )
set all = GetUnitCountDone( 'n00Q' )
call AddAttackUnit( all, all, 'n00Q' )
set all = GetUnitCountDone( 'nwgs' )
call AddAttackUnit( all, all, 'nwgs' )
set all = GetUnitCountDone( 'n01E' )
call AddAttackUnit( all, all, 'n01E' )
set all = GetUnitCountDone( 'nmyr' )
call AddAttackUnit( all, all, 'nmyr' )
set all = GetUnitCountDone( 'nnsw' )
call AddAttackUnit( all, all, 'nnsw' )
set all = GetUnitCountDone( 'nhyc' )
call AddAttackUnit( all, all, 'nhyc' )
set all = GetUnitCountDone( 'n00E' )
call AddAttackUnit( all, all, 'n00E' )
set all = GetUnitCountDone( 'n00T' )
call AddAttackUnit( all, all, 'n00T' )
set all = GetUnitCountDone( 'n01D' )
call AddAttackUnit( all, all, 'n01D' )
set all = GetUnitCountDone( 'n007' )
call AddAttackUnit( all, all, 'n007' )
endif
endfunction
//===========================================================================
// Prepares an attack group based on the current attack wave
//===========================================================================
function PrepareForces takes nothing returns nothing
if (attackWave == 1) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 2) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 3) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 4) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 5) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 6) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 7) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 8) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 9) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 10) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 11) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 12) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 13) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 14) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 15) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 16) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 17) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 18) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 19) then
call PrepareAttackGroup( 1 )
elseif (attackWave == 20) then
call PrepareAttackGroup( 1 )
endif
endfunction
//===========================================================================
// Sleep delays for each attack wave
//===========================================================================
function AttackWaveDelay takes integer inWave returns nothing
if (inWave < nextDelay) then
return
endif
if (inWave == 0) then
call Sleep( 200 )
elseif (inWave == 1) then
call Sleep( 80 )
elseif (inWave == 2) then
call Sleep( 80 )
elseif (inWave == 3) then
call Sleep( 80 )
elseif (inWave == 4) then
call Sleep( 80 )
elseif (inWave == 5) then
call Sleep( 80 )
elseif (inWave == 6) then
call Sleep( 80 )
elseif (inWave == 7) then
call Sleep( 80 )
elseif (inWave == 8) then
call Sleep( 80 )
elseif (inWave == 9) then
call Sleep( 80 )
elseif (inWave == 10) then
call Sleep( 80 )
elseif (inWave == 11) then
call Sleep( 80 )
elseif (inWave == 12) then
call Sleep( 80 )
elseif (inWave == 13) then
call Sleep( 80 )
elseif (inWave == 14) then
call Sleep( 80 )
elseif (inWave == 15) then
call Sleep( 80 )
elseif (inWave == 16) then
call Sleep( 80 )
elseif (inWave == 17) then
call Sleep( 80 )
elseif (inWave == 18) then
call Sleep( 80 )
elseif (inWave == 19) then
call Sleep( 80 )
elseif (inWave == 20) then
call Sleep( 80 )
endif
set nextDelay = inWave + 1
endfunction
//===========================================================================
// Advances attack wave counter
//===========================================================================
function AttackWaveUpdate takes nothing returns nothing
call AttackWaveDelay( attackWave )
set attackWave = attackWave + 1
if (attackWave > 20) then
set attackWave = 1
set nextDelay = attackWave + 1
endif
endfunction
//===========================================================================
// Basic attack functionality
//===========================================================================
function AttackTarget takes unit target, boolean addAlliance returns nothing
if (target == null) then
return
endif
if (addAlliance) then
call SetAllianceTarget( target )
endif
call FormGroup( 3, true )
call AttackMoveKillA( target )
if (not addAlliance) then
call SetAllianceTarget( null )
endif
endfunction
//===========================================================================
// Initiates an attack based on target priorities
//===========================================================================
function LaunchAttack takes nothing returns nothing
local unit target = null
local boolean setAlly = true
// Don't launch any attack while town is threatened
if (TownThreatened()) then
call Sleep( 2 )
return
endif
// Target Priority #1
if (target == null) then
set target = GetAllianceTarget()
if (target != null) then
set setAlly = false
endif
endif
// Target Priority #2
if (gCond_Food_C) then
if (target == null) then
set target = GetExpansionFoe()
if (target != null) then
set take_exp = false
endif
endif
// Target Priority #3
endif
if (target == null) then
set target = GetMegaTarget()
endif
// Target Priority #4
if (target == null) then
set target = GetEnemyExpansion()
endif
// Target Priority #5
if (target == null) then
set target = GetEnemyExpansion()
if (target == null) then
call StartGetEnemyBase( )
loop
exitwhen (not WaitGetEnemyBase())
call SuicideSleep( 1 )
endloop
set target = GetEnemyBase()
endif
endif
// Target Priority #6
if (target == null) then
set target = GetCreepCamp( 0, 9, false )
endif
// Target Priority #7
if (gCond_Food_C) then
if (target == null) then
set target = GetCreepCamp( 10, 100, true )
endif
endif
// Attack the target and increment attack wave
if (target != null) then
call AttackTarget( target, setAlly )
call AttackWaveUpdate( )
else
// If no target was found, sleep a bit before trying again
call Sleep( 20 )
endif
endfunction
//===========================================================================
// Determines all attacking assignments
//===========================================================================
function AttackAssignment takes nothing returns nothing
call StaggerSleep( 0, 2 )
if (attackWave == 1) then
call AttackWaveDelay( 0 )
endif
loop
loop
call UpdateConditions( )
exitwhen (HaveMinimumAttackers() and not CaptainRetreating())
call Sleep( 2 )
endloop
call ResetAttackUnits( )
call PrepareForces( )
call LaunchAttack( )
endloop
endfunction
//===========================================================================
// Debug loop
//===========================================================================
function DebugLoop takes nothing returns nothing
loop
call WaitForSignal()
set gCond_Debug = not gCond_Debug
endloop
endfunction
//***************************************************************************
//*
//* Main Entry Point
//*
//***************************************************************************
//===========================================================================
function main takes nothing returns nothing
call InitAI( )
call SetPlayerName( ai_player, "Shellgan" )
call InitOptions( )
call SelectHeroes( )
call CreateCaptains( )
call SetHeroLevels( function ChooseHeroSkill )
call Sleep( 0.1 )
call StartThread( function WorkerAssignment )
call StartThread( function AttackAssignment )
call StartThread( function DebugLoop )
call PlayGame( )
endfunction
function BuildPriorities takes nothing returns nothing
local integer mine = TownWithMine()
local integer workersCount = 0
if (gCond_Food_A) then
call SetBuildAll( BUILD_UNIT, 1, 'nntg', -1 )
endif
if (gCond_Food_B) then
call SetBuildAll( BUILD_UNIT, 2, 'nntg', -1 )
endif
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 3, 'nntg', -1 )
endif
if (gCond_Food_D) then
call SetBuildAll( BUILD_UNIT, 4, 'nntg', -1 )
endif
if (gCond_Food_E) then
call SetBuildAll( BUILD_UNIT, 5, 'nntg', -1 )
endif
if (gCond_Hero_A) then
call SetBuildAll( BUILD_UNIT, 1, hero_id, -1 )
endif
call SetBuildAll( BUILD_UNIT, 1, 'etol', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 3, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 4, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 5, 'ewsp', -1 )
set workersCount = 5
if (gCond_Justify_More_Workers) then
call SetBuildAll( BUILD_UNIT, 6, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 7, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 8, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 9, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 10, 'ewsp', -1 )
set workersCount = 10
endif
call SetBuildAll( BUILD_UNIT, 1, 'nnad', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'nnsg', -1 )
// set the number of works to build equal to 6, or 11,
//conditionally based on the previous value of workersCount
set workersCount = workersCount + 1
call SetBuildAll( BUILD_UNIT, workersCount, 'ewsp', -1 )
set workersCount = workersCount + 1
call SetBuildAll( BUILD_UNIT, workersCount, 'ewsp', -1 )
set workersCount = workersCount + 1
call SetBuildAll( BUILD_UNIT, workersCount, 'ewsp', -1 )
call SetBuildAll( BUILD_UNIT, 1, 'n005', -1 )
call SetBuildAll( BUILD_UNIT, 2, 'nnsg', -1 )
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnam', -1 )
if (gCond_Food_C) then
call SetBuildAll( BUILD_UNIT, 1, 'etoa', -1 )
endif
if (gCond_Justify_Expansion) then
call BuildExpansion( 'etol', 'etol' )
endif
call SetBuildAll( BUILD_UPGRADE, 1, 'Rnat', -1 )
endfunction