• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Antares' Hero Selection v1.3.3

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Create stunning, cinematic hero selection screens and easily integrate them into your map!

Features:
  • Highly customizable.
  • Easy to interface.
  • Supports any number of heroes with multiple pages.
  • Repick, Restart, Ban phase, and All Random.
  • Shared and separate hero selection.
  • Open and concealed hero selection.
  • Different selection screens for each team.
  • Different hero rosters for each team.



Keeping three different versions of a giant system like this completely bug-free is almost impossible. Please help me by reporting any bugs you find!

This hero selection system allows players to get a full preview of the hero they're about to pick, with a mouse-over tooltip and a preview of their abilities. Heroes are represented as special effects, not as units, allowing for the hero to be shown locally, only to the player selecting it. Heroes can play animations and emotes when they are preselected and/or picked. The system has many additional features, such as All Random, Ban Phase, and Repick.

While the config is quite long, it is only because every part of the presentation can be customized. If you don't like any of the features shown in the showcase map, you can simply disable it. Getting a working system should be relatively easy, although setting up all your heroes may be tedious if you have a lot of them.

I recommend using this system in conjunction with Neat Text Messages.

Based on the Particle Party hero selection system.


Showcase Map Credits:

Terrain by illbean.

Trees - Fingolfin
Night Elf Archway - eubz, Stormknight
Fog and Glow - Embercraft
Hero Highlight Effects - Vinz
Music - Nightsong (World of Warcraft)


Change Log

v1.3.3:
  • Fixed a bug that caused the menu to not go into the widescreen area in the vJASS and GUI versions.
  • Fixed a bug that caused the pages to not cycle to a hero on a different page when selected through Suggest Random.

v1.3.2:
  • Fixed a bug that could cause a desync due hiding/showing ConsoleUIBackdrop locally.
  • Two additional arguments are passed to the HeroSelectionOnPick callback function. These are wasRandomPick and wasRepick.

v1.3:
  • Improved GUI documentation and import instructions.
  • Enabled hero selection menu and tooltips to be put into the widescreen area. For the menu, this is done by setting MENU_X_LEFT to a negative number. The menu will automatically be adjusted for players who aren't using widescreen monitors.
  • Added the option to add player name texttags over the background heroes. The option in the config is PLAYER_TEXT_TAGS under "Sounds and visuals of background heroes."

v1.2:
  • Added many page cycle button styles.
  • Added OnRestart callback function.
  • Moved all globals that can be used in callbacks into the callbacks block.
  • Cleaned up code and fixed minor bugs.

v1.1:
  • Added support for large number of heroes by adding option to setup multiple pages.
  • Split config and callbacks into two files.
  • You no longer need to set the model paths of heroes manually.
  • Tinting colors of heroes will now be shown.
  • Consolidated select and ban buttons into one button.
  • Added option to set the scale of the accept button.
  • Added option to lock top edge of tooltips instead of bottom edge.
  • Cleaned up code and fixed minor bugs.
Contents

Antares' Hero Selection v1.3.3 GUI (Map)

Antares' Hero Selection v1.3.3 Lua (Map)

Antares' Hero Selection v1.3.3 vJASS (Map)

Level 7
Joined
Sep 16, 2016
Messages
185
Wow this looks dope wtf, what if my map has over 120 characters and max 3 players in a team up to 3v3v3, do you think its possible to have it support all those playable characters?
 
Wow this looks dope wtf, what if my map has over 120 characters and max 3 players in a team up to 3v3v3, do you think its possible to have it support all those playable characters?
It will be difficult to get 120 heroes on the menu and still have any space for the heroes that were picked. You'd have to do it with different pages that you can cycle through, say 3 or 4 pages of 30 to 40 heroes. I don't have that implemented yet, but I'm planning on doing it. If you need it, I can prioritize it.

3v3v3 shouldn't be a problem. You'll need to use the full horizontal space though, so I would recommend putting the menu at the top, very wide with lots of columns but only few rows (it might look a bit janky, but I plan on improving that).
 
Level 7
Joined
Sep 16, 2016
Messages
185
It will be difficult to get 120 heroes on the menu and still have any space for the heroes that were picked. You'd have to do it with different pages that you can cycle through, say 3 or 4 pages of 30 to 40 heroes. I don't have that implemented yet, but I'm planning on doing it. If you need it, I can prioritize it.

3v3v3 shouldn't be a problem. You'll need to use the full horizontal space though, so I would recommend putting the menu at the top, very wide with lots of columns but only few rows (it might look a bit janky, but I plan on improving that).

I have a community for my map, and we have plans on improving the hero selection since its very outdated. Having categories that you can swap between like Agility, Strength, etc would be a huge thing, because our map has characters from over 10 different IPs, so to be able to categorize each IP with their own character would lessen the burden a lot. I feel bad making you prioritize this, since theres no rush to change our hero selection, it has always been a to-do thing, but not of utmost importance since we already have one in place, albeit many years old (xD)
 
Then when you get around to updating your hero selection, my system should support any number of heroes without a problem :psmile:. Just keep in mind that it will be a lot of hours importing all of your 120 heroes! :peek:

But it's probably a feature more people would like to see. A lot of people have far too many heroes in their map :plol:.
 
Level 7
Joined
Sep 16, 2016
Messages
185
Then when you get around to updating your hero selection, my system should support any number of heroes without a problem :psmile:. Just keep in mind that it will be a lot of hours importing all of your 120 heroes! :peek:

But it's probably a feature more people would like to see. A lot of people have far too many heroes in their map :plol:.
Hehe that sounds sweet Antares, yeah I guess I can't escape the work of importing all the heroes, but if its for a hero selection screen of your caliber, it is of no issue :grin:
 
Level 3
Joined
Feb 2, 2024
Messages
11
Does this work for older game versions like 1.26? For me it doesn't appear in the map list when I try to run it.
 
Does this work for older game versions like 1.26? For me it doesn't appear in the map list when I try to run it.
I helped someone set up one of my systems on 1.31 and it should be possible here too, but I'm afraid 1.26 is too far back.

@Regno multiple pages are now implemented. Still have to work on the layout options a bit more.
 
Level 7
Joined
Sep 16, 2016
Messages
185
I helped someone set up one of my systems on 1.31 and it should be possible here too, but I'm afraid 1.26 is too far back.

@Regno multiple pages are now implemented. Still have to work on the layout options a bit more.
Sweeeet! I'll give it a try right away. :)
 
Level 7
Joined
Sep 16, 2016
Messages
185
@Antares A I have some questions regarding the UI :grin:

By the way, I love the setup of the code so far, just wondering how feasible would a layout for the UI be for something like this with this system? A dropdown could also work to avoid category buttons but both would work nicely, I guess with a dropdown you save more space on the selection screen
1707817138891.png


With this, only the sound for the hero picked played for the player who picked it, so you don't hear the other unit sounds

This is one of the bugs with UI I noticed
1707817240879.png

:sad:
 
Level 7
Joined
Sep 16, 2016
Messages
185
Please attach your config/hero list so I can investigate what's going on.
JASS:
library HeroSelectionConfig requires optional NeatMessages

   //=================================================================================================================================
   //These constants determine important aspects of the hero selection. You can fine-tune visuals, sounds etc. further down below.
   //=================================================================================================================================

   globals
       constant boolean HERO_SELECTION_ENABLE_DEBUG_MODE    = true                    //Printout errors and check for function crashes.
 
       //Overall behavior.
       constant boolean HERO_CAN_BE_PICKED_MULTIPLE_TIMES    = false                 //Set to true if the same hero should be able to be picked multiple times.
       constant boolean AUTO_SET_SELECTING_PLAYERS            = false                    //Set to true if hero selection should be enabled for all human players. Set to false if you want to set the player list manually (which can include computer players).
       constant boolean COMPUTER_AUTO_PICK_RANDOM_HERO        = false                    //Set to true if computer players that are in hero selection should automatically pick a random hero after all human players have picked.
       constant boolean ESCAPE_PLAYER_AFTER_SELECTING        = false                 //Set to true if a player picking a hero should kick him or her out of the hero selection menu and camera.
       constant boolean CONCEAL_HERO_PICKS_FROM_ENEMIES    = false                 //Set to true if hero picks should be concealed from enemies (players in another team or all players if there are no teams), including emote, effect, and text messages.
       constant boolean MENU_INCLUDE_RANDOM_PICK            = true                    //Include button for picking a random hero at the bottom of the menu.
       constant boolean MENU_INCLUDE_SUGGEST_RANDOM        = true                    //Include button to pre-select a random hero next to the random pick button.
       constant real TIME_LIMIT                            = 60                    //Set a time limit after which players who haven't chosen a hero will be assigned one at random. Set to 0 for no time limit.

       //Camera and foreground hero positions (background hero locations are set in GetPlayerBackgroundHeroLocation).
       constant boolean SEPARATE_LOCATIONS_FOR_EACH_TEAM    = false                    //Set to true if each team gets a different selection screen (all following values will be ignored and you have to set the array equivalents in InitArrays).
       constant real FOREGROUND_HERO_X                        = 9421                    //x-Position of foreground hero.
       constant real FOREGROUND_HERO_Y                        = 9043                    //y-Position of foreground hero.
       constant real HERO_SELECTION_ANGLE                    = 0                        //Hero selection viewing direction of camera (0 = facing east, 90 = facing north etc.).

       //Visuals.
       constant boolean ENFORCE_CAMERA                        = true                    //Set to false if players' camera should not be changed during hero selection.
       constant boolean HIDE_GAME_UI                       = true                  //Set to true if all UI elements other than the hero selection menu should be hidden.
       constant boolean CREATE_FOREGROUND_HERO                = true                    //Set to false if no foreground hero should appear on preselection.
       constant boolean CREATE_BACKGROUND_HEROES              = true                  //Set to true if players should be able to see other players' picks in the background.
   endglobals

   //=================================================================================================================================

   globals
       string array CATEGORY_NAMES                            //Names of the hero categories that appear in the hero selection menu.
       integer array PAGE_OF_CATEGORY                        //Set the page at which that category appears within the menu. When there is more than one page, page cycle buttons appear in the menu.
       boolean array PLAYER_SELECTS_HERO                    //List of all players that are supposed to participate in hero selection (true = participates).
       integer array TEAM_OF_PLAYER                        //Team of player, 1, 2 etc. 0 = no teams.
       string array PLAYER_COLOR                            //Hex color string (including "|cff") for each player.
   endglobals

   function SetCategories takes nothing returns nothing
       //Set the names of the categories in the hero selection menu. Starts at index 1. Set to null for no category caption.
       set CATEGORY_NAMES[1]                        = "|cffffcc00Strength|r"
       set CATEGORY_NAMES[2]                        = "|cffffcc00Agility|r"
       set CATEGORY_NAMES[3]                        = "|cffffcc00Intelligence|r"
       set CATEGORY_NAMES[4]                        = "|cffffcc00Reborn|r"
       set CATEGORY_NAMES[5]                        = "|cffffcc00Bleach|r"

       //Set the pages of the categories in the hero selection menu. Pages start at 1.
       set PAGE_OF_CATEGORY[1]                        = 1
       set PAGE_OF_CATEGORY[2]                        = 2
       set PAGE_OF_CATEGORY[3]                        = 3
       set PAGE_OF_CATEGORY[4]                        = 4
       set PAGE_OF_CATEGORY[5]                        = 5
   endfunction

   function HeroSelectionInitPlayers takes nothing returns nothing
       //Set the list of players for which hero selection is enabled (only if AUTO_SET_SELECTING_PLAYERS = false). It is disabled here because computer players must be added to the hero selection.
       set PLAYER_SELECTS_HERO[0]                    = true
       set PLAYER_SELECTS_HERO[1]                    = true
       set PLAYER_SELECTS_HERO[2]                    = true
       set PLAYER_SELECTS_HERO[3]                    = false
       set PLAYER_SELECTS_HERO[4]                    = true
       set PLAYER_SELECTS_HERO[5]                    = true
       set PLAYER_SELECTS_HERO[6]                    = true
       set PLAYER_SELECTS_HERO[7]                    = false
       set PLAYER_SELECTS_HERO[8]                    = true
       set PLAYER_SELECTS_HERO[9]                    = true
       set PLAYER_SELECTS_HERO[10]                    = true
       set PLAYER_SELECTS_HERO[11]                    = false
 
       //Set the teams of players. Players with team 0 are enemies to all players.
       set TEAM_OF_PLAYER[0]                        = 1
       set TEAM_OF_PLAYER[1]                        = 1
       set TEAM_OF_PLAYER[2]                        = 1
       set TEAM_OF_PLAYER[3]                        = 1
       set TEAM_OF_PLAYER[4]                        = 2
       set TEAM_OF_PLAYER[5]                        = 2
       set TEAM_OF_PLAYER[6]                        = 2
       set TEAM_OF_PLAYER[7]                        = 2
       set TEAM_OF_PLAYER[8]                        = 3
       set TEAM_OF_PLAYER[9]                        = 3
       set TEAM_OF_PLAYER[10]                        = 3
       set TEAM_OF_PLAYER[11]                        = 3
   endfunction

   //=================================================================================================================================

   globals
       real array TEAM_FOREGROUND_HERO_X                    //x-Position of foreground hero.
       real array TEAM_FOREGROUND_HERO_Y                    //y-Position of foreground hero.
       real array TEAM_HERO_SELECTION_ANGLE                //Hero selection camera yaw in degrees (0 = facing east, 90 = facing north etc.).
   endglobals

   function HeroSelectionInitArrays takes nothing returns nothing
       //If you set SEPARATE_LOCATIONS_FOR_EACH_TEAM = true, initialize the above array variables here.
   endfunction
 
   function GetPlayerBackgroundHeroLocation takes integer playerIndex, integer whichSlot, integer numberOfPlayers, integer whichTeam, integer slotInTeam, integer teamSize returns location
       local real deltaHorizontal
       local real deltaVertical

       //=================================================================================================================================
       /*
        CREATE_BACKGROUND_HEROES only.
        Here you can customize the positions of the background heroes. Init loops through and calls this function for each player.

        Input:
        playerIndex
        whichSlot                 The position of the player when enumerating all players for which hero selection is enabled.
        numberOfPlayers         The number of players for which hero selection is enabled.
        whichTeam                 The team the player is assigned to. Discard if there are no teams.
        slotInTeam                 The position of that player within his or her team. Discard if there are no teams.
        teamSize                 The size of the player's team. Discard if there are no teams.

        Output:
        deltaVertical            The distance between the background hero and the camera eye position along the camera viewing direction.
        deltaHorizontal            The offset between the background hero and the camera eye position perpendicular to the camera viewing direction.
        */
       //==================================================================================================================================

       //Example code:
       local real angle
       local real dist
       local real BACKGROUND_HERO_OFFSET_BACKROW = 1425
       local real BACKGROUND_HERO_OFFSET_FRONTROW = 1250

       if teamSize == 1 then
           set angle = 9
           set dist = BACKGROUND_HERO_OFFSET_BACKROW
       elseif slotInTeam == 1 then
           set angle = 5
           set dist = BACKGROUND_HERO_OFFSET_BACKROW
       elseif slotInTeam == 2 then
           set angle = 13
           set dist = BACKGROUND_HERO_OFFSET_BACKROW
       else
           set angle = 9
           set dist = BACKGROUND_HERO_OFFSET_FRONTROW
       endif
 
       if whichTeam == 2 then
           set angle = -angle
       endif

       set deltaHorizontal = Sin(Deg2Rad(angle))*dist
       set deltaVertical = Cos(Deg2Rad(angle))*dist

       //==================================================================================================================================

       return Location(deltaHorizontal, deltaVertical)
   endfunction



   //==================================================================================================================================
   //                                                    F I N E - T U N I N G
   //==================================================================================================================================



   globals
       //How hero selection looks like before it is enabled (you can ignore this if you plan on enabling hero selection right away).
       constant boolean SHOW_MENU_BEFORE_ENABLED            = false                    //Set to true if players should be able to see the hero selection menu before hero selection is enabled.
       constant boolean PRE_SELECT_BEFORE_ENABLED          = false                 //Set to true if players should be able to pre-select heroes before hero selection is enabled.
 
       //Camera setup (ENFORCE_CAMERA).
       constant real CAMERA_PITCH                            = 12                    //Hero selection camera angle of attack in degrees. 0 = facing horizon, 90 = facing ground.
       constant real CAMERA_DISTANCE                        = 1300                    //Hero selection camera distance from camera target.
       constant real CAMERA_TARGET_OFFSET                    = 500                    //Distance between foreground hero and camera target. Positive = Camera target is behind the hero.
       constant real CAMERA_PERPENDICULAR_OFFSET            = 0                        //Shifts the camera left (negative) or right (positive) with respect to the foreground hero.
       constant real CAMERA_Z_OFFSET                        = 100                    //Hero selection camera z-offset.
       constant real CAMERA_FIELD_OF_VIEW                    = 70                    //Hero selection camera field of view.

       //Sounds and visuals of hero pre-selection (CREATE_FOREGROUND_HERO).
       constant string PRESELECT_EFFECT                    = null                    //Special effect played on the hero's position for the triggering player when switching to a new hero during pre-selection. Set to null for no effect.
       constant boolean PLAY_EMOTE_ON_PRESELECT            = true                  //Set to true if the hero should play its selection emote when the player switches to that hero during pre-selection.
       constant boolean PLAY_ANIMATION_ON_PRESELECT        = true                  //Set to true if the hero should play the selection animation when the player switches to that hero during pre-selection.
       constant boolean PHANTOM_HERO_WHEN_CANNOT_BE_PICKED    = true                    //Set to true if a hero should be black and transparent when it is pre-selected but cannot be picked.
       constant real FOREGROUND_HERO_Z                        = 0                        //z-Position of foreground hero.

       //Sounds and visuals on hero pick.
       constant string PICK_EFFECT                            = "HolyLight.mdx"        //Special effect played on the hero's position for the triggering player when picking a hero. Set to null for no effect.
       constant string PICK_SOUND                            = "Sound\\Interface\\ItemReceived.flac"    //Sound effect played for the triggering player when selecting a hero. Set to null for no sound.
       constant boolean PLAY_EMOTE_ON_PICK                    = false                 //Set to true if a hero should play its selection emote when a player chooses that hero.
       constant boolean PLAY_ANIMATION_ON_PICK                = false                 //Set to true if a hero should play the selection animation when a player chooses that hero.
       constant real PLAYER_PICK_ESCAPE_DELAY                = 4.0                    //Delay between selecting a hero and being kicked out of hero selection (ESCAPE_PLAY_AFTER_SELECTING only).
       constant real FOREGROUND_HERO_FADEOUT_DELAY            = 1.0                   //The time it takes for the foreground hero to start fading out after being selected.
       constant real FOREGROUND_HERO_FADEOUT_TIME            = 1.5                   //The time it takes for the foreground hero to fade out after being selected.
       constant string OTHER_PLAYER_HERO_PICK_SOUND        = "Sound\\Interface\\InGameChatWhat1.flac"    //Sound played when another player picks a hero. Set to null for no sound.
 
       //Text messages on hero pick.
       constant boolean CREATE_TEXT_MESSAGE_ON_PICK        = true                    //Set to true if a text message should be sent to all other players when a hero is picked (except to enemies when concealed).
       constant real TEXT_MESSAGE_X_OFFSET                    = 0.35                    //x-Offset of text messages from default. Text messages will still suck. Recommend using NeatMessages.
       constant real TEXT_MESSAGE_Y_OFFSET                    = 0                        //y-Offset of text messages from default.
       constant boolean USE_HERO_PROPER_NAME                = false                    //Instead of the hero's name, its proper name will be displayed in the text message. For example, "Uther" instead of "Paladin". Will temporarily create a hero to get the proper name.
       constant boolean MESSAGE_EVEN_WHEN_CONCEALED        = true                    //Set to true if players should still get a message notifying that a player has picked a hero even when it is concealed which hero was picked (CONCEAL_HERO_PICKS_FROM_ENEMIES).
       constant boolean INCLUDE_PROGRESSION_IN_MESSAGE        = false                 //Set to true if the displayed text message should include how many players have selected their hero.

       //Sounds and visuals of background heroes (CREATE_BACKGROUND_HEROES).
       constant real BACKGROUND_HERO_FADEIN_TIME            = 1.0                   //The time it takes for the background hero to fade in after being selected.
       constant boolean PLAY_EMOTE_ON_BACKGROUND_HERO      = true                     //Set to true if a hero should play its selection emote for all other players as it fades in.
       constant boolean PLAY_ANIMATION_ON_BACKGROUND_HERO  = true                  //Set to true if the background hero should play its selection animation as it fades in.
       constant string BACKGROUND_HERO_FADEIN_EFFECT       = "HolyLightRoyal.mdx"  //Special effect played on the background hero as it fades in.
       constant string BACKGROUND_HERO_SELF_HIGHLIGHT        = "RadianceHoly.mdx"    //Special effect added at the location of a player's own background hero to highlight it. Set to null for no highlight.
       constant real BACKGROUND_HERO_HIGHLIGHT_Z            = 70                    //z-Position of background hero self highlight.
       constant real BACKGROUND_HERO_FACING_POINT_OFFSET    = -500                    //Adjusts where the background heroes face. 0 = Background heroes will face the foreground hero. Negative value = Face a point closer to the camera. Positive value = Face a point further from the camera.
       constant string CONCEALED_HERO_EFFECT                = "Objects\\InventoryItems\\QuestionMark\\QuestionMark.mdl"    //Model for the background hero seen by a player for which the hero pick was concealed.

       //Last player picks a hero.
       constant real LAST_PLAYER_SELECT_END_DELAY            = 6.0                    //The amount of time after the last player selects a hero and the hero selection ends (ignore if ESCAPE_PLAYER_AFTER_SELECTING)
       constant boolean DELETE_BACKGROUND_HEROES_AFTER_END    = false                    //Set to false if background heroes should not get removed when hero selection ends. For example, when a player repicks, they are still there.

       //Layout of hero selection menu.
       constant integer MENU_NUMBER_OF_COLUMNS                = 2                        //Number of hero buttons per row.
       constant real MENU_X_LEFT                            = 0                        //x-Position of left edge of hero selection menu.
       constant real MENU_Y_TOP                            = 0.55                    //y-Position of top edge of hero selection menu.
       constant real MENU_BUTTON_SIZE                        = 0.039                    //Size of individual hero buttons.
       constant real MENU_LEFT_RIGHT_EDGE_GAP                = 0.02                    //Gap between left and right edges of menu and first and last buttons.
       constant real MENU_TOP_EDGE_GAP                        = 0.015                    //Gap between top edge of menu and first button/first category title.
       constant real MENU_BOTTOM_EDGE_GAP                    = 0.02                    //Gap between bottom edge of menu and last button.
       constant real MENU_BUTTON_BUTTON_GAP                = 0.005                    //Gap between two individual hero buttons.
       constant real MENU_CATEGORY_FONT_SIZE                = 16                    //Font size of category titles.
       constant real MENU_CATEGORY_GAP                        = 0.028                    //Gap between buttons of two different categories.
       constant real MENU_CATEGORY_TITLE_Y                    = -0.001                //y-Position shift between category title and center of gap between categories.
       constant real MENU_BORDER_TILE_SIZE                    = 0.03                    //This rounds up the width and height of the menu to an integer multiple of the specified number. This is useful if you're using a tiled border texture, so that there's no discontinuity in the texture.
                                                                                   //Value should be equal to BackdropCornerSize in the HeroSelectionMenu.fdf. Set to 0 to disable.
       constant real MENU_HEROES_RANDOM_GAP                = 0.02                    //Additional gap between last hero button and random pick button.
 
       //Select button.
       constant string SELECT_BUTTON_TEXT                    = "Accept"                //The text in the select hero button at the bottom of the menu.
       constant real SELECT_BUTTON_SCALE                    = 1.0                    //The scale of the select hero button at the bottom of the menu.
       constant real SELECT_BUTTON_WIDTH                    = 0.092                    //The width of the select hero button at the bottom of the menu.

       //Display of random options.
       constant string RANDOM_HERO_TOOLTIP                    = "Choose a random hero."
       constant string SUGGEST_RANDOM_TOOLTIP                = "Suggest a random hero, but don't select it just yet."
       constant string RANDOM_HERO_ICON                    = "ReplaceableTextures\\CommandButtons\\BTNRandomIncredibleIcon.blp"
       constant string SUGGEST_RANDOM_ICON                    = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp"
       constant boolean RANDOM_SELECT_CYCLE_STYLE            = true                    //Set to true if the foreground hero should cycle randomly between different heroes while random hero is pre-selected. Set to false if a question mark should be shown.
       constant real RANDOM_SELECT_CYCLE_INTERVAL            = 0.2                    //How fast the heroes are cycled through when random hero is pre-selected (RANDOM_SELECT_CYCLE_STYLE).
 
       //Layout of ability preview buttons.
       constant real HERO_ABILITY_PREVIEW_BUTTON_X            = 0.0                    //x-Position of topmost ability preview button relative to topright corner of menu.
       constant real HERO_ABILITY_PREVIEW_BUTTON_Y            = -0.016                //y-Position of topmost ability preview button relative to topright corner of menu.
       constant real HERO_ABILITY_PREVIEW_BUTTON_SIZE        = 0.025                    //The size of the hero ability preview buttons that appear on the right side of the menu when pre-selecting a hero.
       constant boolean ABILITY_BUTTON_HORIZONTAL_LAYOUT    = false                    //Set to true if ability preview buttons should be arranged horizontally instead of vertically.
       constant string HERO_ABILITY_LEVEL_DELIMITER        = " - ["                //To get the name of a hero ability without the level-text from the tooltip (such as "Stormbolt - [Level 1]" -> "Stormbolt"). This string is used to detect where the name of the ability ends. Set to null if not necessary.

       //Page cycle buttons (when multiple pages are set).
       constant real MENU_PAGE_DOWN_X                        = 0.03                    //x-Position of the page cycle down button relative to bottomleft corner of menu.                  
       constant real MENU_PAGE_DOWN_Y                        = 0.03                    //y-Position of the page cycle down button relative to bottomleft corner of menu.
       constant real MENU_PAGE_UP_X                        = 0.03                    //x-Position of the page cycle up button relative to bottomright corner of menu.
       constant real MENU_PAGE_UP_Y                        = 0.03                    //y-Position of the page cycle up button relative to bottomright corner of menu.
       constant string MENU_PAGE_DOWN_ICON                    = "ReplaceableTextures\\CommandButtons\\BTNNagaBurrow.blp"
       constant string MENU_PAGE_UP_ICON                    = "ReplaceableTextures\\CommandButtons\\BTNNagaUnBurrow.blp"

       //Display of big caption.
       constant string HERO_SELECTION_CAPTION                = "Choose your Hero!"    //The text displayed on the screen during hero selection. Set null to omit text.
       constant real CAPTION_FONT_SIZE                        = 30                    //Font size of hero selection caption.
       constant real CAPTION_X                                = 0.4                    //x-Position of caption center.
       constant real CAPTION_Y                                = 0.41                    //y-Position of caption center.
       constant string CAPTION_COLOR_1                        = "|cffffcc00"            //Caption will cycle between color 1 and color 2. Set the same for no color cycling.
       constant string CAPTION_COLOR_2                        = "|cffffffff"            //Caption will cycle between color 1 and color 2. Set the same for no color cycling.
       constant integer CAPTION_ALPHA_1                    = 255                    //Caption will cycle between alpha 1 and alpha 2. Set the same for no alpha cycling.
       constant integer CAPTION_ALPHA_2                    = 255                    //Caption will cycle between alpha 1 and alpha 2. Set the same for no alpha cycling.
       constant real CAPTION_CYCLE_TIME                    = 4.0                    //The time it takes for the caption to cycle between color 1/2 and alpha 1/2.
       constant real CAPTION_FADEOUT_TIME                    = 2.0                    //The time it takes for the caption to fade out after a player has picked a hero. Set to -1 for no fade out.
 
       //Position of hero button and ability preview button mouse-over tooltips.
       constant real TOOLTIP_LEFT_X                        = 0.51
       constant real TOOLTIP_Y                              = 0.13
       constant boolean TOOLTIP_LOCK_TOP                    = false                    //Set to true if TOOLTIP_Y should refer to top instead of bottom edge.
       constant real TOOLTIP_WIDTH                         = 0.29

       //Display of countdown timer.
       constant string TIMER_TEXT                            = "Time Remaining: |cffffcc00"    //Text before the time remaining display
       constant string TIMER_BAN_PHASE_TEXT                = "Ban Phase: |cffffcc00"        //Text before the time remaining display during the ban phase.
       constant real TIMER_FONT_SIZE                        = 11                    //Font size of the time remaining display.
       constant real TIMER_X                                = 0.4                    //x-Position of center of the time remaining display.
       constant real TIMER_Y                                = 0.59                    //y-Position of the center of the time remaining display.

       //Shadows of heroes.
       constant boolean CREATE_SHADOWS                        = false                    //Create shadows with destructables for heroes (since they are special effects and don't have shadows).
       constant integer SHADOW_DESTRUCTABLE_ID                = 'Dsha'                //Destructable id of the shadow that's created for heroes.
       constant integer NO_SHADOW_DESTRUCTABLE_ID            = 'Dnsh'                //Dummy destructable without a shadow.
   endglobals

   //=================================================================================================================================

   function HeroSelectionSetPlayerColors takes nothing returns nothing
       //Set the colors of players shown for their names in text messages.
       set PLAYER_COLOR[0]                         = "|cffff0402"
       set PLAYER_COLOR[1]                         = "|cff1052ff"
       set PLAYER_COLOR[2]                         = "|cff1BE6BA"
       set PLAYER_COLOR[3]                         = "|cff8530b1"
       set PLAYER_COLOR[4]                         = "|cfffffc00"
       set PLAYER_COLOR[5]                         = "|cffff8a0d"
       set PLAYER_COLOR[6]                         = "|cff20bf00"
       set PLAYER_COLOR[7]                            = "|cffE35BAF"
       set PLAYER_COLOR[8]                            = "|cff949697"
       set PLAYER_COLOR[9]                         = "|cff7EBFF1"
       set PLAYER_COLOR[10]                         = "|cff106247"
       set PLAYER_COLOR[11]                         = "|cff4F2B05"
       set PLAYER_COLOR[12]                         = "|cff9C0000"
       set PLAYER_COLOR[13]                         = "|cff0000C2"
       set PLAYER_COLOR[14]                         = "|cff00EBEB"
       set PLAYER_COLOR[15]                        = "|cffBE00FF"
       set PLAYER_COLOR[16]                        = "|cffECCC86"
       set PLAYER_COLOR[17]                         = "|cffF7A48B"
       set PLAYER_COLOR[18]                         = "|cffBFFF80"
       set PLAYER_COLOR[19]                         = "|cffDBB8EC"
       set PLAYER_COLOR[20]                         = "|cff4F4F55"
       set PLAYER_COLOR[21]                         = "|cffECF0FF"
       set PLAYER_COLOR[22]                         = "|cff00781E"
       set PLAYER_COLOR[23]                        = "|cffA46F34"
   endfunction

endlibrary

JASS:
library HeroDeclaration
    globals
        Hero MountainKing
        Hero Paladin
        Hero Archmage
        Hero BloodMage
        Hero PriestessOfTheMoon
        Hero DemonHunter
        Hero KeeperOfTheGrove
        Hero Warden
        Hero Warden1
        Hero Warden2
        Hero Warden3
        Hero Warden4
        Hero Warden5
        Hero Warden6
        Hero Warden7
    endglobals
 
    function HeroDeclaration takes nothing returns nothing
        //========================================================================================
        //Here you declare all heroes in your map. The order in which you create them determine the order in which they appear in the hero selection menu.
        //The fields that should be set are:
        /*
        integer array abilities                     The abilities of this hero. Starts at index 1.
        boolean array isNonHeroAbility              Set this flag if the ability at the index is a non-hero ability. This will make the tooltip instead of the research tooltip appear on mouse-over.
        integer unitId                              Unit id of the hero.
        integer tooltipAbility                      Set up any non-hero ability with one level for each hero and write the hero's description in its tooltip.
        string selectEmote                          Sound path of the emote the hero should play when selected.
        animtype selectAnim                         animType of select animation. For example, "spell" is ANIMTYPE_SPELL.
        subanimtype selectSubAnim                   subanimtype of select animation. For example "spell slam" is ANIMTYPE_SPELL + SUBANIMTYPE_SLAM.
        real selectAnimLength                       Length of the select animation. If set incorrectly, animation will be interrupted or freeze.
        integer category                            In which category in the menu should this hero be put?
        boolean needsHeroGlow                       A hero glow will be added to heroes with models that don't have a glow. Requires "GeneralHeroGlow.mdx" to be imported.
        boolean unavailable                         Heroes with this flag will appear in the menu but cannot be picked.
        boolean array unavailableToTeam             Hero will not appear in the menu for players in a team for which this flag was set. Can be used to create completely different hero rosters for different teams.
        */
        //========================================================================================
        set MountainKing                            = Hero.create()
        set Paladin                                 = Hero.create()
        set Archmage                                = Hero.create()
        set BloodMage                               = Hero.create()
        set PriestessOfTheMoon                      = Hero.create()
        set DemonHunter                             = Hero.create()
        set KeeperOfTheGrove                        = Hero.create()
        set Warden                                  = Hero.create()
        set Warden1                                 = Hero.create()
        set Warden2                                 = Hero.create()
        set Warden3                                 = Hero.create()
        set Warden4                                 = Hero.create()
        set Warden5                                 = Hero.create()
        set Warden6                                 = Hero.create()
        set Warden7                                 = Hero.create()
        //========================================================================================
        set Archmage.abilities[1]                   = 'AHbz'
        set Archmage.abilities[2]                   = 'AHwe'
        set Archmage.abilities[3]                   = 'AHab'
        set Archmage.selectEmote                    = "Units\\Human\\HeroArchMage\\HeroArchMageWarcry1.flac"
        set Archmage.unitId                         = 'Hamg'
        set Archmage.tooltipAbility                 = 'T000'
        set Archmage.needsHeroGlow                  = false
        set Archmage.category                       = 3
        set Archmage.selectAnim                     = ANIM_TYPE_SPELL
        set Archmage.selectSubAnim                  = null
        set Archmage.selectAnimLength               = 2.7
        //========================================================================================
   
        set Paladin.abilities[1]                    = 'AHhb'
        set Paladin.abilities[2]                    = 'AHds'
        set Paladin.abilities[3]                    = 'AHad'
        set Paladin.abilities[4]                    = 'AHre'
        set Paladin.selectEmote                     = "Units\\Human\\HeroPaladin\\HeroPaladinYesAttack1.flac"
        set Paladin.unitId                          = 'Hpal'
        set Paladin.tooltipAbility                  = 'Tpal'
        set Paladin.needsHeroGlow                   = false
        set Paladin.category                        = 1
        set Paladin.selectAnim                      = ANIM_TYPE_SPELL
        set Paladin.selectSubAnim                   = null
        set Paladin.selectAnimLength                = 2.167
   
        //========================================================================================
   
        set MountainKing.abilities[1]               = 'AHtb'
        set MountainKing.abilities[2]               = 'AHtc'
        set MountainKing.abilities[3]               = 'AHbh'
        set MountainKing.abilities[4]               = 'AHav'
        set MountainKing.selectEmote                = "Units\\Human\\HeroMountainKing\\HeroMountainKingYesAttack1.flac"
        set MountainKing.unitId                     = 'Hmkg'
        set MountainKing.tooltipAbility             = 'Tmkg'
        set MountainKing.needsHeroGlow              = false
        set MountainKing.category                   = 1
        set MountainKing.selectAnim                 = ANIM_TYPE_SPELL
        set MountainKing.selectSubAnim              = SUBANIM_TYPE_SLAM
        set MountainKing.selectAnimLength           = 1.0
   
        //========================================================================================
   
        set BloodMage.abilities[1]                  = 'AHfs'
        set BloodMage.abilities[2]                  = 'AHbn'
        set BloodMage.abilities[3]                  = 'AHdr'
        set BloodMage.abilities[4]                  = 'AHpx'
        set BloodMage.selectEmote                   = "Units\\Human\\HeroBloodElf\\BloodElfMageYesAttack2.flac"
        set BloodMage.unitId                        = 'Hblm'
        set BloodMage.tooltipAbility                = 'Tblm'
        set BloodMage.needsHeroGlow                 = false
        set BloodMage.category                      = 3
        set BloodMage.selectAnim                    = ANIM_TYPE_SPELL
        set BloodMage.selectSubAnim                 = SUBANIM_TYPE_CHANNEL
        set BloodMage.selectAnimLength              = 2.0
   
        //========================================================================================
   
        set PriestessOfTheMoon.abilities[1]         = 'AEst'
        set PriestessOfTheMoon.abilities[2]         = 'AHfa'
        set PriestessOfTheMoon.abilities[3]         = 'AEar'
        set PriestessOfTheMoon.abilities[4]         = 'AEsf'
   
        set PriestessOfTheMoon.selectEmote          = "Units\\nightElf\\HeroMoonPriestess\\HeroMoonPriestessYesAttack2.flac"
        set PriestessOfTheMoon.unitId               = 'Emoo'
        set PriestessOfTheMoon.tooltipAbility       = 'Tmoo'
        set PriestessOfTheMoon.needsHeroGlow        = false
        set PriestessOfTheMoon.category             = 2
        set PriestessOfTheMoon.selectAnim           = ANIM_TYPE_SPELL
        set PriestessOfTheMoon.selectSubAnim        = null
        set PriestessOfTheMoon.selectAnimLength     = 1.333
        //========================================================================================
   
        set DemonHunter.abilities[1]                = 'AEmb'
        set DemonHunter.abilities[2]                = 'AEim'
        set DemonHunter.abilities[3]                = 'AEev'
        set DemonHunter.abilities[4]                = 'AEme'
   
        set DemonHunter.selectEmote                 = "Units\\NightElf\\HeroDemonHunter\\HeroDemonHunterYesAttack1.flac"
        set DemonHunter.unitId                      = 'Edem'
        set DemonHunter.tooltipAbility              = 'Tdem'
        set DemonHunter.needsHeroGlow               = false
        set DemonHunter.category                    = 2
        set DemonHunter.selectAnim                  = ANIM_TYPE_SPELL
        set DemonHunter.selectSubAnim               = SUBANIM_TYPE_THROW
        set DemonHunter.selectAnimLength            = 0.9
        //========================================================================================
   
        set KeeperOfTheGrove.abilities[1]           = 'AEer'
        set KeeperOfTheGrove.abilities[2]           = 'AEfn'
        set KeeperOfTheGrove.abilities[3]           = 'AEah'
        set KeeperOfTheGrove.abilities[4]           = 'AEtq'
   
        set KeeperOfTheGrove.selectEmote            = "Units\\NightElf\\HeroKeeperOfTheGrove\\KeeperOfTheGroveYesAttack2.flac"
        set KeeperOfTheGrove.unitId                 = 'Ekee'
        set KeeperOfTheGrove.tooltipAbility         = 'Tkee'
        set KeeperOfTheGrove.needsHeroGlow          = false
        set KeeperOfTheGrove.category               = 3
        set KeeperOfTheGrove.selectAnim             = ANIM_TYPE_STAND
        set KeeperOfTheGrove.selectSubAnim          = SUBANIM_TYPE_VICTORY
        set KeeperOfTheGrove.selectAnimLength       = 3.333
        //========================================================================================
   
        set Warden.abilities[1]                     = 'AEfk'
        set Warden.abilities[2]                     = 'AEbl'
        set Warden.abilities[3]                     = 'AEsh'
        set Warden.abilities[4]                     = 'AEsv'
   
        set Warden.selectEmote                      = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden.unitId                           = 'Ewar'
        set Warden.tooltipAbility                   = 'Twar'
        set Warden.needsHeroGlow                    = false
        set Warden.category                         = 2
        set Warden.selectAnim                       = ANIM_TYPE_SPELL
        set Warden.selectSubAnim                    = null
        set Warden.selectAnimLength                 = 1.2
   
        //========================================================================================
   
        set Warden1.abilities[1]                    = 'AEfk'
        set Warden1.abilities[2]                    = 'AEbl'
        set Warden1.abilities[3]                    = 'AEsh'
        set Warden1.abilities[4]                    = 'AEsv'
   
        set Warden1.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden1.unitId                          = 'Ewar'
        set Warden1.tooltipAbility                  = 'Twar'
        set Warden1.needsHeroGlow                   = false
        set Warden1.category                            = 2
        set Warden1.selectAnim                      = ANIM_TYPE_SPELL
        set Warden1.selectSubAnim                   = null
        set Warden1.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden2.abilities[1]                    = 'AEfk'
        set Warden2.abilities[2]                    = 'AEbl'
        set Warden2.abilities[3]                    = 'AEsh'
        set Warden2.abilities[4]                    = 'AEsv'
   
        set Warden2.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden2.unitId                          = 'Ewar'
        set Warden2.tooltipAbility                  = 'Twar'
        set Warden2.needsHeroGlow                   = false
        set Warden2.category                            = 2
        set Warden2.selectAnim                      = ANIM_TYPE_SPELL
        set Warden2.selectSubAnim                   = null
        set Warden2.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden3.abilities[1]                    = 'AEfk'
        set Warden3.abilities[2]                    = 'AEbl'
        set Warden3.abilities[3]                    = 'AEsh'
        set Warden3.abilities[4]                    = 'AEsv'
   
        set Warden3.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden3.unitId                          = 'Ewar'
        set Warden3.tooltipAbility                  = 'Twar'
        set Warden3.needsHeroGlow                   = false
        set Warden3.category                            = 2
        set Warden3.selectAnim                      = ANIM_TYPE_SPELL
        set Warden3.selectSubAnim                   = null
        set Warden3.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden4.abilities[1]                    = 'AEfk'
        set Warden4.abilities[2]                    = 'AEbl'
        set Warden4.abilities[3]                    = 'AEsh'
        set Warden4.abilities[4]                    = 'AEsv'
   
        set Warden4.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden4.unitId                          = 'Ewar'
        set Warden4.tooltipAbility                  = 'Twar'
        set Warden4.needsHeroGlow                   = false
        set Warden4.category                            = 2
        set Warden4.selectAnim                      = ANIM_TYPE_SPELL
        set Warden4.selectSubAnim                   = null
        set Warden4.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden5.abilities[1]                    = 'AEfk'
        set Warden5.abilities[2]                    = 'AEbl'
        set Warden5.abilities[3]                    = 'AEsh'
        set Warden5.abilities[4]                    = 'AEsv'
   
        set Warden5.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden5.unitId                          = 'Ewar'
        set Warden5.tooltipAbility                  = 'Twar'
        set Warden5.needsHeroGlow                   = false
        set Warden5.category                            = 2
        set Warden5.selectAnim                      = ANIM_TYPE_SPELL
        set Warden5.selectSubAnim                   = null
        set Warden5.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden6.abilities[1]                    = 'AEfk'
        set Warden6.abilities[2]                    = 'AEbl'
        set Warden6.abilities[3]                    = 'AEsh'
        set Warden6.abilities[4]                    = 'AEsv'
   
        set Warden6.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden6.unitId                          = 'Ewar'
        set Warden6.tooltipAbility                  = 'Twar'
        set Warden6.needsHeroGlow                   = false
        set Warden6.category                            = 2
        set Warden6.selectAnim                      = ANIM_TYPE_SPELL
        set Warden6.selectSubAnim                   = null
        set Warden6.selectAnimLength                    = 1.2
   
        //========================================================================================
   
        set Warden7.abilities[1]                    = 'AEfk'
        set Warden7.abilities[2]                    = 'AEbl'
        set Warden7.abilities[3]                    = 'AEsh'
        set Warden7.abilities[4]                    = 'AEsv'
   
        set Warden7.selectEmote                     = "Units\\nightElf\\HeroWarden\\HeroWardenYesAttack3.flac"
        set Warden7.unitId                          = 'Ewar'
        set Warden7.tooltipAbility                  = 'Twar'
        set Warden7.needsHeroGlow                   = false
        set Warden7.category                            = 2
        set Warden7.selectAnim                      = ANIM_TYPE_SPELL
        set Warden7.selectSubAnim                   = null
        set Warden7.selectAnimLength                    = 1.2
   
        //========================================================================================
    endfunction
