• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[General] AI system by me. Specially for AoS/MOBA but still includes lot of bugs (i think)

Status
Not open for further replies.
Level 17
Joined
Jun 2, 2009
Messages
1,191
Hello everyone. Last year i was created AI system for my AoS map (moba) and i wanted to share it with you. Before we go into details, let me warn you first. This system created by myself and probably it is not well optimized and includes bugs. Probably. This is what i thinking. In other words, we can improve my system if you want.

Contents. 1) Heroes list 2) Select heroes 3) Set their lanes 4) Telling them leave your lane 5) Teach them to skills 6-) Order them to follow specific route and/or creeps 7) 7-) Order them when they have stucked 8) Order them to base for the heal 9-) Order them to their lanes after heal 10-) Fall back if friendly creeps died by tower 11-) Send them to the base for heal 12-) Fall back if attacked by enemy creep 13-) Fall back if heroes attacks to them 14-) NextTarget, CurrentTarget, Previous Target setup 15) Setting towers 16) Cast spells (aoe) 17) Cast spells (target) 18) Stop casting spells on non-hero units.


1) Heroes list

First of all we have to set Heroes. Here is the example from my map.

  • Events
    • Map initialization
  • Conditions
  • Actions
    • Set BotHerolar[1] = Arcane Mistress Lady Violet
    • Set BotHerolar[2] = Elementalist Kalsz Myst
    • Set BotHerolar[3] = Flame Master Zagan Hellfire
    • Set BotHerolar[4] = Monk Chris Battleaid
etc etc...........


2) Select Heroes

We are picking all players from 1 to 12 and if their controller equal to computer, create random hero from the list. There are few conditions in here.
If their player lumber less than or equal to 6, that means they are from team 1. If not, team 2.
Another restrictions in here, if they will select a hero, other AI controlled players and human players are not able to select their heroes and turning on lane decide.
Special thanks to @Antares A for the LoopInt, HeroChoosen[randomInt] system. I am able to prevent AI and players pick their own heroes with this system.

  • Time - Elapsed game time is 20.00 seconds
  • 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
            • ((Player((Integer A))) controller) Equal to Computer
            • BotHeroSecti[(Integer A)] Equal to False
          • Then - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Player number of (Player((Integer A)))) Less than or equal to 6
              • Then - Actions
                • For each (Integer LoopInt) from 0 to 1, do (Actions)
                  • Loop - Actions
                    • Set randomInt = (Random integer number between 1 and 13)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • HeroChoosen[randomInt] Equal to False
                      • Then - Actions
                        • Set LoopInt = 1
                      • Else - Actions
                        • Set LoopInt = 0
                • Set BotHeroSecti[(Integer A)] = True
                • Unit - Create 1 BotHerolar[randomInt] for (Player((Integer A))) at (Center of MarketUst <gen>) facing Default building facing degrees
                • Player Group - Pick every player in (All players) and do (Actions)
                  • Loop - Actions
                    • Player - Make BotHerolar[randomInt] Unavailable for training/construction by (Picked player)
                • Neutral Building - Remove BotHerolar[randomInt] from all marketplaces
                • Set zU_AIHero[(Integer A)] = (Last created unit)
                • Set HeroChoosen[randomInt] = True
                • Unit Group - Add (Last created unit) to HerolarALL
                • Unit Group - Add (Last created unit) to HerolarBotALL
                • Unit Group - Add (Last created unit) to HerolarBotDevil
                • Unit Group - Add (Last created unit) to HerolarDevilAll
                • Player Group - Add (Player((Integer A))) to ClanDevilPlayers
                • Player Group - Add (Player((Integer A))) to ClanDevilBotlar
                • Player Group - Add (Player((Integer A))) to Botlar
                • Set HeroCountDevil = (HeroCountDevil + 1)
              • Else - Actions
                • For each (Integer LoopInt) from 0 to 1, do (Actions)
                  • Loop - Actions
                    • Set randomInt = (Random integer number between 1 and 13)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • HeroChoosen[randomInt] Equal to False
                      • Then - Actions
                        • Set LoopInt = 1
                      • Else - Actions
                        • Set LoopInt = 0
                • Set BotHeroSecti[(Integer A)] = True
                • Unit - Create 1 BotHerolar[randomInt] for (Player((Integer A))) at (Center of GameGuideReaper <gen>) facing Default building facing degrees
                • Player Group - Pick every player in (All players) and do (Actions)
                  • Loop - Actions
                    • Player - Make BotHerolar[randomInt] Unavailable for training/construction by (Picked player)
                • Set zU_AIHero[(Integer A)] = (Last created unit)
                • Set HeroChoosen[randomInt] = True
                • Unit Group - Add (Last created unit) to HerolarALL
                • Unit Group - Add (Last created unit) to HerolarBotALL
                • Unit Group - Add (Last created unit) to HerolarReaperALL
                • Unit Group - Add (Last created unit) to HerolarBotReaper
                • Player Group - Add (Player((Integer A))) to ClanReaperPlayers
                • Player Group - Add (Player((Integer A))) to ClanReaperBotlar
                • Player Group - Add (Player((Integer A))) to Botlar
                • Set HeroCountReaper = (HeroCountReaper + 1)
          • Else - Actions
    • Wait 3.00 seconds
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Trigger - Run HeroSectirmeDevam <gen> (checking conditions)
    • Wait 102.00 seconds
    • Trigger - Turn off LaneKararTakim1Gelismis <gen>
    • Trigger - Turn off LaneKararTakim2Gelismis <gen>
    • Trigger - Turn off BotToptanGitDevil <gen>
    • Trigger - Turn off BotMiddenGitDevil <gen>
    • Trigger - Turn off BotBottanGitDevil <gen>
    • Trigger - Turn off BotToptanGitReaper <gen>
    • Trigger - Turn off BotMiddenGitReaper <gen>
    • Trigger - Turn off BotBottanGitReaper <gen>
Ok, make it work many times (HeroSectirmeDevam) looks silly but if i remember correctly, some of them cannot pick sometimes when i will not do that.


3-) Set their lanes

I assume your map have a 3 lanes just like the moba maps. There are 3 corridors are available. 2 For bottom, 2 for top and 1 for middle.
Before do that, we have a few variiables
First of all we are rolling the dice. We will use 1 for bottom, 2 for top and 3 for middle.
Set PN = (Player number of (Picked player))
Set Roll = (Random integer number between 1 and 3)
If the player will added to their lane, we will set LaneKararBOT(player number of picked player) True

4-) Telling them to leave your lane.

