• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Ai won't harvest wood if player is night elf

Status
Not open for further replies.
Level 10
Joined
Jun 6, 2007
Messages
392
I have replaced standard races with custom races and made an ai for each race. Everything works as it should, except that demons (replaces night elf race) don't harvest wood. Here's the trigger I use to replace starting units:
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked player) is in (All players controlled by a User player)) Equal to False
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Race of (Picked player)) Equal to Human
                • Then - Actions
                  • Unit Group - Pick every unit in (Units owned by (Picked player)) and do (Actions)
                    • Loop - Actions
                      • Unit - Remove (Picked unit) from the game
                  • Unit - Create 1 Town Hall (custom) for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                  • Unit - Create 5 Worker for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                  • AI - Start melee AI script for (Picked player): war3mapImported\ElfTestAi.ai
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Race of (Picked player)) Equal to Orc
                    • Then - Actions
                      • Unit Group - Pick every unit in (Units owned by (Picked player)) and do (Actions)
                        • Loop - Actions
                          • Unit - Remove (Picked unit) from the game
                      • Unit - Create 1 Great Hall for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                      • Unit - Create 5 Peon for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                      • AI - Start melee AI script for (Picked player): war3mapImported\OrcTestAi.ai
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Race of (Picked player)) Equal to Undead
                        • Then - Actions
                          • Unit Group - Pick every unit in (Units owned by (Picked player)) and do (Actions)
                            • Loop - Actions
                              • Unit - Remove (Picked unit) from the game
                          • Unit - Create 1 Necropolis for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • Unit - Create 5 Acolyte for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • AI - Start melee AI script for (Picked player): war3mapImported\UndeadTestAi.ai
                        • Else - Actions
                          • Unit Group - Pick every unit in (Units owned by (Picked player)) and do (Actions)
                            • Loop - Actions
                              • Unit - Remove (Picked unit) from the game
                          • Unit - Create 1 Hall of Chaos for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • Unit - Create 5 Demon Worker for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • AI - Start melee AI script for (Picked player): war3mapImported\DemonTestAi.ai
            • Else - Actions
If I replace any other race with demon units, they harvest wood just as they should, so it I don't think the problem is in the ai script. I even tried removing gold from harvest priorities, but they still harvest gold, but not wood. Demon workers have an ability to harvest gold and lumber, just like peons.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
What is DemonTestAi even, we can't tell what is the problem just by this trigger.

Also human using a file with name elf, madness.
 
Level 10
Joined
Jun 6, 2007
Messages
392
The script runs, because workers build. I made the following test: I swapped the actions in orc part with the actions in else (hight elf) part. Result: Demon race worked as it should, but orcs only gathered gold.

I can paste demon test ai here, though I don't think that's the issue. It's based on an ai file made by ai editor, so it contains some useless functions and other stuff. Demon ai works if the replaced player isn't night elf.
JASS:
//===========================================================================
// 
// ElfAi
// 
//   Warcraft III AI script
//   Generated by the Warcraft III World Editor
//   Date: Tue Aug 12 10:18:27 2014
// 
//===========================================================================

//***************************************************************************
//*
//*  Global Variables
//*
//***************************************************************************

globals
    integer D_WAR_ZEPPELIN              = 'h00M'
    integer D_VOIDWALKER                = 'h007'
    integer D_INFERNAL_MACHINE          = 'o00P'
    integer D_EFREETI                   = 'o00Q'
    integer D_NETHER_DRAKE              = 'n00F'
    integer D_BLOODFIEND                = 'n000'
    integer D_OVERLORD                  = 'n001'
    integer D_IMP                       = 'n00A'
    integer D_BEHOLDER                  = 'n00E'
    integer D_DOOMBRINGER               = 'n00G'
    integer D_DEMON_WORKER              = 'n003'
        
    integer D_HALL_OF_CHAOS             = 'o00E'
    integer D_HALL_OF_CORRUPTION        = 'o00F'
    integer D_HALL_OF_DOOM              = 'o00G'
    integer D_ALTAR_OF_CHAOS            = 'o012'
    integer D_SUMMONING_PORTAL          = 'o00H'
    integer D_DEMONIC_SHRINE            = 'o011'
    integer D_DEMON_GATE                = 'o014'
    integer D_SHRINE_OF_THE_DEATHWALKER = 'o013'
    integer D_BLOOD_PIT                 = 'o00N'
    integer D_DEMON_TOWER               = 'n00O'
    integer D_FUSION_CANNON             = 'n00P'
    integer D_IMMOLATOR                 = 'n00N'
        
    integer D_SUCCUBUS_MISTRESS         = 'E006'
    integer D_CHAOS_GENERAL             = 'O00T'
    integer D_WARLOCK                   = 'U001'
    
    integer MARK_OF_DOOM                = 'A02T'
    integer LIFE_DRAIN                  = 'A02U'
    integer AURA_OF_SWIFTNESS           = 'A003'
    integer SEDUCTION                   = 'A024'
    
    integer DEMONIC_LEAP                = 'A04F'
    integer CLEAVE                      = 'A04G'
    integer INSPIRING_PRESENCE          = 'A039'
    integer ARMAGEDDON                  = 'A02B'
    
    integer CHAOS_STRIKE                = 'A006'
    integer DARK_MINIONS                = 'A008'
    integer COUNTERSPELL                = 'A043'
    integer DIMENSIONAL_PORTAL          = 'A03J'
    
    integer UPG_CHAOS_ARMOR             = 'R00W'
    integer UPG_CORRUPTING_ATTACK       = 'R00Z'
    integer UPG_EFREETI                 = 'R011'
    integer UPG_FATAL_WEEP              = 'R012'
    integer UPG_IMPROVED_WEAPONS        = 'R00Y'
    integer UPG_MANA_LEECH              = 'R013'
    integer UPG_PLASMA_GRENADES         = 'R014'
    integer UPG_REINFORCED_HIDES        = 'R00X'
    integer UPG_VOIDWALKER              = 'R010'

    integer                 attackWave                 = 1
    integer                 nextDelay                  = 0
    integer                 awGold                     = 0
    integer                 awWood                     = 0
endglobals

//***************************************************************************
//*
//*  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 == D_DEMON_WORKER) then
        set awGold = awGold + minQty
    endif

    // Track attacking wood workers
    if (unitID == D_DEMON_WORKER) then
        set awWood = awWood + minQty
    endif

    call SetAssaultGroup( minQty, maxQty, unitID )
endfunction

//***************************************************************************
//*
//*  Basic Options
//*
//***************************************************************************

//===========================================================================
function InitOptions takes nothing returns nothing
    call SetMeleeAI(  )
    call SetDefendPlayer( false )
    call SetRandomPaths( false )
    call SetTargetHeroes( true )
    call SetPeonsRepair( true )
    call SetHeroesFlee( true )
    call SetHeroesBuyItems( true )
    call SetUnitsFlee( true )
    call SetGroupsFlee( false )
    call SetWatchMegaTargets( false )
    call SetIgnoreInjured( true )
    call SetHeroesTakeItems( true )
    call SetSlowChopping( false )
    call SetCaptainChanges( false )
    call SetSmartArtillery( true )
endfunction

//***************************************************************************
//*
//*  Conditions
//*
//***************************************************************************

//===========================================================================
// Updates the values of all preset conditions
//===========================================================================
function UpdateConditions takes nothing returns nothing
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 == D_CHAOS_GENERAL) then
            set skills1[ 1] = DEMONIC_LEAP
            set skills1[ 2] = CLEAVE
            set skills1[ 3] = INSPIRING_PRESENCE
            set skills1[ 4] = DEMONIC_LEAP
            set skills1[ 5] = CLEAVE
            set skills1[ 6] = ARMAGEDDON
            set skills1[ 7] = INSPIRING_PRESENCE
            set skills1[ 8] = DEMONIC_LEAP
            set skills1[ 9] = CLEAVE
            set skills1[10] = INSPIRING_PRESENCE
        elseif (heroid == D_WARLOCK) then
            set skills1[ 1] = CHAOS_STRIKE
            set skills1[ 2] = DARK_MINIONS
            set skills1[ 3] = COUNTERSPELL
            set skills1[ 4] = CHAOS_STRIKE
            set skills1[ 5] = DARK_MINIONS
            set skills1[ 6] = DIMENSIONAL_PORTAL
            set skills1[ 7] = COUNTERSPELL
            set skills1[ 8] = CHAOS_STRIKE
            set skills1[ 9] = DARK_MINIONS
            set skills1[10] = COUNTERSPELL
        elseif (heroid == D_SUCCUBUS_MISTRESS) then
            set skills1[ 1] = MARK_OF_DOOM
            set skills1[ 2] = LIFE_DRAIN
            set skills1[ 3] = AURA_OF_SWIFTNESS
            set skills1[ 4] = MARK_OF_DOOM
            set skills1[ 5] = LIFE_DRAIN
            set skills1[ 6] = SEDUCTION
            set skills1[ 7] = AURA_OF_SWIFTNESS
            set skills1[ 8] = MARK_OF_DOOM
            set skills1[ 9] = LIFE_DRAIN
            set skills1[10] = AURA_OF_SWIFTNESS
        endif
    elseif (order == 2) then
        set hero_id2 = heroid
        if (heroid == D_CHAOS_GENERAL) then
            set skills2[ 1] = DEMONIC_LEAP
            set skills2[ 2] = CLEAVE
            set skills2[ 3] = INSPIRING_PRESENCE
            set skills2[ 4] = DEMONIC_LEAP
            set skills2[ 5] = CLEAVE
            set skills2[ 6] = ARMAGEDDON
            set skills2[ 7] = INSPIRING_PRESENCE
            set skills2[ 8] = DEMONIC_LEAP
            set skills2[ 9] = CLEAVE
            set skills2[10] = INSPIRING_PRESENCE
        elseif (heroid == D_WARLOCK) then
            set skills2[ 1] = CHAOS_STRIKE
            set skills2[ 2] = DARK_MINIONS
            set skills2[ 3] = COUNTERSPELL
            set skills2[ 4] = CHAOS_STRIKE
            set skills2[ 5] = DARK_MINIONS
            set skills2[ 6] = DIMENSIONAL_PORTAL
            set skills2[ 7] = COUNTERSPELL
            set skills2[ 8] = CHAOS_STRIKE
            set skills2[ 9] = DARK_MINIONS
            set skills2[10] = COUNTERSPELL
        elseif (heroid == D_SUCCUBUS_MISTRESS) then
            set skills2[ 1] = MARK_OF_DOOM
            set skills2[ 2] = LIFE_DRAIN
            set skills2[ 3] = AURA_OF_SWIFTNESS
            set skills2[ 4] = MARK_OF_DOOM
            set skills2[ 5] = LIFE_DRAIN
            set skills2[ 6] = SEDUCTION
            set skills2[ 7] = AURA_OF_SWIFTNESS
            set skills2[ 8] = MARK_OF_DOOM
            set skills2[ 9] = LIFE_DRAIN
            set skills2[10] = AURA_OF_SWIFTNESS
        endif
    elseif (order == 3) then
        set hero_id3 = heroid
        if (heroid == D_CHAOS_GENERAL) then
            set skills3[ 1] = DEMONIC_LEAP
            set skills3[ 2] = CLEAVE
            set skills3[ 3] = INSPIRING_PRESENCE
            set skills3[ 4] = DEMONIC_LEAP
            set skills3[ 5] = CLEAVE
            set skills3[ 6] = ARMAGEDDON
            set skills3[ 7] = INSPIRING_PRESENCE
            set skills3[ 8] = DEMONIC_LEAP
            set skills3[ 9] = CLEAVE
            set skills3[10] = INSPIRING_PRESENCE
        elseif (heroid == D_WARLOCK) then
            set skills3[ 1] = CHAOS_STRIKE
            set skills3[ 2] = DARK_MINIONS
            set skills3[ 3] = COUNTERSPELL
            set skills3[ 4] = CHAOS_STRIKE
            set skills3[ 5] = DARK_MINIONS
            set skills3[ 6] = DIMENSIONAL_PORTAL
            set skills3[ 7] = COUNTERSPELL
            set skills3[ 8] = CHAOS_STRIKE
            set skills3[ 9] = DARK_MINIONS
            set skills3[10] = COUNTERSPELL
        elseif (heroid == D_SUCCUBUS_MISTRESS) then
            set skills3[ 1] = MARK_OF_DOOM
            set skills3[ 2] = LIFE_DRAIN
            set skills3[ 3] = AURA_OF_SWIFTNESS
            set skills3[ 4] = MARK_OF_DOOM
            set skills3[ 5] = LIFE_DRAIN
            set skills3[ 6] = SEDUCTION
            set skills3[ 7] = AURA_OF_SWIFTNESS
            set skills3[ 8] = MARK_OF_DOOM
            set skills3[ 9] = LIFE_DRAIN
            set skills3[10] = AURA_OF_SWIFTNESS
        endif
    endif
endfunction

//===========================================================================
// Selects hero IDs for three possible heroes
//===========================================================================
function SelectHeroes takes nothing returns nothing
    local integer roll = GetRandomInt(1,100)
    call SetHero( 1, D_CHAOS_GENERAL )
    call SetHero( 2, D_WARLOCK )
    call SetHero( 3, D_SUCCUBUS_MISTRESS )
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
//*
//***************************************************************************
function DoUpgrades takes nothing returns nothing
    call SetBuildUpgr( 1, UPG_FATAL_WEEP )  
    call SetBuildUpgr( 1, UPG_MANA_LEECH ) 
    call SetBuildUpgr( 1, UPG_PLASMA_GRENADES )
    
    call SetBuildUpgr( 1, UPG_CHAOS_ARMOR )
    call SetBuildUpgr( 1, UPG_CORRUPTING_ATTACK )
    call SetBuildUpgr( 1, UPG_IMPROVED_WEAPONS )
    call SetBuildUpgr( 1, UPG_REINFORCED_HIDES ) 
    call SetBuildUpgr( 1, UPG_EFREETI )
    call SetBuildUpgr( 1, UPG_VOIDWALKER )
    
    call SetBuildUpgr( 2, UPG_CHAOS_ARMOR )
    call SetBuildUpgr( 2, UPG_CORRUPTING_ATTACK )
    call SetBuildUpgr( 2, UPG_IMPROVED_WEAPONS )
    call SetBuildUpgr( 2, UPG_REINFORCED_HIDES )    
    call SetBuildUpgr( 2, UPG_EFREETI )
    call SetBuildUpgr( 2, UPG_VOIDWALKER )
    
    call SetBuildUpgr( 3, UPG_CHAOS_ARMOR )
    call SetBuildUpgr( 3, UPG_CORRUPTING_ATTACK )
    call SetBuildUpgr( 3, UPG_IMPROVED_WEAPONS )
    call SetBuildUpgr( 3, UPG_REINFORCED_HIDES )
    
endfunction
//===========================================================================
// Specifies building priorities for workers
//===========================================================================
function BuildPriorities takes nothing returns nothing
    local integer mine = TownWithMine()
    call SetBuildAll( BUILD_UNIT, 1, D_HALL_OF_CHAOS, -1 )
    call SetBuildAll( BUILD_UNIT, 6, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_ALTAR_OF_CHAOS, -1 )
    call SetBuildAll( BUILD_UNIT, 7, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_SUMMONING_PORTAL, -1 )
    call SetBuildAll( BUILD_UNIT, 9, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, hero_id, -1 )
    call SetBuildAll( BUILD_UNIT, 11, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_IMP, -1 )
    call SetBuildAll( BUILD_UNIT, 12, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 2, D_IMP, -1 )
    call SetBuildAll( BUILD_UNIT, 13, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 15, D_DEMON_WORKER, -1 )
    call SetBuildAll( BUILD_UNIT, 4, D_IMP, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_DEMONIC_SHRINE, -1 )
    call SetBuildAll( BUILD_UNIT, 4, D_BEHOLDER, -1 )
    if GetGoldOwned() < 1000 then
        call BuildExpansion( D_HALL_OF_CHAOS, D_HALL_OF_CHAOS )
    endif
    call SetBuildAll( BUILD_UNIT, 1, D_DEMON_TOWER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_FUSION_CANNON, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_IMMOLATOR, -1 )
    call DoUpgrades()
    
    if MeleeDifficulty() > MELEE_NEWBIE then
        call SetBuildAll( BUILD_UNIT, 2, D_DEMON_TOWER, -1 )
        call SetBuildAll( BUILD_UNIT, 2, D_FUSION_CANNON, -1 )
        if MeleeDifficulty() > MELEE_NORMAL then
            call SetBuildAll( BUILD_UNIT, 3, D_DEMON_TOWER, -1 )
            call SetBuildAll( BUILD_UNIT, 3, D_FUSION_CANNON, -1 )
            call SetBuildAll( BUILD_UNIT, 2, D_IMMOLATOR, -1 )
        endif
    endif
        
    call SetBuildAll( BUILD_UNIT, 1, D_HALL_OF_CORRUPTION, -1 )
    call SetBuildAll( BUILD_UNIT, 1, hero_id2, -1 )
    call SetBuildAll( BUILD_UNIT, 3, D_BLOODFIEND, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_BLOOD_PIT, -1 )
    call SetBuildAll( BUILD_UNIT, 2, D_INFERNAL_MACHINE, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_SHRINE_OF_THE_DEATHWALKER, -1 )
    call SetBuildAll( BUILD_UNIT, 2, D_VOIDWALKER, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_EFREETI, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_HALL_OF_DOOM, -1 )
    call SetBuildAll( BUILD_UNIT, 1, hero_id3, -1 )
    call SetBuildAll( BUILD_UNIT, 2, D_OVERLORD, -1 )
    call SetBuildAll( BUILD_UNIT, 2, D_NETHER_DRAKE, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_WAR_ZEPPELIN, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_DEMON_GATE, -1 )
    call SetBuildAll( BUILD_UNIT, 1, D_DOOMBRINGER, -1 )
    
    if MeleeDifficulty() > MELEE_NEWBIE then
        call SetBuildAll( BUILD_UNIT, 3, D_DEMON_TOWER, -1 )
            call SetBuildAll( BUILD_UNIT, 3, D_FUSION_CANNON, -1 )
            call SetBuildAll( BUILD_UNIT, 2, D_IMMOLATOR, -1 )
        if MeleeDifficulty() > MELEE_NORMAL then
            call SetBuildAll( BUILD_UNIT, 4, D_DEMON_TOWER, -1 )
            call SetBuildAll( BUILD_UNIT, 4, D_FUSION_CANNON, -1 )
            call SetBuildAll( BUILD_UNIT, 3, D_IMMOLATOR, -1 )
        endif
    endif
endfunction

//===========================================================================
// Specifies harvesting priorities for workers
//===========================================================================
function HarvestPriorities takes nothing returns nothing
    local integer mine = TownWithMine()
    local integer allGold = GetUnitCountDone(D_DEMON_WORKER)
    local integer allWood = GetUnitCountDone(D_DEMON_WORKER)
    local integer numWorkers
    set numWorkers = 5
    call HarvestGold( mine, numWorkers )
    set numWorkers = 5
    call HarvestWood( mine, numWorkers )
    set numWorkers = 5
    call HarvestGold( 1, 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 > 1) then
    //    return false
    //endif

    // First Hero Only
    if ((GetUnitCountDone(hero_id) > 0) or (GetUnitCountDone(hero_id2) > 0) or (GetUnitCountDone(hero_id3) > 0)) and (GetUnitCountDone(D_IMP) > 2) and (GetUnitCountDone(D_BEHOLDER) > 2) then
        return true
    endif

    return false
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( D_WAR_ZEPPELIN )
        call AddAttackUnit( all, all, D_WAR_ZEPPELIN )
        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( D_VOIDWALKER )
        call AddAttackUnit( all, all, D_VOIDWALKER )
        set all = GetUnitCountDone( D_INFERNAL_MACHINE )
        call AddAttackUnit( all, all, D_INFERNAL_MACHINE )
        set all = GetUnitCountDone( D_IMP )
        set all = all - 2
        if (all < 0) then
            set all = 0
        endif
        call AddAttackUnit( all, all, D_IMP )
        set all = GetUnitCountDone( D_EFREETI )
        call AddAttackUnit( all, all, D_EFREETI )
        set all = GetUnitCountDone( D_NETHER_DRAKE )
        call AddAttackUnit( all, all, D_NETHER_DRAKE )
        set all = GetUnitCountDone( D_BLOODFIEND )
        call AddAttackUnit( all, all, D_BLOODFIEND )
        set all = GetUnitCountDone( D_OVERLORD )
        call AddAttackUnit( all, all, D_OVERLORD )
        set all = GetUnitCountDone( D_DOOMBRINGER )
        call AddAttackUnit( all, all, D_DOOMBRINGER )
        set all = GetUnitCountDone( D_BEHOLDER )
        set all = all - 2
        if (all < 0) then
            set all = 0
        endif
        call AddAttackUnit( all, all, D_BEHOLDER )

    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 )
    //endif
endfunction

//===========================================================================
// Sleep delays for each attack wave
//===========================================================================
function AttackWaveDelay takes integer inWave returns nothing
    if (inWave < nextDelay) then
        return
    endif

    if (inWave == 1) then
        call Sleep( 0 )
    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 > 1) 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 (target == null) then
        set target = GetExpansionFoe()
        if (target != null) then
            set take_exp = false
        endif
    endif

    // Target Priority #3
    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 (target == null) then
        set target = GetCreepCamp( 10, 100, true )
    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 RemoveInjuries(  )
        call ResetAttackUnits(  )
        call PrepareForces(  )
        call LaunchAttack(  )
    endloop
endfunction

//***************************************************************************
//*
//*  Main Entry Point
//*
//***************************************************************************

//===========================================================================
function main takes nothing returns nothing
    call InitAI(  )
    call InitOptions(  )
    call SelectHeroes(  )
    call CreateCaptains(  )
    call SetHeroLevels( function ChooseHeroSkill )

    call Sleep( 0.1 )
    call StartThread( function WorkerAssignment )
    call StartThread( function AttackAssignment )
    call PlayGame(  )
endfunction

Files are named like that, because I've replaced default races

humans -> elves
orcs -> custom orc race
undeads -> custom undead race
night elves -> demons

Later, if I add more races, I might add an ingame race selection.
 
Level 12
Joined
Jun 15, 2016
Messages
472
This is the elf melee ai from RoC. I don't see something special in it. It's a bit hard to tell because OP didn't give us any test map, but perhaps he put the wrong ability for harvesting lumber?
 

Attachments

  • elf.pdf
    47.2 KB · Views: 83
Status
Not open for further replies.
Top