• 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!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Trigger making help - Altered Melee

Status
Not open for further replies.
Level 6
Joined
Feb 6, 2008
Messages
166
Hello. I'm making a map right now, which I believe is an Altered Melee style map. I need help with making triggers, which according to the Triggers and Scripts forum ("Threads regarding the creation of a trigger, how-to-do-this-type, go on the World Editor Help Zone, as do general World Editor-related questions."), I should post here.

I would like to have an efficient system for randomizing player start locations. I just started learning triggers a short while ago, and I'm still very confused. IMO, I'm rather terrible at GUI, and I'm having an even harder time with JASS. The only experience I have with trigger making is with staredit, back when I made maps for Starcraft.

The only proof I can offer to show that I'm not just trying to get "free labor" is that I've been trying to think this through. Currently, my plan is to do this:
1. Create a hashtable to store numbers from 1 to 8. (First question: Are hashtables like tables in Excel? Rows and columns of data?)
2. Randomize the order of the numbers. (Second question: How can I do this? Under hashtable actions, there's only "create x", "save x", and "clear x".)
3. Read the new first number. Player 1 will be given a race selector building will be generated in the region "Base X", depending on the number read. There are regions numbering the potential start locations around the map clockwise. (Struggling with this. All I know is that there is a "Hashtable - Load Location Handle" thing.)
4. Repeat 3, using the second number for player 2, third number for player 3, etc. until all the players have been given a base location randomly.

The race selector building is named "Select Your Race", and its model is that of a Start Location. It has several copies of Channel, each one renamed to the name of a playable race. By using a specific ability, the race selector building will be replaced by the town hall of that race and its corresponding workers will be generated in a nearby region. Also, there is a region on each of the gold mines. If the race selector uses the ability "Undead" or "Night Elf", the trigger will remove the gold mine and in its place create a Haunted Gold Mine or Entangled Gold Mine, respectively.

I also need help understanding what each of the Melee Initialization triggers do. (I would like to know if I'm right or not, or if I'm missing any info.)
Use Melee Time Of Day: I think this one just sets up the clock and starts it like any other melee game. I think I can keep this one in.
Hero Limits: I'm pretty sure this one makes it so that you can't have three Demon Hunters, two Crypt Lords, or five Far Seers from the same person.
Hero Starting Items: This gives all heroes a scroll of town portal when trained.
Set Starting Resources: All players get their starting gold and wood.
Remove Excess Units: This clears out all creeps from used start locations. I don't think I should keep this one, as all my start locations are in the center of the map, and I might put a creep camp there. Also, I should run triggers to clear out all units from a given base before the race selector building is created.
Create Starting Units: I won't be needing this one, because it creates the town hall and workers for whichever race was chosen in the game room.
Run AI: I will probably need this one run if I make this map playable by computers, but then I will need to make custom AIs for the custom races.
Victory/Defeat Conditions: I need to make my own version of this I think. I'm guessing this controls the "2 minutes without town hall = reveal player" thing.

Any help with setting up the triggers and such would be appreciated. If you want, I can give credit in the map info. As I move along in this map project, if anyone wants screenshots for any reason from my map, just ask away. I will definitely do what I can to help you help me. After all, if I can't get the help, it's my loss. Also, I'm not expecting anyone to just give me the triggers I need. I personally prefer tips and hints to guide me in the right direction, so that I learn and understand what's going on.

Edit: I have tried looking through the tutorials, but to be honest, most of the time, I read to the end feeling more confused than before.
 
Last edited:
Level 7
Joined
May 3, 2007
Messages
210
Where to begin, where indeed.

Hashtable works like this. Firstly, it needs a hashtable to refence (the first argument in JASS) then it needs a parent key, then a child key, then the actual value.

I suppose you can say it works like Excel, where the parent key is the Letter or x-axis, and the child key is the number or y-axis, however the number of potential x-axis points is equal to the total size of an integer in JASS (or 8 bytes), however storing that amount of information is probably not the greatest of ideas.

Now, for what you're doing, using a hashtable is a little overzealous, a simple integer array would do just fine. (Although, you'd probably use less space with the hashtable). Now best on what you want, you just need to set the integer arrays 0 position (which would be the pointer for player 1) equal to a Random number from 1 to 8. When you actually plot the position of one, you will reference the array (at position 0 for player 1) and then use the number you acquired.