endlibrary

JASS:
library HeroSelectionConfig requires optional NeatMessages
    //=================================================================================================================================
    //These constants determine important aspects of the hero selection. You can fine-tune visuals, sounds etc. further down below.
    //=================================================================================================================================
    globals
        constant boolean HERO_SELECTION_ENABLE_DEBUG_MODE   = true                  //Printout errors and check for function crashes.
 
        //Overall behavior.
        constant boolean HERO_CAN_BE_PICKED_MULTIPLE_TIMES  = false                 //Set to true if the same hero should be able to be picked multiple times.
        constant boolean AUTO_SET_SELECTING_PLAYERS         = false                 //Set to true if hero selection should be enabled for all human players. Set to false if you want to set the player list manually (which can include computer players).
        constant boolean COMPUTER_AUTO_PICK_RANDOM_HERO     = false                 //Set to true if computer players that are in hero selection should automatically pick a random hero after all human players have picked.
        constant boolean ESCAPE_PLAYER_AFTER_SELECTING      = false                 //Set to true if a player picking a hero should kick him or her out of the hero selection menu and camera.
        constant boolean CONCEAL_HERO_PICKS_FROM_ENEMIES    = false                 //Set to true if hero picks should be concealed from enemies (players in another team or all players if there are no teams), including emote, effect, and text messages.
        constant boolean MENU_INCLUDE_RANDOM_PICK           = true                  //Include button for picking a random hero at the bottom of the menu.
        constant boolean MENU_INCLUDE_SUGGEST_RANDOM        = true                  //Include button to pre-select a random hero next to the random pick button.
        constant real TIME_LIMIT                            = 60                    //Set a time limit after which players who haven't chosen a hero will be assigned one at random. Set to 0 for no time limit.
        //Camera and foreground hero positions (background hero locations are set in GetPlayerBackgroundHeroLocation).
        constant boolean SEPARATE_LOCATIONS_FOR_EACH_TEAM   = false                 //Set to true if each team gets a different selection screen (all following values will be ignored and you have to set the array equivalents in InitArrays).
        constant real FOREGROUND_HERO_X                     = 9421                  //x-Position of foreground hero.
        constant real FOREGROUND_HERO_Y                     = 9043                  //y-Position of foreground hero.
        constant real HERO_SELECTION_ANGLE                  = 0                     //Hero selection viewing direction of camera (0 = facing east, 90 = facing north etc.).
        //Visuals.
        constant boolean ENFORCE_CAMERA                     = true                  //Set to false if players' camera should not be changed during hero selection.
        constant boolean HIDE_GAME_UI                       = true                  //Set to true if all UI elements other than the hero selection menu should be hidden.
        constant boolean CREATE_FOREGROUND_HERO             = true                  //Set to false if no foreground hero should appear on preselection.
        constant boolean CREATE_BACKGROUND_HEROES           = true                  //Set to true if players should be able to see other players' picks in the background.
    endglobals
    //=================================================================================================================================
    globals
        string array CATEGORY_NAMES                         //Names of the hero categories that appear in the hero selection menu.
        integer array PAGE_OF_CATEGORY                      //Set the page at which that category appears within the menu. When there is more than one page, page cycle buttons appear in the menu.
        boolean array PLAYER_SELECTS_HERO                   //List of all players that are supposed to participate in hero selection (true = participates).
        integer array TEAM_OF_PLAYER                        //Team of player, 1, 2 etc. 0 = no teams.
        string array PLAYER_COLOR                           //Hex color string (including "|cff") for each player.
    endglobals
    function SetCategories takes nothing returns nothing
        //Set the names of the categories in the hero selection menu. Starts at index 1. Set to null for no category caption.
        set CATEGORY_NAMES[1]                       = "|cffffcc00Strength|r"
        set CATEGORY_NAMES[2]                       = "|cffffcc00Agility|r"
        set CATEGORY_NAMES[3]                       = "|cffffcc00Intelligence|r"
        set CATEGORY_NAMES[4]                       = "|cffffcc00Reborn|r"
        set CATEGORY_NAMES[5]                       = "|cffffcc00Bleach|r"
        //Set the pages of the categories in the hero selection menu. Pages start at 1.
        set PAGE_OF_CATEGORY[1]                     = 1
        set PAGE_OF_CATEGORY[2]                     = 2
        set PAGE_OF_CATEGORY[3]                     = 3
        set PAGE_OF_CATEGORY[4]                     = 4
        set PAGE_OF_CATEGORY[5]                     = 5
    endfunction
    function HeroSelectionInitPlayers takes nothing returns nothing
        //Set the list of players for which hero selection is enabled (only if AUTO_SET_SELECTING_PLAYERS = false). It is disabled here because computer players must be added to the hero selection.
        set PLAYER_SELECTS_HERO[0]                  = true
        set PLAYER_SELECTS_HERO[1]                  = true
        set PLAYER_SELECTS_HERO[2]                  = true
        set PLAYER_SELECTS_HERO[3]                  = false
        set PLAYER_SELECTS_HERO[4]                  = true
        set PLAYER_SELECTS_HERO[5]                  = true
        set PLAYER_SELECTS_HERO[6]                  = true
        set PLAYER_SELECTS_HERO[7]                  = false
        set PLAYER_SELECTS_HERO[8]                  = true
        set PLAYER_SELECTS_HERO[9]                  = true
        set PLAYER_SELECTS_HERO[10]                 = true
        set PLAYER_SELECTS_HERO[11]                 = false
 
        //Set the teams of players. Players with team 0 are enemies to all players.
        set TEAM_OF_PLAYER[0]                       = 1
        set TEAM_OF_PLAYER[1]                       = 1
        set TEAM_OF_PLAYER[2]                       = 1
        set TEAM_OF_PLAYER[3]                       = 1
        set TEAM_OF_PLAYER[4]                       = 2
        set TEAM_OF_PLAYER[5]                       = 2
        set TEAM_OF_PLAYER[6]                       = 2
        set TEAM_OF_PLAYER[7]                       = 2
        set TEAM_OF_PLAYER[8]                       = 3
        set TEAM_OF_PLAYER[9]                       = 3
        set TEAM_OF_PLAYER[10]                      = 3
        set TEAM_OF_PLAYER[11]                      = 3
    endfunction
    //=================================================================================================================================
    globals
        real array TEAM_FOREGROUND_HERO_X                   //x-Position of foreground hero.
        real array TEAM_FOREGROUND_HERO_Y                   //y-Position of foreground hero.
        real array TEAM_HERO_SELECTION_ANGLE                //Hero selection camera yaw in degrees (0 = facing east, 90 = facing north etc.).
    endglobals
    function HeroSelectionInitArrays takes nothing returns nothing
        //If you set SEPARATE_LOCATIONS_FOR_EACH_TEAM = true, initialize the above array variables here.
    endfunction
 
    function GetPlayerBackgroundHeroLocation takes integer playerIndex, integer whichSlot, integer numberOfPlayers, integer whichTeam, integer slotInTeam, integer teamSize returns location
        local real deltaHorizontal
        local real deltaVertical
        //=================================================================================================================================
        /*
        CREATE_BACKGROUND_HEROES only.
        Here you can customize the positions of the background heroes. Init loops through and calls this function for each player.
        Input:
        playerIndex
        whichSlot               The position of the player when enumerating all players for which hero selection is enabled.
        numberOfPlayers         The number of players for which hero selection is enabled.
        whichTeam               The team the player is assigned to. Discard if there are no teams.
        slotInTeam              The position of that player within his or her team. Discard if there are no teams.
        teamSize                The size of the player's team. Discard if there are no teams.
        Output:
        deltaVertical           The distance between the background hero and the camera eye position along the camera viewing direction.
        deltaHorizontal         The offset between the background hero and the camera eye position perpendicular to the camera viewing direction.
        */
        //==================================================================================================================================
        //Example code:
        local real angle
        local real dist
        local real BACKGROUND_HERO_OFFSET_BACKROW = 1425
        local real BACKGROUND_HERO_OFFSET_FRONTROW = 1250
        if teamSize == 1 then
            set angle = 9
            set dist = BACKGROUND_HERO_OFFSET_BACKROW
        elseif slotInTeam == 1 then
            set angle = 5
            set dist = BACKGROUND_HERO_OFFSET_BACKROW
        elseif slotInTeam == 2 then
            set angle = 13
            set dist = BACKGROUND_HERO_OFFSET_BACKROW
        else
            set angle = 9
            set dist = BACKGROUND_HERO_OFFSET_FRONTROW
        endif
     
        if whichTeam == 2 then
            set angle = -angle
        endif
        set deltaHorizontal = Sin(Deg2Rad(angle))*dist
        set deltaVertical = Cos(Deg2Rad(angle))*dist
        //==================================================================================================================================
        return Location(deltaHorizontal, deltaVertical)
    endfunction


    //==================================================================================================================================
    //                                                  F I N E - T U N I N G
    //==================================================================================================================================


    globals
        //How hero selection looks like before it is enabled (you can ignore this if you plan on enabling hero selection right away).
        constant boolean SHOW_MENU_BEFORE_ENABLED           = false                 //Set to true if players should be able to see the hero selection menu before hero selection is enabled.
        constant boolean PRE_SELECT_BEFORE_ENABLED          = false                 //Set to true if players should be able to pre-select heroes before hero selection is enabled.
     
        //Camera setup (ENFORCE_CAMERA).
        constant real CAMERA_PITCH                          = 12                    //Hero selection camera angle of attack in degrees. 0 = facing horizon, 90 = facing ground.
        constant real CAMERA_DISTANCE                       = 1300                  //Hero selection camera distance from camera target.
        constant real CAMERA_TARGET_OFFSET                  = 500                   //Distance between foreground hero and camera target. Positive = Camera target is behind the hero.
        constant real CAMERA_PERPENDICULAR_OFFSET           = 0                     //Shifts the camera left (negative) or right (positive) with respect to the foreground hero.
        constant real CAMERA_Z_OFFSET                       = 100                   //Hero selection camera z-offset.
        constant real CAMERA_FIELD_OF_VIEW                  = 70                    //Hero selection camera field of view.
        //Sounds and visuals of hero pre-selection (CREATE_FOREGROUND_HERO).
        constant string PRESELECT_EFFECT                    = null                  //Special effect played on the hero's position for the triggering player when switching to a new hero during pre-selection. Set to null for no effect.
        constant boolean PLAY_EMOTE_ON_PRESELECT            = true                  //Set to true if the hero should play its selection emote when the player switches to that hero during pre-selection.
        constant boolean PLAY_ANIMATION_ON_PRESELECT        = true                  //Set to true if the hero should play the selection animation when the player switches to that hero during pre-selection.
        constant boolean PHANTOM_HERO_WHEN_CANNOT_BE_PICKED = true                  //Set to true if a hero should be black and transparent when it is pre-selected but cannot be picked.
        constant real FOREGROUND_HERO_Z                     = 0                     //z-Position of foreground hero.
        //Sounds and visuals on hero pick.
        constant string PICK_EFFECT                         = "HolyLight.mdx"       //Special effect played on the hero's position for the triggering player when picking a hero. Set to null for no effect.
        constant string PICK_SOUND                          = "Sound\\Interface\\ItemReceived.flac" //Sound effect played for the triggering player when selecting a hero. Set to null for no sound.
        constant boolean PLAY_EMOTE_ON_PICK                 = false                 //Set to true if a hero should play its selection emote when a player chooses that hero.
        constant boolean PLAY_ANIMATION_ON_PICK             = false                 //Set to true if a hero should play the selection animation when a player chooses that hero.
        constant real PLAYER_PICK_ESCAPE_DELAY              = 4.0                   //Delay between selecting a hero and being kicked out of hero selection (ESCAPE_PLAY_AFTER_SELECTING only).
        constant real FOREGROUND_HERO_FADEOUT_DELAY         = 1.0                   //The time it takes for the foreground hero to start fading out after being selected.
        constant real FOREGROUND_HERO_FADEOUT_TIME          = 1.5                   //The time it takes for the foreground hero to fade out after being selected.
        constant string OTHER_PLAYER_HERO_PICK_SOUND        = "Sound\\Interface\\InGameChatWhat1.flac"  //Sound played when another player picks a hero. Set to null for no sound.
     
        //Text messages on hero pick.
        constant boolean CREATE_TEXT_MESSAGE_ON_PICK        = true                  //Set to true if a text message should be sent to all other players when a hero is picked (except to enemies when concealed).
        constant real TEXT_MESSAGE_X_OFFSET                 = 0.35                  //x-Offset of text messages from default. Text messages will still suck. Recommend using NeatMessages.
        constant real TEXT_MESSAGE_Y_OFFSET                 = 0                     //y-Offset of text messages from default.
        constant boolean USE_HERO_PROPER_NAME               = false                 //Instead of the hero's name, its proper name will be displayed in the text message. For example, "Uther" instead of "Paladin". Will temporarily create a hero to get the proper name.
        constant boolean MESSAGE_EVEN_WHEN_CONCEALED        = true                  //Set to true if players should still get a message notifying that a player has picked a hero even when it is concealed which hero was picked (CONCEAL_HERO_PICKS_FROM_ENEMIES).
        constant boolean INCLUDE_PROGRESSION_IN_MESSAGE     = false                 //Set to true if the displayed text message should include how many players have selected their hero.
        //Sounds and visuals of background heroes (CREATE_BACKGROUND_HEROES).
        constant real BACKGROUND_HERO_FADEIN_TIME           = 1.0                   //The time it takes for the background hero to fade in after being selected.
        constant boolean PLAY_EMOTE_ON_BACKGROUND_HERO      = true                  //Set to true if a hero should play its selection emote for all other players as it fades in.
        constant boolean PLAY_ANIMATION_ON_BACKGROUND_HERO  = true                  //Set to true if the background hero should play its selection animation as it fades in.
        constant string BACKGROUND_HERO_FADEIN_EFFECT       = "HolyLightRoyal.mdx"  //Special effect played on the background hero as it fades in.
        constant string BACKGROUND_HERO_SELF_HIGHLIGHT      = "RadianceHoly.mdx"    //Special effect added at the location of a player's own background hero to highlight it. Set to null for no highlight.
        constant real BACKGROUND_HERO_HIGHLIGHT_Z           = 70                    //z-Position of background hero self highlight.
        constant real BACKGROUND_HERO_FACING_POINT_OFFSET   = -500                  //Adjusts where the background heroes face. 0 = Background heroes will face the foreground hero. Negative value = Face a point closer to the camera. Positive value = Face a point further from the camera.
        constant string CONCEALED_HERO_EFFECT               = "Objects\\InventoryItems\\QuestionMark\\QuestionMark.mdl" //Model for the background hero seen by a player for which the hero pick was concealed.
        //Last player picks a hero.
        constant real LAST_PLAYER_SELECT_END_DELAY          = 6.0                   //The amount of time after the last player selects a hero and the hero selection ends (ignore if ESCAPE_PLAYER_AFTER_SELECTING)
        constant boolean DELETE_BACKGROUND_HEROES_AFTER_END = false                 //Set to false if background heroes should not get removed when hero selection ends. For example, when a player repicks, they are still there.
        //Layout of hero selection menu.
        constant integer MENU_NUMBER_OF_COLUMNS             = 2                     //Number of hero buttons per row.
        constant real MENU_X_LEFT                           = 0                     //x-Position of left edge of hero selection menu.
        constant real MENU_Y_TOP                            = 0.55                  //y-Position of top edge of hero selection menu.
        constant real MENU_BUTTON_SIZE                      = 0.039                 //Size of individual hero buttons.
        constant real MENU_LEFT_RIGHT_EDGE_GAP              = 0.02                  //Gap between left and right edges of menu and first and last buttons.
        constant real MENU_TOP_EDGE_GAP                     = 0.015                 //Gap between top edge of menu and first button/first category title.
        constant real MENU_BOTTOM_EDGE_GAP                  = 0.02                  //Gap between bottom edge of menu and last button.
        constant real MENU_BUTTON_BUTTON_GAP                = 0.005                 //Gap between two individual hero buttons.
        constant real MENU_CATEGORY_FONT_SIZE               = 16                    //Font size of category titles.
        constant real MENU_CATEGORY_GAP                     = 0.028                 //Gap between buttons of two different categories.
        constant real MENU_CATEGORY_TITLE_Y                 = -0.001                //y-Position shift between category title and center of gap between categories.
        constant real MENU_BORDER_TILE_SIZE                 = 0.03                  //This rounds up the width and height of the menu to an integer multiple of the specified number. This is useful if you're using a tiled border texture, so that there's no discontinuity in the texture.
                                                                                    //Value should be equal to BackdropCornerSize in the HeroSelectionMenu.fdf. Set to 0 to disable.
        constant real MENU_HEROES_RANDOM_GAP                = 0.02                  //Additional gap between last hero button and random pick button.
     
        //Select button.
        constant string SELECT_BUTTON_TEXT                  = "Accept"              //The text in the select hero button at the bottom of the menu.
        constant real SELECT_BUTTON_SCALE                   = 1.0                   //The scale of the select hero button at the bottom of the menu.
        constant real SELECT_BUTTON_WIDTH                   = 0.092                 //The width of the select hero button at the bottom of the menu.
        //Display of random options.
        constant string RANDOM_HERO_TOOLTIP                 = "Choose a random hero."
        constant string SUGGEST_RANDOM_TOOLTIP              = "Suggest a random hero, but don't select it just yet."
        constant string RANDOM_HERO_ICON                    = "ReplaceableTextures\\CommandButtons\\BTNRandomIncredibleIcon.blp"
        constant string SUGGEST_RANDOM_ICON                 = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp"
        constant boolean RANDOM_SELECT_CYCLE_STYLE          = true                  //Set to true if the foreground hero should cycle randomly between different heroes while random hero is pre-selected. Set to false if a question mark should be shown.
        constant real RANDOM_SELECT_CYCLE_INTERVAL          = 0.2                   //How fast the heroes are cycled through when random hero is pre-selected (RANDOM_SELECT_CYCLE_STYLE).
     
        //Layout of ability preview buttons.
        constant real HERO_ABILITY_PREVIEW_BUTTON_X         = 0.0                   //x-Position of topmost ability preview button relative to topright corner of menu.
        constant real HERO_ABILITY_PREVIEW_BUTTON_Y         = -0.016                //y-Position of topmost ability preview button relative to topright corner of menu.
        constant real HERO_ABILITY_PREVIEW_BUTTON_SIZE      = 0.025                 //The size of the hero ability preview buttons that appear on the right side of the menu when pre-selecting a hero.
        constant boolean ABILITY_BUTTON_HORIZONTAL_LAYOUT   = false                 //Set to true if ability preview buttons should be arranged horizontally instead of vertically.
        constant string HERO_ABILITY_LEVEL_DELIMITER        = " - ["                //To get the name of a hero ability without the level-text from the tooltip (such as "Stormbolt - [Level 1]" -> "Stormbolt"). This string is used to detect where the name of the ability ends. Set to null if not necessary.
        //Page cycle buttons (when multiple pages are set).
        constant real MENU_PAGE_DOWN_X                      = 0.03                  //x-Position of the page cycle down button relative to bottomleft corner of menu.                    
        constant real MENU_PAGE_DOWN_Y                      = 0.03                  //y-Position of the page cycle down button relative to bottomleft corner of menu.
        constant real MENU_PAGE_UP_X                        = 0.03                  //x-Position of the page cycle up button relative to bottomright corner of menu.
        constant real MENU_PAGE_UP_Y                        = 0.03                  //y-Position of the page cycle up button relative to bottomright corner of menu.
        constant string MENU_PAGE_DOWN_ICON                 = "ReplaceableTextures\\CommandButtons\\BTNNagaBurrow.blp"
        constant string MENU_PAGE_UP_ICON                   = "ReplaceableTextures\\CommandButtons\\BTNNagaUnBurrow.blp"
        //Display of big caption.
        constant string HERO_SELECTION_CAPTION              = "Choose your Hero!"   //The text displayed on the screen during hero selection. Set null to omit text.
        constant real CAPTION_FONT_SIZE                     = 30                    //Font size of hero selection caption.
        constant real CAPTION_X                             = 0.4                   //x-Position of caption center.
        constant real CAPTION_Y                             = 0.41                  //y-Position of caption center.
        constant string CAPTION_COLOR_1                     = "|cffffcc00"          //Caption will cycle between color 1 and color 2. Set the same for no color cycling.
        constant string CAPTION_COLOR_2                     = "|cffffffff"          //Caption will cycle between color 1 and color 2. Set the same for no color cycling.
        constant integer CAPTION_ALPHA_1                    = 255                   //Caption will cycle between alpha 1 and alpha 2. Set the same for no alpha cycling.
        constant integer CAPTION_ALPHA_2                    = 255                   //Caption will cycle between alpha 1 and alpha 2. Set the same for no alpha cycling.
        constant real CAPTION_CYCLE_TIME                    = 4.0                   //The time it takes for the caption to cycle between color 1/2 and alpha 1/2.
        constant real CAPTION_FADEOUT_TIME                  = 2.0                   //The time it takes for the caption to fade out after a player has picked a hero. Set to -1 for no fade out.
 
        //Position of hero button and ability preview button mouse-over tooltips.
        constant real TOOLTIP_LEFT_X                        = 0.51
        constant real TOOLTIP_Y                             = 0.13
        constant boolean TOOLTIP_LOCK_TOP                   = false                 //Set to true if TOOLTIP_Y should refer to top instead of bottom edge.
        constant real TOOLTIP_WIDTH                         = 0.29
        //Display of countdown timer.
        constant string TIMER_TEXT                          = "Time Remaining: |cffffcc00"  //Text before the time remaining display
        constant string TIMER_BAN_PHASE_TEXT                = "Ban Phase: |cffffcc00"       //Text before the time remaining display during the ban phase.
        constant real TIMER_FONT_SIZE                       = 11                    //Font size of the time remaining display.
        constant real TIMER_X                               = 0.4                   //x-Position of center of the time remaining display.
        constant real TIMER_Y                               = 0.59                  //y-Position of the center of the time remaining display.
        //Shadows of heroes.
        constant boolean CREATE_SHADOWS                     = false                 //Create shadows with destructables for heroes (since they are special effects and don't have shadows).
        constant integer SHADOW_DESTRUCTABLE_ID             = 'Dsha'                //Destructable id of the shadow that's created for heroes.
        constant integer NO_SHADOW_DESTRUCTABLE_ID          = 'Dnsh'                //Dummy destructable without a shadow.
    endglobals
    //=================================================================================================================================
    function HeroSelectionSetPlayerColors takes nothing returns nothing
        //Set the colors of players shown for their names in text messages.
        set PLAYER_COLOR[0]                         = "|cffff0402"
        set PLAYER_COLOR[1]                         = "|cff1052ff"
        set PLAYER_COLOR[2]                         = "|cff1BE6BA"
        set PLAYER_COLOR[3]                         = "|cff8530b1"
        set PLAYER_COLOR[4]                         = "|cfffffc00"
        set PLAYER_COLOR[5]                         = "|cffff8a0d"
        set PLAYER_COLOR[6]                         = "|cff20bf00"
        set PLAYER_COLOR[7]                         = "|cffE35BAF"
        set PLAYER_COLOR[8]                         = "|cff949697"
        set PLAYER_COLOR[9]                         = "|cff7EBFF1"
        set PLAYER_COLOR[10]                        = "|cff106247"
        set PLAYER_COLOR[11]                        = "|cff4F2B05"
        set PLAYER_COLOR[12]                        = "|cff9C0000"
        set PLAYER_COLOR[13]                        = "|cff0000C2"
        set PLAYER_COLOR[14]                        = "|cff00EBEB"
        set PLAYER_COLOR[15]                        = "|cffBE00FF"
        set PLAYER_COLOR[16]                        = "|cffECCC86"
        set PLAYER_COLOR[17]                        = "|cffF7A48B"
        set PLAYER_COLOR[18]                        = "|cffBFFF80"
        set PLAYER_COLOR[19]                        = "|cffDBB8EC"
        set PLAYER_COLOR[20]                        = "|cff4F4F55"
        set PLAYER_COLOR[21]                        = "|cffECF0FF"
        set PLAYER_COLOR[22]                        = "|cff00781E"
        set PLAYER_COLOR[23]                        = "|cffA46F34"
    endfunction
endlibrary

Sure :)

edit: I noticed
FOREGROUND_HERO_X &
FOREGROUND_HERO_Y are definitely wrong values 💀
Whats foreground hero? the hero that shows the 3d model and stuff?
 
Oh, I thought you were refering to the fact that the warden is showing up multiple times.

The buttons overlapping isn't really a bug. You have to adjust the positions of those buttons manually. It should look better if you increase MENU_BOTTOM_EDGE_GAP.

As I mentioned, the layout of the page cycle buttons is still wonky. I will make preset options instead of requiring the user to manually adjust their positions. I will also include the option to change them to text buttons.

FOREGROUND_HERO_X/Y is the position of the hero that you see when you preselect. The camera position is not the same, but shifted by CAMERA_TARGET_OFFSET.

Regarding your layout suggestions, seeing hero picks as icons on the top is something that I thought of as well. Including the option to change the random button to a text button next to the select button is also something I should be able to do easily.
 
Level 7
Joined
Sep 16, 2016
Messages
185
An update with the page cycle button style options and a few other improvements.

I still haven't figured out how one moves a complex frame like this into the widescreen area with simpleframes. Any help on this would be appreciated!
@Tasyen Perhaps you might know?
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,906
@Antares A I have some questions regarding the UI :grin:

By the way, I love the setup of the code so far, just wondering how feasible would a layout for the UI be for something like this with this system? A dropdown could also work to avoid category buttons but both would work nicely, I guess with a dropdown you save more space on the selection screen
View attachment 461709

