- Joined
- May 12, 2018
- Messages
- 145
Greetings,
I want to write Campaign AI Script that has creeping and building expansion town.
I need this to force player to do macro actively.
The basic melee AIs in WC3 seems to have a completely different configuration from campaign AI, so I'm asking for help.
I am using common_v2.ai utility.
www.hiveworkshop.com
Here's my example script.
I want to write Campaign AI Script that has creeping and building expansion town.
I need this to force player to do macro actively.
The basic melee AIs in WC3 seems to have a completely different configuration from campaign AI, so I'm asking for help.
I am using common_v2.ai utility.
[JASS] - JASS Campaign AI 2.0
JASS CAMPAIGN AI 2.0 We all know JASS Campaign AI is... clunky, at best. I always loved its ease of use and even tried to imitate it in Starcraft 2 in the past. However, while working on Warcraft 3 Re-Reforged, I soon realized some of the built-in limitations were an hindrance to my game...

Here's my example script.
JASS:
globals
player User = Player(0)
constant real ATTACK_WAVE_START_X = 4880
constant real ATTACK_WAVE_START_Y = -3886
boolean AttackUser = false
integer COMMAND_ATTACK_USER = 1
integer DATA_ATTACK_USER_ENABLE = 1
integer DATA_ATTACK_USER_DISABLE = 0
constant integer COMMAND_DEFEAT = -1
constant integer DATA_DEFEAT_ENABLE = 1
constant integer DATA_DEFEAT_DISABLE = 0
endglobals
function ResearchUpgrades takes nothing returns nothing
endfunction
function SetBuildOrder takes nothing returns nothing
call SetBuildUnitEx(1, 1, 1, UNIT_UNDEAD_WORKER)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_GOLD)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_HALL1)
call SetBuildUnitEx(5, 5, 5, UNIT_UNDEAD_WORKER)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_FARM)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_BARRACKS)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_ALTAR)
call SetBuildUnitEx(2, 2, 2, BUILD_UNDEAD_FARM)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_FARMTOWERFROST)
call SetBuildUnitEx(3, 3, 3, UNIT_UNDEAD_GHOUL)
call SetBuildUnitEx(2, 2, 2, BUILD_UNDEAD_BARRACKS)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_HALL2)
call SetBuildUnitEx(4, 4, 4, BUILD_UNDEAD_FARM)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_BLACKSMITH)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_FARMTOWER)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_SHOP)
call SetBuildUnitEx(1, 1, 1, BUILD_UNDEAD_SLAUGHTERHOUSE)
call SetBuildUnitEx(2, 2, 2, BUILD_UNDEAD_TEMPLE)
call SetBuildUnitEx(2, 2, 2, BUILD_UNDEAD_SLAUGHTERHOUSE)
call SetBuildUnitEx(3, 3, 3, BUILD_UNDEAD_BARRACKS)
call SetBuildUnitEx(3, 3, 3, BUILD_UNDEAD_FARMTOWER)
call SetBuildUnitEx(9, 9, 9, BUILD_UNDEAD_FARM)
endfunction
function SetDefenders takes nothing returns nothing
call CampaignDefenderEx(1, 1, 1, HERO_UNDEAD_DEATHKNIGHT)
call CampaignDefenderEx(3, 3, 3, UNIT_UNDEAD_GHOUL)
call CampaignDefenderEx(2, 2, 2, UNIT_UNDEAD_FIEND)
call CampaignDefenderEx(1, 1, 1, UNIT_UNDEAD_WAGON)
call CampaignDefenderEx(2, 2, 2, UNIT_UNDEAD_NECRO)
call CampaignDefenderEx(2, 2, 2, UNIT_UNDEAD_BANSHEE)
call CampaignDefenderEx(1, 1, 1, UNIT_UNDEAD_OBSIDIAN)
endfunction
function AttackWavesAttackUser takes nothing returns nothing
local boolean AttackWaveAttackUser = AttackUser
call AdvDebugDisplayToPlayer("AI Info: attacking User...")
call AdvSetPrioritizeTownHalls(false)
call AdvSetContinueAttackReducePercentage(10)
loop
// *** WAVE 1 ***
call AdvSetPrioritizeNearest(false)
call AdvSetSearchPreferredLocations(true)
call AdvSetContinueAttackPercentage(100)
call InitAssaultGroup()
call CampaignAttackerEx(1, 1, 1, HERO_UNDEAD_DEATHKNIGHT)
call CampaignAttackerEx(7, 7, 7, UNIT_UNDEAD_GHOUL)
call CampaignAttackerEx(3, 3, 3, UNIT_UNDEAD_FIEND)
call AdvSuicideOnPlayerEx(45, 45, 45, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_WEAPON_MELEE)
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_CANNIBALIZE)
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_ARMOR_MELEE)
// *** WAVE 2 ***
call AdvSetPrioritizeNearest(true)
call AdvSetSearchPreferredLocations(false)
call AdvSetContinueAttackPercentage(0)
call InitAssaultGroup()
call CampaignAttackerEx(9, 9, 9, UNIT_UNDEAD_FIEND)
call CampaignAttackerEx(4, 4, 4, UNIT_UNDEAD_GHOUL)
call AdvSuicideOnPlayerEx(70, 70, 70, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_WEAPON_RANGE)
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_ARMOR_RANGE)
// *** WAVE 3 ***
call AdvSetPrioritizeNearest(false)
call AdvSetSearchPreferredLocations(true)
call AdvSetContinueAttackPercentage(100)
call InitAssaultGroup()
call CampaignAttackerEx(1, 1, 1, HERO_UNDEAD_DEATHKNIGHT)
call CampaignAttackerEx(8, 8, 8, UNIT_UNDEAD_GHOUL)
call CampaignAttackerEx(4, 4, 4, UNIT_UNDEAD_FIEND)
call CampaignAttackerEx(2, 2, 2, UNIT_UNDEAD_NECRO)
call CampaignAttackerEx(1, 1, 1, UNIT_UNDEAD_WAGON)
call AdvSuicideOnPlayerEx(70, 70, 70, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_FIEND_BURROW)
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_WEAPON_CASTER)
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_WAGON_CORPSE)
// *** WAVE 4 ***
call AdvSetPrioritizeNearest(false)
call AdvSetSearchPreferredLocations(true)
call AdvSetContinueAttackPercentage(100)
call InitAssaultGroup()
call CampaignAttackerEx(10, 10, 10, UNIT_UNDEAD_GHOUL)
call CampaignAttackerEx(5, 5, 5, UNIT_UNDEAD_BANSHEE)
call CampaignAttackerEx(1, 1, 1, UNIT_UNDEAD_OBSIDIAN)
call CampaignAttackerEx(3, 3, 3, UNIT_UNDEAD_WAGON)
call AdvSuicideOnPlayerEx(70, 70, 70, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
call SetBuildUpgrEx(1, 1, 1, UPG_UNDEAD_GHOUL_FRENZY)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_WEAPON_RANGE)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_ARMOR_RANGE)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_WEAPON_MELEE)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_ARMOR_MELEE)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_WEAPON_CASTER)
call SetBuildUpgrEx(2, 2, 2, UPG_UNDEAD_ARMOR_STRUCTURE)
loop
// *** WAVE 5 ***
call AdvSetPrioritizeNearest(false)
call AdvSetSearchPreferredLocations(false)
call AdvSetContinueAttackPercentage(100)
call InitAssaultGroup()
call CampaignAttackerEx(1, 1, 1, HERO_UNDEAD_DEATHKNIGHT)
call CampaignAttackerEx(9, 9, 9, UNIT_UNDEAD_FIEND)
call CampaignAttackerEx(3, 3, 3, UNIT_UNDEAD_WAGON)
call CampaignAttackerEx(4, 4, 4, UNIT_UNDEAD_NECRO)
call AdvSuicideOnPlayerEx(90, 90, 90, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
// *** WAVE 6 ***
call AdvSetPrioritizeNearest(true)
call AdvSetSearchPreferredLocations(false)
call AdvSetContinueAttackPercentage(0)
call InitAssaultGroup()
call CampaignAttackerEx(3, 3, 3, UNIT_UNDEAD_FIEND)
call CampaignAttackerEx(6, 6, 6, UNIT_UNDEAD_GHOUL)
call CampaignAttackerEx(2, 2, 2, UNIT_UNDEAD_NECRO)
call CampaignAttackerEx(4, 4, 4, UNIT_UNDEAD_BANSHEE)
call CampaignAttackerEx(2, 2, 2, UNIT_UNDEAD_OBSIDIAN)
call CampaignAttackerEx(2, 2, 2, UNIT_UNDEAD_WAGON)
call AdvSuicideOnPlayerEx(80, 80, 80, User, ATTACK_WAVE_START_X, ATTACK_WAVE_START_Y)
exitwhen AttackWaveAttackUser != AttackUser
endloop
// Make sure to leave both loops
exitwhen AttackWaveAttackUser != AttackUser
endloop
call AdvDebugDisplayToPlayer("AI Info: finished attacking User!")
endfunction
function AttackLoop takes nothing returns nothing
loop
// Attack the user and/or the trolls depending on the condition
if AttackUser then
call AttackWavesAttackUser()
else
endif
// Wait a little time before looping again
call Sleep(5)
endloop
endfunction
function CommandFetch takes nothing returns nothing
local integer Command
local integer Data
// Check if there is any command waiting
loop
exitwhen CommandsWaiting() <= 0
// Get command and data
set Command = GetLastCommand()
set Data = GetLastData()
call PopLastCommand()
// We set the suicide flag to disable all attack routines upon defeat
if Command == COMMAND_DEFEAT then
//call AdvSetSuicide(true)
set AttackUser = false
call AdvSetSuicide(false)
//call AdvDebugDisplayToPlayer("AI Warning: Invalid defeat command data received!")
// Update attack user behaviour command (to start/stop attack against the user)
elseif Command == COMMAND_ATTACK_USER then
set AttackUser = true
else
call AdvDebugDisplayToPlayer("AI Warning: Unknown command received!")
endif
endloop
endfunction
function CommandLoop takes nothing returns nothing
// Keep fetching commands while the AI is active
call CommandFetch()
call StaggerSleep(1, 5)
loop
call CommandFetch()
call Sleep(2)
endloop
endfunction
function hero_levels takes nothing returns integer
local integer hero = GetHeroId()
local integer level = GetHeroLevelAI()
local integer a = 0
if hero == HERO_UNDEAD_DEATHKNIGHT then
if level == 1 or level == 3 or level == 5 or level == 7 or level == 9 then
set a = AID_UNDEAD_DEATHKNIGHT_COIL
endif
if level == 4 then
set a = AID_UNDEAD_DEATHKNIGHT_AURA
endif
endif
return a
endfunction
function main takes nothing returns nothing
call CampaignAI(BUILD_UNDEAD_FARM, function hero_levels)
call SetSlowChopping(false)
set campaign_wood_peons = 4
call DoCampaignFarms(true)
call SetPeonsRepair( true )
call SetHeroesBuyItems(true)
call AdvSetPrioritizeTownHalls(false)
call AdvSetContinueAttackReducePercentageIfFarAway(false)
call AdvSetAttackWaveGatherReturnXY(8323.0, 7881.0)
call SetReplacements(9, 9, 9)
call GroupTimedLife(true)
call AdvSetSearchPreferredLocations(false)
call SetBuildOrder()
call SetDefenders()
call StartThread(function ResearchUpgrades)
call StartThread(function CommandLoop)
call AttackLoop()
endfunction
Last edited: