1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

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

Discussion in 'Triggers & Scripts' started by Erkki2, Jul 20, 2015.

  1. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    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:
    trigger
    • 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.
     
  2. RobertMKD

    RobertMKD

    Joined:
    Jan 23, 2015
    Messages:
    787
    Resources:
    1
    Maps:
    1
    Resources:
    1
    First, put a debug message in the Actions where you start the AI script to see if it actually runs..
     
  3. Ceday

    Ceday

    Joined:
    Feb 22, 2010
    Messages:
    1,102
    Resources:
    0
    Resources:
    0
    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.
     
  4. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    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.
    ai
    Code (vJASS):
    //===========================================================================
    //
    // 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.
     
  5. Unregret

    Unregret

    Joined:
    Jun 15, 2016
    Messages:
    748
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Sorry to pull this thread out. Is there any solution for this problem? Force custom races based on Night Elf gathering lumber?
     
  6. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,716
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    You might have to delve deep into JASS and custom AI scripts to find a solution. There might be some flag that is set that controls the AI gather behaviour. By default NE players might have it turned off for wisp harvesting.
     
  7. Nowow

    Nowow

    Joined:
    Jun 15, 2016
    Messages:
    438
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    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?
     

    Attached Files:

    • elf.pdf
      File size:
      47.2 KB
      Views:
      50
  8. Erkki2

    Erkki2

    Joined:
    Jun 6, 2007
    Messages:
    382
    Resources:
    7
    Skins:
    6
    Spells:
    1
    Resources:
    7
    It's been a while, but... I think the problem was a syntax error in the ai script (or actually in all 4 scripts). It's just really weird, that the scripts still worked for most races.