You want to play on middle corridor but one of the bots assigned in there. What will happens now?In my map we have a 120 seconds for the change their corridors. First we have to set integer when we enter the region.
We have a 3 corridors and when we enter the region, AI will check which slot is empty, and we will send the AI to selected corridor.

  • Events
    • Unit - A unit enters 3 <gen>
  • Conditions
    • ((Owner of (Triggering unit)) controller) Equal to User
  • Actions
    • Set xDevilSayiTop = (xDevilSayiTop + 1)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • xDevilSayiMid Not equal to 1
      • Then - Actions
        • Set xDevilSayiTop = (xDevilSayiTop - 1)
        • Set xDevilSayiMid = (xDevilSayiMid + 1)
        • Unit Group - Pick every unit in (Random 1 units from zUG_LanerDevilTOP) and do (Actions)
          • Loop - Actions
            • Unit Group - Remove (Picked unit) from zUG_LanerDevilTOP
            • Unit Group - Add (Picked unit) to zUG_LanerDevilMID
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilOrtaKule)
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • xDevilSayiBot Not equal to 2
          • Then - Actions
            • Set xDevilSayiTop = (xDevilSayiTop - 1)
            • Set xDevilSayiBot = (xDevilSayiBot + 1)
            • Unit Group - Pick every unit in (Random 1 units from zUG_LanerDevilTOP) and do (Actions)
              • Loop - Actions
                • Unit Group - Remove (Picked unit) from zUG_LanerDevilTOP
                • Unit Group - Add (Picked unit) to zUG_LanerDevilBOT
                • Unit - Order (Picked unit) to Attack-Move To (Center of DevilAltKule)
And this one is important.

  • TopLaneHooman
    • Events
      • Unit - A unit leaves 3 <gen>
    • Conditions
      • ((Owner of (Triggering unit)) controller) Equal to User
    • Actions
      • Set xDevilSayiTop = (xDevilSayiTop - 1)
This is a sample for 1 corridor. We have to set this number when human player enters region. Why i have created this system? Here is the example.
Your friend went to the middle lane. And you went to the top lane. If we will not increase this number, bot will not detect your friend and tries to goes there.

5-) Teach them to skills

This one was a tricky one. Because there are 2 options in there.

1-) When they have selected and entered the map.
2-) When they leveled up.

I have found great solution for that.

  • Events
    • Unit - A unit enters (Entire map)
  • Conditions
    • (Unspent skill points of (Triggering unit)) Equal to 1
    • (Hero level of (Triggering unit)) Equal to 1
    • ((Triggering unit) is in HerolarBotALL) Equal to True
  • Actions
    • Trigger - Run GainLevel <gen> (ignoring conditions)
With this trigger you can check they have a points to spent and they are level 1.
Additionally this trigger works when they have leveled up.

  • Events
    • Unit - A unit Gains a level
  • Conditions
    • ((Triggering unit) is in HerolarBotALL) Equal to True
  • Actions
    • Hero - Learn skill for (Triggering unit): Nether Pulse //
    • Hero - Learn skill for (Triggering unit): Arcane Explosion //
............................................... goes like this.

6-) Order them to follow specific route and/or creeps.

Let me tell you what happens here. Every seconds i am picking every unit within HerolarBotDevil (team 1) heroes and checking few conditions.
Booleans are self explanatory.

  • Events
    • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in HerolarBotDevil and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (zU_AIHero[(Integer B)] is in zUG_RegenDevil) Equal to False
              • zBool_AIFallBackCREEP[(Player number of (Owner of (Picked unit)))] Equal to False
              • zBool_AIFallBackHERO[(Player number of (Owner of (Picked unit)))] Equal to False
              • zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] Equal to False
              • And - All (Conditions) are true
                • Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • ((Picked unit) is in zUG_TankOFF_DEVIL) Equal to False
                      • ((Picked unit) is in zUG_TankDEF_DEVIL) Equal to False
And here comes the actions part. First, am creating TempPoint and TempGroup.
TempGroup are checking only for one thing. Creeps of the Clan Devil (team 1) within 500 range.
If there are more than 1 creep, i am sending them to their NextTarget (i will talk about Next, current and previous targets later)
If else, that means there are no creeps around the AI do not give order.

  • Then - Actions
    • Set TempPoint = (Position of (Picked unit))
    • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Number of units in TempGroup) Greater than or equal to 1
      • Then - Actions
        • Set TempLoc = (Center of NextTarget[(Player number of (Owner of (Picked unit)))])
        • Unit - Order (Picked unit) to Attack-Move To TempLoc
        • Custom script: call DestroyGroup (udg_TempGroup)
        • Custom script: call RemoveLocation (udg_TempPoint)
      • Else - Actions
        • Custom script: call RemoveLocation (udg_TempPoint)
        • Custom script: call DestroyGroup (udg_TempGroup)
  • Else - Actions
7-) Order them when they have stucked.

Bots can be stucked sometimes and it is hard to detect where they stucked. I was thinking how to detect where they, then i have changed my way of thinking.
Why they are not stuck on the lanes? Because they are detecting creeps. Then i have decided to send them to the lanes. I am simply picking units around the bots and if there are no creeps around, that means it is stucked. I am simply sending them to last tower they have according to their lanes. I will talk about towers later.

  • HeroTakilincaDevil
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
      • LordSavasiBasladi Equal to False
    • Actions
      • For each (Integer A) from 2 to 6, do (Actions)
        • Loop - Actions
          • Set TempPoint = (Position of zU_AIHero[(Integer A)])
          • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in TempGroup) Less than or equal to 0
              • And - All (Conditions) are true
                • Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • zBool_AIFallBackCREEP[(Integer A)] Equal to False
                      • zBool_AIFallBackHERO[(Integer A)] Equal to False
                      • zBool_AIFallBackTOWER[(Integer A)] Equal to False
                      • (zU_AIHero[(Integer A)] is in zUG_RegenDevil) Equal to False
                      • (zU_AIHero[(Integer A)] is in zUG_TankOFF_DEVIL) Equal to False
                      • (zU_AIHero[(Integer A)] is in zUG_TankDEF_DEVIL) Equal to False
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (zU_AIHero[(Integer A)] is in zUG_LanerDevilTOP) Equal to True
                • Then - Actions
                  • Unit - Order zU_AIHero[(Integer A)] to Attack-Move To (Center of DevilUstKule)
                  • Custom script: call RemoveLocation (udg_TempPoint)
                  • Custom script: call DestroyGroup (udg_TempGroup)
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (zU_AIHero[(Integer A)] is in zUG_LanerDevilMID) Equal to True
                    • Then - Actions
                      • Unit - Order zU_AIHero[(Integer A)] to Attack-Move To (Center of DevilOrtaKule)
                      • Custom script: call RemoveLocation (udg_TempPoint)
                      • Custom script: call DestroyGroup (udg_TempGroup)
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (zU_AIHero[(Integer A)] is in zUG_LanerDevilBOT) Equal to True
                        • Then - Actions
                          • Unit - Order zU_AIHero[(Integer A)] to Attack-Move To (Center of DevilAltKule)
                          • Custom script: call RemoveLocation (udg_TempPoint)
                          • Custom script: call DestroyGroup (udg_TempGroup)
                        • Else - Actions
            • Else - Actions
8) Order them to base for the heal.

This simple trigger sending them to their bases for the regeneration. During the process i am adding them to the Regen unit group.

  • Events
    • Unit - A unit Is attacked
  • Conditions
    • ((Attacked unit) is A Hero) Equal to True
    • (Percentage life of zU_AIHero[(Player number of (Owner of (Attacked unit)))]) Less than or equal to 30.00
  • Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Player number of (Owner of zU_AIHero[(Player number of (Owner of (Attacked unit)))])) Less than or equal to 6
      • Then - Actions
        • Unit Group - Add zU_AIHero[(Player number of (Owner of (Attacked unit)))] to zUG_RegenDevil
        • Unit Group - Add zU_AIHero[(Player number of (Owner of (Attacked unit)))] to zUG_RegenALL
      • Else - Actions
        • Unit Group - Add zU_AIHero[(Player number of (Owner of (Attacked unit)))] to zUG_RegenALL
        • Unit Group - Add zU_AIHero[(Player number of (Owner of (Attacked unit)))] to zUG_RegenReaper
9-) Order them to their lanes after heal

After their heal is completed, we have to send them again to their lanes.

  • Events
    • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
    • Unit Group - Pick every unit in (Units in ClanDevilBaseIcerisi <gen> matching (((Integer((Percentage life of (Matching unit)))) Greater than or equal to 95) and (((Matching unit) is in HerolarBotALL) Equal to True))) and do (Actions)
      • Loop - Actions
        • Unit Group - Remove (Picked unit) from zUG_RegenDevil
        • Unit Group - Remove (Picked unit) from zUG_RegenALL
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_LanerDevilTOP) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilUstKule)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_LanerDevilBOT) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilAltKule)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_LanerDevilMID) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilOrtaKule)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_TankDEF_DEVIL) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilAltKule)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_TankOFF_DEVIL) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilsTankSpawn <gen>)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_LanerDevilDEFANS) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of DevilBase <gen>)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_LanerReaperDEFANS) Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of ReaperBase <gen>)
          • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • LordSavasiBasladi Equal to True
          • Then - Actions
            • Unit - Order (Picked unit) to Attack-Move To (Center of ReaperBase <gen>)
          • Else - Actions
10-) Fall back if friendly creeps died by tower

This one was a difficult to me and i remember i was spend 3 or 4 days because of this. I am checking how many creeps left while attacking tower. And i have just realized, why i am checking tower based.
This trigger picks creeps within 500 range of the "attacked creep by tower" and orders bot to the previous tower.

  • Events
    • Unit - A unit Is attacked
  • Conditions
    • zBool_AIFallBackTOWER[(Player number of (Owner of (Attacked unit)))] Equal to False
  • Actions
    • -------- Top --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Attacking unit) Equal to Soul Tower Level 1 0037 <gen>
      • Then - Actions
        • Set TempPoint = (Position of (Attacked unit))
        • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Number of units in TempGroup) Less than or equal to 2
          • Then - Actions
            • Custom script: call DestroyGroup (udg_TempGroup)
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Set TempPoint = (Position of (Attacked unit))
            • Set TempGroup = (Units within 500.00 of TempPoint matching ((((Matching unit) is in HerolarBotDevil) Equal to True) and (((Matching unit) is in zUG_TankOFF_DEVIL) Equal to False)))
            • Unit Group - Pick every unit in TempGroup and do (Actions)
              • Loop - Actions
                • Set zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] = True
                • Unit - Order (Picked unit) to Move To (Center of DevilUstKule)
                • Unit Group - Remove (Picked unit) from zUG_DALANLAR_DEVIL
                • Countdown Timer - Start BotKuledenKacmaTimer[(Player number of (Owner of (Picked unit)))] as a One-shot timer that will expire in 2.00 seconds
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
          • Else - Actions
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
      • Else - Actions
        • -------- Reaper Tower 2, 3 --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Attacked unit) is in zUG_CreepsDevil) Equal to True
            • Or - Any (Conditions) are true
              • Conditions
                • (Attacking unit) Equal to Soul Tower Level 2 0036 <gen>
                • (Attacking unit) Equal to Soul Tower Level 3 0027 <gen>
          • Then - Actions
            • Set TempPoint = (Position of (Attacked unit))
            • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Number of units in TempGroup) Less than or equal to 2
              • Then - Actions
                • Custom script: call DestroyGroup (udg_TempGroup)
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Set TempPoint = (Position of (Attacked unit))
                • Set TempGroup = (Units within 500.00 of TempPoint matching ((((Matching unit) is in HerolarBotDevil) Equal to True) and (((Matching unit) is in zUG_TankOFF_DEVIL) Equal to False)))
                • Unit Group - Pick every unit in TempGroup and do (Actions)
                  • Loop - Actions
                    • Set zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] = True
                    • Unit - Order (Picked unit) to Move To (Center of DevilUstKule)
                    • Unit Group - Remove (Picked unit) from zUG_DALANLAR_DEVIL
                    • Countdown Timer - Start BotKuledenKacmaTimer[(Player number of (Owner of (Picked unit)))] as a One-shot timer that will expire in 2.00 seconds
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Custom script: call DestroyGroup (udg_TempGroup)
              • Else - Actions
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Custom script: call DestroyGroup (udg_TempGroup)
          • Else - Actions
    • -------- Bottom --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Attacking unit) Equal to Soul Tower Level 1 0038 <gen>
        • ((Attacked unit) is in zUG_CreepsDevil) Equal to True
      • Then - Actions
        • Set TempPoint = (Position of (Attacked unit))
        • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Number of units in TempGroup) Less than or equal to 2
          • Then - Actions
            • Custom script: call DestroyGroup (udg_TempGroup)
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Set TempPoint = (Position of (Attacked unit))
            • Set TempGroup = (Units within 500.00 of TempPoint matching ((((Matching unit) is in HerolarBotDevil) Equal to True) and (((Matching unit) is in zUG_TankOFF_DEVIL) Equal to False)))
            • Unit Group - Pick every unit in TempGroup and do (Actions)
              • Loop - Actions
                • Set zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] = True
                • Unit - Order (Picked unit) to Move To (Center of DevilAltKule)
                • Unit Group - Remove (Picked unit) from zUG_DALANLAR_DEVIL
                • Countdown Timer - Start BotKuledenKacmaTimer[(Player number of (Owner of (Picked unit)))] as a One-shot timer that will expire in 2.00 seconds
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
          • Else - Actions
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
      • Else - Actions
        • -------- Reaper Tower 2, 3 --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Attacked unit) is in zUG_CreepsDevil) Equal to True
            • Or - Any (Conditions) are true
              • Conditions
                • (Attacking unit) Equal to Soul Tower Level 2 0034 <gen>
                • (Attacking unit) Equal to Soul Tower Level 3 0029 <gen>
          • Then - Actions
            • Set TempPoint = (Position of (Attacked unit))
            • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Number of units in TempGroup) Less than or equal to 2
              • Then - Actions
                • Custom script: call DestroyGroup (udg_TempGroup)
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Set TempPoint = (Position of (Attacked unit))
                • Set TempGroup = (Units within 500.00 of TempPoint matching ((((Matching unit) is in HerolarBotDevil) Equal to True) and (((Matching unit) is in zUG_TankOFF_DEVIL) Equal to False)))
                • Unit Group - Pick every unit in TempGroup and do (Actions)
                  • Loop - Actions
                    • Set zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] = True
                    • Unit - Order (Picked unit) to Move To (Center of DevilAltKule)
                    • Unit Group - Remove (Picked unit) from zUG_DALANLAR_DEVIL
                    • Countdown Timer - Start BotKuledenKacmaTimer[(Player number of (Owner of (Picked unit)))] as a One-shot timer that will expire in 2.00 seconds
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Custom script: call DestroyGroup (udg_TempGroup)
              • Else - Actions
                • Custom script: call RemoveLocation (udg_TempPoint)
                • Custom script: call DestroyGroup (udg_TempGroup)
          • Else - Actions
    • -------- Middle --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • ((Attacked unit) is in zUG_CreepsDevil) Equal to True
        • Or - Any (Conditions) are true
          • Conditions
            • (Attacking unit) Equal to Soul Tower Level 2 0035 <gen>
            • (Attacking unit) Equal to Soul Tower Level 3 0028 <gen>
      • Then - Actions
        • Set TempPoint = (Position of (Attacked unit))
        • Set TempGroup = (Units within 500.00 of TempPoint matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Number of units in TempGroup) Less than or equal to 2
          • Then - Actions
            • Custom script: call DestroyGroup (udg_TempGroup)
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Set TempPoint = (Position of (Attacked unit))
            • Set TempGroup = (Units within 500.00 of TempPoint matching ((((Matching unit) is in HerolarBotDevil) Equal to True) and (((Matching unit) is in zUG_TankOFF_DEVIL) Equal to False)))
            • Unit Group - Pick every unit in TempGroup and do (Actions)
              • Loop - Actions
                • Set zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] = True
                • Unit - Order (Picked unit) to Move To (Center of DevilOrtaKule)
                • Unit Group - Remove (Picked unit) from zUG_DALANLAR_DEVIL
                • Countdown Timer - Start BotKuledenKacmaTimer[(Player number of (Owner of (Picked unit)))] as a One-shot timer that will expire in 2.00 seconds
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
          • Else - Actions
            • Custom script: call RemoveLocation (udg_TempPoint)
            • Custom script: call DestroyGroup (udg_TempGroup)
      • Else - Actions
11-) Send them to the base for heal

This periodic trigger simply checks every units within Regen groups and orders them for the base.

  • Events
    • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
    • Unit Group - Pick every unit in zUG_RegenReaper and do (Actions)
      • Loop - Actions
        • Unit Group - Order zUG_RegenReaper to Move To (Center of PreviousTarget[(Player number of (Owner of (Picked unit)))])
    • Unit Group - Pick every unit in zUG_RegenDevil and do (Actions)
      • Loop - Actions
        • Unit Group - Order zUG_RegenDevil to Move To (Center of PreviousTarget[(Player number of (Owner of (Picked unit)))])
12-) Fall back if attacked by enemy creep

When creeps attacks one of your bots, they are falling back for a while. In here i have set another condition in here. I am checking their levels and i am not runing this trigger when their levels are greater than 21.

  • Events
    • Unit - A unit Is attacked
  • Conditions
    • ((Attacked unit) is in zUG_RegenALL) Equal to False
    • ((Attacked unit) is in HerolarBotDevil) Equal to True
    • ((Attacking unit) is in zUG_CreepsReaper) Equal to True
    • zBool_AIFallBackCREEP[(Player number of (Owner of (Attacked unit)))] Equal to False
    • (Level of (Attacked unit)) Less than or equal to 21
  • Actions
    • Set zBool_AIFallBackCREEP[(Player number of (Owner of (Attacked unit)))] = True
    • Set TempPoint = ((Position of (Attacked unit)) offset by 375.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])) - 0.00) degrees)
    • Unit - Order (Attacked unit) to Move To TempPoint
    • Custom script: call RemoveLocation (udg_TempPoint)
    • Countdown Timer - Start CreeptenKacmaBittiSeysi[(Player number of (Owner of (Attacked unit)))] as a One-shot timer that will expire in 5.00 seconds
    • Wait (2.00 - ((Real((Level of (Attacked unit)))) x 0.10)) seconds
    • Set TempGroup = (Units within 500.00 of (Position of (Attacked unit)) matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
    • Unit Group - Pick every unit in TempGroup and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Number of units in TempGroup) Greater than or equal to 1
          • Then - Actions
            • Unit - Order zU_AIHero[(Player number of (Owner of (Attacked unit)))] to Attack-Move To (Center of NextTarget[(Player number of (Owner of (Attacked unit)))])
          • Else - Actions
            • Unit - Order zU_AIHero[(Player number of (Owner of (Attacked unit)))] to Attack-Move To (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])
    • Custom script: call DestroyGroup (udg_TempGroup)
  • And there are 10 times for 10 slots just like this.
  • Timer2Kacma
    • Events
      • Time - CreeptenKacmaBittiSeysi[2] expires
    • Conditions
    • Actions
      • Set zBool_AIFallBackCREEP[2] = False
13-) Fall back when heroes attacks to them

If enemy heroes attacks them, they are checking for their level difference. If the attacker level is higher than attacked unit, i am simply sending them to their back.

  • Events
    • Unit - A unit Is attacked
    • Conditions
      • ((Attacking unit) is in ReaperHerolariPlayer) Equal to True
      • (Attacked unit) Equal to zU_AIHero[2]
      • zBool_AIFallBackHERO[2] Equal to False
      • ((Attacked unit) is in zUG_RegenDevil) Equal to False
      • ((Attacked unit) is in CHANNEL) Equal to False
    • Actions
      • Set xINT_TEMP[2] = (Level of (Attacking unit))
      • -------- 15 --------
      • Set xINT_TEMP2[2] = (Level of (Attacked unit))
      • -------- 10 --------
      • Set xINT_TEMP3[2] = (xINT_TEMP[2] - xINT_TEMP2[2])
      • -------- 5 --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • xINT_TEMP3[2] Greater than or equal to 3
        • Then - Actions
          • Set zBool_AIFallBackHERO[2] = True
          • Set TempPoint = ((Position of (Attacked unit)) offset by 800.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[2])) - 0.00) degrees)
          • Unit - Order (Attacked unit) to Move To TempPoint
          • Custom script: call RemoveLocation (udg_TempPoint)
          • Wait 4.00 seconds
          • Set zBool_AIFallBackHERO[2] = False
          • Set TempGroup = (Units within 800.00 of (Position of (Attacked unit)) matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
          • Unit Group - Pick every unit in TempGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in TempGroup) Greater than or equal to 1
                • Then - Actions
                  • Unit - Order zU_AIHero[(Player number of (Owner of (Attacked unit)))] to Attack-Move To (Center of NextTarget[2])
                  • Custom script: call DestroyGroup (udg_TempGroup)
                • Else - Actions
                  • Custom script: call DestroyGroup (udg_TempGroup)
        • Else - Actions
