• 🏆 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!

[AI] AI harvesting priority sometimes does not work

Status
Not open for further replies.
Level 2
Joined
Aug 21, 2010
Messages
17
Hi, I have this huge problem and I can't figure out how to solve it: I'm currently developing an AI for an altered melee map. At the beginning of this scenario, the human players choose a race through a dialog window, then the following trigger is run:

  • GameStart
    • Events
    • Conditions
    • Actions
      • Countdown Timer - Start countdown as a One-shot timer that will expire in 5.00 seconds
      • Countdown Timer - Create a timer window for (Last started timer) with title Game starting in:
      • Wait until ((Remaining time for countdown) Less than or equal to 0.00), checking every 0.10 seconds
      • Countdown Timer - Hide (Last created timer window)
      • Set game_started = True
      • Trigger - Run Timer Board <gen> (ignoring conditions)
      • Game - Display to (All players) the text: The battle has begu...
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • debugMode Equal to True
        • Then - Actions
          • Player Group - Pick every player in (All players controlled by a Computer player) and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Undead Citadel for (Picked player) at ((Picked player) start location) facing Default building facing degrees
              • Unit - Create 4 Specter for (Picked player) at ((Picked player) start location) facing Default building facing degrees
              • AI - Start melee AI script for (Picked player): LodUndeadDemo.ai
        • Else - Actions
          • Player Group - Pick every player in (All players controlled by a Computer player) and do (Actions)
            • Loop - Actions
              • Set aiRandInt = (Random integer number between 1 and 6)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • aiRandInt Equal to 1
                • Then - Actions
                  • Unit - Create 1 Undead Citadel for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                  • Unit - Create 4 Specter for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                  • Set ai_rand_list[ai_rand_list_index] = 1
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • aiRandInt Equal to 2
                    • Then - Actions
                      • Unit - Create 1 Demon Gate for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                      • Unit - Create 4 Demon Raider for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                      • Set ai_rand_list[ai_rand_list_index] = 2
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • aiRandInt Equal to 3
                        • Then - Actions
                          • Unit - Create 1 Argonian Command Center for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • Unit - Create 4 Barbarian slave for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                          • Set ai_rand_list[ai_rand_list_index] = 3
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • aiRandInt Equal to 4
                            • Then - Actions
                              • Unit - Create 1 Eternal Tower for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                              • Unit - Create 4 Elemental Worker for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                              • Set ai_rand_list[ai_rand_list_index] = 4
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • aiRandInt Equal to 5
                                • Then - Actions
                                  • Unit - Create 1 Imperial Village for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                                  • Unit - Create 4 Citizen for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                                  • Set ai_rand_list[ai_rand_list_index] = 5
                                • Else - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • aiRandInt Equal to 6
                                    • Then - Actions
                                      • Unit - Create 1 Bug Den for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                                      • Unit - Create 4 Ratling for (Picked player) at ((Picked player) start location) facing Default building facing degrees
                                      • Set ai_rand_list[ai_rand_list_index] = 6
                                    • Else - Actions
              • Set ai_rand_list_index = (ai_rand_list_index + 1)
          • Set ai_rand_list_index = 0
          • Wait until (all_ai_spawned Equal to True), checking every 0.10 seconds
          • Player Group - Pick every player in (All players controlled by a Computer player) and do (Actions)
            • Loop - Actions
              • Set aiRandInt = (Random integer number between 1 and 6)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ai_rand_list[ai_rand_list_index] Equal to 1
                • Then - Actions
                  • AI - Start melee AI script for (Picked player): LodUndeadDemo.ai
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ai_rand_list[ai_rand_list_index] Equal to 2
                    • Then - Actions
                      • AI - Start melee AI script for (Picked player): LodDemonDemo.ai
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ai_rand_list[ai_rand_list_index] Equal to 3
                        • Then - Actions
                          • AI - Start melee AI script for (Picked player): LodArgonianDemo.ai
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ai_rand_list[ai_rand_list_index] Equal to 4
                            • Then - Actions
                              • AI - Start melee AI script for (Picked player): LodInquisitionDemo.ai
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • ai_rand_list[ai_rand_list_index] Equal to 5
                                • Then - Actions
                                  • AI - Start melee AI script for (Picked player): LodEmpireDemo.ai
                                • Else - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • ai_rand_list[ai_rand_list_index] Equal to 6
                                    • Then - Actions
                                      • AI - Start melee AI script for (Picked player): LodBugDemo.ai
                                    • Else - Actions
              • Set ai_rand_list_index = (ai_rand_list_index + 1)
      • Set defeatEnabled = True
      • Wait 1.00 seconds
      • Trigger - Run InactivePlayers <gen> (ignoring conditions)

