- Joined
- Nov 19, 2007
- Messages
- 8
Hail and greetings, comrades.
Herein contains a method for using "Previous" / "Select" / "Next" buttons in hero selection - without requiring a separate "hero" ability for each desired hero, or vast If/Then loops as described here.
Instead, we will be making use of a HeroType[] array, properly initialized, and some additional helper arrays to control camera use and hero generation.
PSN Hero Selection: Simplified
1. Setup
Before writing up the triggers, it's best to have all the necessary references in place. What you will need:
*Note: wherever P# is used, this means Player Number. Thus, Player 3 (Teal) would be SelCAM P3, and SelectP3 region.
2. Trigger - Map Initialization
The important chunk of map init is as follows: check to see if PlayerSlot is occupied, check to see if PlayerSlot is a computer player (optional?).
For this purpose, I have essentially reused the bPlayerDead[] array from Warchasers, albeit with some adjustments.
PlayerStatus[] - Boolean Array
The second rank (+total players) tracks whether the player is "Active" or not - "Active" in this sense refers to whether or not the player has chosen a hero. It is used for the camera snaps, to determine whether to switch between Game mode or Selection mode, since some method of camera lock is preferred during character generation. Referred to as PlayerStatus[2nd] and implies Player Number + "Total Number of Players possible" (Note - if you have eight open slots, but only three are filled, you want to use 8 as the total number, since your map can allow for UP TO eight players).
Also, pay note of the "Guardians" line - Guardians is a Player Group variable. It gets called mainly for camera funtions, but can also be employed for system messages or other instances when you need to select human players (and computer companions, if desired).
3. Triggers - Hero Initialization and Camera Setup
The Hero init and Camera are set as two separate (linked) triggers, to allow for more versatility. First up, the Hero init:
You can also see the PlayerStatus[] bool coming into play.
Note that PlayerStatus[2nd] is set to True once the computer has selected its hero (randomized) and that HeroSelected[] is set for the comp as well. These are important and will serve you well if you choose to implement computer AI heroes.
What it does:
The For loop checks to see if the player is active [and] a user (human player), and if so generates one unit for the specified player at the Select region (as initialized earlier in the SelectPNreg[] array). It sets the HeroSelected[] array to the user's current hero, and snaps their selection circle to it.
The Unit Group function further down sets up the "Selection" abilities (Prev - Sel - Next), and removes "Shadow Meld" from any heroes, to keep them from ghosting at startup. Be sure to remove any other odd default abilities from custom heroes in this area (I have a hero who can 'eat tree' for example, so remove ability Eat Tree would also be applied in this area)
*NOTE: If you want to spawn heroes at random locations, you can (and should) reuse the SelectPNreg[] array to initialize in the starting regions. Then, later on when the StartGen region is called, you might replace it with a call to the SelectPNreg[], with a randomized index value. Just be sure not to randomize yourself back to the hero-selection area!
Now, for the Camera functions...
4. Triggers - Prev/Next and Select
The part you're probably reading this for. Well, having seen my previous use of arrays, it probably won't shock you when you see what happens here. You'll need one more array:
HeroCount[] - Integer Array
The reason this is used as an array is due to multiple players using the same function. Its purpose is to track each player's selection based on the index value (HeroCount[PlayerNumber]), so that each player does not need a separate variable.
In a nutshell, what this trigger does is increment that HeroCount[] integer for the calling (read: casting) player and swap out the casting unit for the next hero up or down in the HeroType[] array. The unit 'casting' "Previous" or "Next", which is set up as a spell-ability (a la Azeroth Grand Prix) is removed from HeroGroup, replaced, and the replacing unit is added into the group where it runs through the same functions for erasing default abilities and adding the Prev/Sel/Next buttons. HeroSelected[] tracks the unit's type (by instance), and the ability increases/decreases the HeroCount[] by one (depending on whether the previous or next button was 'cast').
*Note: I mentioned earlier that a Skip>>5 hero button might be useful for large quantities of heroes. If you find yourself in need of this, or wish to insert a 'random hero' button as a selector as well, just stick them into the unit-group loop at the bottom as "Add Ability" and copy the Prev/Next triggers (renaming appropriately). Then, all you need to do is change the increment value from 1 to however many heroes you wish to skip ahead.
*Warning: Note these lines
Now, for the selection button...
Finally, the casting unit is removed. Always clean up your toys when you're finished playing. And again, remember that if adjusting for more or fewer players, that +4 in the PlayerStatus[] lines will need to change.
5. Game Trigger - SnapCam
In the demo map, you'll find a lot of uses of the Arithmatic function to allow user control over the camera. Those can be found at the comment "Functions for Game Camera."
However, for our purposes here, I'm going to focus on the uses during character selection.
Now, pay attention to the Lock Camera line. See that CAMindex[] thing nestled in the HeroSelected[] index? That's a function call for the demo map's additional camera options. It's explained below, but if you choose not to use those options, simply erase CAMindex and leave "Player number of (Picked)" nested in HeroSelected[]'s index brackets.
6. Game Trigger - Hero Death
Simple, right?
In the download, you'll find a few other functions here. Those handle the resurrection conditions for this particular map. As such, you'd want to insert your own actions/conditions/triggers in here as well, to deal with the possibility of a hero coming back to life. For the hero-management pieces of this code, just know that once a hero dies, the first rank of PlayerStatus[] should get set to True.
7. Additional Trigger Functions
SnapCam - Game Mode
For camera control in the demo map, two new arrays were initialized at startup.
CAMorientation[], a Real array, handles the camera's rotation AND zoom, using the same 1st/2nd rank method as PlayerStatus[]
-1st Rank controls rotation, and should be the same index as Player#
-2nd Rank controls zoom in/out (distance to target) and its index should be incremented by the number of open slots in your map (+total players)
CAMIndex[], another Integer array that tracks camera lock-ons.
Above, see that CAMorient[2nd] is applied as "Distance to Target" and CAMorient[1st] is set as Rotation.
Do you remember CAMIndex[]?
Hero Revival
It's also nice to re-select their hero for them, so they don't go flailing about with the mouse.
And be sure to set PlayerStatus[] back to False, now that they're alive again.
*Note: these lines are actually found in the HeroDeath trigger, in the demo.
Camera Rotation/Cycling
Note that CAMIndex only comes into play if PlayerStatus[1st] is True (dead). And thanks to those lines in the Hero Death/Revival section, the CAMIndex is reset once the player's back among the living, so you're not accidentally stuck rotating yourself around someone else's hero.
By extension, the Zoom Out function uses a similar If to prevent you from zooming yourself out into low orbit.
8. Credits
My thanks to the makers of Azeroth Grand Prix, for the idea.
To Fulla, for the snippets of code from his map, and the inspiration it sparked that helped me get everything working.
To the other tutorial writers, for helping me relearn GUI triggers. May I one day comprehend JASS.
(Must find time to read all the tutorials I've saved...)
To Fox, for getting me back into "WarCrafting".
To Blizzard, for such an awesome product.
And thanks to you, for reading.
Herein contains a method for using "Previous" / "Select" / "Next" buttons in hero selection - without requiring a separate "hero" ability for each desired hero, or vast If/Then loops as described here.
Instead, we will be making use of a HeroType[] array, properly initialized, and some additional helper arrays to control camera use and hero generation.
- A few brief notes:
- The system was originally designed for a 4-player "Warchasers"-type map, so the code is all based on a 4-player scenario. This is easily adjusted, aside from the computer controllers used in the attached demo map.
- An adjustable camera system is integrated with this setup as well, and will be explained briefly at the end. Since the "SnapCam" functions are required for controlling the view of heroes during selection, I deemed it necessary to include them, although control of the game camera could be set aside as a separate trigger cluster.
- The code is as efficient as I could make it, though I'm certain that a JASS-based version of this method could cut down on the number of arrays needed and reduce memory use even further.
- I use many array-type variables, so for those who don't know already - a variable with brackets[] is an array. Furthermore, the number inside the brackets[#] is the index value. This can be set to any integer, including the integer value of a Player Number (thus Player 1 would be an array index of 1, or array[1]). The purpose of this document is to show a new method for hero selection - if you need a bit more help understanding arrays, I recommend looking here first.
- A healthy chunk of credit should be given to Fulla for the ability-removal codes, Hero-spawning, creep/enemy spawning, and also some alliance-setup functions in the demo's map initialization (although the latter items are used for the demo's playability, not strictly the hero-selection).
PSN Hero Selection: Simplified
1. Setup
Before writing up the triggers, it's best to have all the necessary references in place. What you will need:
- An area on the map set aside for Hero selection. This may take any form you like, from a line of duplicate environments (see demo), to a small circle with each SelectP# region visible to the other players.
- A number of SelCAM P# camera objects and SelectP# regions equal to the number of Players you wish to allow in-game.
- Three custom abilities, Previous / Select / Next - set to do essentially 'nothing' and all based on different null spell IDs.
- At least one "StartGen" starting region, for spawning heroes into the game once selected. For random locations, you may wish to place more.
*Note: wherever P# is used, this means Player Number. Thus, Player 3 (Teal) would be SelCAM P3, and SelectP3 region.
2. Trigger - Map Initialization
The important chunk of map init is as follows: check to see if PlayerSlot is occupied, check to see if PlayerSlot is a computer player (optional?).
For this purpose, I have essentially reused the bPlayerDead[] array from Warchasers, albeit with some adjustments.
PlayerStatus[] - Boolean Array
- The "PlayerStatus" boolean tracks two things
- Is Player's Hero alive?
- Is Player "Active"?
The second rank (+total players) tracks whether the player is "Active" or not - "Active" in this sense refers to whether or not the player has chosen a hero. It is used for the camera snaps, to determine whether to switch between Game mode or Selection mode, since some method of camera lock is preferred during character generation. Referred to as PlayerStatus[2nd] and implies Player Number + "Total Number of Players possible" (Note - if you have eight open slots, but only three are filled, you want to use 8 as the total number, since your map can allow for UP TO eight players).
-
Initialize
-
Events
- Map initialization
- Conditions
-
Actions
- -------- Initializing for 1-4 Players --------
-
For each (Integer A) from 1 to 4, do (Actions)
-
Loop - Actions
- Player Group - Add (Player((Integer A))) to Guardians
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- ((Player((Integer A))) slot status) Not equal to Is playing
-
Then - Actions
- Set PlayerStatus[(Integer A)] = True
- Set PlayerStatus[((Integer A) + 4)] = True
- Else - Actions
-
If - Conditions
-
Loop - Actions
- Trigger - Run Initialize Heroes <gen> (ignoring conditions)
-
Events
- You'll note that if a player slot is empty, both the 1st and 2nd ranks of PlayerStatus[] are set to True. These iron out as follows:
- 1st - "True" = Hero is 'dead' (Player is not active and can be ignored for future functions involving hero processing)
- 2nd - "True" = Hero is Selected (Player is finished with Chargen)
Also, pay note of the "Guardians" line - Guardians is a Player Group variable. It gets called mainly for camera funtions, but can also be employed for system messages or other instances when you need to select human players (and computer companions, if desired).
3. Triggers - Hero Initialization and Camera Setup
The Hero init and Camera are set as two separate (linked) triggers, to allow for more versatility. First up, the Hero init:
-
Initialize Heroes
- Events
- Conditions
-
Actions
- -------- Initialize Region Array --------
- Set SelectPNreg[1] = SelectP1 <gen>
- Set SelectPNreg[2] = SelectP2 <gen>
- Set SelectPNreg[3] = SelectP3 <gen>
- Set SelectPNreg[4] = SelectP4 <gen>
- -------- Initialize Hero-Type Arra --------
- Set HeroType[1] = Paladin
- Set HeroType[2] = Blood Mage
- Set HeroType[3] = Blademaster of Blackrock Clan
- Set HeroType[4] = Shadow Hunter
- Set HeroType[5] = Crypt Lord
- Set HeroType[6] = Demon Hunter
- Set HeroType[7] = Firelord
- Set HeroType[8] = Pit Lord
- Set HeroType[9] = Lady Vashj
-
For each (Integer A) from 1 to 4, do (Actions)
-
Loop - Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- PlayerStatus[(Integer A)] Equal to False
- ((Player((Integer A))) controller) Equal to User
-
Then - Actions
- Selection - Clear selection for (Player((Integer A)))
- Unit - Create 1 HeroType[1] for (Player((Integer A))) at (Center of SelectPNreg[(Integer A)]) facing 270.00 degrees
- Unit Group - Add (Last created unit) to HeroGroup
- Selection - Select (Last created unit) for (Player((Integer A)))
- Set HeroSelected[(Integer A)] = (Last created unit)
- Else - Actions
-
If - Conditions
- -------- Optional Code - Generates a random hero for a computer opponent --------
- -------- Requires additional Triggers for Computer Hero's AI --------
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- ((Player((Integer A))) controller) Equal to Computer
-
Then - Actions
- Unit - Create 1 HeroType[(Random integer number between 1 and 9)] for (Player((Integer A))) at (Center of StartGen <gen>) facing 270.00 degrees
- Set PlayerStatus[((Integer A) + 4)] = True
- Set HeroSelected[(Integer A)] = (Last created unit)
- Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Items\AIem\AIemTarget.mdl
- Else - Actions
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Loop - Actions
-
Unit Group - Pick every unit in HeroGroup and do (Actions)
-
Loop - Actions
- Custom script: call UnitRemoveAbility(GetEnumUnit(),'Amov')
- Custom script: call UnitRemoveAbility(GetEnumUnit(),'Aatk')
- Unit - Add View Next Hero (CharGen) to (Picked unit)
- Unit - Add View Previous Hero (CharGen) to (Picked unit)
- Unit - Add Select Hero (CharGen) to (Picked unit)
- Unit - Remove Shadow Meld from (Picked unit)
- Hero - Modify unspent skill points of (Picked unit): Set to 0 points
- Unit - Make (Picked unit) Invulnerable
-
Loop - Actions
- -------- Onward! To the hero-viewer! --------
- Trigger - Run Set Cameras <gen> (checking conditions)
- In the initialization there, you'll want three arrays and a UnitGroup variable.
- SelectPNreg[] - Region array
During initialization, this sets each player-selection area to the array, so that a simple For/Integer loop can be used to cycle through the whole system at once, eliminating the need for specific <gen>-based triggers for each hero 'initial' spawn. - HeroType[] - Unit-Type array
This is where it starts to get good. Use that line of Set Variable triggers to initialize each hero you want to use. For long lists, say 15 or more, you may wish to implement a few extra "selection abilities" like "Prev/Next>>5" (skip back/ahead 5 heroes), Select Random (random hero), or something else entirely. This area of the method is as versatile as you choose to make it. - HeroSelected[] - Unit Array
This array tracks (by player number) the unit currently selected. Doing so will tell the triggers further on what hero to spawn, as well as lock the camera onto the player-specific hero during CharGen. Having the chosen hero stored in a player array also makes for a number of other possibilities, but for this writing I'll stick to the Hero Selection methods. - HeroGroup - Unit Group
Probably not [essential] to the code, but having all heroes lumped into one heading makes the ability edits much easier to handle.
Some of this code was borrowed from Fulla's hero selection method - my thanks to him, there.
You can also see the PlayerStatus[] bool coming into play.
Note that PlayerStatus[2nd] is set to True once the computer has selected its hero (randomized) and that HeroSelected[] is set for the comp as well. These are important and will serve you well if you choose to implement computer AI heroes.
What it does:
The For loop checks to see if the player is active [and] a user (human player), and if so generates one unit for the specified player at the Select region (as initialized earlier in the SelectPNreg[] array). It sets the HeroSelected[] array to the user's current hero, and snaps their selection circle to it.
The Unit Group function further down sets up the "Selection" abilities (Prev - Sel - Next), and removes "Shadow Meld" from any heroes, to keep them from ghosting at startup. Be sure to remove any other odd default abilities from custom heroes in this area (I have a hero who can 'eat tree' for example, so remove ability Eat Tree would also be applied in this area)
*NOTE: If you want to spawn heroes at random locations, you can (and should) reuse the SelectPNreg[] array to initialize in the starting regions. Then, later on when the StartGen region is called, you might replace it with a call to the SelectPNreg[], with a randomized index value. Just be sure not to randomize yourself back to the hero-selection area!
Now, for the Camera functions...
-
Set Cameras
- Events
- Conditions
-
Actions
- Set CAM_ID[1] = SelCAM P1 <gen>
- Set CAM_ID[2] = SelCAM P2 <gen>
- Set CAM_ID[3] = SelCAM P3 <gen>
- Set CAM_ID[4] = SelCAM P4 <gen>
- For each (Integer A) from 1 to 4, do (Camera - Apply CAM_ID[(Integer A)] for (Player((Integer A))) over 0.00 seconds)
-
Player Group - Pick every player in Guardians and do (Actions)
-
Loop - Actions
- Cinematic - Fade in over 2.00 seconds using texture Black Mask and color (0.00%, 0.00%, 0.00%) with 0.00% transparency
- Camera - Set (Picked player)'s camera Field of view to 50.00 over 5.00 seconds
- Camera - Lock camera target for (Picked player) to HeroSelected[(Player number of (Triggering player))], offset by (0.00, 0.00) using The unit's rotation
-
Loop - Actions
- Trigger - Turn on SnapCam to Player <gen>
4. Triggers - Prev/Next and Select
The part you're probably reading this for. Well, having seen my previous use of arrays, it probably won't shock you when you see what happens here. You'll need one more array:
HeroCount[] - Integer Array
The reason this is used as an array is due to multiple players using the same function. Its purpose is to track each player's selection based on the index value (HeroCount[PlayerNumber]), so that each player does not need a separate variable.
-
View Next Hero
-
Events
- Unit - A unit Begins casting an ability
-
Conditions
- (Ability being cast) Equal to View Next Hero (CharGen)
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- HeroCount[(Player number of (Triggering player))] Less than 9
-
Then - Actions
- Set HeroCount[(Player number of (Triggering player))] = (HeroCount[(Player number of (Triggering player))] + 1)
-
Else - Actions
- Set HeroCount[(Player number of (Owner of (Triggering unit)))] = 1
-
If - Conditions
- Unit Group - Remove HeroSelected[(Player number of (Triggering player))] from HeroGroup
- Unit - Replace HeroSelected[(Player number of (Triggering player))] with a HeroType[HeroCount[(Player number of (Triggering player))]] using The new unit's default life and mana
- Unit Group - Add (Last replaced unit) to HeroGroup
-
Unit Group - Pick every unit in HeroGroup and do (Actions)
-
Loop - Actions
- Custom script: call UnitRemoveAbility(GetEnumUnit(),'Amov')
- Custom script: call UnitRemoveAbility(GetEnumUnit(),'Aatk')
- Unit - Add View Previous Hero (CharGen) to (Picked unit)
- Unit - Add View Next Hero (CharGen) to (Picked unit)
- Unit - Add Select Hero (CharGen) to (Picked unit)
- Unit - Remove Shadow Meld from (Picked unit)
- Hero - Modify unspent skill points of (Picked unit): Set to 0 points
- Unit - Make (Picked unit) Invulnerable
-
Loop - Actions
- Selection - Select (Last replaced unit) for (Owner of (Triggering unit))
- Set HeroSelected[(Player number of (Triggering player))] = (Last replaced unit)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Events
In a nutshell, what this trigger does is increment that HeroCount[] integer for the calling (read: casting) player and swap out the casting unit for the next hero up or down in the HeroType[] array. The unit 'casting' "Previous" or "Next", which is set up as a spell-ability (a la Azeroth Grand Prix) is removed from HeroGroup, replaced, and the replacing unit is added into the group where it runs through the same functions for erasing default abilities and adding the Prev/Sel/Next buttons. HeroSelected[] tracks the unit's type (by instance), and the ability increases/decreases the HeroCount[] by one (depending on whether the previous or next button was 'cast').
*Note: I mentioned earlier that a Skip>>5 hero button might be useful for large quantities of heroes. If you find yourself in need of this, or wish to insert a 'random hero' button as a selector as well, just stick them into the unit-group loop at the bottom as "Add Ability" and copy the Prev/Next triggers (renaming appropriately). Then, all you need to do is change the increment value from 1 to however many heroes you wish to skip ahead.
*Warning: Note these lines
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- HeroCount[(Player number of (Triggering player))] Less than 9
-
If - Conditions
-
Else - Actions
- Set HeroCount[(Player number of (Owner of (Triggering unit)))] = 1
Now, for the selection button...
-
Confirm Hero
-
Events
- Unit - A unit Begins casting an ability
-
Conditions
- (Ability being cast) Equal to Select Hero (CharGen)
- PlayerStatus[((Player number of (Owner of (Triggering unit))) + 4)] Equal to False
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- ((Unit-type of (Triggering unit)) is A Hero) Equal to True
-
Then - Actions
- Set PlayerStatus[((Player number of (Triggering player)) + 4)] = True
- Unit - Create 1 (Unit-type of (Triggering unit)) for (Triggering player) at (Center of StartGen <gen>) facing 270.00 degrees
- Selection - Select (Last created unit) for (Triggering player)
- Set HeroSelected[(Player number of (Triggering player))] = (Last created unit)
- Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Items\AIem\AIemTarget.mdl
- Else - Actions
-
If - Conditions
- Unit - Remove (Triggering unit) from the game
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Events
Finally, the casting unit is removed. Always clean up your toys when you're finished playing. And again, remember that if adjusting for more or fewer players, that +4 in the PlayerStatus[] lines will need to change.
5. Game Trigger - SnapCam
In the demo map, you'll find a lot of uses of the Arithmatic function to allow user control over the camera. Those can be found at the comment "Functions for Game Camera."
However, for our purposes here, I'm going to focus on the uses during character selection.
-
SnapCam to Player
-
Events
- Time - Every 0.05 seconds of game time
- Conditions
-
Actions
-
Player Group - Pick every player in Guardians and do (Actions)
-
Loop - Actions
- Camera - Lock camera target for (Picked player) to HeroSelected[CAMindex[(Player number of (Picked player))]], offset by (0.00, 0.00) using The unit's rotation
- Camera - Set (Picked player)'s camera Roll to 0.00 over 1.00 seconds
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- PlayerStatus[((Player number of (Picked player)) + 4)] Equal to True
-
Then - Actions
- -------- Functions for Game Camera --------
-
Else - Actions
- -------- Functions for CharGen Camera --------
- Camera - Set (Picked player)'s camera Angle of attack to (Angle of attack of CAM_ID[(Player number of (Picked player))]) over 0.00 seconds
- Camera - Set (Picked player)'s camera Rotation to (Rotation of CAM_ID[(Player number of (Picked player))]) over 0.00 seconds
-
If - Conditions
-
Loop - Actions
-
Player Group - Pick every player in Guardians and do (Actions)
-
Events
Now, pay attention to the Lock Camera line. See that CAMindex[] thing nestled in the HeroSelected[] index? That's a function call for the demo map's additional camera options. It's explained below, but if you choose not to use those options, simply erase CAMindex and leave "Player number of (Picked)" nested in HeroSelected[]'s index brackets.
6. Game Trigger - Hero Death
-
HeroDeath
-
Events
- Unit - A unit owned by Player 1 (Red) Dies
- Unit - A unit owned by Player 2 (Blue) Dies
- Unit - A unit owned by Player 3 (Teal) Dies
- Unit - A unit owned by Player 4 (Purple) Dies
-
Conditions
- (Triggering unit) Equal to HeroSelected[(Player number of (Triggering player))]
-
Actions
- Set PlayerStatus[(Player number of (Triggering player))] = True
-
Events
Simple, right?
In the download, you'll find a few other functions here. Those handle the resurrection conditions for this particular map. As such, you'd want to insert your own actions/conditions/triggers in here as well, to deal with the possibility of a hero coming back to life. For the hero-management pieces of this code, just know that once a hero dies, the first rank of PlayerStatus[] should get set to True.
7. Additional Trigger Functions
SnapCam - Game Mode
-
Then - Actions
- -------- Functions for Game Camera --------
- Camera - Set (Picked player)'s camera Distance to target to (CAMorientation[((Player number of (Picked player)) + 4)] + 2048.00) over 1.00 seconds
- Camera - Set (Picked player)'s camera Angle of attack to 305.00 over 2.00 seconds
- Camera - Set (Picked player)'s camera Field of view to 75.00 over 2.00 seconds
- Camera - Set (Picked player)'s camera Rotation to CAMorientation[(Player number of (Picked player))] over 2.00 seconds
- -------- Uses Hero's orientation for camera. Dizzying in quick turns. --------
- DIS-Camera - Set (Picked player)'s camera Rotation to (CAMorientation[(Player number of (Picked player))] + (Facing of HeroSelected[(Player number of (Picked player))])) over 2.00 seconds
For camera control in the demo map, two new arrays were initialized at startup.
CAMorientation[], a Real array, handles the camera's rotation AND zoom, using the same 1st/2nd rank method as PlayerStatus[]
-1st Rank controls rotation, and should be the same index as Player#
-2nd Rank controls zoom in/out (distance to target) and its index should be incremented by the number of open slots in your map (+total players)
CAMIndex[], another Integer array that tracks camera lock-ons.
Above, see that CAMorient[2nd] is applied as "Distance to Target" and CAMorient[1st] is set as Rotation.
Do you remember CAMIndex[]?
-
Player Group - Pick every player in Guardians and do (Actions)
-
Loop - Actions
- Camera - Lock camera target for (Picked player) to HeroSelected[CAMindex[(Player number of (Picked player))]], offset by (0.00, 0.00) using The unit's rotation
- Camera - Set (Picked player)'s camera Roll to 0.00 over 1.00 seconds
-
Loop - Actions
Hero Revival
- Set PlayerStatus[(Player number of (Triggering player))] = False
- Set CAMindex[(Player number of (Triggering player))] = (Player number of (Triggering player))
- Selection - Select (Triggering unit) for (Triggering player)
It's also nice to re-select their hero for them, so they don't go flailing about with the mouse.
And be sure to set PlayerStatus[] back to False, now that they're alive again.
*Note: these lines are actually found in the HeroDeath trigger, in the demo.
Camera Rotation/Cycling
-
AdjCam Left
-
Events
- Player - Player 1 (Red) Presses the Left Arrow key
- Player - Player 2 (Blue) Presses the Left Arrow key
- Player - Player 3 (Teal) Presses the Left Arrow key
- Player - Player 4 (Purple) Presses the Left Arrow key
- Conditions
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- PlayerStatus[(Player number of (Triggering player))] Equal to False
-
Then - Actions
- -------- Hero is Alive - Rotate Camera --------
- Set CAMorientation[(Player number of (Triggering player))] = (CAMorientation[(Player number of (Triggering player))] - 5.00)
- If (CAMorientation[(Player number of (Triggering player))] Less than or equal to -360.00) then do (Set CAMorientation[(Player number of (Triggering player))] = 0.00) else do (Do nothing)
-
Else - Actions
- -------- Hero is Dead - cycle through other Heroes --------
- Set CAMorientation[(Player number of (Triggering player))] = 0.00
- If (CAMindex[(Player number of (Triggering player))] Greater than 1) then do (Set CAMindex[(Player number of (Triggering player))] = (CAMindex[(Player number of (Triggering player))] - 1)) else do (Set CAMindex[(Player number of (Triggering player))] = 4)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Events
Note that CAMIndex only comes into play if PlayerStatus[1st] is True (dead). And thanks to those lines in the Hero Death/Revival section, the CAMIndex is reset once the player's back among the living, so you're not accidentally stuck rotating yourself around someone else's hero.
-
AdjCam ZoomIn
-
Events
- Player - Player 1 (Red) Presses the Up Arrow key
- Player - Player 2 (Blue) Presses the Up Arrow key
- Player - Player 3 (Teal) Presses the Up Arrow key
- Player - Player 4 (Purple) Presses the Up Arrow key
- Conditions
-
Actions
- Set CAMorientation[((Player number of (Triggering player)) + 4)] = (CAMorientation[((Player number of (Triggering player)) + 4)] - 32.00)
- If (CAMorientation[((Player number of (Triggering player)) + 4)] Less than or equal to -1024.00) then do (Set CAMorientation[((Player number of (Triggering player)) + 4)] = -1024.00) else do (Do nothing)
-
Events
By extension, the Zoom Out function uses a similar If to prevent you from zooming yourself out into low orbit.
8. Credits
My thanks to the makers of Azeroth Grand Prix, for the idea.
To Fulla, for the snippets of code from his map, and the inspiration it sparked that helped me get everything working.
To the other tutorial writers, for helping me relearn GUI triggers. May I one day comprehend JASS.
(Must find time to read all the tutorials I've saved...)
To Fox, for getting me back into "WarCrafting".
To Blizzard, for such an awesome product.
And thanks to you, for reading.
Attachments
Last edited: