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

How can i prevent same heroes

Status
Not open for further replies.
Level 17
Joined
Jun 2, 2009
Messages
1,137
Hello everyone. Here is my system.

I can prevent players getting heroes selected by AI Controlled Players with this trigger.

  • HeroSectirme
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Game - Display to (All players) for 5.00 seconds the text: |cff00ff00Yapay zek...
      • Wait 10.00 seconds
      • Game - Display to (All players) for 5.00 seconds the text: |cff00ff00Yapay zek...
      • Wait 5.00 seconds
      • Game - Display to (All players) for 5.00 seconds the text: |cff00ff00Yapay zek...
      • Wait 5.00 seconds
      • 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 10)
                      • 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
                  • Hero - Modify Strength of (Last created unit): Add 10
                  • Hero - Modify Agility of (Last created unit): Add 10
                  • Hero - Modify Intelligence of (Last created unit): Add 10
                  • 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
                  • Unit - Set the custom value of (Last created unit) to 0
                  • 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 11)
                      • 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
                  • Hero - Modify Strength of (Last created unit): Add 10
                  • Hero - Modify Agility of (Last created unit): Add 10
                  • Hero - Modify Intelligence of (Last created unit): Add 10
                  • 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
                  • Unit - Set the custom value of (Last created unit) to 0
                  • Set HeroCountReaper = (HeroCountReaper + 1)
            • Else - Actions
