Login
Register
Menu
Home
Forum
JassDoc
Types
Functions
Variables
Help
Chat
Media
Search
Search posts
WC3 JASS.com
"The Jass Vault" plus vJASS and Zinc
WC3 Modding Information Center
Forum
Warcraft (WC3) Modding
Triggers & Scripting
WC3JASS.com
Jass Tutorials
How to make a Campaign AI
Warcraft III:
Maps
Models
Skins
Icons
Spells / Systems
Tools
Tutorials
Snippets
JASS vJASS Spells and Systems
Tutorials
Chat @Discord
vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation
-
Zinc documentation
-
WC3 Optimizer documentation
How to make a Campaign AI
Jass Tutorials
Started by
Guest
Views
28751
Replies
1
Users
1
2
Pages:
1
Go Down
0 Members and 1 Guest are viewing this topic.
moyack
Site Owner
Administrator
Posts:
971
WC3 Models: 20
WC3 Tutorials: 17
WC3 Tools: 19
WC3 Maps: 12
WC3 Skins: 0
WC3 Icons: 1
WC3 Spells: 16
Reputation:
1153
Site Admin - I love fix things
How to make a Campaign AI
on:
January 14, 2011, 09:19:32 AM
HOW TO MAKE A CAMPAIGN AI.
By Moyack
Index.
Introduction
AI Types
Tools Needed
What is JASS AI???
Let's Start
Building Strategy
Attacking Strategy
Upgrading Strategy
Hero Abilities
Controlling the AI via triggers
Testing the AI
Introduction.
The main objective with this tutorial is to give an introduction in the development of a simple AI, focused in attack one player following an attack sequence, a building sequence and an upgrade sequence.
AI Types
Before starting, I want to clarify that there are two kind of AI: Campaign AI and Standard AI. The Campaign AI is the simplest AI that can be made, because it follows a rigid and predictable behaviour. An standard AI, in the other hand, is focused in simulate the human behaviour, so it will be more random, sometimes more agressive and many times extremely difficult to debug.
So if we want to begin with JASS AI, it's recommended to start working with a campaign AI, that is easy to debug.
Tools needed.
If you want to make an Standard AI, you have the WE with the AI editor, with its easy but slow interface, but if you want to do a Campaign AI, you can do it with notepad.
I strongly suggest to use
JASSCRAFT
because this program let us access the common.ai commands easily, the syntax highlithing, etc.
What is JASS AI??
JASS AI is the language used by BLIZZARD to make AI programming. JASS AI uses the same JASS syntaxis and variable types, so if you are familiar with JASS, you will understand JASS AI perfectly.
The commands focused in AI are contained in the file
common.ai
file that can be found in the
war3.mpq
and
war3x.mpq
pack files. It's important to clarify that this functions are not the only that can be used to work with this scripting, you can use perfectly functions from
common.j
(well, it's the base file for programming with JASS language after all). Anyways, I've found that some functions from common.j just don't work in a JASS AI script, and the only way to get those functions is by practice.
Let's start
Well, I think I've talked a lot, so let's start the AI.
Open JASSCRAFT or JASS SHOP PRO and open a new document. Before begin writing, we must know how the code is arranged in JASS.
JASS Structure
Code: jass
globals
// We put the globals variables here
endglobals
function
blabla
takes
blabla
returns
blabla
// Custom function stuff
endfunction
...
function
main
takes
nothing
returns
nothing
//The main code goes here
endfunction
For people who are new with JASS, the code is arranged in a global section, where we declare the global variables, then we put the custom functions that will be used in the script and the last function called
main
, which will use the globals and the functions that we have writen before and will be the function that will be executed by the game.
With those definitions, we can put to work with this script. First we're going to begin the AI code creating at the global section a global variable that will point the player which will be attacked by the AI, we will call it
MyVictim
Global variables
Code: jass
globals
player
MyVictim =
Player
(0)
// This is the player 1 (red)
endglobals
Now we will create the main function
Code: jass
function
main
takes
nothing
returns
nothing
call
CampaignAI
( <Farm ID>,
null
)
endfunction
The
CampaignAI
function initializes and configures the AI in order to have a behaviour that fits with campaign maps. This function has two arguments, the farm unitID, which help the function to define the food provider unit, and the hero code which makes reference to a function that will manage the hero abilities that a hero will have when it increases its level. This option will be treated later, so at the moment we are going to set this parameter as
null
.
now we're going to set some parameters into the AI. Campaign AIs have this caracteristics by default:
They don't give attack priority to heroes.
Units don't flee
Peons only repair buildings in insane mode
Gather resources very slowly (each peon gather 1 gold and 1 lumber to the town hall)
This characteristics are given in this way to the AI because in campaign maps, you need the AI player keeps alive in the game until it's destroyed, so the AI will "simulate" a gathering, and you will control the AI resources via triggers. Other thing is units can't flee because the function of this kind of AI is to put difficulty or taunting the user player.
So if you need to change these behaviours you need to configure them with some ai functions. I'm going to list some of the most used:
Basic configuration functions
SetTargetHeroes
(Boolean)
: makes the AI to give attack priority toward heroes
SetUnitsFlee
(Boolean)
: If units are seriously damaged, they will retreat
SetHeroesFlee
(Boolean)
: The same but with heroes
SetGroupsFlee
(Boolean)
: The same but with the attacking group in general (I really don't recommend to set true this option, the AI behaves like a chicken)
SetSlowChopping
(Boolean)
: Workers gather very few resources
SetPeonsRepair
(Boolean)
: Workers will repair damaged mechanical units
SetHeroesBuyItems
(Boolean)
: Make heroes buy items from their racial shop and sell items.
SetHeroesTakeItems
(Boolean)
: Make heroes to take items on the ground.
For testing, I'm going to set some options in the main code.
Now we will create the main function
main function
Code: jass
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
// I like the Night elf race,
// so this AI will train NE
call
SetSlowChopping
(
false
)
//AI will do a normal harvesting
call
SetPeonsRepair
(
true
)
//AI will repair damaged structures
endfunction
Note
probably you've noticed that in the function
call
CampaignAI
(
MOON_WELL
,
null
)
we set the name of the unit instead of its rawcode. All the units used in the Warcraft Campaigns have this
constant names
. If you create a modified race with custom units, you have to use the rawcode. This function can be written in this way:
call
CampaignAI
(
'emow'
,
null
)
And is perfectly equivalent. I will use this constant names in all this tutorial so it can be more readable.
How to get the unit, ability, buff and upgrade rawcode?? easy, open the object editor and press
CTRL+D
, you will see that all the units , items, abilities, upgrades names are shown by their rawcode. To change again pres again
CTRL+D
If you want to be more organized, we can create a custom configuration function and then we will call it in the
main
function:
main function
Code: jass
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
endfunction
Building Strategy.
It's time to put this AI to build structures. First we must take in account the order and the dependencies, for example, in the case of this Night Elf AI, we can't build an ancient protector without have built a Huntress Hall.
With this idea in mind, we're going to set the building order in the script.
NE Campaign AI - only Buildings
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
// **********************************
// * End Building Strategy *
// **********************************
endfunction
Now we've done the basic tier 1 buildings. :emote_grin: Let's see the new functions.
SetBuildUnit
( n, UnitID )
is easy to read, this function orders to AI to build or train
n
units of type
UnitID
.
SetBuildUnitEx
( e, n, i, UnitID )
is the same but better, becasue it lets you set how many units will be trained in
e
asy,
n
ormal and
i
nsane mode.
Now we need to build the units that will defend our town, so we're going to train this units adding this functions to the AI.
NE Campaign AI - Buildings and defensive units
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
call
SetReplacements
( 1, 2, 3 )
// <==(1)
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
SetBuildUnitEx
( 0, 1, 2,
ANCIENT_PROTECT
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
// <==(2)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
// **********************************
// * End Building Strategy *
// **********************************
endfunction
Let's explain the new functions:
SetReplacements
(e, n, i)
: Set how many times the AI replaces preplaced units of the same type, in the code above, it makes this replacement up to one unit, up to 2 units for normal mode and up to 3 units of a type in insane mode. (thanks
Starquizer
for the discovery
)
CampaignDefenderEx
(e, n, i, UnitID)
: similar to
SetUnitBuild
, but the units trained with this function will be replaced if they're killed n times according with the function
SetReplacements
.
Now the defensive strategy for this AI is arranged (at the moment) as:
Defensive Strategy
Easy
Normal
Insane
Archers
2
2
3
Huntress
1
1
1
Ancient Protector
0
1
2
Attacking Strategy
Now this baby is ready to fight, so we need to make the AI takes some units and order them to attack a target. The function structure is as follows:
Attack Function Arrangement
Code: jass
function
main
takes
nothing
returns
nothing
// Building code goes here
//*** WAVE 1 ***
call
InitAssaultGroup
()
// <==(1)
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
// <==(2)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 0, 1, 1,
BALLISTA
)
call
SuicideOnPlayerEx
(
M2
,
M3
,
M3
, MyVictim )
// <==(3)
endfunction
These functions do the following:
InitAssaultGroup
()
: Clear any previous assault group and creates a new empty one.
CampaignAttackerEx
( e, n, i, UnitID )
: Like
SetBuildUnitEx
but adds these units to the assault group.
SuicideOnPlayerEx
( te, tn, ti, TargetPlayer )
: Waits
te
seconds in easy mode,
tn
seconds in normal mode and
ti
seconds in insane mode to attack the specified player.
One question is: what does it mean M2, M3??? well, M2 is two minutes (2*60 sec.), M3 is three minutes (3*60 sec.) an so on. We can use values from M1 to M15. You can check it out these constants in the
common.ai
file.
Note
There are other ways to get enemies to attack.
SuicideOnPlayerEx
gets the main player town hall (player start location), but probably you want to take a specific unit, so you will need to use a function like
AttackMoveKillA
( TargetUnit )
. as an example, this script will attack a creep camp, targeting a specific creep:
Attack script for creeping
Code: jass
function
main
takes
nothing
returns
nothing
local
unit
crp
// Building code goes here
//*** WAVE 1 ***
call
InitAssaultGroup
()
set
crp =
GetCreepCamp
(0,9,
false
)
// Stores the target unit
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
Sleep
(
M3
)
// Waits 3 minutes before attacking
call
AttackMoveKillA
(crp)
// Order assault group to attack that unit
endfunction
Where:
GetCreepCamp
( min, max, flyers )
: Get a creep unit in a camp with a strength between
min
and
max
including
(flyers=true)
or not including
(flyers=false)
flying creeps.
Sleep
( n )
: put the script to wait
n
seconds.
AttackMoveKillA
( Unit )
: Order assault group to attack that unit.
Now we have this wave working. the idea is to add more waves, incrementing the amount of units or their type (for example one wave with tier 1 units, other with more tier 1 units, the next with tier 1 and 2 units and casters, etc). check this example:
Building + Attacking script. All tiers
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
//
// Tier 1 Buildings
call
SetReplacements
( 1, 2, 3 )
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
call
CampaignDefenderEx
( 0, 1, 2,
ANCIENT_PROTECT
)
// Tier 2 buildings
call
SetBuildUnit
( 1,
TREE_AGES
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_LORE
)
call
SetBuildUnit
( 1,
ANCIENT_WIND
)
// Tier 3 buildings
call
SetBuildUnit
( 1,
TREE_ETERNITY
)
call
SetBuildUnitEx
( 0, 1, 1,
CHIMAERA_ROOST
)
// **********************************
// * End Building Strategy *
// **********************************
// **********************************
// * Attack Strategy *
// **********************************
//*** WAVE 1 ***
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 2 *** Between 2 or 3 minutes after Wave 1
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 3 *** Between 2 or 3 minutes after Wave 2
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 4 *** Between 2 or 3 minutes after Wave 3
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 5 *** Between 3 or 4 minutes after Wave 4
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 0, 1, 2,
DRYAD
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** WAVE 6 *** Between 3 or 4 minutes after Wave 5
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** WAVE 7 *** Between 3 or 5 minutes after Wave 6
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 8 *** Between 3 or 5 minutes after Wave 7
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
//*** WAVE 9 *** Between 4 or 6 minutes after Wave 8
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
CampaignAttackerEx
( 1, 1, 2,
FAERIE_DRAGON
)
call
CampaignAttackerEx
( 0, 1, 2,
CHIMAERA
)
call
SuicideOnPlayerEx
(
M6
,
M5
,
M4
, MyVictim )
// **********************************
// * End Attack Strategy *
// **********************************
endfunction
After training the last wave, the script is finished and the AI won't send more units to attack the target player. If you require the the attack never ends we can add a loop to the script, so it will repeat for example the last three waves. The scripts will look like this:
Building + Attacking script with infinite loop. All tiers
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
//
// Tier 1 Buildings
call
SetReplacements
( 1, 2, 3 )
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
call
CampaignDefenderEx
( 0, 1, 2,
ANCIENT_PROTECT
)
// Tier 2 buildings
call
SetBuildUnit
( 1,
TREE_AGES
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_LORE
)
call
SetBuildUnit
( 1,
ANCIENT_WIND
)
// Tier 3 buildings
call
SetBuildUnit
( 1,
TREE_ETERNITY
)
call
SetBuildUnitEx
( 0, 1, 1,
CHIMAERA_ROOST
)
// **********************************
// * End Building Strategy *
// **********************************
// **********************************
// * Attack Strategy *
// **********************************
//*** WAVE 1 ***
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 2 *** Between 2 or 3 minutes after Wave 1
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 3 *** Between 2 or 3 minutes after Wave 2
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 4 *** Between 2 or 3 minutes after Wave 3
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 5 *** Between 3 or 4 minutes after Wave 4
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 0, 1, 2,
DRYAD
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** WAVE 6 *** Between 3 or 4 minutes after Wave 5
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
loop
//Init the infinite attack loop
//*** WAVE 7 *** Between 3 or 5 minutes after Wave 6
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 8 *** Between 3 or 5 minutes after Wave 7
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
//*** WAVE 9 *** Between 4 or 6 minutes after Wave 8
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
CampaignAttackerEx
( 1, 1, 2,
FAERIE_DRAGON
)
call
CampaignAttackerEx
( 0, 1, 2,
CHIMAERA
)
call
SuicideOnPlayerEx
(
M6
,
M5
,
M4
, MyVictim )
endloop
// **********************************
// * Attack Strategy never ends *
// **********************************
endfunction
Upgrading Strategy.
We have almost all the AI. Now it's time to add the upgrades. They can be put in any place inside the code, but I suggest to put this upgrades between each wave, so the AI has a progressive evolution in damage and looks more natural.
Let's see the functions that we're going to use:
SetBuildUpgrEx
( e, n, i, UpgradeID )
: Sets the levels of the upgrade that will be done by the AI in
e
asy,
n
ormal and
i
nsane mode.
The script now will look in this way:
Building + Attacking script with infinite loop + Upgrading scripts. All tiers
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
null
)
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
//
// Tier 1 Buildings
call
SetReplacements
( 1, 2, 3 )
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
call
SetBuildUnitEx
( 0, 1, 2,
ANCIENT_PROTECT
)
// Tier 2 buildings
call
SetBuildUnit
( 1,
TREE_AGES
)
call
SetBuildUnitEx
( 1, 1, 2,
ANCIENT_LORE
)
call
SetBuildUnit
( 1,
ANCIENT_WIND
)
// Tier 3 buildings
call
SetBuildUnit
( 1,
TREE_ETERNITY
)
call
SetBuildUnitEx
( 0, 1, 1,
CHIMAERA_ROOST
)
// **********************************
// * End Building Strategy *
// **********************************
// **********************************
// * Attack Strategy *
// **********************************
//*** WAVE 1 *** AI will begin to attack in 5 minutes
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M5
,
M5
,
M5
, MyVictim )
//*** Basic upgrades from HUNTERS HALL ***
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_MOON
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_MOON_ARMOR
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_WILD
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_HIDES
)
//*** WAVE 2 *** Between 2 or 3 minutes after Wave 1
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 3 *** Between 2 or 3 minutes after Wave 2
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 4 *** Between 2 or 3 minutes after Wave 3
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 0, 1, 1,
BALLISTA
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** Dryad Upgrade
call
SetBuildUpgrEx
( 1, 1, 1,
UPG_ABOLISH
)
//*** WAVE 5 *** Between 3 or 4 minutes after Wave 4
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 0, 1, 2,
DRYAD
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** Druid of the Claw Upgrade
call
SetBuildUpgrEx
( 0, 1, 2,
UPG_DRUID_CLAW
)
//*** WAVE 6 *** Between 3 or 4 minutes after Wave 5
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** chimaera Upgrade
call
SetBuildUpgrEx
( 0, 0, 1,
UPG_CHIM_ACID
)
loop
//Init the infinite attack loop
//*** WAVE 7 *** Between 3 or 5 minutes after Wave 6
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 8 *** Between 3 or 5 minutes after Wave 7
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
//*** WAVE 9 *** Between 4 or 6 minutes after Wave 8
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
CampaignAttackerEx
( 1, 1, 2,
FAERIE_DRAGON
)
call
CampaignAttackerEx
( 0, 1, 2,
CHIMAERA
)
call
SuicideOnPlayerEx
(
M6
,
M5
,
M4
, MyVictim )
endloop
// **********************************
// * Attack Strategy never ends *
// **********************************
endfunction
Hero Abilities.
If we test this AI, we can notice that heroes don't learn any abilities, the question is how can we make that??? the answer is adding the ability learning script to the function
CampaignAI
. This function will have an effect when the hero has ability levels avaliable. I made this script so it can fix with the example, which trains a Demon Hunter and a Priestress of the Moon.
Hero Leveling Script
Code: jass
function
hero_levels
takes
nothing
returns
integer
local
integer
hero =
GetHeroId
()
local
integer
level =
GetHeroLevelAI
()
local
integer
a = 0
if
hero ==
DEMON_HUNTER
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
IMMOLATION
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
MANA_BURN
endif
if
level >= 8
then
set
a =
EVASION
endif
if
level == 6
then
set
a =
METAMORPHOSIS
endif
endif
if
hero ==
MOON_CHICK
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
TRUESHOT
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
SEARING_ARROWS
endif
if
level >= 8
then
set
a =
SCOUT
endif
if
level == 6
then
set
a =
STARFALL
endif
endif
return
a
endfunction
As you can see, this function takes nothing and returns the ability Rawcode that the hero must learn. REMEMBER: This function
MUST
return an integer
ALWAYS
.
Now that we have this function configured, we are going to add to the script, remeber that it must be put bafore the
main
function so it can call it. To set the function in the main script, we write it in this way:
call
CampaignAI
(
MOON_WELL
,
function
hero_levels )
And the whole code will llook like this:
Building + Attacking script with infinite loop + Upgrading (including heroes) scripts. All tiers
Code: jass
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
hero_levels
takes
nothing
returns
integer
local
integer
hero =
GetHeroId
()
local
integer
level =
GetHeroLevelAI
()
local
integer
a = 0
if
hero ==
DEMON_HUNTER
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
IMMOLATION
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
MANA_BURN
endif
if
level >= 8
then
set
a =
EVASION
endif
if
level == 6
then
set
a =
METAMORPHOSIS
endif
endif
if
hero ==
MOON_CHICK
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
TRUESHOT
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
SEARING_ARROWS
endif
if
level >= 8
then
set
a =
SCOUT
endif
if
level == 6
then
set
a =
STARFALL
endif
endif
return
a
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
function
hero_levels )
//<== Now this function upgrades heroes
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
//
// Tier 1 Buildings
call
SetReplacements
( 1, 2, 3 )
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 2, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
call
SetBuildUnitEx
( 1, 2, 3,
ANCIENT_PROTECT
)
// Tier 2 buildings
call
SetBuildUnit
( 1,
TREE_AGES
)
call
SetBuildUnitEx
( 1, 2, 2,
ANCIENT_LORE
)
call
SetBuildUnit
( 1,
ANCIENT_WIND
)
// Tier 3 buildings
call
SetBuildUnit
( 1,
TREE_ETERNITY
)
call
SetBuildUnitEx
( 0, 1, 1,
CHIMAERA_ROOST
)
// **********************************
// * End Building Strategy *
// **********************************
// **********************************
// * Attack Strategy *
// **********************************
//*** WAVE 1 *** AI will begin to attack in 5 minutes
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M5
,
M5
,
M5
, MyVictim )
//*** Basic upgrades from HUNTERS HALL ***
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_MOON
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_MOON_ARMOR
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_WILD
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_HIDES
)
//*** WAVE 2 *** Between 2 or 3 minutes after Wave 1
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 3 *** Between 2 or 3 minutes after Wave 2
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 4 *** Between 2 or 3 minutes after Wave 3
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 0, 1, 1,
BALLISTA
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** Dryad Upgrade
call
SetBuildUpgrEx
( 1, 1, 1,
UPG_ABOLISH
)
//*** WAVE 5 *** Between 3 or 4 minutes after Wave 4
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 0, 1, 2,
DRYAD
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** Druid of the Claw Upgrade
call
SetBuildUpgrEx
( 0, 1, 2,
UPG_DRUID_CLAW
)
//*** WAVE 6 *** Between 3 or 4 minutes after Wave 5
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** chimaera Upgrade
call
SetBuildUpgrEx
( 0, 0, 1,
UPG_CHIM_ACID
)
loop
//Init the infinite attack loop
//*** WAVE 7 *** Between 3 or 5 minutes after Wave 6
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 8 *** Between 3 or 5 minutes after Wave 7
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
//*** WAVE 9 *** Between 4 or 6 minutes after Wave 8
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
CampaignAttackerEx
( 1, 1, 2,
FAERIE_DRAGON
)
call
CampaignAttackerEx
( 0, 1, 2,
CHIMAERA
)
call
SuicideOnPlayerEx
(
M6
,
M5
,
M4
, MyVictim )
endloop
// **********************************
// * Attack Strategy never ends *
// **********************************
endfunction
Controlling the AI via triggers.
when we're creating a campaign, we need to keep the AI controlled in some way, for example we need that the AI attacks when an unit enters on a region or the player kills some unit. As an example, We are going to create a trigger that will start the AI attacks when an unit enters in one region.
Start AI attack
Events
Unit -
A unit enters Militia birth1 <gen>
Conditions
(Owner of (Triggering unit)) Equal to Player 1 (Red)
Actions
AI -
Send Player 2 (Blue) the AI Command (0, 0)
Custom script:
call DestroyTrigger( GetTriggeringTrigger() )
And now we need that the AI begins when it receives this AI Command, it can be done putting the function
WaitForSignal
()
before the attacking script in the AI. This function takes nothing and returns an integer that is the command received. So we can use this function in two ways.
Code: jass
function
main
takes
nothing
returns
nothing
local
integer
cmd
// <==Only set it if you are going to use the option 2
...
// Your building code here
// Option 1
call
WaitForSignal
()
// <== Just waits until the map sends a command
// Option 2
set
cmd =
WaitForSignal
()
// <== Get the command received and makes react the AI accordingly.
if
cmd == 0
then
//do option 0
elseif
cmd == 1
then
//do option 1. etc
...
endif
endfunction
The second option is the most interesting because we can make react the AI in different ways (for example, that one time attack the player 1 and in other time attack the player 3, etc.)
Testing the AI.
Now the most important part. If we want to test this AI there's two ways, the slowest but the most accurate, which we attach the AI file inside the map and run it to check how it bahaves (check this
tutorial
from Av3n about AI importing) or the fastest one. I'll explain the fastest one.
Save your AI script as an
*.AI
file.
Open WE
Press
F8
or make click on the button AI Editor.
With the AI Editor open, select the fourth tab
Test Configuration
Here, set the game speed in 3X (Now you understand why it's the fastest way)
Set the map where you want to test your AI. By default, WE sets the PlunderIsle map. You can change it pressing the button [BUTTON]Set Map[/BUTTON].
Set your Players. Remember that if you configure the AI to attack player 1 (Player(0) in JASS) you MUST use a slot different to 1 so it can works. it sounds redundant, but sometimes we forget it.
Set the race of your AI accordingly (don't put human or random race in a Night Elf AI fr example).
for the slot where our AI will work, change in the AI option to
Custom
. when you do that, it activates a button with label [BUTTON]Set[/BUTTON]. Press it, and you can select the AI file that you have created.
Set the target player as a computer with a current AI.
Ensure that your AI player and the target player are in different teams.
Set an user player as an observer in the team selection.
Press CTRL + F9 or the button
Test AI
Here's an AI Editor screenshot that shows how you should have configured this test:
And the test will run. If the AI works fine you will see the workers starting buildings. :emote_grin:
If you see workers only gathering resources and don't do anything else, it means that you have a JASS error in you file, check the syntax, save and test again, remember that JASS is case sensitive so a lower case letter will do the AI fail.
[BTABLE=Final Thoughts]I Hope this tutorial can be helpful to everybody. If I have time, I'll try to do other tutorial about Standard AI. Suggestions and questions are welcome.
Meanwhile, play with this AI, change the units, do experiments with it, it is the only way to get more knowledge about the Wacraft AI.[/BTABLE]
PS: Because I'm still learning English, I could have commited some mistakes, please let me know about that and I will fix them ASAP.
"Campaign Complete"
Campaign script complete
Code: jass
//******************************************************************************
//* Night Elf Campaign AI *
//* By Moyack *
//******************************************************************************
//*
globals
player
MyVictim =
Player
( 0 )
endglobals
function
ConfigureAI
takes
nothing
returns
nothing
call
SetSlowChopping
(
false
)
call
SetPeonsRepair
(
true
)
endfunction
function
hero_levels
takes
nothing
returns
integer
local
integer
hero =
GetHeroId
()
local
integer
level =
GetHeroLevelAI
()
local
integer
a = 0
if
hero ==
DEMON_HUNTER
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
IMMOLATION
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
MANA_BURN
endif
if
level >= 8
then
set
a =
EVASION
endif
if
level == 6
then
set
a =
METAMORPHOSIS
endif
endif
if
hero ==
MOON_CHICK
then
if
level == 1
or
level == 3
or
level == 5
then
set
a =
TRUESHOT
endif
if
level == 2
or
level == 4
or
level == 7
then
set
a =
SEARING_ARROWS
endif
if
level >= 8
then
set
a =
SCOUT
endif
if
level == 6
then
set
a =
STARFALL
endif
endif
return
a
endfunction
function
main
takes
nothing
returns
nothing
call
CampaignAI
(
MOON_WELL
,
function
hero_levels )
call
ConfigureAI( )
// **********************************
// * Building Strategy *
// **********************************
//
// Tier 1 Buildings
call
SetReplacements
( 1, 2, 3 )
call
SetBuildUnitEx
( 1, 1, 1,
TREE_LIFE
)
call
SetBuildUnit
( 15,
WISP
)
call
SetBuildUnitEx
( 1, 2, 3,
MOON_WELL
)
call
SetBuildUnitEx
( 1, 2, 2,
ANCIENT_WAR
)
call
SetBuildUnit
( 1,
ELF_ALTAR
)
call
SetBuildUnit
( 1,
HUNTERS_HALL
)
call
CampaignDefenderEx
( 2, 2, 3,
ARCHER
)
call
CampaignDefenderEx
( 1, 1, 1,
HUNTRESS
)
call
SetBuildUnitEx
( 1, 2, 3,
ANCIENT_PROTECT
)
// Tier 2 buildings
call
SetBuildUnit
( 1,
TREE_AGES
)
call
SetBuildUnitEx
( 1, 2, 2,
ANCIENT_LORE
)
call
SetBuildUnit
( 1,
ANCIENT_WIND
)
// Tier 3 buildings
call
SetBuildUnit
( 1,
TREE_ETERNITY
)
call
SetBuildUnitEx
( 0, 1, 1,
CHIMAERA_ROOST
)
// **********************************
// * End Building Strategy *
// **********************************
// **********************************
// * Attack Strategy *
// **********************************
//*** WAVE 1 *** AI will begin to attack in 5 minutes
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 0, 1, 2,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M5
,
M5
,
M5
, MyVictim )
//*** Basic upgrades from HUNTERS HALL ***
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_MOON
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_MOON_ARMOR
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_STR_WILD
)
call
SetBuildUpgrEx
( 1, 2, 3,
UPG_HIDES
)
//*** WAVE 2 *** Between 2 or 3 minutes after Wave 1
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 3 *** Between 2 or 3 minutes after Wave 2
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** WAVE 4 *** Between 2 or 3 minutes after Wave 3
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 4, 4,
ARCHER
)
call
CampaignAttackerEx
( 1, 2, 3,
HUNTRESS
)
call
CampaignAttackerEx
( 0, 1, 1,
BALLISTA
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
SuicideOnPlayerEx
(
M3
,
M2
,
M2
, MyVictim )
//*** Dryad Upgrade
call
SetBuildUpgrEx
( 1, 1, 1,
UPG_ABOLISH
)
//*** WAVE 5 *** Between 3 or 4 minutes after Wave 4
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 3, 3, 3,
ARCHER
)
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 0, 1, 2,
DRYAD
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** Druid of the Claw Upgrade
call
SetBuildUpgrEx
( 0, 1, 2,
UPG_DRUID_CLAW
)
//*** WAVE 6 *** Between 3 or 4 minutes after Wave 5
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M4
,
M3
,
M3
, MyVictim )
//*** chimaera Upgrade
call
SetBuildUpgrEx
( 0, 0, 1,
UPG_CHIM_ACID
)
loop
//Init the infinite attack loop
//*** WAVE 7 *** Between 3 or 5 minutes after Wave 6
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 8 *** Between 3 or 5 minutes after Wave 7
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
SuicideOnPlayerEx
(
M5
,
M4
,
M3
, MyVictim )
//*** WAVE 9 *** Between 4 or 6 minutes after Wave 8
call
InitAssaultGroup
()
call
CampaignAttackerEx
( 2, 2, 2,
HUNTRESS
)
call
CampaignAttackerEx
( 1, 1, 1,
DEMON_HUNTER
)
call
CampaignAttackerEx
( 1, 1, 1,
MOON_CHICK
)
call
CampaignAttackerEx
( 1, 2, 3,
DRYAD
)
call
CampaignAttackerEx
( 0, 1, 2,
DRUID_CLAW
)
call
CampaignAttackerEx
( 0, 1, 2,
MOUNTAIN_GIANT
)
call
CampaignAttackerEx
( 1, 1, 2,
FAERIE_DRAGON
)
call
CampaignAttackerEx
( 0, 1, 2,
CHIMAERA
)
call
SuicideOnPlayerEx
(
M6
,
M5
,
M4
, MyVictim )
endloop
// **********************************
// * Attack Strategy never ends *
// **********************************
endfunction
«
Last Edit: March 20, 2020, 07:34:35 PM by moyack
»
WC3 Modding Information Center
moyack
Site Owner
Administrator
Posts:
971
WC3 Models: 20
WC3 Tutorials: 17
WC3 Tools: 19
WC3 Maps: 12
WC3 Skins: 0
WC3 Icons: 1
WC3 Spells: 16
Reputation:
1153
Site Admin - I love fix things
How to make a Campaign AI
Reply #1 on:
January 20, 2013, 10:35:54 PM
Updated with a fix in the definition of a function. Thanks
Starquizer
«
Last Edit: June 24, 2017, 11:44:43 PM by moyack
»
WC3 Modding Information Center
Print
Pages:
1
Go Up
« previous
next »
WC3 Modding Information Center
Forum
Warcraft (WC3) Modding
Triggers & Scripting
WC3JASS.com
Jass Tutorials
How to make a Campaign AI
Suggested Topics
vJASS Syntax Highlighter for notepad++
Started by
moyack
Replies: 2
Views: 6131
WC3 Editing Tools
Jassdoc introduction
Started by
moyack
Replies: 3
Views: 4229
Jassdoc
The Jass NewGen Pack (JNGP) 2.0
Started by
moyack
Replies: 225
Views: 315333
WC3 Editing Tools
coding efficient vjass structs
Started by
nestharus
Replies: 0
Views: 2288
Jass Tutorials
wc3jass.... R.I.P??
Started by
moyack
Replies: 1
Views: 8085
Tavern
PortaMx-SEF 1.54
|
PortaMx © 2008-2015
,
PortaMx corp.
Search
Username
Password
Always stay logged in
Forgot your password?