Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
I'm working on my HTD map, which is combination of Hero & Tower defense. In my map i have 40 heroes, 33 races and 240 basic levels. Starting the map, every player is allowed to make his choice (hero or race he want to play). For 240 levels U can have 7 heroes and also races (but one of each kind)!
I would like to give to the players also a possibility to choose RANDOM hero or race. With heroes there is not that big problem, because i have a "gallery" in the map, so i can put them into a unit group and than fix it using triggers (i hope - pick unit from unit group, create unit for player and than remove last created unit from the group, that next time is not possible creat the same hero)...
But i don't have any idea ho to make this with reces, because i'm not able make a unit group of units (unit of type..) in the editor...
Is there any way how to do this, that player can make his own choice or use random and he will get only one from each race everytime??? Sorry for my english.. thanx for help if its possible
So you want to select a random race, but have the races be unique?
A simple way of doing this is:
1) Make a Unit-Type Array, and initialize the values to the unit types of your race builders (index 0-32) or whatever you use to represent your races.
2) Randomly select a unit type from it (Random integer between 0, 32)
3) Create the builder, and set the unit-type index that he has randomed to Unit Type Of (No Unit)
4) Now, when the user types random, make a variable for the temporary selected type, initialized to Unit Type Of (No Unit) and do a while loop: while the selected type is equal to Unit Type Of (No Unit), go back to step 2 (re-select a race). After the loop, perform step 3. Step 1 should be done in an initialization trigger.
The system can get a lot more sophisticated, but this is a fine way of doing it.
3) Create the builder, and set the unit-type index that he has randomed to Unit Type Of (No Unit)
4) Now, when the user types random, make a variable for the temporary selected type, initialized to Unit Type Of (No Unit) and do a while loop: while the selected type is equal to Unit Type Of (No Unit), go back to step 2 (re-select a race). After the loop, perform step 3.
Thanx for Your advice.. Looks it's working... But...
To tell complete information.. I need the race to be "unique", but just for "triggering" player.. Its not a problem, when more than one player has the same race.. The point is to limit the selection for every single player.. (If red choose random race and get (for example demons)- i need to make it that next time he won't get demons.. and also when red picks demons as his choice and then for second race he goes for "random race", that he won't get demons again..
My system is based on "spells".. U have a unit (buildnig - race chooser building), inside there are 4 spells (3 spellbooks - everyone contains 11 spells - races and spell for random) Than u click on icon for spell (race) and the race chooser building is replaced with desired race.. the map is for 9 players...
So each player gets to pick 2 races? Don't do what I posted above, since that will mess up the randomness for each player. You need to have a unit-type array corresponding to the builder you have already spawned for each player and then check against that. Note that you will also need to set this variable (PlayerFirstBuilder[] in my below triggers) when the units choose their first race too so that you can't random the race you've already chosen as your second one).
Events
Unit - A unit starts the effect of an ability
Conditions
Ability being cast equal to RANDOM
Actions
Set PID = Player number of (Owner of (Triggering Unit)) //Depending on the specifics of how your spells work this line may need to be different, but this is my guess
For each integer YOUR_INT from 1 to 1 do actions
Loop - Actions
Set Ind = Random integer between 1 and Max_Builders
If (All conditions are true) then do (then actions) else do (else actions)
If - Conditions
BuilderTypes[Ind] not equal to PlayerFirstBuilder[PID]
Then - Actions
Set PlayerFirstBuilder[PID] = BuilderTypes[Ind]
Unit - Create 1 BuilderTypes[Ind] for...
Else - Actions
Set YOUR_INT = YOUR_INT - 1
-------- In whatever trigger spawns the specific builder unit when a player casts the spell for that race --------
Unit - Create 1 <whatever type however your get it> for <the player>...
Set PlayerFirstBuilder[Player Id of (<the player>)] = <whatever type however you get it>
Noo.. There are 9 players in the map. Each player has limit of 15 food, that means every player is allowed to pick:
1hero = 2food
1race = 1food
So during the game (240 levels) every player can pick 7 heroes or 15 races or some combination of hero/races.. (for example 4 heroes (4x2 = 8food) and 7 races (7x1 = 7food)...
And that is what im asking.. If a player is allowed to pick up to 15 races (and the player can make a choice if he would like the pick the race by himself or go random (everytime he take a new race), how can i fix it via triggers, that everytime the player will get a different race...
As i posted above, it doesnt matter if 2 or more players get the same race.. I just dont want the game to "put" to the player 5races of the same kind, when he could have 15 different..
Oh okay. That requires an additional loop to check all the active builders and a simulated 2-D array. I slightly modified my above trigger:
-------- At map init --------
Set Max_Races = 15
Set Num_Players = 9 //Set this equal to the highest used player # in your map. For example, if one of the players is #11 (dark green) then Num_Players = 11
Events
Unit - A unit starts the effect of an ability
Conditions
Ability being cast equal to RANDOM
Actions
Set PID = Player number of (Owner of (Triggering Unit)) //Depending on the specifics of how your spells work this line may need to be different, but this is my guess
For each integer YOUR_INT from 1 to 1 do actions
Loop - Actions
Set Ind = Random integer between 1 and Max_Builders
For each integer OTHER_INT from 0 to (Player_Race_Count[PID]-1) do (actions)
Loop - Actions
If (All conditions are true) then do (then actions) else do (else actions)
If - Conditions
BuilderTypes[Ind] equal to Player_Builders[PID*Max_Races + OTHER_INT] //This simulates a 2-D array in GUI
Then - Actions
Set YOUR_INT = YOUR_INT - 1
Custom script: exitwhen true
Else - Actions
Set Player_Builders[PID*Max_Races + Player_Race_Count[PID]] = BuilderTypes[Ind]
Set Player_Race_Count[PID] = Player_Race_Count[PID]+1
Unit - Create 1 BuilderTypes[Ind] for...
-------- In whatever trigger spawns the specific builder unit when a player casts the spell for that race --------
Set PID = Player Id of (<the player>)
Set Player_Builders[PID*Max_Races + Player_Race_Count[PID]] = <whatever type however you get it>
Set Player_Race_Count[PID] = Player_Race_Count[PID]+1
Unit - Create 1 <whatever type however your get it> for <the player>...
Thanx for Your help, but im completely lost in that trigger... Im absolute noob in WE.. Im learning everything the way try/is not working/is working... My map is almost finished (Im working on it almost 2years), the random function is the last thing i need (wish) to do..
I set:
Max_Random_Races = 32 (there are 33 posible races in my map, i made an array 0-32) - Max_Builders in your trigger
Max_Races = 15
Number_Of_Players = 9 (in my map are 9 players - red to grey)
PID = Player number of (Owner of (Casting Unit))
Ind = Random integer between 0 and Max_Random_Races
What is:
Player_Race_Count ?? (I mean what is that variable and its basic value??)
YOUR_INT ??
OTHER_INT ??
BuilderTypes[Ind] equal to Player_Builders[PID*Max_Races + OTHER_INT] - This I dont understand completely..
custom script - never used it before...
Don't You know about some map or DEMO, where I can find this trigger to have a look at it in the editor?? Or is it possible to send U my map, that U can make that trigger right in the map and i can have a look at it after??
Max_Random_Races = 32 (there are 33 posible races in my map, i made an array 0-32) - Max_Builders in your trigger
Max_Races = 15
Number_Of_Players = 9 (in my map are 9 players - red to grey)
PID = Player number of (Owner of (Casting Unit))
Ind = Random integer between 0 and Max_Random_Races
All correct, but I would suggest you use triggering unit in stead of casting unit.
Player_Race_Count[] keeps track of how many different races each player has chosen so that when a random one is chosen it doesn't match any of the previously chosen races. If Player 2 has chosen 6 different races then Player_Race_Count[2] = 6. Starts at 0 for everyone and increases by 1 every time they pick a race. YOUR_INT and OTHER_INT are just integer variables. You need to use them in the For Each Integer <Variable> from _ to _ do (Actions) lines. Just make 2 new integer variables and don't use them for anything else.
Custom script is for JASS lines. Things you can't do in GUI because there is no action for them. Whenever you need to use one, type whatever you're supposed to put there letter-by-letter to make sure it's the same (capitalization matters).
If you don't know what a 2D array is, you should google it; what Player_Builders[PID*Max_Races + OTHER_INT] does is simulate one. Normally you'd write like Player_Builders[3][1] or Player_Builders[3][2] or Player_Builders[9][1] but you can't do that in GUI. Instead we have to map each [x][y] double address to a single address (index).
JASS:
Player_Builders[# of the player][# of the race]
//Player 1's 3rd race: Player_Builders[1][3]
//Player 7's 12th race: Player_Builders[7][12]
//How does this become a single index?
//Multiply the Player # by the total number of races each player can possibly have and then add on the race #
//# races = NR = 15
Player_Builders[x][y] = Player_Builders[x*NR + y]
Player_Builders[1][1] = Player_Builders[1*15 + 1] = Player_Builders[16]
Player_Builders[1][2] = Player_Builders[1*15 + 2] = Player_Builders[17]
Player_Builders[1][3] = Player_Builders[1*15 + 3] = Player_Builders[18]
Player_Builders[1][15] = Player_Builders[1*15 + 15] = Player_Builders[30]
Player_Builders[2][1] = Player_Builders[2*15 + 1] = Player_Builders[31]
Player_Builders[2][2] = Player_Builders[2*15 + 2] = Player_Builders[32]
Player_Builders[2][15] = Player_Builders[2*15 + 15] = Player_Builders[45]
Player_Builders[3][1] = Player_Builders[3*15 + 1] = Player_Builders[46]
Player_Builders[4][1] = Player_Builders[4*15 + 1] = Player_Builders[61]
Player_Builders[5][1] = Player_Builders[5*15 + 1] = Player_Builders[76]
//etc.
//Note that this doesn't start by mapping [1][1] to [0], which may be a problem if your 2d array needs to be very large, but in this case you only need (9+1)*15=150 indices so it's not an issue.
To understand what that line does you need to understand the 2 nested loops in the trigger I posted. The outermost loop ("YOUR_INT from 1 to 1") is what keeps picking new random races until we get one the player doesn't already have. Each time the loop runs Ind is set to a new random integer, and when this loop exits, BuilderTypes[Ind] corresponds to the unit-type of the new builder unit we should create for the player.
The inner loop compares the chosen BuilderTypes[Ind] to the unit types of all builders previously given to the player. If it doesn't match any previously created builder type, then the inner loop and outer loop will both exit (leaving BuilderTypes[Ind] ready to be used as described above). We need to check against all the previously chosen races, so the easiest way to do that is to loop through: Player_Builders[PID][1], Player_Builders[PID][2], Player_Builders[PID][3], etc.. Keeping in mind the conversion I wrote before, you can see that the line you quoted just checks to see if the <OTHER_INT>th race builder is not the same as the randomly chosen race builder. If they do match, then YOUR_INT is decreased by one so that the outer loop runs 1 more time.
Perfect! Thanx for that advice and great explanationt!
It was my idea to make "index and index" so now i know why i was not able to do it.. Your explanation was perfect to me, so for now i understand it little bit more..
The random system is now working fine..
Because i have very "curious" friends, for which i am making this map, small improvements came to my mind.. Is it possible to check also in my "specific race trigger", that a race was given to the player randomly and make it impossible to pick that race again?? (My idea was if someone click mistekenly the same race - and also i know my friends will look for "mistakes" in the "core function" of the map, specially one of them) :-D To make it working "both sides" - a randomly given race can't be picked by player and a picked race can't be given randomly..
I think its something with conditions, to comper "Player_Builders", but i can't match the "correct way"..
Yeah that can be done, but it would be easier for me to show you what you need to modify in the trigger that detects when a player picks a race and gives them the proper builder. Can you post that here?
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.