14-) NextTarget, CurrentTarget, Previous Target setup

I have created 3 RegionArray triggers for the detect their locations. I am increasing their custom values when they are entered specific regions. There are 20 copies of this trigger for specific regions.

  • Events
    • Unit - A unit enters 0 <gen>
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Triggering unit) is in HerolarBotDevil) Equal to True
        • Then - Actions
          • Set CurrentTarget[(Player number of (Owner of (Triggering unit)))] = 0 <gen>
          • Set NextTarget[(Player number of (Owner of (Triggering unit)))] = 1 <gen>
          • Set PreviousTarget[(Player number of (Owner of (Triggering unit)))] = GameGuideDevil <gen>
          • Unit - Set the custom value of (Entering unit) to 27
          • Set i_customvalue[(Player number of (Owner of (Triggering unit)))] = 1
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Triggering unit) is in HerolarBotReaper) Equal to True
            • Then - Actions
              • Set CurrentTarget[(Player number of (Owner of (Triggering unit)))] = 0 <gen>
              • Set NextTarget[(Player number of (Owner of (Triggering unit)))] = GameGuideDevil <gen>
              • Set PreviousTarget[(Player number of (Owner of (Triggering unit)))] = DevilSpawn2 <gen>
              • Unit - Set the custom value of (Entering unit) to 27
              • Set i_customvalue[(Player number of (Owner of (Triggering unit)))] = 1
            • Else - Actions
15) Setting towers

We should tell the bots where they have to fall back. Towers are key structures for this and i am sending them to the last tower for their lanes. My system is simple. When you start the game, i am setting Tower 3 = DevilTowerTop. If Tower 3 destroys, i am setting DevilTowerTop2 as DevilTowerTop.

  • Events
    • Map initialization
    • Conditions
    • Actions
      • Set ClanDevilPlayer = Player 1 (Red)
      • Set ClanReaperPlayer = Player 7 (Green)
      • Set DevilOrtaKule = 22 <gen>
      • Set DevilAltKule = DevilSol <gen>
      • Set DevilUstKule = DevilSag <gen>
      • Set ReaperOrtaKule = 24 <gen>
      • Set ReaperUstKule = 5 <gen>
      • Set ReaperAltKule = 15 <gen>
      • Set DevilTowerCount = 8
      • Set DevilTowerCountBot = 3
      • Set DevilTowerCountMid = 2
      • Set DevilTowerCountTop = 3
      • Set ReaperTowerCount = 8
      • Set ReaperTowerCountBot = 3
      • Set ReaperTowerCountMid = 2
      • Set ReaperTowerCountTop = 3
  • Events
    • Unit - A unit Dies
  • Conditions
  • Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Fire Tower Level 1 0043 <gen>
      • Then - Actions
        • Set DevilUstKule = 2 <gen>
        • Set DevilTowerCountTop = (DevilTowerCountTop - 1)
        • Set DevilTowerCount = (DevilTowerCount - 1)
        • Set zU_DevilUstKule = Fire Tower Level 2 0042 <gen>
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Fire Tower Level 2 0042 <gen>
          • Then - Actions
            • Set DevilUstKule = 1 <gen>
            • Set DevilTowerCountTop = (DevilTowerCountTop - 1)
            • Set DevilTowerCount = (DevilTowerCount - 1)
            • Set zU_DevilUstKule = Fire Tower Level 3 0026 <gen>
          • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Dying unit) Equal to Fire Tower Level 3 0026 <gen>
              • Then - Actions
                • Set zU_DevilUstKule = Slayer Devil 0124 <gen>
                • Set DevilUstKule = 1 <gen>
                • Set DevilTowerCountTop = (DevilTowerCountTop - 1)
                • Set DevilTowerCount = (DevilTowerCount - 1)
              • Else - Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Fire Tower Level 1 0040 <gen>
      • Then - Actions
        • Set zU_DevilUstKule = Fire Tower Level 2 0039 <gen>
        • Set DevilAltKule = 12 <gen>
        • Set DevilTowerCountBot = (DevilTowerCountBot - 1)
        • Set DevilTowerCount = (DevilTowerCount - 1)
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Fire Tower Level 2 0039 <gen>
          • Then - Actions
            • Set zU_DevilUstKule = Fire Tower Level 3 0024 <gen>
            • Set DevilAltKule = 11 <gen>
            • Set DevilTowerCountBot = (DevilTowerCountBot - 1)
            • Set DevilTowerCount = (DevilTowerCount - 1)
          • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Dying unit) Equal to Fire Tower Level 3 0024 <gen>
              • Then - Actions
                • Set zU_DevilUstKule = Slayer Devil 0124 <gen>
                • Set DevilAltKule = 11 <gen>
                • Set DevilTowerCountBot = (DevilTowerCountBot - 1)
                • Set DevilTowerCount = (DevilTowerCount - 1)
              • Else - Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Fire Tower Level 2 0041 <gen>
      • Then - Actions
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Fire Tower Level 2 0039 <gen>
          • Then - Actions
            • Set zU_DevilUstKule = Fire Tower Level 3 0025 <gen>
            • Set DevilOrtaKule = 21 <gen>
            • Set DevilTowerCountMid = (DevilTowerCountMid - 1)
            • Set DevilTowerCount = (DevilTowerCount - 1)
          • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Dying unit) Equal to Fire Tower Level 3 0024 <gen>
              • Then - Actions
                • Set zU_DevilUstKule = Slayer Devil 0124 <gen>
                • Set DevilOrtaKule = DevilSpawn2 <gen>
                • Set DevilTowerCountMid = (DevilTowerCountMid - 1)
                • Set DevilTowerCount = (DevilTowerCount - 1)
              • Else - Actions
    • -------- reaper top --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Soul Tower Level 1 0037 <gen>
      • Then - Actions
        • Set zU_ReaperUstKule = Soul Tower Level 2 0036 <gen>
        • Set ReaperUstKule = 6 <gen>
        • Set ReaperTowerCountTop = (ReaperTowerCountTop - 1)
        • Set ReaperTowerCount = (ReaperTowerCount - 1)
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Soul Tower Level 2 0036 <gen>
          • Then - Actions
            • Set zU_ReaperUstKule = Soul Tower Level 3 0027 <gen>
            • Set ReaperUstKule = 7 <gen>
            • Set ReaperTowerCountTop = (ReaperTowerCountTop - 1)
            • Set ReaperTowerCount = (ReaperTowerCount - 1)
          • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Dying unit) Equal to Soul Tower Level 3 0027 <gen>
              • Then - Actions
                • Set zU_ReaperUstKule = Slayer Reaper 0054 <gen>
                • Set ReaperUstKule = ReaperSpawn3 <gen>
                • Set ReaperTowerCountTop = (ReaperTowerCountTop - 1)
                • Set ReaperTowerCount = (ReaperTowerCount - 1)
              • Else - Actions
    • -------- reaper bot --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Soul Tower Level 1 0038 <gen>
      • Then - Actions
        • Set zU_ReaperUstKule = Soul Tower Level 2 0034 <gen>
        • Set ReaperAltKule = 16 <gen>
        • Set ReaperTowerCountBot = (ReaperTowerCountBot - 1)
        • Set ReaperTowerCount = (ReaperTowerCount - 1)
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Soul Tower Level 2 0034 <gen>
          • Then - Actions
            • Set zU_ReaperUstKule = Soul Tower Level 3 0029 <gen>
            • Set ReaperAltKule = 17 <gen>
            • Set ReaperTowerCountBot = (ReaperTowerCountBot - 1)
            • Set ReaperTowerCount = (ReaperTowerCount - 1)
          • Else - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Dying unit) Equal to Soul Tower Level 3 0029 <gen>
              • Then - Actions
                • Set zU_ReaperUstKule = Slayer Reaper 0054 <gen>
                • Set ReaperAltKule = 17 <gen>
                • Set ReaperTowerCountBot = (ReaperTowerCountBot - 1)
                • Set ReaperTowerCount = (ReaperTowerCount - 1)
              • Else - Actions
    • -------- reaper mid --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Dying unit) Equal to Soul Tower Level 2 0035 <gen>
      • Then - Actions
        • Set zU_ReaperOrtaKule = Soul Tower Level 3 0028 <gen>
        • Set ReaperOrtaKule = 25 <gen>
        • Set ReaperTowerCountMid = (ReaperTowerCountMid - 1)
        • Set ReaperTowerCount = (ReaperTowerCount - 1)
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Dying unit) Equal to Soul Tower Level 3 0028 <gen>
          • Then - Actions
            • Set zU_ReaperOrtaKule = Slayer Reaper 0054 <gen>
            • Set ReaperOrtaKule = ReaperSpawn2 <gen>
            • Set ReaperTowerCountMid = (ReaperTowerCountMid - 1)
            • Set ReaperTowerCount = (ReaperTowerCount - 1)
          • Else - Actions