With this, only the sound for the hero picked played for the player who picked it, so you don't hear the other unit sounds

This is one of the bugs with UI I noticed

:sad:
Player selected hero model isn't that feasible, it requires the model to have no glow, no particle emitters and a few other things.
It is kind of out of the scope for this :p
 
Level 7
Joined
Sep 16, 2016
Messages
185
I meant when you click on the frame, you create a dummy unit using that model, I think it is feasible, I have it in my current map :p But so does this system have
 
Could you perhaps add Wurst too? </3
It has been translated into all relevant languages. :ogre_hurrhurr:

I mean, what's the point of Wurst these days? You have GUI for the people who just want to throw together a map or two. You have vJASS for the people who are a bit more into programming and then you have Lua for the people who want to take the time to learn a proper language, set up their IDE etc. Where does Wurst fit into this?
 
Level 7
Joined
Sep 27, 2010
Messages
54
I have tried to add this system to my map GUI, but it does not detect the library in the trigger with the imported file, In the end the editor ends up crashing.
or if you can make a video on how to import it in GUI, please.
 
I have tried to add this system to my map GUI, but it does not detect the library in the trigger with the imported file, In the end the editor ends up crashing.
or if you can make a video on how to import it in GUI, please.
I think you need to enable the option in the editor "Automatically create unknown variables while pasting trigger data". You find it under File -> Preferences. I did that and then I copy pasted the Hero Selection parent folder and it worked for me.