The trigger which sets the global variable all_ai_spawned is the following:

  • ChekAISpawn
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
      • game_started Equal to True
    • Actions
      • Trigger - Turn off (This trigger)
      • Set all_ai_spawned = False
      • Player Group - Pick every player in (All players controlled by a Computer player) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Count structures controlled by (Picked player) (Exclude incomplete structures)) Greater than 0
            • Then - Actions
              • Set all_ai_spawned = True
            • Else - Actions
              • Set all_ai_spawned = False
      • If (all_ai_spawned Equal to True) then do (Do nothing) else do (Trigger - Turn on (This trigger))

In each AI script the harvesting priority is more or less the same: send 4 or 5 workers to harvet gold, then 5 more to harvest lumber.
What happens is that sometimes the AI randomly chooses to send 5 workers to harves lumber, just like a "hidden AI" takes command and forces them to harvest lumber.
My first thought was the AI started before having a town with a mine, so having found none, it started harvest lumber, but now the trigger is checking the AI has at least one building before running the script.
Do you have any idea why?
 
Level 2
Joined
Aug 21, 2010
Messages
17
Ok, maybe I solved this (but I say MAYBE because this is the weirdest stuff ever seen in game scripting): I rewrote the HarvestPriorities function like this:

JASS:
function HarvestPriorities takes nothing returns nothing
    local integer mine = TownWithMine()
    local integer workers = GetUnitCountDone('u00C')
	if workers < 6 then
		call HarvestGold(-1, 5)
		call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Few workers. Harvesting gold ")
	else
		call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Normal harvesting ")
		call HarvestGold(mine, 5)
		call HarvestWood(0, workers - 5)
		if (GetMinesOwned() > 1) then
			call HarvestGold( mine + 1, 5)
			call HarvestWood( mine + 1, 4)
			call HarvestGold( mine + 2, 5 )
			call HarvestGold( mine + 3, 5 )
			call HarvestGold( mine + 4, 5 )
		endif
	endif
endfunction

Does anybody have any idea why the same function without the first check (that is, just harvest gold if you have less than 6 workers) doesn't work and force workers to chop trees?

JASS:
call HarvestGold(mine, 5)
		call HarvestWood(0, workers - 5)
		if (GetMinesOwned() > 1) then
			call HarvestGold( mine + 1, 5)
			call HarvestWood( mine + 1, 4)
			call HarvestGold( mine + 2, 5 )
			call HarvestGold( mine + 3, 5 )
			call HarvestGold( mine + 4, 5 )
		endif

This is the loop for worker assignment:

JASS:
function WorkerAssignment takes nothing returns nothing
    loop
        call UpdateConditions(  )

        // Harvesting
		call ClearHarvestAI(  )
        call HarvestPriorities(  )

        // Building
        call InitBuildArray(  )
        call BuildPriorities(  )

        call Sleep( 2 )
    endloop
endfunction
 
Level 2
Joined
Aug 21, 2010
Messages
17
I told you I rewrote the script for harvesting priorities. Besides the first version was the same priority order used for the standard human ai, so since workers are basically equivalent to human workers it should run fine, but it has the same problem. At this point I managed to write a workaround, but I think it is the HarvestGold and HarvestLumber functions which have a bug with custom units, basically sometimes the AI inverts the priority of gold with lumber, I'm sure of this because if I run the script with 7 players with the same race (so same script on different instances) some AI's play fine while others play with inverted priorities.
 
Status
Not open for further replies.
Top