BUT AI Controlled Heroes can select our own heroes. I want to prevent this. And this trigger is my hero select trigger.

  • Heroes Sent2
    • Events
      • Unit - A unit enters Altars <gen>
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Level of (Triggering unit)) Equal to 1
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Triggering unit)) is in ClanDevilPlayers) Equal to True
        • Then - Actions
          • Wait 0.10 seconds
          • Unit - Move (Triggering unit) instantly to (Center of GameGuideDevil <gen>)
          • Unit Group - Add (Triggering unit) to DevilHerolariPlayer
          • Unit Group - Add (Triggering unit) to HerolarALL
          • Unit Group - Add (Triggering unit) to HerolarDevilAll
          • Set HeroOyuncu[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set TPUnit[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set HeroCountDevil = (HeroCountDevil + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Triggering unit)) is in ClanReaperPlayers) Equal to True
        • Then - Actions
          • Wait 0.10 seconds
          • Unit - Move (Triggering unit) instantly to (Center of GameGuideReaper <gen>)
          • Unit Group - Add (Triggering unit) to ReaperHerolariPlayer
          • Unit Group - Add (Triggering unit) to HerolarALL
          • Unit Group - Add (Triggering unit) to HerolarReaperALL
          • Set HeroOyuncu[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set TPUnit[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set HeroCountReaper = (HeroCountReaper + 1)
        • Else - Actions
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
You want a list that tracks all available heroes. When a player or AI selects a hero it is removed from that list. The AI can only pick heroes that are inside that list, such as by getting an element at a random position. Like wise the player can only choose heroes inside that list with a condition to make sure the picked hero is inside that list otherwise selection fails.

Careful using TriggerSleepAction (Wait/Wait game time) since that can allow for race conditions in your script that cause unintended results. For example performing a test and then waiting might result in the test conditions no longer being valid after the wait, or that during that time another trigger could run similar logic due to the conditions still being true.
 
Level 17
Joined
Jun 2, 2009
Messages
1,137
You want a list that tracks all available heroes. When a player or AI selects a hero it is removed from that list. The AI can only pick heroes that are inside that list, such as by getting an element at a random position. Like wise the player can only choose heroes inside that list with a condition to make sure the picked hero is inside that list otherwise selection fails.

Careful using TriggerSleepAction (Wait/Wait game time) since that can allow for race conditions in your script that cause unintended results. For example performing a test and then waiting might result in the test conditions no longer being valid after the wait, or that during that time another trigger could run similar logic due to the conditions still being true.
Honestly, i don't know how to create list just like this. Maybe it is very simple but nothing appears in my mind.
 
Level 39
Joined
Feb 27, 2007
Messages
5,016
You have decided to brute force the randomization repeatedly until it picks a hero that has not been chosen. While not efficient, this solution should be acceptable because the chances you randomly pick already chosen heroes 30,000+ times in a row is incredibly small. What you've done seems mostly correct, but it looks like you're not setting HeroChosen[] = True when players pick their heroes. To know which is the correct index to use, you'll have to compare the unit type of the entering unit to the unit type stored in BotHerolar[]:
  • -------- These should be the first actions of Heroes Sent2 --------
  • For each (Integer A) from 1 to 10 do (Actions)
    • Loop - Actions
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • (Unit-type of (Triggering Unit)) equal to BotHerolar[(Integer A)]
        • Then - Actions
          • Set HeroChosen[(Integer A)] = True
        • Else - Actions
I also noticed this, which might be an error: For players 1-6 you randomize a number from 1 to 10, but for players 7-12 you randomize a number from 1 to 11:
  • Set randomInt = (Random integer number between 1 and 10)
  • ...
  • Set randomInt = (Random integer number between 1 and 11)
It would be best, instead of using a hardcoded 10 or 11, to make a gobal integer variable that counts how many total heroes there are to randomize from. That way the number is always correct as long as you update that variable's value in the editor whenever you add new heroes. Something like this:
  • Set randomInt = (Random integer number between 1 and MAX_HEROES) //MAX_HEROES has a default value of 10
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,199
Honestly, i don't know how to create list just like this. Maybe it is very simple but nothing appears in my mind.
The list is made by storing elements in sequential indices of an array. For example...
Code:
HeroChoices[1] = Paladin
HeroChoices[2] = Death Knight
HeroChoices[3] = Demon Hunter
HeroChoiceN = 3
A random hero can be selected by rolling a number between 1 and the end of the list, HeroChoiceN which in this case is 3. Since the order of the list does not matter for this use situation you can remove elements by replacing the removed element with the end element of the list and decrementing the end of list variable.

For example if a human was to choose a Paladin then you can linear search through the list to find what index it is at, in this case 1, and then remove it from the list. The list will transform to be...
Code:
HeroChoices[1] = Demon Hunter
HeroChoices[2] = Death Knight
HeroChoiceN = 2
An AI can then choose a hero randomly using the above described mechanic. In this case the roll chooses 2 which can then be removed...
Code:
HeroChoices[1] = Demon Hunter
HeroChoiceN = 1
If another player were to try to pick Paladin again then the linear search will fail to find a match. In this case you could print an error message to the player that that hero was already selected.

Logically this assumes the list contains more heroes than can be chosen. If this is not the case you will need special logic to handle the case that there are no more heroes to choose.
 
Level 17
Joined
Jun 2, 2009
Messages
1,137
It tooks few days and still i don't get it. First of all let me answer your questions. First i have to share my whole system for the hero pick because it seems there are few misunderstandings in here.

First of all i have created list includes 18 heroes in here.

  • HeroSetuplar
    • 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
      • Set BotHerolar[5] = Warlock Archimonde
      • Set BotHerolar[6] = Thundercaller Pollon
      • Set BotHerolar[7] = Abomination Brutillus
      • Set BotHerolar[8] = Captain Fabius Ironshield
      • Set BotHerolar[9] = Chillwind Spider Iratha
      • Set BotHerolar[10] = Crusader Lord Nicholas
      • Set BotHerolar[11] = Dreadlord Varimathras
      • Set BotHerolar[12] = Mammoth Grob Thornedskin
      • Set BotHerolar[13] = Demon Hunter Illidan Stormrage
      • Set BotHerolar[14] = Manslayer Himura Kenshin
      • Set BotHerolar[15] = Ranger Anya Moonbow
      • Set BotHerolar[16] = Warden Maiev Shadowsong
      • Set BotHerolar[17] = Raider Nazgrel
      • Set BotHerolar[18] = Overlord Flint Frozencleave

Update? I have an idea, wait for my response.

Then i want to make them pick one of the heroes within these list.

Q: But it seems i forgot to extend it from 18 and i think Set randomInt = (Random integer number between 1 and 10) detects the first 10 heroes within the list. Corret me if i am wrong.

And this trigger prevents them for picking same heroes. It is working without issue.

  • 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)
Now i have to do this.

  • Heroes Sent2
    • Events
      • Unit - A unit enters Altars <gen>
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Level of (Triggering unit)) Equal to 1
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Triggering unit)) is in ClanDevilPlayers) Equal to True
        • Then - Actions
          • Wait 0.10 seconds
          • Unit - Move (Triggering unit) instantly to (Center of GameGuideDevil <gen>)
          • Unit Group - Add (Triggering unit) to DevilHerolariPlayer
          • Unit Group - Add (Triggering unit) to HerolarALL
          • Unit Group - Add (Triggering unit) to HerolarDevilAll
          • Set HeroOyuncu[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set TPUnit[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set HeroCountDevil = (HeroCountDevil + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Owner of (Triggering unit)) is in ClanReaperPlayers) Equal to True
        • Then - Actions
          • Wait 0.10 seconds
          • Unit - Move (Triggering unit) instantly to (Center of GameGuideReaper <gen>)
          • Unit Group - Add (Triggering unit) to ReaperHerolariPlayer
          • Unit Group - Add (Triggering unit) to HerolarALL
          • Unit Group - Add (Triggering unit) to HerolarReaperALL
          • Set HeroOyuncu[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set TPUnit[(Player number of (Owner of (Triggering unit)))] = (Triggering unit)
          • Set HeroCountReaper = (HeroCountReaper + 1)
        • Else - Actions
When player picks hero, for example this player picked Arcane Mistress. And Arcane Mistress equals to BotHerolar[1] for their pick list.
I have to remove/delete/forbid/exclude etc etc BotHerolar[1] for their selection. But nothing appears in my mind.

@Dr Super Good But still i don't get it. Is your trigger prevents AI from picking the hero you choose?

Update: It seems i have solved the issue but i don't think it is a proper and reliable way. I will let you know after dozens of tests.
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
5,016
Update: It seems i have solved the issue but i don't think it is a proper and reliable way. I will let you know after dozens of tests.
I solved your problem for you in my last reply but you ignored me. You literally just need to add a single if block to one of your triggers. It really is this simple:
You have decided to brute force the randomization repeatedly until it picks a hero that has not been chosen. While not efficient, this solution should be acceptable because the chances you randomly pick already chosen heroes 30,000+ times in a row is incredibly small. What you've done seems mostly correct, but it looks like you're not setting HeroChosen[] = True when players pick their heroes. To know which is the correct index to use, you'll have to compare the unit type of the entering unit to the unit type stored in BotHerolar[]:
  • -------- These should be the first actions of Heroes Sent2 --------
  • For each (Integer A) from 1 to 10 do (Actions)
    • Loop - Actions
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • (Unit-type of (Triggering Unit)) equal to BotHerolar[(Integer A)]
        • Then - Actions
          • Set HeroChosen[(Integer A)] = True
        • Else - Actions
I also noticed this, which might be an error: For players 1-6 you randomize a number from 1 to 10, but for players 7-12 you randomize a number from 1 to 11:
  • Set randomInt = (Random integer number between 1 and 10)
  • ...
  • Set randomInt = (Random integer number between 1 and 11)
It would be best, instead of using a hardcoded 10 or 11, to make a gobal integer variable that counts how many total heroes there are to randomize from. That way the number is always correct as long as you update that variable's value in the editor whenever you add new heroes. Something like this:
  • Set randomInt = (Random integer number between 1 and MAX_HEROES) //MAX_HEROES has a default value of 10
 
Level 17
Joined
Jun 2, 2009
Messages
1,137
@Pyrogasm No no i haven't ignored. I have solved it with by my own methods. I have changed many things within trigger and now i am controlling heroes picked by player and checking current food for AI controlled heroes and i have combined my trigger with this one

  • BotHeroSecmeOC
    • Events
      • Unit - A unit enters (Entire map)
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 54, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • BotHerolar[(Integer A)] Equal to (Unit-type of (Entering unit))
            • Then - Actions
              • Set BotHerolar[(Integer A)] = No unit-type
            • Else - Actions
I was already made many changes before your post. Now it seems it is working. Thank you for your aid.
 
Status
Not open for further replies.
Top