This is assuming you have set x and y positions for 8 separate start locations. Under this assumption, you would need to continualy randomize for the 1 position (or player 2) until they get a number that is NOT stored in the 0 position (or player 1), or else you will have the possibility of overlapping positions. So once you've generated the positions, all you need to do is reference them, and create the desired units at them.

Now as for Melee Initalization:

Melee Initalization sets up specific JASS calls that are a little less mysterious. However i'm under the impression you don't know JASS, so i'll just explain the GUI.

Melee time of day just iniates the default time of day. Under gameplay constants you have the option to setup your own time scheme, if you alter that, but maintain this, it overwrites that. (Actually don't know that for a fact, but i'm very confident)

Hero Limits limit the amount of heroes, the duplication of heroes, and the tier limit of heroes. By which I mean, it establishes that you can only have 3 heroes total, that you can't have the same hero twice, and that you can only get a hero for the level of your tier. You can alter this under the heroes settings themselves, if you go down tectree you should notice it. There is also fields in gameplay constants you will need to edit in order to effect this (i.e. add a fourth tier, or have 2 heroes per tier, or what have you)

You've got the resources one fine. As well as the remove excess units. And the create units.

Run AI runs the melee AI, Computers Easy, Computers Normal, Compters Hard.

You're correct about Victory/Defeat as well, it generates the countdown timer if a person doesn't have a town hall, defeats them if they have no buildings, etc etc.
 
Level 8
Joined
Mar 3, 2009
Messages
327
If i was you, I'd put the start locations in the places where the bases will actually be, and use a region for the race select buildings. Then you can use "Triggering player start location" instead of doing each player individually :D
I know nothing about hashtables or JASS, so there isnt much else i can help you with. Good luck :D
 
Level 6
Joined
Feb 6, 2008
Messages
166
Thanks for the help, WhitePhoenix. I really appreciate it. I've been struggling to learn triggers for the past year and a half to no avail. I tried starting off by learning JASS and got freaked out. Then I moved to GUI, but it was so different from Starcraft's GUI that I got lost immediately.

Okay. I got some of this figured out. I struggled a lot with naming arrays, too. No matter how I name it, I still felt confused. One minute I would have an idea and follow through, and the next minute I would have no idea what I just did.
001-RandomNumbers.png


So. Here's what I have planned:
I have eight players. I assigned each player to one of eight indexes in an array of players called "Player_Index". That way, I would read it as Player_Index[1] and immediately think "Player Number 1". I also made an array of regions called "StartLocation". That way, I would know that these are my new Start Locations, and I would have my triggers create the town halls in the Start Location regions. I need to generate a random integer though. I have player 1. The trigger generates a random integer from 1-8. It's 5, for example. He gets base number 5. When all players have been given a different random number, triggers will remove all creep from now occupied bases. In this case, all creep in "Base Creep 5" will be removed. His race selector will be created in the region "Start Location 5". When his race selector picks a race, it will be removed and the appropriate town hall would be created in the region "Start Location 5". Then his matching workers would be created in "Workers 5". If his race selector chose Night Elf, his gold mine would be removed from "Gold 5" and an entangled gold mine would take it's place. Once all the proper creep have been removed and all starting units/buildings have been placed, the game will begin, units can be given commands, and the melee clock will start.

Here's what I thought of doing. However, it brings me to a potentially infinite amount of coding.

Set IntegerArray[1] = random integer 1 through 8
Set IntegerArray[2] = random integer 1 through 8

