Unit count

Kam

Kam

Community Development Manager
Level 38
Joined
Aug 3, 2004
Messages
2,820
I have the following trigger that deals with custom AI. The issue is that it is not counting units in production. In the standard AI editor there is an option to count incomplete units as well. Is there a way to do this with triggers?

To be clear it is supposed to stop at 15 Footmen, but is makes extra because it doesn't count in production.

  • AI Unit Composition
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Race of (Player((Integer A)))) Equal to Human) and (((Player((Integer A))) controller) Equal to Computer)
            • Then - Actions
              • -------- Unit Production Structures --------
              • Set AI_Human_Barracks = (Units owned by (Player((Integer A))) of type Barracks)
              • Set AI_Human_Workshop = (Units owned by (Player((Integer A))) of type Workshop)
              • Set AI_Human_Sanctum = (Units owned by (Player((Integer A))) of type Arcane Sanctum)
              • Set AI_Human_Aviary = (Units owned by (Player((Integer A))) of type Gryphon Aviary)
              • Set AI_Human_Altar = (Units owned by (Player((Integer A))) of type Altar of Kings)
              • -------- Support Structures --------
              • Set AI_Human_Hall = (Number of living Town Hall units owned by (Player((Integer A))))
              • Set AI_Human_Keep = (Number of living Keep units owned by (Player((Integer A))))
              • Set AI_Human_Castle = (Number of living Castle units owned by (Player((Integer A))))
              • Set AI_Human_Lumber = (Number of living Lumber Mill units owned by (Player((Integer A))))
              • Set AI_Human_Blacksmith = (Number of living Blacksmith units owned by (Player((Integer A))))
              • -------- Unit Count --------
              • Set AI_Human_Footman = (Number of living Footman units owned by (Player((Integer A))))
              • Set AI_Human_Knight = (Number of living Knight units owned by (Player((Integer A))))
              • Set AI_Human_Rifleman = (Number of living Rifleman units owned by (Player((Integer A))))
              • Set AI_Human_Mortar = (Number of living Mortar Team units owned by (Player((Integer A))))
              • Set AI_Human_Machine = (Number of living Flying Machine units owned by (Player((Integer A))))
              • Set AI_Human_Gryphon = (Number of living Gryphon Rider units owned by (Player((Integer A))))
              • Set AI_Human_Priest = (Number of living Priest units owned by (Player((Integer A))))
              • Set AI_Human_Sorceress = (Number of living Sorceress units owned by (Player((Integer A))))
              • Set AI_Human_Engine = (Number of living Siege Engine units owned by (Player((Integer A))))
              • Set AI_Human_Breaker = (Number of living Spell Breaker units owned by (Player((Integer A))))
              • Set AI_Human_Rider = (Number of living Dragonhawk Rider units owned by (Player((Integer A))))
              • Set AI_Human_Hero_A = (Number of living Paladin units owned by (Player((Integer A))))
              • Set AI_Human_Hero_B = (Number of living Archmage units owned by (Player((Integer A))))
              • Set AI_Human_Hero_C = (Number of living Mountain King units owned by (Player((Integer A))))
              • Set AI_Human_Hero_D = (Number of living Blood Mage units owned by (Player((Integer A))))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Melee AI of (Player((Integer A)))) Equal to Normal AI
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current research level of 1 for (Player((Integer A)))) Equal to 1
                    • Then - Actions
                      • -------- HEAVY GROUND --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Number of units in AI_Human_Altar) Greater than 0
                          • ((Player((Integer A))) Food used) Less than or equal to (((Player((Integer A))) Food cap) - 5)
                          • AI_Human_Hero_C Less than 1
                          • ((Player((Integer A))) Available free Heroes) Greater than 0
                        • Then - Actions
                          • Unit - Order (Random unit from AI_Human_Altar) to train/upgrade to a Mountain King
                        • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Number of units in AI_Human_Barracks) Greater than 0
                          • ((Player((Integer A))) Current gold) Greater than or equal to 135
                          • ((Player((Integer A))) Food used) Less than or equal to (((Player((Integer A))) Food cap) - 2)
                          • AI_Human_Footman Less than 15
                        • Then - Actions
                          • Unit - Order (Random unit from AI_Human_Barracks) to train/upgrade to a Footman
                        • Else - Actions
                    • Else - Actions
                • Else - Actions
              • Custom script: call DestroyGroup(udg_AI_Human_Barracks)
              • Custom script: call DestroyGroup(udg_AI_Human_Workshop)
              • Custom script: call DestroyGroup(udg_AI_Human_Sanctum)
              • Custom script: call DestroyGroup(udg_AI_Human_Aviary)
              • Custom script: call DestroyGroup(udg_AI_Human_Altar)
            • Else - Actions
 
