Create an AI Final Wave

Level 11
Joined
Sep 30, 2017
Messages
169
Hello everyone, I just need a little help. How to create a final wave like in the ones with defensive missions? (Like Humans 05 Arthas) I have created an AI script based upon one of the undead players in that mission, but still the AI doesn't work. Any tips?

JASS:
//============================================================================
//  Chapter02 -- Brown player -- AI Script
//============================================================================
globals
    player Target = PlayerEx(4) //player 4 Purple 
    
    constant integer Peasant = 'h60C'
    constant integer Swordsman = 'h601'
    constant integer Bowman = 'n605'
    constant integer Mage = 'h60X'
    constant integer Catapult = 'o601'
    constant integer Protector = 'h60Y'
    constant integer Sargeant = 'H62T'
    constant integer Cavalier = 'h602'
    constant integer Sorceress = 'h60Z'
    constant integer Ballista = 'e600'
    constant integer Armor_Piercing = 'R605'
    constant integer Great_Bows = 'R603'
    constant integer Iron_Forged_Swords = 'R600'
    constant integer Long_Bows = 'R604'
    constant integer Shieldwall = 'R606'
    constant integer Sorceress_Adept_Training = 'R60P'
    constant integer Mage_Adept_Training = 'R60M'
    constant integer Scalemail_Armor = 'R601'
    constant integer Ranger_Armorset = 'R602'
endglobals

function main takes nothing returns nothing
    call CampaignAI('h60G',null) //House
    call SetReplacements(1,1,1)
    call GroupTimedLife(true)
    call SetPeonsRepair(true)
    call SetSlowChopping(true)
    set campaign_wood_peons = 3

    //Building Strategy
    //Tier 1
    call SetBuildUnitEx(10,10,10,Peasant) //Peasant
    call SetBuildUnitEx(2,2,2,'h60I') //Barracks
    call SetBuildUnitEx(3,3,3,'h60O') //Watch Tower
    call SetBuildUnitEx(7,7,7,'h60P') //Guard Tower
    call SetBuildUnitEx(1,1,1,'h60H') //Altar
    call SetBuildUnitEx(1,1,1,'h60J') //Saw Mill
    call SetBuildUnitEx(1,1,1,'h60K') //Blacksmith
    call SetBuildUnitEx(30,30,30,'h60G') //House
    //Tier 2
    call SetBuildUnitEx(1,1,1,'h60L') //Siege Workshop
    call SetBuildUnitEx(1,1,1,'h60T') //Market
    call SetBuildUnitEx(2,2,2,'h610') //Arcane Tower
    call SetBuildUnitEx(3,3,3,'h60Q') //Cannon Tower
    //Tier 3
    call SetBuildUnitEx(1,1,1,'h60F') //Palace
    //Build Units
    call SetBuildUnitEx(9,9,9,Swordsman) //Swordsman
    call SetBuildUnitEx(6,6,6,Bowman) //Bishop
    call SetBuildUnitEx(1,1,1,Cavalier) //Cavalier
    call SetBuildUnitEx(1,1,1,Sargeant) //Sergeant
    call SetBuildUnitEx(2,2,2,Protector) //Protector
    call SetBuildUnitEx(2,2,2,Sorceress) //Sorceress
    call SetBuildUnitEx(2,2,2,Catapult) //Catapult
    call SetBuildUpgrEx( 1,1,1,Iron_Forged_Swords)
    call SetBuildUpgrEx( 1,1,1,Armor_Piercing)
    call SetBuildUpgrEx( 1,1,1,Long_Bows)
    call SetBuildUpgrEx( 1,1,1,Shieldwall)
    call SetBuildUpgrEx( 1,1,1,Great_Bows)
    call SetBuildUpgrEx( 1,1,1,Sorceress_Adept_Training)
    call SetBuildUpgrEx( 1,1,1,Mage_Adept_Training)
    //Defenders Units
    call CampaignDefenderEx(2,2,2,Swordsman)  //Swordsman
    call CampaignDefenderEx(2,2,2,Mage) //Mage
    call CampaignDefenderEx(1,1,1,Cavalier) //Cavalier
    call CampaignDefenderEx(1,1,1,Catapult) //Catapult
    
    call WaitForSignal()
    
    set allow_signal_abort = true

    //Attack Waves

    //Wave 1
    call InitAssaultGroup()
    call CampaignAttackerEx(4,4,4,Swordsman)
    call CampaignAttackerEx(3,3,3,Bowman)
    call CampaignAttackerEx(1,1,1,Protector)
    call SuicideOnPlayerEx(M3,M3,M3,Target)
    
    //Wave 2
    call InitAssaultGroup()
    call CampaignAttackerEx(4,4,4,Swordsman)
    call CampaignAttackerEx(3,3,3,Bowman)
    call CampaignAttackerEx(2,2,2,Cavalier)
    call CampaignAttackerEx(2,2,2,Mage)
    call SuicideOnPlayerEx(M3,M3,M3,Target)
    
    //Wave 3
    call InitAssaultGroup()
    call CampaignAttackerEx(5,5,5,Swordsman)
    call CampaignAttackerEx(4,4,4,Bowman)
    call CampaignAttackerEx(1,1,1,Sargeant)
    call CampaignAttackerEx(1,1,1,Catapult)
    call CampaignAttackerEx(2,2,2,Mage)
    call SuicideOnPlayerEx(M3,M3,M3,Target)
    
    
    loop
        //Wave 5
        call InitAssaultGroup()
        call CampaignAttackerEx(4,4,4,Swordsman)
        call CampaignAttackerEx(3,3,3,Bowman)
        call CampaignAttackerEx(2,2,2,Cavalier)
        call CampaignAttackerEx(2,2,2,Mage)
        call CampaignAttackerEx(2,2,2,Sorceress)
        call SuicideOnPlayerEx(M3,M3,M3,Target)
        
        //Wave 7
        call InitAssaultGroup()
        call CampaignAttackerEx(4,4,4,Swordsman)
        call CampaignAttackerEx(3,3,3,Bowman)
        call CampaignAttackerEx(1,1,1,Sargeant)
        call CampaignAttackerEx(2,2,2,Cavalier)
        call SuicideOnPlayerEx(M3,M3,M3,Target)
        
        //Wave 8
        call InitAssaultGroup()
        call CampaignAttackerEx(5,5,5,Swordsman)
        call CampaignAttackerEx(3,3,3,Bowman)
        call CampaignAttackerEx(3,3,3,Cavalier)
        call CampaignAttackerEx(1,1,1,Sargeant)
        call CampaignAttackerEx(2,2,2,Mage)
        call CampaignAttackerEx(2,2,2,Sorceress)
        call SuicideOnPlayerEx(M3,M3,M3,Target)
              
    endloop
    
    call SuicideUnits( Swordsman, Bowman, Cavalier, Sargeant, Mage, Sorceress, Catapult, 0 )
    