If (all conditions are true) then do (then actions) else do (else actions)
--- If...
------ IntegerArray[2] = IntegerArray[1]
--- Then...
------ Set IntegerArray[2] = random integer 1 through 8
--- Else...
------ Set IntegerArray[3] = random integer 1 through 8
------ If (all conditions are true) then do (then actions) else do (else actions)
--------- If...
------------ IntegerArray[3] = IntegerArray[1]
------------ IntegerArray[3] = IntegerArray[2]
--------- Then...
------------ Set IntegerArray[3] = random integer 1 through 8
--------- Else...
------------ Set IntegerArray[3] = random integer 1 through 8
------------ If (all conditions are true) then do (then actions) else do (else actions)
...and so on...

As you can see, this is hugely inefficient, and even then, not really going to work.

Also, the reason for the Integer Array was because I was thinking of somehow using "ArrayOne [ArrayTwo [Index]]" - Using an integer array to define which index of ArrayOne to use, ArrayOne being Player_Index[Index].

Edit: Okay. I got to this point. The only thing I can't figure out is how to make sure IntegerArray[1 through 8] don't repeat the same numbers. Still stuck on that part. Everything else should work, though rather inefficiently. Any suggestions on simplifying the code would be nice. I've been thinking about the trigger editor for the past eight hours and I'm getting a headache.
002-RandomNumbers.png
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,243
  • Untitled Trigger 079
    • Events
    • Conditions
    • Actions
      • Set Temp_Integer_1 = 0
      • Set Temp_Integer_2 = 0
      • For each (Integer A) from 1 to 8, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Temp_Integer_Array_2[(Integer A)] Equal to 0
            • Then - Actions
              • Set Temp_Integer_Array_1[(Integer A)] = (Random integer number between 1 and 8)
              • For each (Integer B) from 1 to 8, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Integer A) Not equal to (Integer B)
                      • Temp_Integer_Array_1[(Integer A)] Not equal to Temp_Integer_Array_1[(Integer B)]
                    • Then - Actions
                      • Set Temp_Integer_1 = (Temp_Integer_1 + 1)
                    • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Temp_Integer_1 Equal to 7
                • Then - Actions
                  • Set Temp_Integer_Array_2[(Integer A)] = 1
                • Else - Actions
            • Else - Actions
              • Set Temp_Integer_2 = (Temp_Integer_2 + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Temp_Integer_2 Not equal to 8
        • Then - Actions
          • Trigger - Run Untitled Trigger 079 <gen> (ignoring conditions)
        • Else - Actions
          • For each (Integer Temp_Integer_3) from 1 to 8, do (Actions)
            • Loop - Actions
              • Game - Display to (All players) the text: (String(Temp_Integer_Array_1[Temp_Integer_3]))
 

Attachments

  • Numbers.w3x
    17.2 KB · Views: 67
Level 6
Joined
Feb 6, 2008
Messages
166
Thanks, Maker.
The first few times I tested that map through World Editor's Test Map button, I kept getting the same mix of numbers. Once I finally opened WC3 and ran the map myself, I started getting new sets of numbers. Is this just a glitch of some sort with World Editor's Test Map button?
Anyways, I'm going to read through the triggers to see if I can understand what's going on inside of it.

Edit 2: Okay... I'm starting to understand the trigger. I just have a question though. Where it says, "For each (Integer A) from 1 to 8, do (Actions)", the first time you run through with A=1, Temp_Integer_1 will =7. When it begins re-running the loop of actions with A=2, does it remember that Temp_Integer_1 was originally 0? or does it continue to add +1's to the 7 from before?
 
Last edited:
Level 37
Joined
Mar 6, 2006
Messages
9,243
The first few times I tested that map through World Editor's Test Map button, I kept getting the same mix of numbers.

File -> preferences -> Test Map -> Uncheck "Use fixed random seed".


Where it says, "For each (Integer A) from 1 to 8, do (Actions)", the first time you run through with A=1, Temp_Integer_1 will =7. When it begins re-running the loop of actions with A=2, does it remember that Temp_Integer_1 was originally 0? or does it continue to add +1's to the 7 from before?

Whoops, it should be like this so it's likely to run fewer times:

  • Untitled Trigger 079
    • Events
    • Conditions
    • Actions
      • Set Temp_Integer_2 = 0
      • For each (Integer A) from 1 to 8, do (Actions)
        • Loop - Actions
          • Set Temp_Integer_1 = 0
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • ...
 
Level 6
Joined
Feb 6, 2008
Messages
166
After testing your earlier trigger, I attempted to hook it up to my other stuff. The game finished the loading screen, and then crashed immediately after. There was no Fatal Error message, but the whole WC3 game closed.

This is how I have it hooked up (sorry it's a little blurry - I think it's a photobucket thing)
003-PossiblyFatalError.png


My guess is that it's crashing because I can't hook up the random number generator trigger to "Map Initialization".

Edit: Woah. I just noticed - your trigger things aren't pictures. o_O
 
Level 37
Joined
Mar 6, 2006
Messages
9,243
Post triggers by right clicking on the trigger's name on the right pane, and select "copy as text". The paste it here and use trigger tags.

Unit groups and locations (Position of...) leak. Read a leak tutorial.

You're trying to remove triggering unit, remove picked unit.

You can use <Trigger - Run Random Number Generator> in the initialization trigger.

Don't run the initialization trigger in the initialization trigger, it causes an infinite loop. Remove that <Trigger - Run Player List Check v4>.
 
Level 6
Joined
Feb 6, 2008
Messages
166
Okay, I'm lost again. If I destroy the variable to remove the leak and need to use the variable again in another trigger, then I need to set the variable again, right? If I'm going to use it in another trigger, why not just keep the variables until the game setup triggers are done, instead of setting them again every time I use them?

Yeah, that's where I messed up. The initialization trigger was supposed to run the random number trigger. I replaced it and now it works. I changed (Triggering Unit) to (Picked Unit).

I also probably need another array to organize the list of races. The more I work on this, the more confused I get about which variables are which and which arrays are which.

Edit: Another question. This one isn't about triggers though. I gave my "Select A Race" building four abilities. All of them are emptied and altered copies of "Channel". When I check the building in-game, it doesn't have any of the abilities. Any idea why?

Edit 2: OHHH!! THAT'S what the tutorial meant?
I used Leak Check 3.0 and it found two leaks in my "Random Number Generator" trigger. This is what it came up with:
(Line: 44) (Word: 7) Unit Group Leak
Unit Group - Pick every unit in (Units in BaseCreep[Temp_Integer_Array_1[Temp_Integer_3]]) and do (Unit - Remove (Picked unit) from the game)
Unit Group - Pick every unit in ^Leak
(Suggested Fix) Set MyUnitGroup = (Units in BaseCreep[Temp_Integer_Array_1[Temp_Integer_3]]) and do (Unit - Remove (Picked unit) from the game)
(Suggested Fix) Unit Group Pick every unit MyUnitGroup game)
(Suggested Fix) Custom script: call DestroyGroup(udg_MyUnitGroup)

(Line: 45) (Word: 10) Location Leak
Unit - Create 1 Select a Race for Player_Index[Temp_Integer_3] at (Center of StartLocation[Temp_Integer_Array_1[Temp_Integer_3]]) facing Default building facing degrees
Unit - Create 1 Select a Race for Player_Index[Temp_Integer_3] at ^Leak
(Suggested Fix) Set MyLocation = (Center of StartLocation[Temp_Integer_Array_1[Temp_Integer_3]]) facing Default building facing degrees
(Suggested Fix) Unit - Create 1 Select a Race for Player_Index[Temp_Integer_3] at MyLocation degrees
(Suggested Fix) Custom script: call RemoveLocation(udg_MyLocation)


Edit 3: I checked another trigger I made and I found 13 leaks. :/

Edit 4: All leaks currently fixed.

Edit 5: Got the Channel abilities fixed. Turns out I missed the Data - Options - Visible thing in Channel. No more questions as of right now.
 
Last edited:
Status
Not open for further replies.
Top