Level 29
Joined
Oct 24, 2012
Messages
6,545
More than twice would be the better suggestion in my opinion.

a lot of the things are better when used twice to store them as a variable.

@TO
im not sure about the system. and if a building is destroyed then it will not trigger the unit is trained unless the unit is trained. in a unit dies trigger just set the counter to counter - 1
 
Level 5
Joined
May 20, 2013
Messages
161
Kam, i tinkered with your trigger all night & my conclusion is that it works flawlessly if you have it check every 22 seconds (20 second footman buildtime +2 second bumper) instead of every second -with a couple of minor modifications. Instead of a random barrack building a unit, just order all the barracks to build a unit. For your food supply & gold conditions, just use the arithmetic function to multiply times # of barracks. I don't know if there was a special reason why you wanted to run the trigger every second, but it seems to be less buggy when ran less often -i never once had the barracks backlogged, & they even built a second one later on. This makes sense to me in that by the time you start adding triggers for upgrades, repair orders, base expansions etc etc etc, running a footman train order every 22 seconds may be a better interval in terms of computational resources. I don't know what your ultimate objective was, but its just an observation & a thought.

BTW... you are probably aware already, but the comp controller wasn't upgrading anything or selecting hero skills for the MK, or expanding. However, it did a very good job of building footmen, & sending them out to attack.

Anyway, if i'm not making any sense it could be that i've been up all night! :p
 
Level 5
Joined
May 20, 2013
Messages
161
Kam, the problem i couldn't get around on a solution trigger is that on events, the GUI trigger wont detect "a unit begins training a unit". It detects "Unit finishes training a unit" just fine. I tested that by broadcasting a floating text integer every time a training unit was counted. My question then would be, is there a Custom Script command you could use that would detect "begins training a unit" in this situation where the GUI doesn't. Other than that the only way i was able to prevent it from back-logging footmen was to wait 20+ seconds between ques like i mentioned in previous post
 

Kam

Kam

Community Development Manager
Level 38
Joined
Aug 3, 2004
Messages
2,820
Here is what I want to do:

Unit production will be controlled by triggers via the following method:

Trigger A:
-If # of Footmen + Dummy Units is less than 5 pick random Barracks and create Dummy Unit with locust at location
-Dummy Unit set to flying 0 movement
-Add 15 second expiration timer to last created unit

Trigger B:
A unit dies equal to Dummy Unit
Create 1 Footman at location

What does this accomplish?
I can now issue "train" orders to computer buildings via triggers and not deal with the computer filling the que with Footmen because it can't count incomplete Footmen outside of the AI editor.

Issues:
1) Barracks is destroyed - I believe this can be solved with a hashtable by storing dummy units in it upon entering?
2) It needs to detect if there is a dummy unit already present within an area of the Barracks so it doesn't "train" more than one at a time
3) If an ability that causes building function to stop for a time is used then the expiration timer on the dummy needs to be paused when the buff is present and unpasued when the buff expires

Why do I want to do this?
This will allow me to create a new kind of dynamic AI that builds units based on what you build.

Example:
http://www.hiveworkshop.com/forums/world-editor-help-zone-98/detect-remove-unit-group-204799/
 
Last edited:

Kam

Kam

Community Development Manager
Level 38
Joined
Aug 3, 2004
Messages
2,820
I've decided to go with using dummy units.

This approach is fairly successful. The only issue I encounter is that the counter bugs when a Barracks is destroyed while training a unit.

I was also unsure of how to assign each AI player a unique integer for the AI_Trainer_Footman_Count.

Anyway the basic premise here is that the trigger is using dummy unit to keep track of what units are in play. This is important because it will the basis for an adaptive AI.

Edit: Looking back this is the same issue I was having before except now I have a way to track units in production. The main is issue is: How do I assign each player a unique integer?
 

Attachments

  • AI Trainer Test.w3x
    27 KB · Views: 115

Kam

Kam

Community Development Manager
Level 38
Joined
Aug 3, 2004
Messages
2,820
I believe I've solved all the issues now.

If you use a dummy model and assign the region to a remote area of the map it should rarely be noticed by any human players.

I need to clean up leaks, but this correctly monitors units in production and allows you to adjust unit production via integers.

Edit: This is leakless now as well.
 

Attachments

  • AI Trainer Test.w3x
    27.7 KB · Views: 92
Last edited:
Top