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

[Trigger] Adding random non-duplicate abilities

Status
Not open for further replies.
Level 1
Joined
Oct 21, 2016
Messages
4
So i have been looking around but couldn't find a way to solve this problem so i thought that i might as well give it a try here.

I'm trying to create a trigger that will give a unit a random ability from a list of about 10 with an equal chance for each. (I use GUI)

The problem is that i don't want to have duplicate abilities.

I think this may be doable with some sort of loop but don't quite know how.
 
Level 28
Joined
Feb 18, 2014
Messages
3,574
You can store all those 10 abilities inside an array then create a random integer that gives an ability depending on the chance rate.
  • Init Abilities ID
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set AbilityID[1] = Bash
      • Set AbilityID[2] = Blizzard
      • Set AbilityID[3] = Firebolt
      • Set AbilityID[4] = War Stomp
      • Set AbilityID[5] = Divine Shield
      • Set AbilityID[6] = Thunder Clap
      • Set AbilityID[7] = Rain of Fire
      • Set AbilityID[8] = Roar
      • Set AbilityID[9] = Bloodlust
      • Set AbilityID[10] = Frost Armor
  • Give Random Ability
    • Events
      • Player - Player 1 (Red) types a chat message containing test as An exact match
    • Conditions
    • Actions
      • Set RandomInteger = (Random integer number between 1 and 100)
      • Game - Display to (All players) the text: (String(RandomInteger))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 0
          • RandomInteger Lesser than or Equal to 10
        • Then - Actions
          • Unit - Add AbilityID[1] to Paladin 0000 <gen>
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 11
          • RandomInteger Lesser than or Equal to 20
        • Then - Actions
          • Unit - Add AbilityID[2] to Paladin 0000 <gen>
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 21
          • RandomInteger Lesser than or Equal to 30
        • Then - Actions
          • Unit - Add AbilityID[3] to Paladin 0000 <gen>
        • Else - Actions
 
Level 9
Joined
Jul 30, 2018
Messages
445
  • Give Random Ability
    • Events
      • Player - Player 1 (Red) types a chat message containing test as An exact match
    • Conditions
    • Actions
      • Set RandomInteger = (Random integer number between 1 and 100)
      • Game - Display to (All players) the text: (String(RandomInteger))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 0
          • RandomInteger Lesser than or Equal to 10
        • Then - Actions
          • Unit - Add AbilityID[1] to Paladin 0000 <gen>
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 11
          • RandomInteger Lesser than or Equal to 20
        • Then - Actions
          • Unit - Add AbilityID[2] to Paladin 0000 <gen>
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RandomInteger Greater than or Equal to 21
          • RandomInteger Lesser than or Equal to 30
        • Then - Actions
          • Unit - Add AbilityID[3] to Paladin 0000 <gen>
        • Else - Actions

But if that is run more than once, it can give the same spell again.

I had a similar situation where I wanted to give random abilities, but didn't want them to have same abilities twice, so I did this:

  • Actions
    • -------- First Ability --------
    • Set TempInteger[0] = (Random integer number between 1 and HeroAbilities1Count)
    • Unit - Add HeroAbilitiesQ1[TempInteger[0]] to BuildingAbiShop[LoopInteger_HeroChoose]
    • -------- Second Ability --------
    • Custom script: loop
    • Set TempInteger[1] = (Random integer number between 1 and HeroAbilities1Count)
    • Custom script: exitwhen udg_TempInteger[1] != udg_TempInteger[0]
    • Custom script: endloop
    • Unit - Add HeroAbilitiesW1[TempInteger[1]] to BuildingAbiShop[LoopInteger_HeroChoose]
    • -------- Third Ability --------
    • Custom script: loop
    • Set TempInteger[2] = (Random integer number between 1 and HeroAbilities1Count)
    • Custom script: exitwhen udg_TempInteger[2] != udg_TempInteger[0] and udg_TempInteger[2] != udg_TempInteger[1]
    • Custom script: endloop
    • Unit - Add HeroAbilitiesE1[TempInteger[2]] to BuildingAbiShop[LoopInteger_HeroChoose]
    • -------- Fourth Ability --------
    • Custom script: loop
    • Set TempInteger[3] = (Random integer number between 1 and HeroAbilities1Count)
    • Custom script: exitwhen udg_TempInteger[3] != udg_TempInteger[0] and udg_TempInteger[3] != udg_TempInteger[1] and udg_TempInteger[3] != udg_TempInteger[2]
    • Custom script: endloop
    • Unit - Add HeroAbilitiesR1[TempInteger[3]] to BuildingAbiShop[LoopInteger_HeroChoose]
There is no while-loop in GUI, so I made custom scripts. And instead of traditional exitwhen x > y I made a while-loop checking when the previous abilities were not equal (!=) to the abilities I have already randomly given.
 
Last edited:
Level 38
Joined
Feb 27, 2007
Messages
4,951
Sabe’s solution is the simplest though it can be done entirely in GUI as below:
  • For each Integer LoopInt from 1 to 1 do (actions)
    • Loop - Actions
      • Set Abil1 = Random Integer from 1 to 10
      • Set Abil2 = Random Integer from 1 to 10
      • Set Abil3 = Random integer from 1 to 10
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • Abil1 not equal to Abil2
          • Abil2 not equal to Abil3
          • Abil3 not equal to Abil1
        • Then - Actions
          • <Add abilities here>
        • Else - Actions
          • Set LoopInt = LoopInt-1
Yes it may take a few loops to randomize three nonequal integers but that should be trivial to the game engine. In general the solution involves cloning the data you want to randomize into a new array then:
  • Randomize an option R between 1 and MAX
  • Store R somewhere
  • Move the MAX’th index into the R’th index
  • Reduce MAX by 1
  • Repeat
 
Level 18
Joined
Oct 17, 2012
Messages
818
  • Setup Abilities
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set MaxNumberOfAbilities = (MaxNumberOfAbilities + 1)
      • Set abilities[MaxNumberOfAbilities] = Acid Bomb
      • -------- --------
      • Set MaxNumberOfAbilities = (MaxNumberOfAbilities + 1)
      • Set abilities[MaxNumberOfAbilities] = Animate Dead
      • -------- --------
      • Set MaxNumberOfAbilities = (MaxNumberOfAbilities + 1)
      • Set abilities[MaxNumberOfAbilities] = Banish
      • -------- --------
  • Get Random Ability
    • Events
    • Conditions
    • Actions
      • Set RandomInteger = (Random integer number between 1 and MaxNumberOfAbilities)
      • Unit - Add abilities[RandomInteger] to WhateverUnit
      • Set abilities[RandomInteger] = abilities[MaxNumberOfAbilities]
      • Set MaxNumberOfAbilities = (MaxNumberOfAbilities - 1)
FYI, there are several threads about randomizing without repeats. You just got to search for it.
Random non-repeating variable
Picking random variable in an array once only
Random - No Repeat (Maker's Post #18)
 
Last edited:
Status
Not open for further replies.
Top