16) Casting spells to AoE

And here is my worst nightmare of my AI system. Still it is not stable because uhm.. I don't know how to explain this. They are acting like they are canceling orders.

  • SkillsAoEn
    • Events
      • Time - Every 1.10 seconds of game time
    • Conditions
    • Actions
      • -------- First of all, i am picking every hero controlled by AI with few conditions. --------
      • Unit Group - Pick every unit in HerolarBotALL and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is in zUG_RegenALL) Equal to False
              • zBool_AIFallBackCREEP[(Player number of (Owner of (Picked unit)))] Equal to False
              • zBool_AIFallBackHERO[(Player number of (Owner of (Picked unit)))] Equal to False
              • zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] Equal to False
            • Then - Actions
              • -------- Then i am creating TempPoint, TempGroups and TempBotCasters --------
              • Set TempBotPointCaster = (Picked unit)
              • Set TempPointCaster = (Position of (Picked unit))
              • -------- There is a HUGE FLAW in here. I think they can try to cast spells from thousands range away enemies. And they stop casting because they cannot reach them. --------
              • -------- I am not sure about it but is that a correct picking? --------
              • Set TempGroupEnemy = (Units within 1000.00 of TempPointCaster matching ((((Matching unit) is in HerolarALL) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True) and (((Matching unit) is alive) Equal to True))))
              • Set TempPointTarget = (Position of (Random unit from TempGroupEnemy))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in TempGroupEnemy) Greater than or equal to 1
                • Then - Actions
                  • Unit Group - Add (Picked unit) to TempCastGroup
                  • Unit - Order (Picked unit) to Undead Dreadlord - Carrion Swarm TempPointTarget
                  • Unit - Order (Picked unit) to Human Archmage - Blizzard TempPointTarget
                  • Unit - Order (Picked unit) to Neutral Pit Lord - Rain Of Fire TempPointTarget
                  • Unit - Order (Picked unit) to Undead Dreadlord - Inferno TempPointTarget
                  • Unit - Order (Picked unit) to Orc Tauren Chieftain - Shockwave TempPointTarget
                  • -------- This trigger picks CreepsDevil around the Hero. Because after it casts spells, it has go to next or previous target --------
                  • -------- If player number lesser than or equal to 6 that means CreepsDevil are allies. (Player 1 red ally with 2-3-4-5-6) --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Player number of (Owner of (Picked unit))) Less than or equal to 6
                    • Then - Actions
                      • -------- I am creating TempGroup2 that includes CreepsDevil (allies of picked unit) --------
                      • Set TempGroupNew2 = (Units within 500.00 of (Position of (Picked unit)) matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
                      • -------- Don't worry, i am removing dying CreepsDevil from CreepsDevil unit group --------
                      • Unit Group - Pick every unit in TempGroupNew2 and do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Number of units in TempGroupNew2) Greater than or equal to 1
                            • Then - Actions
                              • -------- There are still 1 or more creeps available around the picked unit. Go for the NextTarget --------
                              • Unit - Order TempBotTargetCaster to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of TempBotPointCaster))])
                            • Else - Actions
                              • -------- There are no creeps. Fall back to the previous target. --------
                              • Unit - Order TempBotTargetCaster to Attack-Move To (Center of PreviousTarget[(Player number of (Owner of TempBotPointCaster))])
                      • Custom script: call DestroyGroup (udg_TempGroupNew2)
                    • Else - Actions
                      • Set TempGroupNew2 = (Units within 500.00 of (Position of (Picked unit)) matching (((Matching unit) is in zUG_CreepsReaper) Equal to True))
                      • -------- Else. That means player number of picked player NOT lesser or equal to 6. That means picked unit ally with CreepsReaper (player 7 allied with 8-9-10-11-12) --------
                      • Unit Group - Pick every unit in TempGroupNew2 and do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Number of units in TempGroupNew2) Greater than or equal to 1
                            • Then - Actions
                              • Unit - Order TempBotTargetCaster to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of TempBotTargetCaster))])
                            • Else - Actions
                              • Unit - Order TempBotTargetCaster to Attack-Move To (Center of PreviousTarget[(Player number of (Owner of TempBotTargetCaster))])
                      • Custom script: call DestroyGroup (udg_TempGroupNew2)
                • Else - Actions
                  • Custom script: call RemoveLocation (udg_TempPointCaster)
                  • Custom script: call RemoveLocation (udg_TempPointTarget)
                  • Custom script: call DestroyGroup (udg_TempGroupEnemy)
                  • Set TempBotPointCaster = No unit
              • Custom script: call RemoveLocation (udg_TempPointCaster)
              • Custom script: call RemoveLocation (udg_TempPointTarget)
              • Custom script: call DestroyGroup (udg_TempGroupEnemy)
              • Set TempBotPointCaster = No unit
              • Unit Group - Remove all units from TempCastGroup
            • Else - Actions