Tell me if this works for you as well. Unfortunately, I'm not an expert in GUI. Just recently started translating my resources.
 

Attachments

  • unknownVariables.png
    unknownVariables.png
    116.6 KB · Views: 5
good system, i can add in my map ;D thanks
There it is again! Blizzard's decision to, for some reason, disable JassHelper by default biting us in the butt again :plol:. Glad it works now! I'll add better import instructions to the GUI version and make it easier to find. :psmile:
 
Finally figured out widescreen support. Here is version 1.3:
  • Improved GUI documentation and import instructions.
  • Enabled hero selection menu and tooltips to be put into the widescreen area. For the menu, this is done by setting MENU_X_LEFT to a negative number. The menu will automatically be adjusted for players who aren't using widescreen monitors.
  • Added the option to add player name texttags over the background heroes. The option in the config is PLAYER_TEXT_TAGS. If you have already customized the Config and don't want to overwrite it, simply add the line below to the Config under "Sounds and visuals of background heroes."
vJASS:
constant boolean PLAYER_TEXT_TAGS					= true					//Create text tags that show the players' names over the background heroes.
 
Level 6
Joined
Nov 18, 2014
Messages
25
Wow, this look great ! :eek:2
Now that I have seen that, clicking on a hero to pick him seems a bit... bland :grin:


I certainly want to add this on the map I'm working on. I have a few questions:
  • Can a player "leave" selection screen when he picked his hero without waiting the others ?
  • Can a player re-enter the selection screen without triggering selection for every player ?

And here comes the part where I'm under heavy copium
  • Could you be a fantastic developer, and add support for multiple picks ? :cute: There is a dual mode where players can pick 2 heroes, and I guess it could come handy for other maps as well. When selecting a hero, previous ones would be pushed on the side/on the back, or something like that.


Anyway, it looks neat, great job :thumbs_up:
 
Thank you!

Yes, you can have a player leave hero selection without waiting for others by setting ESCAPE_PLAYER_AFTER_SELECTING to true. There is, however, right now a potential desync associated with that setting. It should be easy enough for me to fix, I just haven't gotten to it yet.

A player can also re-enter hero selection with PlayerReturnToHeroSelection.

Regarding your request, I'd have to think about how to accomplish that. There's the "good enough" implementation, which should be doable for me in a reasonable amount of time, and then there's the perfect solution, which would need me to rewrite large chunks of the system.

I can probably modify the system so that a player can select multiple heroes and leave all the visual effects stuff up for you to deal with with the custom code you can write. I don't know, it's tough. I have to think about it.

Which language are you using?
 
Level 6
Joined
Nov 18, 2014
Messages
25
Yes, you can have a player leave hero selection without waiting for others by setting ESCAPE_PLAYER_AFTER_SELECTING to true. There is, however, right now a potential desync associated with that setting. It should be easy enough for me to fix, I just haven't gotten to it yet.
Fixing it would be great indeed. Desync are not something I want to tackle with :con:

A player can also re-enter hero selection with PlayerReturnToHeroSelection.

So, if I'm not mistaken, hero selection will be running in background for the whole game ?
Or does it "end" when every player has picked, and thus I need to restart it when a player want to return to selection ?

Regarding your request, I'd have to think about how to accomplish that. There's the "good enough" implementation, which should be doable for me in a reasonable amount of time, and then there's the perfect solution, which would need me to rewrite large chunks of the system.

I can probably modify the system so that a player can select multiple heroes and leave all the visual effects stuff up for you to deal with with the custom code you can write. I don't know, it's tough. I have to think about it.

Which language are you using?

I'm using GUI/Jass.

As I already have a (dusty and old) selection system, I can wait for a revamp to get the perfect solution :grin:
If you think it will be too hard / annoying to do, don't worry about me, I knew I was coping :xxd:
 
Fixing it would be great indeed. Desync are not something I want to tackle with :con:
I will look into it soon.

So, if I'm not mistaken, hero selection will be running in background for the whole game ?
Or does it "end" when every player has picked, and thus I need to restart it when a player want to return to selection ?
There is the DELETE_BACKGROUND_HEROES_AFTER_END option. If you disable it, the heroes that other players picked will remain after hero selection ends. If you enable it, the heroes will be removed, so if a player returns to it to repick, they will be gone, which might be undesirable.

I don't quite know what you mean with "running in background." There's no script running in the background that's draining resources, if that's what you mean, but you can choose if the effects get cleaned up or not.

As I already have a (dusty and old) selection system, I can wait for a revamp to get the perfect solution :grin:
If you think it will be too hard / annoying to do, don't worry about me, I knew I was coping :xxd:
I won't be making a perfect solution that works in all combinations of settings, but if what you need is doable in a reasonable amount of time, I'm open to it.
 
Level 6
Joined
Nov 18, 2014
Messages
25
There is the DELETE_BACKGROUND_HEROES_AFTER_END option. If you disable it, the heroes that other players picked will remain after hero selection ends. If you enable it, the heroes will be removed, so if a player returns to it to repick, they will be gone, which might be undesirable.

I don't quite know what you mean with "running in background." There's no script running in the background that's draining resources, if that's what you mean, but you can choose if the effects get cleaned up or not.

Sorry, bad choice of words here. I meant, there isn't anything reset when selection end, so you can resume it whenever you want (variable in the same state, picked heroes unavailable etc.).
As I go a bit of spare time, I played more with demo and read more of the code, and I see you have that with repick, which is perfect for me. My apologies for not seeing that earlier.

I won't be making a perfect solution that works in all combinations of settings, but if what you need is doable in a reasonable amount of time, I'm open to it.

Well, my need would be the following:
  • Being able to launch single or duo hero selection
  • In duo mode, when clicking on "accept", your hero goes on your circle, and you can select an other hero. When both hero are picked, I think the result would look like attached picture (for red).
    Malfurion being the first picked hero, Maeiv the second
    1713982848078.png
  • Repick would obviously reset both heroes and allow 2 selections again.
  • A "Both random" button would be a nice bonus too.
Aside from the duo mode, I would live to see those addition (I tried to see if they were available but couldn't find them, hope I'm not just blind :grin: )
  • Function/variable available after selection to know if players selected randomly their heroes
  • Function/variable available after selection to know if players repicked their heroes
  • An option to force random selection for all players (but still having the random animation for a few seconds before everyone leave selection), with possibility to have a forced random or free repick.

I hope I'm not too annoying :gg:
 
You have two ways to return to hero selection. In the test map, you can try out the two options on the goblin in the forest to see the difference. When you repick, you won't get the "Heroes have gathered blahblah..." text because that's triggered by BeginHeroSelection. When you restart, you get the text, because BeginHeroSelection is called again.

Doing the hero visual stuff would be a lot of work. If you can take care of those, that will be much more doable because you can just put in the numbers that you need for your specific selection screen and they don't need to make sense for every single combination of parameters someone might use.

There is currently no function to query if a hero was picked randomly or repicked. Adding those will be no problem. I'll include them in the next version!

I hope I'm not too annoying :gg:
Not at all :psmile:. It's nice that this generates some interest and I receive feedback.
 
Level 6
Joined
Nov 18, 2014
Messages
25
Doing the hero visual stuff would be a lot of work. If you can take care of those, that will be much more doable because you can just put in the numbers that you need for your specific selection screen and they don't need to make sense for every single combination of parameters someone might use.

If you can allow multiple selections via a parameters like HEROES_PER_PLAYERS, and have arrays for X and Y positions so we can tweak them and get what we want, that should be enough. No need for you to compute them all :xxd:

There is currently no function to query if a hero was picked randomly or repicked. Adding those will be no problem. I'll include them in the next version!
Great news :thumbs_up:
 
Version 1.3.2:

  • Fixed a bug that could cause a desync due hiding/showing ConsoleUIBackdrop locally.
  • Two additional arguments are passed to the HeroSelectionOnPick callback function. These are wasRandomPick and wasRepick.

To update with an already existing configuration, replace the main script as well as the HeroSelectionOnPick function (this is going to become a problem, isn't it?)
 
Top