endfunction
 
SuicideUnits takes 10 arguments, right now you have 8 so that causes the whole script to be regarded as faulty. Try like this

JASS:
call SuicideUnits( Swordsman, Bowman, Cavalier, Sargeant, Mage, Sorceress, Catapult, 0, 0, 0 )

That being said, I'm not sure that function can run because it's after a loop, although I can be wrong about it. Still, if you want that to happen at the end of the mission, I'd use a WaitForSignal right before and then send the signal via trigger
 
SuicideUnits takes 10 arguments, right now you have 8 so that causes the whole script to be regarded as faulty. Try like this

JASS:
call SuicideUnits( Swordsman, Bowman, Cavalier, Sargeant, Mage, Sorceress, Catapult, 0, 0, 0 )

That being said, I'm not sure that function can run because it's after a loop, although I can be wrong about it. Still, if you want that to happen at the end of the mission, I'd use a WaitForSignal right before and then send the signal via trigger
Yeah I wouldn't use a loop if it's exactly a scenario like the Human 05 mission. Unless you need an infinite loop until an event happens (which can occur on 30th min or 50th min etc, depending on the player).
I've never exited a loop before in JASS now that I think about it.

Something I wanted to ask @Chaosium:
so call SuicideUnits() will not work with more than 10 arguments?
 
SuicideUnits takes 10 arguments, right now you have 8 so that causes the whole script to be regarded as faulty. Try like this

JASS:
call SuicideUnits( Swordsman, Bowman, Cavalier, Sargeant, Mage, Sorceress, Catapult, 0, 0, 0 )

That being said, I'm not sure that function can run because it's after a loop, although I can be wrong about it. Still, if you want that to happen at the end of the mission, I'd use a WaitForSignal right before and then send the signal via trigger
so i did what you said and the AI works now, but noe the AI doesn't send the final wave and also the game starts to lag a bit. I think it's something to do with the loop but i have no idea how to fix this, really.
 
so i did what you said and the AI works now, but noe the AI doesn't send the final wave and also the game starts to lag a bit. I think it's something to do with the loop but i have no idea how to fix this, really.
What @Chaosium said.
Just remove the loop. You can keep the initial call WaitForSignal()
simply add another call WaitForSignal() before the mass suicide attack and call the trigger again -> AI - Send Command(0, 0)
when you need it.
I think it will skip any pending attack waves and directly send the suicide, because imagine you have 10 normal attack waves before that, with 3 minute interval between each one. Meaning that it'll take 30 minutes (more or less) for all 10 normal attack waves to complete. Now imagine you call the signal for the mass suicide attack wave on the 20th minute for whatever reason. I believe that it will skip the remaining normal attack waves and directly force the AI to do the mass suicide attack wave. Although I recommend doing the math yourself so more or less the mass suicide attack wave is called (with some delay) after the final normal attack.
 
The problem is that it is an infinite loop, and i think one function can run only 2^13 lines until it stops - to prevent infinite loops. So the part after the loop never gets called.
if you want to run the code a certain amount of times, do something like this
JASS:
local integer i = 0
loop
   exitwhen i > 3
   // do stuff
   set i = i + 1
endloop

if you want the code to be executed in a certain interval, you have to use timers.
 
Back
Top