17) Cast spells on target

  • Events
    • Time - Every 1.00 seconds of game time
  • Conditions
  • Actions
    • Unit Group - Pick every unit in HerolarBotALL and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Picked unit) is in zUG_RegenALL) Equal to False
            • zBool_AIFallBackCREEP[(Player number of (Owner of (Picked unit)))] Equal to False
            • zBool_AIFallBackHERO[(Player number of (Owner of (Picked unit)))] Equal to False
            • zBool_AIFallBackTOWER[(Player number of (Owner of (Picked unit)))] Equal to False
          • Then - Actions
            • Set TempGroupT = (Units within 1000.00 of (Position of (Picked unit)) matching ((((Matching unit) is in HerolarALL) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True) and (((Matching unit) is alive) Equal to True))))
            • Set TempUnit = (Random unit from TempGroupT)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Number of units in TempGroupT) Greater than or equal to 1
              • Then - Actions
                • Unit Group - Add (Picked unit) to TempCastGroup
                • Unit - Order (Picked unit) to Human Sorceress - Polymorph TempUnit
                • Unit - Order (Picked unit) to Orc Shadow Hunter - Hex TempUnit
                • Unit - Order (Picked unit) to Orc Far Seer - Chain Lightning TempUnit
                • Unit - Order (Picked unit) to Neutral - Firebolt TempUnit
                • Unit - Order (Picked unit) to Undead Lich - Frost Nova TempUnit
                • Unit - Order (Picked unit) to Undead Necromancer - Cripple TempUnit
                • Unit - Order (Picked unit) to Neutral Naga Sea Witch - Forked Lightning TempUnit
                • Unit - Order (Picked unit) to Special Archimonde - Finger Of Death TempUnit
                • Unit - Order (Picked unit) to Neutral Fire Lord - Soul Burn TempUnit
                • Unit - Order (Picked unit) to Neutral Naga Sea Witch - Forked Lightning TempUnit
                • Unit - Order (Picked unit) to Special Archimonde - Finger Of Death TempUnit
                • Unit - Order (Picked unit) to Neutral - Firebolt TempUnit
                • Unit - Order (Picked unit) to Human Sorceress - Polymorph TempUnit
                • Unit - Order (Picked unit) to Orc Raider - Ensnare TempUnit
                • Game - Display to DebugBotSkills for 1.00 seconds the text: ((Name of (Owner of (Picked unit))) + ( >>> + (Name of (Owner of TempUnit))))
                • -------- This trigger picks CreepsDevil around the Hero. Because after it casts spells, it has go to next or previous target --------
                • -------- If player number lesser than or equal to 6 that means CreepsDevil are allies. (Player 1 red ally with 2-3-4-5-6) --------
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • (Player number of (Owner of (Picked unit))) Less than or equal to 6
                  • Then - Actions
                    • -------- I am creating TempGroup2 that includes CreepsDevil (allies of picked unit) --------
                    • Set TempGroup2 = (Units within 500.00 of (Position of (Picked unit)) matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
                    • -------- Don't worry, i am removing dying CreepsDevil from CreepsDevil unit group --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • (Number of units in TempGroup2) Greater than or equal to 1
                      • Then - Actions
                        • -------- There are still 1 or more creeps available around the picked unit. Go for the NextTarget --------
                        • Unit - Order TempBotTargetCaster to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of TempBotTargetCaster))])
                      • Else - Actions
                        • -------- There are no creeps. Fall back to the previous target. --------
                        • Unit - Order TempBotTargetCaster to Attack-Move To (Center of PreviousTarget[(Player number of (Owner of TempBotTargetCaster))])
                    • Custom script: call DestroyGroup (udg_TempGroup2)
                  • Else - Actions
                    • Set TempGroup2 = (Units within 500.00 of (Position of (Picked unit)) matching (((Matching unit) is in zUG_CreepsReaper) Equal to True))
                    • -------- Else. That means player number of picked player NOT lesser or equal to 6. That means picked unit ally with CreepsReaper (player 7 allied with 8-9-10-11-12) --------
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • (Number of units in TempGroup2) Greater than or equal to 1
                      • Then - Actions
                        • Unit - Order TempBotTargetCaster to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of TempBotTargetCaster))])
                      • Else - Actions
                        • Unit - Order TempBotTargetCaster to Attack-Move To (Center of PreviousTarget[(Player number of (Owner of TempBotTargetCaster))])
                    • Custom script: call DestroyGroup (udg_TempGroup2)
              • Else - Actions
                • Custom script: call RemoveLocation (udg_TempPointCasterTarget)
                • Custom script: call DestroyGroup (udg_TempGroupT)
                • Set TempBotTargetCaster = No unit
                • Set TempUnit = No unit
            • Set TempBotTargetCaster = No unit
            • Set TempUnit = No unit
            • Unit Group - Remove all units from TempCastGroup
          • Else - Actions
    • Unit Group - Remove all units from TempCastGroup
18) Prevent them cast spells on non-heroes

I have created this trigger because bots we're casting spells on creeps. And somehow they are losing their mana, this is why i am adding mana to them.

  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • ((Casting unit) is in HerolarBotALL) Equal to True
    • ((Unit-type of (Target unit of ability being cast)) is A Hero) Equal to False
    • ((Casting unit) belongs to an ally of (Owner of (Target unit of ability being cast))) Equal to False
  • Actions
    • Unit - Order (Casting unit) to Stop
    • Wait 0.10 seconds
    • Unit - Order (Casting unit) to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of (Casting unit)))])
    • Unit - Set mana of (Casting unit) to ((Mana of (Casting unit)) + 100.00)
And here is my history. I know it has lot of flaws but creating AI system was a challenging to me. You can suggest "anything" about the system.
And i hope it will be useful for anything who need it.
 
Great that you made your A.I. system work and that you're happy with how it turned out!

If you want to further improve your system and make your bots appear smarter, you might want to change from a "If X, then do Y" system to a priority system. Basically, you list all tasks the bot could do, then you evaluate a score for each task based on the current game state and make the bot perform the one with the highest score. For example, the score of "Go back to base to regenerate" is dependent on the percentage health of the bot. But if there's something else to do that's really important, that would override it even if the bot is at 20% health.

You are still leaking a lot of locations in your script. For example, the line
  • Set TempPoint = ((Position of (Attacked unit)) offset by 375.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])) - 0.00) degrees)
leaks Position of (Attacking unit) as well as Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))]. It is not enough to save the location with the angular offset to a variable, you must also save and destroy the origin location.

18) Prevent them cast spells on non-heroes

I have created this trigger because bots we're casting spells on creeps. And somehow they are losing their mana, this is why i am adding mana to them.

  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • ((Casting unit) is in HerolarBotALL) Equal to True
    • ((Unit-type of (Target unit of ability being cast)) is A Hero) Equal to False
    • ((Casting unit) belongs to an ally of (Owner of (Target unit of ability being cast))) Equal to False
  • Actions
    • Unit - Order (Casting unit) to Stop
    • Wait 0.10 seconds
    • Unit - Order (Casting unit) to Attack-Move To (Center of CurrentTarget[(Player number of (Owner of (Casting unit)))])
    • Unit - Set mana of (Casting unit) to ((Mana of (Casting unit)) + 100.00)
[/TRIGGER]

You want to use the "Unit - A unit begins casting an ability" event for this one. Then they shouldn't lose mana.
Unit - A unit begins casting an ability = Beginning of cast animation.
Unit - A unit Starts the effect of an ability = Successful spell cast.
 
Last edited:
  • Set TempPoint = ((Position of (Attacked unit)) offset by 375.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])) - 0.00) degrees)
You want to change this to:
  • Set TempPoint2 = Position of (Attacked unit)
  • Set TempPoint3 = Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))]
  • Set TempPoint = TempPoint2 offset by 375.00 towards (TempPoint2 to TempPoint3 degrees)
  • //Do your stuff
  • call RemoveLocation(udg_TempPoint)
  • call RemoveLocation(udg_TempPoint2)
  • call RemoveLocation(udg_TempPoint3)
This is not only in those lines, but in a lot of other situations as well:
  • Set TempGroup = (Units within 800.00 of (Position of (Attacked unit)) matching (((Matching unit) is in zUG_CreepsDevil) Equal to True))
This one, for example. leaks as well.

But if you value your sanity, remove only the leaks in the functions that are executed often. If you have one location leak every second, after 1 hour of game time you would have leaked approx. 2MB, so in the end it doesn't really matter.
 
Level 17
Joined
Jun 2, 2009
Messages
1,191
Uhm. Just like this right? I want to be sure. And it is the first time someone gave me example about leaking. (every sec after 1 hour approximately 2mb)

  • Actions
    • Unit - Order (Casting unit) to Stop
    • Wait 0.10 seconds
    • Set TempPoint = (Center of CurrentTarget[(Player number of (Owner of (Casting unit)))])
    • Unit - Order (Casting unit) to Attack-Move To TempPoint
    • Custom script: call RemoveLocation(udg_TempPoint)
That means we have to always create temporary point or region, then delete it even it sets with trigger right.
That means no difference between Position of Attacked Unit and Position of AttackUnitPoint right?

By the way i couldn't find this one Set TempPoint = TempPoint2 offset by 375.00 towards (TempPoint2 to TempPoint3 degrees)
Which action it has :D
 
Last edited:
Level 40
Joined
Feb 27, 2007
Messages
5,098
By the way i couldn't find this one Set TempPoint = TempPoint2 offset by 375.00 towards (TempPoint2 to TempPoint3 degrees)
Which action it has :D
Antares didn't write out the full text that should be there. It should say "(Angle from TempPoint2 to TempPoint3) degrees". The GUI action is called "Math - Angle Between Points" in English.
 
Level 17
Joined
Jun 2, 2009
Messages
1,191
Uhm. I don't understand it yet.


  • Set TempPoint = ((Position of (Attacked unit)) offset by 800.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[2])) - 0.00) degrees)
  • Set TempPoint2 = (Position of (Attacking unit))
  • Set TempPoint3 = (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])
  • Set TempPoint = ?????


By the way what are you think about my system @Pyrogasm it was hard to create this topic.
 
Level 40
Joined
Feb 27, 2007
Messages
5,098
Uhm. I don't understand it yet.
Okay, I will explain simply from the beginning. This line contains four different points (Antares only noticed 3 of them, they missed one). I have made each of them a different color so it is easy for you to see.
Set TempPoint = ((Position of (Attacked unit)) offset by 375.00 towards ((Angle from (Position of (Attacking unit)) to (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])) - 0.00) degrees)
Lower down in your trigger you do this, which is correct: Custom script: call RemoveLocation (udg_TempPoint)

I have made part of it blue to show you that this custom script line cleans only the blue leak. You are able to do this cleaning line because you assigned the blue point that would have leaked to a variable called TempPoint. By saving it in the variable you can safely remove it after you're done using it in order to prevent the blue data from leaking. I think you understand this.

When you create the blue point, it references three other points that are not getting stored in variables. These are the red, yellow, and purple points. Since they're not stored in variables, they cannot be removed. Since they cannot be removed, they become memory leaks. When you create the blue point, you leak 3 other points in the process that you must deal with.

Antares is showing you how you can save those points into variables before you create the blue point, and then use those points in the trigger action that creates the blue point. You do this so that you can assign the red, yellow, and purple points to variables so that you can remove them later to prevent the leaks they would become. It looks like this:

Set TempPoint2 = (Position of (Attacked Unit))
Set TempPoint3 = (Position of (Attacking Unit))
Set TempPoint4 = (Center of PreviousTarget[(Player number of (Owner of (Attacked unit)))])

Now when create the blue point you will use these variables directly:

Set TempPoint = (TempPoint2 offset by 375.00 towards ((Angle from TempPoint3 to TempPoint4) - 0.00) degrees)

Finally, you will need to clean up each of these points individually with different custom script lines after you are finished using TempPoint:

Custom script: call RemoveLocation (udg_TempPoint)
Custom script: call RemoveLocation (udg_TempPoint2)
Custom script: call RemoveLocation (udg_TempPoint3)
Custom script: call RemoveLocation (udg_TempPoint4)

By the way what are you think about my system @Pyrogasm it was hard to create this topic.
Honestly I didn't read most of your triggers because it was a lot and I figured you mostly wouldn't understand any suggestions I had. But I appreciate that you showed everything for everyone to see; that is very helpful when you want feedback about your system. I am happy you are continuing to ask questions and explore. I am here to help you learn, so if this thread doesn't get attention from anyone else I'll go back and deep dive on your system.
 
That's the best explanation one could give!

Again, don't make yourself crazy about all possible memory leaks. I do that and it's not healthy, please send help. Identify the functions that are executed really often and make those as clean as possible. Removing location leaks in GUI is quite annoying. With what you're doing, you will be concerned mostly about location and unit group leaks. From what I can tell, you got the unit group leaks covered. When you're working on spells and stuff, special effect leaks may be an additional concern.

Regarding the broader feedback on your system, it is hard to read your script and understand what it's exactly trying to do because many of the variable names are abbreviations that we don't know or are in a foreign language, and so they don't make a lot of sense to anyone who doesn't speak it. It is Turkish, if I am not mistaken?

When you post a smaller snippet, it's not a big deal, but for such a large script, it quickly becomes too confusing.
 
Level 17
Joined
Jun 2, 2009
Messages
1,191
Do you intend to have this as tutorial?
Hmmm. It is actually but partially. I just wanted to share my AI system for anyone who might need it. But of course it was created by myself and honestly i have said it can includes bug and not a professional one.

@Pyrogasm and @Antares A thank you so much again. Probably i will update this when i changed few Türkçe lines and after leak thing.
Thank you so much. By the way @Pyrogasm yes i will continue ask but if you mean this one [General] - Is there a system that checks "entered region is equal to" sadly still i don't understand it. Uncle asked for demo map and i said yes. Maybe after the demo map i will get it.
 
Status
Not open for further replies.
Top