• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Ultimate Hero Pick System 2.0.0.4 (vJass)

Ultimate Hero Pick System 2.0.0.4 (vJass)
Created by -Kobas-
Link to GUI version
-------------------------------------------------------------------------
Please if you find any errors or bugs report them to me so I can fix them

attachment.php

Features:
- Easy to understand/edit/import/use.
- Can be mixed with multiboard together.
- Small file size.
- Unique idea, perfect way to show people something new.
- Can support all players.


JASS:
/************************************************************************
*         Ultimate Hero Pick System
*           version: 2.0.0.4 vJass
*
* Created by: -Kobas-
* Credits: ap0calypse (custom interface models)
*          maghteridon96 (code optimization)
*          Maker (code optimization)
*          PurgeandFire111 (http://www.hiveworkshop.com/forums/jass-resources-412/system-track-205760/)
************************************************************************/

library UltimateHeroPickSystem initializer Init
    
    globals
    /* ---------- core system globals ---------- */
        private hashtable          HASH               = InitHashtable()
        private trigger            TRIG_CLICK_HERO    = CreateTrigger()
        private trigger            TRIG_CLICK_OK      = CreateTrigger()
        private trigger            TRIG_CLICK_RND     = CreateTrigger()
        private trigger            TRIG_RUN_SYSTEM    = CreateTrigger()
        private timer              CAMERA_TIMER       = CreateTimer()
        private camerasetup        CAMERA             = null
        
        /* Special Effect string shown when we click on hero icon */
        private string             SFX_CLICK          = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        /* Special Effect string shown when we create hero unit */
        private string             SFX_PICK           = "Abilities\\Spells\\Other\\Awaken\\Awaken.mdl"
        /* If set to TRUE it will allow players to pick more than 1 hero */
        private boolean            ALLOW_MULTI_PICK   = false
        /* Number of heroes we can pick in case ALLOW_MULTI_PICK = false */
        private integer            ALLOWED_HERO_NUMBER = 1
        /* Show selection to Enemies */
        private boolean            SHOW_MSG_E          = true 
        /* Show selection to Allies */
        private boolean            SHOW_MSG_A          = true 
        /* Msg shown when picked */
        private string             P_PICK             = " has choosen " 
        /* Msg shown when randomed */
        private string             P_RND              = " has randomed " 
        
        private integer      array HEROES_CREATED
        private boolean      array SYSTEM_ENABLED
        private real         array HERO_SPAWN_X
        private real         array HERO_SPAWN_Y
        private integer      array HERO_SELECTED
        private string       array COLOR
        
    /* ---------- end core system globals ---------- */
        
    /* ---------- hero ---------- */
        private integer array      HERO_ID
        private integer            HERO_COUNTER   = 0
            
        private destructable array HERO_MODEL
    /* ---------- end hero ---------- */
        
    /* ---------- stats ---------- */
        private integer      array STATS_ID
        private integer            STATS_COUNTER  = 0
            
        private texttag      array TT_NAME
        private real         array TT_NAME_X
        private real         array TT_NAME_Y
            
        private texttag      array TT_VALUE
        private real         array TT_VALUE_X
        private real         array TT_VALUE_Y
        
        private constant integer STAT_HERONAME      = 1
        private constant integer STAT_HEROCLASS     = 2
        private constant integer STAT_ATTRIBUTES    = 3
        private constant integer STAT_AGILITY       = 4
        private constant integer STAT_INTELLIGENCE  = 5
        private constant integer STAT_STRENGTH      = 6
        private constant integer STAT_STATS         = 7
        private constant integer STAT_ATTACKSPEED   = 8
        private constant integer STAT_ATTACKRANGE   = 9
        private constant integer STAT_ATTACKDAMAGE  = 10
        private constant integer STAT_ARMOR         = 11
        private constant integer STAT_MOVEMENTSPEED = 12
        private constant integer STAT_DESCRIPTION   = 13
    /* ---------- end stats ---------- */
    endglobals
    
    private function GetRealSize takes real size returns real
        return size * 0.023 / 10
    endfunction
    
    function ShowDest takes nothing returns nothing
        call ShowDestructable(GetEnumDestructable(), true)
    endfunction
    
    function HideDest takes nothing returns nothing
        call ShowDestructable(GetEnumDestructable(), false)
    endfunction

    private function ShowSystem takes player p, boolean flag returns nothing
        local integer i = 0
        if GetLocalPlayer() == p then
            if flag then
                call EnumDestructablesInRect(gg_rct_SystemRegion, null, function ShowDest)
                loop
                    exitwhen i > STATS_COUNTER
                    call SetTextTagVisibility(TT_NAME[STATS_ID[i]], true)
                    call SetTextTagVisibility(TT_VALUE[STATS_ID[i]], true)
                    call SetTextTagText(TT_VALUE[STATS_ID[i]], " ", 25.00)
                    set i = i + 1
                endloop
                set i = 0
                loop
                    exitwhen i > HERO_COUNTER
                    call ShowDestructable(HERO_MODEL[HERO_ID[i]], false)
                    set i = i + 1
                endloop
            else
                call EnumDestructablesInRect(gg_rct_SystemRegion, null, function HideDest)
                loop
                    exitwhen i > STATS_COUNTER
                    call SetTextTagVisibility(TT_NAME[STATS_ID[i]], false)
                    call SetTextTagVisibility(TT_VALUE[STATS_ID[i]], false)
                    set i = i + 1
                endloop
            endif
        endif
    endfunction
    
    private function SelectHero takes nothing returns nothing
        local integer fake_id = GetHandleId(GetTriggeringTrackable())
        local integer id = LoadInteger(HASH, fake_id, 0)
        local integer i = 0
        local integer counter = 0
        local real x = LoadReal(HASH, fake_id, 1)
        local real y = LoadReal(HASH, fake_id, 2)
        local string s = ""
        
        loop
            exitwhen counter >12
            if SYSTEM_ENABLED[counter] then
                if GetLocalPlayer() == Player(counter) then
                    set HERO_SELECTED[counter] = id
                    set s = SFX_CLICK
    
                    loop
                        exitwhen i > HERO_COUNTER
                        call ShowDestructable(HERO_MODEL[HERO_ID[i]], false)
                        set i = i + 1
                    endloop
                    call ShowDestructable(HERO_MODEL[id], true)
                    
                    set i = 0
                    loop
                        exitwhen i > STATS_COUNTER
                        call SetTextTagVisibility(TT_VALUE[STATS_ID[i]], true)
                        call SetTextTagText(TT_VALUE[STATS_ID[i]], LoadStr(HASH, id, STATS_ID[i]), GetRealSize(10))
                        set i = i + 1
                    endloop
                endif
                call DestroyEffect(AddSpecialEffect(s,x,y))
            endif
            set counter = counter + 1
        endloop
    endfunction
    
    private function RegisterTrack takes player p, integer id, real x, real y, trigger trig returns nothing
        local trackable tr 
        local integer hid
        local string s
        if GetLocalPlayer() == p then
            set s = "war3mapImported\\128x128Track.mdx"
        else
            set s = ""
        endif 
        set tr = CreateTrackable(s, x, y, 0.00)
        set hid = GetHandleId(tr)
        
        call SaveInteger(     HASH, hid, 0, id)
        call SaveReal(        HASH, hid, 1, x )
        call SaveReal(        HASH, hid, 2, y )
        call SavePlayerHandle(HASH, hid, 3, p )
        
        call TriggerRegisterTrackableHitEvent(trig, tr)
        set tr = null
    endfunction
    
    private function RegisterHeroStat takes integer hid, integer sid, string value returns nothing
        call SaveStr(HASH, hid, sid, value)
    endfunction
    
    private function RegisterHeroUnit takes integer hid, integer uid returns nothing
        call SaveInteger(HASH, hid, -666, uid)
    endfunction
    
    private function RegisterHero takes integer id, real x, real y, destructable model, integer uid returns nothing
        local integer i = 0
        
        debug if HERO_MODEL[id] != null then
            debug call BJDebugMsg("UltimateHeroPickSystem_RegisterHero [id is already used!]")
            debug return
        debug endif
        
        set HERO_ID[HERO_COUNTER] = id
        set HERO_COUNTER = HERO_COUNTER + 1
        
        set HERO_MODEL[id] = model
        
        loop
            exitwhen i>12
            call RegisterTrack(Player(i), id, x, y, TRIG_CLICK_HERO)
            set i = i + 1
        endloop
        call RegisterHeroUnit(id, uid)
        
        call ShowDestructable(model, false)
    endfunction
    
    private function RegisterStat takes integer id, string name, real x1, real y1, real size1, string value, real x2, real y2, real size2 returns nothing
        debug if TT_NAME[id] != null or TT_VALUE[id] != null then
            debug call BJDebugMsg("UltimateHeroPickSystem_RegisterStat [id is already used!]")
            debug return
        debug endif
        
        set STATS_ID[STATS_COUNTER] = id
        set STATS_COUNTER = STATS_COUNTER + 1

        if name != "" then
            set TT_NAME[id] = CreateTextTag()
            set TT_NAME_X[id] = x1
            set TT_NAME_Y[id] = y1
            call SetTextTagPos(TT_NAME[id], x1, y1, 25.00)
            call SetTextTagText(TT_NAME[id], name, GetRealSize(size1))
            call SetTextTagVisibility(TT_NAME[id], false)
        endif
         
        if value != "" then
            set TT_VALUE[id] = CreateTextTag()
            set TT_VALUE_X[id] = x2
            set TT_VALUE_Y[id] = y2
            call SetTextTagPos(TT_VALUE[id], x2, y2, 25.00)
            call SetTextTagText(TT_VALUE[id], value, GetRealSize(size2))
            call SetTextTagVisibility(TT_VALUE[id], false)
        endif
    endfunction
    
    private function PanCamera takes nothing returns nothing
        local integer i = 0
        loop 
            exitwhen i > 12
            if SYSTEM_ENABLED[i] then
                
                if GetLocalPlayer() == Player(i) then
                    call CameraSetupApply(CAMERA, true, true)
                endif
                
            endif
            set i = i + 1
        endloop
    endfunction
    
    private function RunSystem takes nothing returns nothing
        local integer id = GetPlayerId(GetTriggerPlayer())
        if HEROES_CREATED[id] >= ALLOWED_HERO_NUMBER then
            if ALLOW_MULTI_PICK then
                set SYSTEM_ENABLED[id] = true
                call ShowSystem(GetTriggerPlayer(), true)
                call TimerStart(CAMERA_TIMER, 0.03, true, function PanCamera)
            endif
        else
            set SYSTEM_ENABLED[id] = true
            call ShowSystem(GetTriggerPlayer(), true)
            call TimerStart(CAMERA_TIMER, 0.03, true, function PanCamera)
        endif
    endfunction
    
    private function CreateHero takes string hs, player p, integer id returns nothing
        local integer pid = GetPlayerId(p)
        local integer i = 0
        local real x = HERO_SPAWN_X[pid]
        local real y = HERO_SPAWN_Y[pid]
        local string s = ""
        local unit u = null
        
        if HERO_SELECTED[pid] == 0 then
            return
        endif
        
        if HEROES_CREATED[pid] < ALLOWED_HERO_NUMBER then
            set u = CreateUnit(p, LoadInteger(HASH, id, -666), x, y, 0.00)
            set HEROES_CREATED[pid] = HEROES_CREATED[pid] + 1
        endif

        if GetLocalPlayer() == p then
            call ResetToGameCamera(0.00)
            call PanCameraToTimed(x, y, 0.00)
            set s = SFX_PICK
            call SelectUnit(u, true)
        endif
        
        call DestroyEffect(AddSpecialEffect(s,x,y))
        set HERO_SELECTED[pid] = 0
        set SYSTEM_ENABLED[pid] = false

        loop
            exitwhen i > 12
                
            if IsPlayerEnemy(p, Player(i)) and SHOW_MSG_E  then
                call DisplayTimedTextToPlayer(Player(i), 0,0, 5, COLOR[i] + GetPlayerName(p) + "|r" + hs + GetUnitName(u))
            endif
            
            if IsPlayerAlly(p, Player(i)) and SHOW_MSG_A then
                call DisplayTimedTextToPlayer(Player(i), 0,0, 5, COLOR[i] + GetPlayerName(p) + "|r" + hs + GetUnitName(u))
            endif
                
            set i = i + 1
        endloop
        
        call ShowSystem(p, false)
        set u = null
    endfunction
    
    private function HitOk takes nothing returns nothing
        call CreateHero(P_PICK, LoadPlayerHandle(HASH, GetHandleId(GetTriggeringTrackable()), 3), HERO_SELECTED[GetPlayerId(LoadPlayerHandle(HASH, GetHandleId(GetTriggeringTrackable()), 3))])
    endfunction
    
    private function HitRandom takes nothing returns nothing
        call CreateHero(P_RND, LoadPlayerHandle(HASH, GetHandleId(GetTriggeringTrackable()), 3), HERO_ID[GetRandomInt(0, HERO_COUNTER)])
    endfunction
    
    private function Init takes nothing returns nothing
        local integer i = 0
        loop 
            exitwhen i > 12
            call TriggerRegisterPlayerEvent(TRIG_RUN_SYSTEM, Player(i), EVENT_PLAYER_END_CINEMATIC)
            
            call ShowSystem(Player(i), false)
            set HERO_SPAWN_X[i] = -1408.00 //X Coordinate, it's value is shown in WE bottom left corner
            set HERO_SPAWN_Y[i] = -1728.00 //Y Coordinate, it's value is shown in WE bottom left corner
            
            call RegisterTrack(Player(i), 666, -2048.00,  1536.00, TRIG_CLICK_OK)
            call RegisterTrack(Player(i), 999, -2560.00,  1536.00, TRIG_CLICK_RND)
            
            set i = i + 1
        endloop
        call TriggerAddAction(TRIG_RUN_SYSTEM, function RunSystem)
        call TriggerAddAction(TRIG_CLICK_HERO, function SelectHero)
        call TriggerAddAction(TRIG_CLICK_RND , function HitRandom)
        call TriggerAddAction(TRIG_CLICK_OK  , function HitOk)
        
        /* system camera */
        set CAMERA = gg_cam_CAMERA    
        
        /* register color codes */
        set COLOR[ 0] = "|c00FF0000" // Red Color Code
        set COLOR[ 1] = "|c000042FF" // Blue Color Code
        set COLOR[ 2] = "|c001CE6B9" // Teal Color Code
        set COLOR[ 3] = "|c00540081" // Purple Color Code
        set COLOR[ 4] = "|c00FFFC01" // Yellow Color Code
        set COLOR[ 5] = "|c00FEBA0E" // Orange Color Code
        set COLOR[ 6] = "|c0020C000" // Green Color Code
        set COLOR[ 7] = "|c00E55BB0" // Pink Color Code
        set COLOR[ 8] = "|c00959697" // Gray Color Code
        set COLOR[ 9] = "|c00FFFFBB" // Light Blue Color Code
        set COLOR[10] = "|c00FF00FF" // Dark Green Color Code
        set COLOR[11] = "|c004E2A04" // Brown Color Code
        
        /* register stats: id     name                n_x      n_y       n_s      value       v_x      v_y      v_s   */
        call RegisterStat( STAT_HERONAME      , "Hero Name:"       , -2592.00, 2368.00,  12.00, "/"        ,  -2304.00, 2368.00, 15.00)
        call RegisterStat( STAT_HEROCLASS     , "Hero Class:"      , -2592.00, 2304.00,  12.00, "/"        ,  -2304.00, 2304.00, 15.00)
        
        call RegisterStat( STAT_ATTRIBUTES    , "Attributes:"      , -2624.00, 2240.00,  12.00, ""         ,      0.00,    0.00,  0.00)
        call RegisterStat( STAT_AGILITY       , "- Agility"        , -2560.00, 2176.00,  10.00, "/"        ,  -2304.00, 2176.00, 10.00)
        call RegisterStat( STAT_INTELLIGENCE  , "- Intelligence"   , -2560.00, 2112.00,  10.00, "/"        ,  -2304.00, 2112.00, 10.00)
        call RegisterStat( STAT_STRENGTH      , "- Strength"       , -2560.00, 2048.00,  10.00, "/"        ,  -2304.00, 2048.00, 10.00)
        
        call RegisterStat( STAT_STATS         , "Stats:"           , -2624.00, 1984.00,  12.00, ""         ,      0.00,    0.00,  0.00)
        call RegisterStat( STAT_ATTACKSPEED   , "- Attack Speed"   , -2560.00, 1920.00,  10.00, "/"        ,  -2304.00, 1920.00, 10.00)
        call RegisterStat( STAT_ATTACKRANGE   , "- Attack Range"   , -2560.00, 1856.00,  10.00, "/"        ,  -2304.00, 1856.00, 10.00)
        call RegisterStat( STAT_ATTACKDAMAGE  , "- Attack Damage"  , -2560.00, 1792.00,  10.00, "/"        ,  -2304.00, 1792.00, 10.00)
        call RegisterStat( STAT_ARMOR         , "- Armor"          , -2560.00, 1728.00,  10.00, "/"        ,  -2304.00, 1728.00, 10.00)
        call RegisterStat( STAT_MOVEMENTSPEED , "- Movement Speed" , -2560.00, 1664.00,  10.00, "/"        ,  -2304.00, 1664.00, 10.00)
        
        call RegisterStat( STAT_DESCRIPTION   , "Description:"     , -1792.00, 1888.00,  12.00, "/"        ,  -1792.00, 1536.00, 10.00)
        
        /* register heroes: id   icon_x    icon_y      model        unit_raw_code  */
        call RegisterHero(  1, -3200.00 , 2432.00, gg_dest_B00D_1022, 'Hamg') // Archmage
        call RegisterHero(  2, -3072.00 , 2432.00, gg_dest_B00J_1299, 'Hblm') // Blood Mage
        call RegisterHero(  3, -2944.00 , 2432.00, gg_dest_B00C_1301, 'Hmkg') // Mountain King
        call RegisterHero(  4, -2816.00 , 2432.00, gg_dest_B00R_1302, 'Hpal') // Paladin
        call RegisterHero(  5, -3200.00 , 2304.00, gg_dest_B00U_1303, 'Obla') // Blademaster
        call RegisterHero(  6, -3072.00 , 2304.00, gg_dest_B00K_1304, 'Ofar') // Far Seer
        call RegisterHero(  7, -2944.00 , 2304.00, gg_dest_B009_1305, 'Oshd') // Shadow Hunter
        call RegisterHero(  8, -2816.00 , 2304.00, gg_dest_B00Q_1307, 'Oshd') // Tauren Chieftain
        call RegisterHero(  9, -3200.00 , 2176.00, gg_dest_B00T_1308, 'Ucrl') // Crypt Lord
        call RegisterHero( 10, -3072.00 , 2176.00, gg_dest_B00S_1309, 'Udea') // Death Knight
        call RegisterHero( 11, -2944.00 , 2176.00, gg_dest_B00P_1310, 'Udre') // Dreadlord
        call RegisterHero( 12, -2816.00 , 2176.00, gg_dest_B00G_1306, 'Ulic') // Lich
        call RegisterHero( 13, -3200.00 , 2048.00, gg_dest_B01H_1314, 'Edem') // Demon Hunter
        call RegisterHero( 14, -3072.00 , 2048.00, gg_dest_B01Y_1313, 'Ekee') // Keeper of the Grove
        call RegisterHero( 15, -2944.00 , 2048.00, gg_dest_B01Z_1312, 'Emoo') // Pristress of the Moon
        call RegisterHero( 16, -2816.00 , 2048.00, gg_dest_B020_1311, 'Ewar') // Warden
        
        /* register hero stat: hero_id, stat_id, stat_value */
        call RegisterHeroStat( 1, STAT_HERONAME      , "|cffc3dbffTenn Flamecaster")
        call RegisterHeroStat( 1, STAT_HEROCLASS     , "|cffc3dbffArchmage")
        call RegisterHeroStat( 1, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat( 1, STAT_INTELLIGENCE  , "|cffffcc0019 + 3.20|r")
        call RegisterHeroStat( 1, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat( 1, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 1, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat( 1, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 1, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 1, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 1, STAT_DESCRIPTION   , "|cffc3dbffMystical Hero, adept at ranged assaults. Can learn Blizzard, Summon Water Elemental, Brilliance Aura and Mass Teleport. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat( 2, STAT_HERONAME      , "|cffc3dbffEldin Sunstrider")
        call RegisterHeroStat( 2, STAT_HEROCLASS     , "|cffc3dbffBlood Mage")
        call RegisterHeroStat( 2, STAT_AGILITY       , "|cffc3dbff14 + 1.00")
        call RegisterHeroStat( 2, STAT_INTELLIGENCE  , "|cffffcc0019 + 3.00|r")
        call RegisterHeroStat( 2, STAT_STRENGTH      , "|cffc3dbff18 + 2.00")
        call RegisterHeroStat( 2, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 2, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat( 2, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 2, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 2, STAT_MOVEMENTSPEED , "|cffc3dbff300.00")
        call RegisterHeroStat( 2, STAT_DESCRIPTION   , "|cffc3dbffMystical Hero, adept at controlling magic and ranged assaults. Can learn Flame Strike, Banish, Siphon Mana and Phoenix. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat( 3, STAT_HERONAME      , "|cffc3dbffBor Stonebreaker")
        call RegisterHeroStat( 3, STAT_HEROCLASS     , "|cffc3dbffMountain King")
        call RegisterHeroStat( 3, STAT_AGILITY       , "|cffc3dbff11 + 1.50")
        call RegisterHeroStat( 3, STAT_INTELLIGENCE  , "|cffc3dbff15 + 1.50|r")
        call RegisterHeroStat( 3, STAT_STRENGTH      , "|cffffcc0024 + 3.00")
        call RegisterHeroStat( 3, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 3, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat( 3, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 3, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 3, STAT_MOVEMENTSPEED , "|cffc3dbff270.00")
        call RegisterHeroStat( 3, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, adept at offensive combat and disrupting enemy troops. Can learn Storm Bolt, Thunder Clap, Bash and Avatar. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat( 4, STAT_HERONAME      , "|cffc3dbffGranis Darkhammer")
        call RegisterHeroStat( 4, STAT_HEROCLASS     , "|cffc3dbffPaladin")
        call RegisterHeroStat( 4, STAT_AGILITY       , "|cffc3dbff13 + 1.50")
        call RegisterHeroStat( 4, STAT_INTELLIGENCE  , "|cffc3dbff17 + 1.80|r")
        call RegisterHeroStat( 4, STAT_STRENGTH      , "|cffffcc0022 + 2.70")
        call RegisterHeroStat( 4, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 4, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat( 4, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 4, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 4, STAT_MOVEMENTSPEED , "|cffc3dbff270.00")
        call RegisterHeroStat( 4, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, exceptional at defense and augmenting nearby friendly troops. Can learn Holy Light, Divine Shield, Devotion Aura and Resurrection. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat( 5, STAT_HERONAME      , "|cffc3dbffTojara")
        call RegisterHeroStat( 5, STAT_HEROCLASS     , "|cffc3dbffBlademaster")
        call RegisterHeroStat( 5, STAT_AGILITY       , "|cffc3dbff23 + 1.75")
        call RegisterHeroStat( 5, STAT_INTELLIGENCE  , "|cffffcc0016 + 2.25|r")
        call RegisterHeroStat( 5, STAT_STRENGTH      , "|cffc3dbff18 + 2.00")
        call RegisterHeroStat( 5, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 5, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat( 5, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 5, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 5, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 5, STAT_DESCRIPTION   , "|cffc3dbffCunning Hero, adept at quickly killing individual units and creating confusion among enemies. Can learn Mirror Image, Wind Walk, Critical Strike and Bladestorm. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat( 6, STAT_HERONAME      , "|cffc3dbffGar'dal Grimsight")
        call RegisterHeroStat( 6, STAT_HEROCLASS     , "|cffc3dbffFar Seer")
        call RegisterHeroStat( 6, STAT_AGILITY       , "|cffc3dbff18 + 1.00")
        call RegisterHeroStat( 6, STAT_INTELLIGENCE  , "|cffffcc0019 + 3.00|r")
        call RegisterHeroStat( 6, STAT_STRENGTH      , "|cffc3dbff15 + 2.00")
        call RegisterHeroStat( 6, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 6, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat( 6, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 6, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 6, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 6, STAT_DESCRIPTION   , "|cffc3dbffMystical Hero, effective at ranged attacks and scouting. Can learn Chain Lightning, Far Sight, Feral Spirit and Earthquake. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat( 7, STAT_HERONAME      , "|cffc3dbffZul'kis")
        call RegisterHeroStat( 7, STAT_HEROCLASS     , "|cffc3dbffShadow Hunter")
        call RegisterHeroStat( 7, STAT_AGILITY       , "|cffffcc0017 + 1.00")
        call RegisterHeroStat( 7, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat( 7, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat( 7, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 7, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat( 7, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 7, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 7, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 7, STAT_DESCRIPTION   , "|cffc3dbffCunning Hero, adept at healing magics and voodoo curses. Can learn Healing Wave, Hex, Serpent Ward and Big Bad Voodoo. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat( 8, STAT_HERONAME      , "|cffc3dbffMarn Thunderhorn")
        call RegisterHeroStat( 8, STAT_HEROCLASS     , "|cffc3dbffTauren Chieftain")
        call RegisterHeroStat( 8, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat( 8, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat( 8, STAT_STRENGTH      , "|cffffcc0014 + 1.80")
        call RegisterHeroStat( 8, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 8, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat( 8, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 8, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 8, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 8, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, exceptional at absorbing damage and melee combat. Can learn Shockwave, War Stomp, Endurance Aura and Reincarnation. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat( 9, STAT_HERONAME      , "|cffc3dbffThebis-Ra")
        call RegisterHeroStat( 9, STAT_HEROCLASS     , "|cffc3dbffCrypt Lord")
        call RegisterHeroStat( 9, STAT_AGILITY       , "|cffffcc0017 + 1.00")
        call RegisterHeroStat( 9, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat( 9, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat( 9, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat( 9, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat( 9, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat( 9, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat( 9, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat( 9, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, adept at summoning insect minions and crushing enemies. Can learn Impale, Spiked Carapace, Carrion Beetles and Locust Swarm. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat(10, STAT_HERONAME      , "|cffc3dbffLord Nightsorrow")
        call RegisterHeroStat(10, STAT_HEROCLASS     , "|cffc3dbffDeath Knight")
        call RegisterHeroStat(10, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat(10, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat(10, STAT_STRENGTH      , "|cffffcc0014 + 1.80")
        call RegisterHeroStat(10, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(10, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat(10, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(10, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(10, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(10, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, evil counterpart to the Human Paladin. Can learn Death Coil, Death Pact, Unholy Aura, and Animate Dead. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat(11, STAT_HERONAME      , "|cffc3dbffTerrordar")
        call RegisterHeroStat(11, STAT_HEROCLASS     , "|cffc3dbffDreadlord")
        call RegisterHeroStat(11, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat(11, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat(11, STAT_STRENGTH      , "|cffffcc0014 + 1.80")
        call RegisterHeroStat(11, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(11, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat(11, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(11, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(11, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(11, STAT_DESCRIPTION   , "|cffc3dbffCunning Hero, adept at controlling combat. Can learn Carrion Swarm, Sleep, Vampiric Aura, and Inferno. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat(12, STAT_HERONAME      , "|cffc3dbffOrdin Frostbane")
        call RegisterHeroStat(12, STAT_HEROCLASS     , "|cffc3dbffLich")
        call RegisterHeroStat(12, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat(12, STAT_INTELLIGENCE  , "|cffffcc0019 + 3.20|r")
        call RegisterHeroStat(12, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat(12, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(12, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat(12, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(12, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(12, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(12, STAT_DESCRIPTION   , "|cffc3dbffMystical Hero, particularly adept at cold magic. Can learn Frost Armor, Frost Nova, Dark Ritual and Death And Decay. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat(13, STAT_HERONAME      , "|cffc3dbffShadowsong")
        call RegisterHeroStat(13, STAT_HEROCLASS     , "|cffc3dbffDemon Hunter")
        call RegisterHeroStat(13, STAT_AGILITY       , "|cffffcc0017 + 1.00")
        call RegisterHeroStat(13, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat(13, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat(13, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(13, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat(13, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(13, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(13, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(13, STAT_DESCRIPTION   , "|cffc3dbffCunning Hero, adept at maneuvering through battles. Can learn Immolation, Evasion, Mana Burn, and Metamorphosis. |n|n|cffffcc00Attacks land units.|r")
        
        call RegisterHeroStat(14, STAT_HERONAME      , "|cffc3dbffLarodar")
        call RegisterHeroStat(14, STAT_HEROCLASS     , "|cffc3dbffKeeper of the Grove")
        call RegisterHeroStat(14, STAT_AGILITY       , "|cffc3dbff17 + 1.00")
        call RegisterHeroStat(14, STAT_INTELLIGENCE  , "|cffffcc0019 + 3.20|r")
        call RegisterHeroStat(14, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat(14, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(14, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat(14, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(14, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(14, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(14, STAT_DESCRIPTION   , "|cffc3dbffMystical Hero, adept at using nature spells. Can learn Entangling Roots, Force of Nature, Thorns Aura, and Tranquility. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat(15, STAT_HERONAME      , "|cffc3dbffKathris Starsong")
        call RegisterHeroStat(15, STAT_HEROCLASS     , "|cffc3dbffPristress of the Moon")
        call RegisterHeroStat(15, STAT_AGILITY       , "|cffffcc0017 + 1.00")
        call RegisterHeroStat(15, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat(15, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat(15, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(15, STAT_ATTACKRANGE   , "|cffc3dbff600.00")
        call RegisterHeroStat(15, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(15, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(15, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(15, STAT_DESCRIPTION   , "|cffc3dbffWarrior Hero, adept at enhancing ranged attacks and slaying enemies from afar. Can learn Scout, Searing Arrows, Trueshot Aura, and Starfall. |n|n|cffffcc00Attacks land and air units.|r")
        
        call RegisterHeroStat(16, STAT_HERONAME      , "|cffc3dbffAlsa Iron-cell")
        call RegisterHeroStat(16, STAT_HEROCLASS     , "|cffc3dbffWarden")
        call RegisterHeroStat(16, STAT_AGILITY       , "|cffffcc0017 + 1.00")
        call RegisterHeroStat(16, STAT_INTELLIGENCE  , "|cffc3dbff19 + 3.20|r")
        call RegisterHeroStat(16, STAT_STRENGTH      , "|cffc3dbff14 + 1.80")
        call RegisterHeroStat(16, STAT_ATTACKSPEED   , "|cffc3dbff2.13")
        call RegisterHeroStat(16, STAT_ATTACKRANGE   , "|cffc3dbff128.00 |cffffcc00(melee)")
        call RegisterHeroStat(16, STAT_ATTACKDAMAGE  , "|cffc3dbff21 - 27 |cffffcc00(Hero)")
        call RegisterHeroStat(16, STAT_ARMOR         , "|cffc3dbff3 |cffffcc00(Hero)")
        call RegisterHeroStat(16, STAT_MOVEMENTSPEED , "|cffc3dbff320.00")
        call RegisterHeroStat(16, STAT_DESCRIPTION   , "|cffc3dbffCunning Hero, adept at entering and escaping combat. Can learn Blink, Fan of Knives, Shadow Strike and Vengeance. |n|n|cffffcc00Attacks land units.|r")
    endfunction
endlibrary

Change Log

Version 1.0
- Uploaded Spell
Version 1.1
- Removed some useless variables
- Added some more documentation
Version 1.2
- Replaced vJass Globals with User Defined Globals (udg)
- Added some more documentation
Version 1.3
- Fixed bug with fast clicking and choosing few heroes at once
- Replaced location variables with coordinates (X and Y)
- Removed some useless lines of code
- Added 3 new Icons (Heroes) to pick (Tauren Chieftain, Dreadlord, Far Seer)
- Few more small changes
Version 1.4
- Fixed that Settings trigger
Version 1.5
- Some optimization
Version 2.0.0.0
- Jass -> vJass
- Replaced huge and bad code with fast and optimized one
- Works for all players
Version 2.0.0.1
- Added Magtheridon96 suggestion for constant globals
Version 2.0.0.2
- Some basic optimization
- globals are now all UPERCASE
- Added MSG display
Version 2.0.0.3
- You can now enable disable multi hero pick
Version 2.0.0.4
- Fixed: If I select Pick hero when no hero has been selected, a special effect is still created.
- Fixed: I can get two heroes if I click random really quickly
Keywords:
Advanced, vJass, Hero, Pick, System, -Kobas-, Interface, Triggers
Contents

Ultimate Hero Pick System (Map)

Reviews
23:43 Dec 7, 2012 Magtheridon96: Approved. Wonderful. =) If you would like an extended review, feel free to PM me.

Moderator

M

Moderator

23:43 Dec 7, 2012
Magtheridon96: Approved.
Wonderful. =)

If you would like an extended review, feel free to PM me.
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
Well, I did not go through the whole system, just a few things, much likely "first impressions":

1, First of all, this is vJASS, not JASS, cuz you're using a globals/endglobals block -> this requires a JASSHelper to compile. So you should get rid of those multiple triggers and merge them all and place everything inside a library. It'd look way better.

2, Sweet tutorial directly from Bribe.

3, Don't use locations. NEVER. Use pure X/Y/Z coords. Each native that uses locations have a non-location version that uses X/Y coords (just like CreateUnitAtLoc and CreateUnit)

4, Use TriggerAddCondition instead of TriggerAddAction

JASS:
function Act takes nothing returns boolean
    ...
    return false
endfunction

function InitTrig_UHPS_Start takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerAddCondition(t,Filter(Act))
endfunction

5, If you merge everything as I said in point #1, use proper data encapsulation. Use private functions with proper names, use library initializers, etc.

I think that's all for now.
 
First of all, this is vJASS, not JASS, cuz you're using a globals/endglobals block -> this requires a JASSHelper to compile. So you should get rid of those multiple triggers and merge them all and place everything inside a library. It'd look way better.
It will look better but it won't be so useful.
I don't care about code beauty here, just like I explained this few times for GUI version.
This here is supposed to show people how system can look like and how easily can be edited. Each new icon, each new system edit will require large number of modifications, easy ones, but still large number of them. For each new hero we need to add like 20 lines of code.
Don't use locations. NEVER. Use pure X/Y/Z coords. Each native that uses locations have a non-location version that uses X/Y coords (just like CreateUnitAtLoc and CreateUnit )
Thanks for info, will improve this.
You still use units :O
I prefer units over trackables, you can always edit unit name into some text just like I did . Nice message can be displayed when you place mouse over it. With tracks you are forced to use floating text, and that will remove nice border and increase number of variables, lines of code etc etc.
Also newbie coders will find units more easier for usage than trackables, you don't need different models imported, you can easily set edit unit dimensions like this as well.
you can still see unit selection circle
Only bad thing, but I can live with it.
Structs for Dummies
Thanks, I already saw that, but honestly I don't like vJass.
Dunno why, maybe because no one showed it to me.

I can use udg variables if globals bother you?
 
-Kobas- said:
I can use udg variables if globals bother you?

and add a trigger which has those globals in GUI for those who don't want to create it themselves...

I'll definitely look at this on the WE... I love the way you used units, especially those texts when you hover over the hero icons...
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
^ this. Also:

- Replaced location variables with coordinates (X and Y)

JASS:
// This code is simple system addon, created to show you how powerful it can be.
function Interface_Human takes nothing returns nothing
    local integer ID = GetDestructableTypeId(GetEnumDestructable())
    local location l = Location(GetDestructableX(GetEnumDestructable()), GetDestructableY(GetEnumDestructable()))
    //   -  Night Elf       - Orc          - Undead
    if ID == 'B01Q' or ID == 'B014' or ID == 'B019'then
        call CreateDestructable('B01I', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01R' or ID == 'B015' or ID == 'B01A' then
        call CreateDestructable('B01J', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01S' or ID == 'B016' or ID == 'B01B' then
        call CreateDestructable('B01K', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01T' or ID == 'B017' or ID == 'B01C' then
        call CreateDestructable('B01L', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01U' or ID == 'B018' or ID == 'B01D' then
        call CreateDestructable('B01M', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01V' or ID == 'B013' or ID == 'B01E' then
        call CreateDestructable('B01N', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01W' or ID == 'B012' or ID == 'B01F' then
        call CreateDestructable('B01O', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01X' or ID == 'B011' or ID == 'B01G' then
        call CreateDestructable('B01P', GetLocationX(l), GetLocationY(l), 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    endif
    call RemoveLocation (l)
    set l = null
endfunction

:vw_wtf:
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Optimization continues (this will be a bit long):

Dont inline TriggerRegisterAnyUnitEventBJ - this only increases size of your map.
JASS:
function CreateTrack takes real X, real Y, integer Id, trigger T, integer UnitID returns nothing
    local integer i = 0
    set udg_UHPS_BUTTON[Id] = CreateUnit(Player(12),UnitID,X,Y,0)
    call SetUnitVertexColor(udg_UHPS_BUTTON[Id],255,255,255,0)
    loop
    exitwhen i>11
        call TriggerRegisterPlayerUnitEvent(T, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
        set i = i+1
    endloop
endfunction
->>
JASS:
function CreateTrack takes real X, real Y, integer Id, trigger T, integer UnitID returns nothing
    set udg_UHPS_BUTTON[Id] = CreateUnit(Player(12),UnitID,X,Y,0)
    call SetUnitVertexColor(udg_UHPS_BUTTON[Id],255,255,255,0)
    call TriggerRegisterAnyUnitEventBJ(T,EVENT_PLAYER_UNIT_SELECTED)
endfunction

Trigger 'UHPS Setup' leaks timers:set udg_UHPS_CAMERA_TIMER[i] = CreateTimer()Remove RegisterEvent(int). Global arrays for ints are by default equal to 0, while booleans favourite 'false'.
JASS:
    loop
        exitwhen i > 11
        call RegisterEvent(i)
        set udg_UHPS_SFX1[i] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        set udg_UHPS_SFX2[i] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
        set udg_UHPS_CAMERA_TIMER[i] = CreateTimer()
        set udg_UHPS_SYSTEM_BOOLEAN[i] = false
        set udg_UHPS_PICKEDHERO[i] = 0
        set udg_UHPS_TXTTAG[i] = CreateTextTag()
        call SetTextTagPos(udg_UHPS_TXTTAG[i],udg_UHPS_STATSX[i],udg_UHPS_STATSY[i],100)
        call SetTextTagText(udg_UHPS_TXTTAG[i],"",0.025)
        call TriggerRegisterTimerExpireEvent(gg_trg_UHPS_Camera_Loop, udg_UHPS_CAMERA_TIMER[i])
        call TriggerRegisterPlayerUnitEvent(gg_trg_UHPS_Click, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
        set i = i + 1
    endloop
endfunction
->>
JASS:
    loop
        exitwhen i > 11
        call TriggerRegisterPlayerChatEvent( gg_trg_UHPS_Start, Player(i), "xxx", true )
        call TriggerRegisterPlayerEvent(gg_trg_UHPS_Start, Player(i), EVENT_PLAYER_END_CINEMATIC)
        set udg_UHPS_SFX1[i] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        set udg_UHPS_SFX2[i] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
        if udg_UHPS_CAMERA_TIMER[i] == null then
            set udg_UHPS_CAMERA_TIMER[i] = CreateTimer()
        endif
        set udg_UHPS_TXTTAG[i] = CreateTextTag()
        call SetTextTagPos(udg_UHPS_TXTTAG[i],udg_UHPS_STATSX[i],udg_UHPS_STATSY[i],100)
        call SetTextTagText(udg_UHPS_TXTTAG[i],"",0.025)
        call TriggerRegisterTimerExpireEvent(gg_trg_UHPS_Camera_Loop, udg_UHPS_CAMERA_TIMER[i])
        set i = i + 1
    endloop
    call TriggerRegisterAnyUnitEventBJ(gg_trg_UHPS_Click, EVENT_PLAYER_UNIT_SELECTED)
endfunction
Trigger 'UHPS Start' - Instead of TriggerAddAction use TriggerAddCondition; basically use conditions everywhere. However if you're going call TriggerExecute(the Start trigger here) than leave the AddActions.

Things like: 0.00 ->> 0.; 0.10 ->> 0.1

Global triggers in your system can be mostly replaced by local triggers which deprecate them.

Trigger UHPS Settin Button:
JASS:
GetDestructableX()    ->>    GetWidgetX()
GetDestructableY()    ->>    GetWidgetY()
Don't you think that spamming GetSoldUnit() and multiple other functions in each line is a bit.. floopy and inefficient? Your functions in that trigger owns soooo many elseifs that... crap, fuck that; rewrite it!

1) UHPS_Settings_Button_Actions:
Use global array int and store those Ids into it at the begining. Those effects too.. This applys to first part of your trigg, but I'm pretty sure that with some formula usage all the Orc/Human/NE/UD and 1st part of function below can be combined into tiny trigg. Meaby I'll try to figure out some usefull formula for you.
JASS:
    elseif GetUnitTypeId(GetSoldUnit()) == 'h007' then
        set udg_UHPS_SFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        set udg_UHPS_SFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h008' then
        set udg_UHPS_SFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl"
        set udg_UHPS_SFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h009' then
        set udg_UHPS_SFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
        set udg_UHPS_SFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h00A' then
        set udg_UHPS_SFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
        set udg_UHPS_SFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    endif
endfunction
Throw that (I assume you've used globa array idea):
JASS:
function UHPS_Settings_Button_Actions takes nothing returns nothing
    local integer i=0
    local unit u = GetSoldUnit()    // that one you need anyways
    local integer id = GetUnitTypeId(u)    // omg this one too >.<
    
    // here are the first 4 'ifs/elseifs'

    endif
    loop
        exitwhen i>3
        if id == IDS[i] then
            set id = i
            set i = 3
        endif
        set i = i+1
    endloop
    if id<4 then
        call RemoveUnit(u)
        set i = GetPlayerId(GetOwningPlayer(u))
        set udg_UHPS_SFX1[i] = SFX[2*id]
        set udg_UHPS_SFX2[i] = SFX[2*id+1]
    endif
    set u = null
endfunction
^Asuming that: IDS[0] = 'h007'; IDS[1] = 'hoo8' etc. while:
SFX[0] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
SFX[1] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
etc..

Trigger UHPS, function UHPS_Click_Actions - you've forgotten to null handles? D;
JASS:
function UHPS_Click_Actions takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local integer P = GetPlayerId(p)
    local integer i = GetRandomInt(1,udg_UHPS_MAXHERO)
    local unit hero
    //Hero Icon 1
    if  GetTriggerUnit() == udg_UHPS_BUTTON[1]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(1,p)
    
    //Hero Icon 2
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[2]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(2,p) 
     
    //Hero Icon 3
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[3]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(3,p)
        
    //Hero Icon 4
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[4]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(4,p)
        
    //Hero Icon 5
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[5]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(5,p)
        
    //Hero Icon 6
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[6]  then
        call SelectUnit(GetTriggerUnit(),false)
        call UHPS_Hero_Icon(6,p)

    //------------------------------------------
    //TEMP BUTTON
    //COPY AND PASTE, COPY AND PASTE this function for each new button
    //JUST BE SURE THAT YOU USE SAME BUTTON ID LIKE IN SETUP TRIGGER, HERE FOR EXAMPLE xxx
    //elseif GetTriggerUnit() == udg_UHPS_BUTTON[xxx]  then
    //    call SelectUnit(GetTriggerUnit(),false)
    //    call UHPS_Hero_Icon(xxx,p)
    //------------------------------------------
    
    //Random
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[99] then 
        call SelectUnit(GetTriggerUnit(),false)
        set udg_UHPS_SYSTEM_BOOLEAN[GetPlayerId(p)] = false
        call DisableTrigger(GetTriggeringTrigger())
        call TriggerSleepAction(0)
        set hero = CreateUnit(p,udg_UHPS_HEROTYPE[i],udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
        if GetLocalPlayer() == p then
            call SelectUnit(hero, true)
            call ResetToGameCamera(0)
            call PanCameraToTimed(udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
            call AttachSoundToUnit(udg_UHPS_SOUND2[i], hero)
            call SetSoundVolume(udg_UHPS_SOUND2[i], 270)
            call StartSound(udg_UHPS_SOUND2[i])
            call DestroyEffect(AddSpecialEffect(udg_UHPS_SFX2,udg_UHPS_SPAWNX,udg_UHPS_SPAWNY))
            call EnumDestructablesInRect(gg_rct_SystemRegion, null,function UHPS_Visibilty_D_OFF)
            call ForGroup(udg_UHPS_G, function UHPS_Visibilty_U_OFF)
            call UHPS_Visibility_F_OFF()
        endif
        call TriggerSleepAction(1)
        call EnableTrigger(GetTriggeringTrigger())
        
    //OK
    elseif GetTriggerUnit() == udg_UHPS_BUTTON[100] then 
        call SelectUnit(GetTriggerUnit(),false)
        set udg_UHPS_SYSTEM_BOOLEAN[GetPlayerId(p)] = false
        call DisableTrigger(GetTriggeringTrigger())
        call TriggerSleepAction(0)
        set hero = CreateUnit(p,udg_UHPS_HEROTYPE[udg_UHPS_PICKEDHERO],udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
        if GetLocalPlayer() == p then
            call SelectUnit(hero, true)
            call ResetToGameCamera(0)
            call PanCameraToTimed(udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
            call AttachSoundToUnit(udg_UHPS_SOUND2[udg_UHPS_PICKEDHERO], hero)
            call SetSoundVolume(udg_UHPS_SOUND2[udg_UHPS_PICKEDHERO], 270)
            call StartSound(udg_UHPS_SOUND2[udg_UHPS_PICKEDHERO])
            call DestroyEffect(AddSpecialEffect(udg_UHPS_SFX2,udg_UHPS_SPAWNX,udg_UHPS_SPAWNY))
            call EnumDestructablesInRect(gg_rct_SystemRegion, null,function UHPS_Visibilty_D_OFF)
            call ForGroup(udg_UHPS_G, function UHPS_Visibilty_U_OFF)
            call UHPS_Visibility_F_OFF()
        endif
        call TriggerSleepAction(1)
        call EnableTrigger(GetTriggeringTrigger())
    endif
endfunction
->>
JASS:
function UHPS_Click_Actions takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local integer P = GetPlayerId(p)
    local integer i = 1
    local boolean b = false
    local unit u = GetTriggerUnit()
    loop
        exitwhen i>6
        if u == udg_UHPS_BUTTON[i] then
            call SelectUnit(u,false)
            call UHPS_Hero_Icon(i,p)
            return
        endif
        set i = i+1
    endloop
    if u == udg_UHPS_BUTTON[99] then
       set b = true
       set i = GetRandomInt(1,udg_UHPS_MAXHERO)
    elseif u == udg_UHPS_BUTTON[100] then
       set b = true
       set i = udg_UHPS_PICKEDHERO
    endif
    if b then
        call SelectUnit(u,false)
        set udg_UHPS_SYSTEM_BOOLEAN = false
        call DisableTrigger(GetTriggeringTrigger())
        call TriggerSleepAction(0)
        set bj_lastCreatedUnit = CreateUnit(p,udg_UHPS_HEROTYPE[i],udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
        if GetLocalPlayer() == p then
            call SelectUnit(bj_lastCreatedUnit, true)
            call ResetToGameCamera(0)
            call PanCameraToTimed(udg_UHPS_SPAWNX,udg_UHPS_SPAWNY,0)
            call AttachSoundToUnit(udg_UHPS_SOUND2[i], bj_lastCreatedUnit)
            call SetSoundVolume(udg_UHPS_SOUND2[i], 270)
            call StartSound(udg_UHPS_SOUND2[i])
            call DestroyEffect(AddSpecialEffect(udg_UHPS_SFX2,udg_UHPS_SPAWNX,udg_UHPS_SPAWNY))
            call EnumDestructablesInRect(gg_rct_SystemRegion, null,function UHPS_Visibilty_D_OFF)
            call ForGroup(udg_UHPS_G, function UHPS_Visibilty_U_OFF)
            call UHPS_Visibility_F_OFF()
        endif
        call TriggerSleepAction(1)
        call EnableTrigger(GetTriggeringTrigger())
    endif
    set u = null
    set p = null
endfunction
^I wasn't checking that in game but hope you get the idea ;p Waits aren't best option too; timers, timers!

There are probably more improvements, but at first lets see, how your code gonna work this shit above (=

Good approach tho ;P
MOVE EVERYTHING INTO ONE TRIGGER SAYS THE COMMUNITY!
 
Last edited:
Thats a bullshit. If someone makes his own system in one trigger then thats the problem, if not then that is. You still can copy trigger directories so no problem with portability.

>_>
Not when you know how to organize your code right.
Comments and whitespace should be used to increase readability.
In it's current state, it's very messy and unreadable.

edit
Kobas, you should avoid using underscores in function names because that's against Jass convention.
The only case where underscores are used in function names is when you create a public function and JassHelper converts it's name to this: LibraryName_FunctionName()
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
That's mostly because GUI is limited to its built-in BJ's (Bad JASS'es) (there are some GUI system out there tho', but not that much), while JASS and vJASS have tons of libraries to choose from, you can use different data structures, libraries and stuffs to write your own system.
 
can you tell me song name ? (i am sorry for offtopic but i really like the song)
Two Steps From Hell - All Drones Go To Hell: Full Length: 09 Dreams of the Seven.mp3

call TriggerRegisterPlayerUnitEvent(T, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
You are right. But this code line show for what player you want it triggered. You will easily split this or remove few players. Point is to be more easier to work with, even for GUI users, that want to enchant their code with few lines of script.

Global arrays for ints are by default equal to 0, while booleans favourite 'false'.
True. Sorry, I forgot to edit this after switching from globals to user defined globals.
Will fix only this, that register trigger even is explained above.

I won't quote code below. But I get your point.
I will fix some things but keep some other.

And last thing, about timers and wait, it is added there to remove bug when you click few times in a row and spawn few heroes, also 0.5 sec delay (more or less) before clicking on another button isn't really such problem, you won't read info so fast or move cursor over screen (I don't care about 100% accurate value).

Kobas, you should avoid using underscores in function names because that's against Jass convention.
The only case where underscores are used in function names is when you create a public function and JassHelper converts it's name to this: LibraryName_FunctionName()
Because of user defined globals I just wanted to make sure that my variables won't mix with any other.
Is this really problem, spell mod?

It looks fucking good,but my favorite is still the system of maps Rise Of Winterchill
Thanks, maybe I decide to add few more things into multiboard and change your mind :razz:

And don't worry about the amount of suggestions. Not your fault really, it's more like 'judging GUI - i dont care , judging jass/vjass/zinc - omg change this that there here ...'
Jassing makes ppl more carefull before they upload something, ofcourse only if you don't want see half of coding community throwing suggestions here and there, telling how bad your shit actually looks like D;
I use jass it will be month or so. And honestly I don't really care, each programmer has it's own style. Ofc there are rules that we all most fallow, but I won't change my system much just because some epic coders find it "less effective", after all this isn't created for them, they can code this easily, ofc if they have idea, this is created for newbies and all people here somewhere that want to create something unique and cool. And 1 last thing I don't care about rating or mark, but I do care about fame. Sorry if I acted arrogant, that wasn't my intention.

I hope that I didn't missed anything.
 
:mad:

JASS:
// This code is simple system addon, created to show you how powerful it can be.
function Interface_Human takes nothing returns nothing
    local integer ID = GetDestructableTypeId(GetEnumDestructable())
    local real x = GetWidgetX(GetEnumDestructable())
    local real y = GetWidgetY(GetEnumDestructable())
    //   -  Night Elf       - Orc          - Undead
    if ID == 'B01Q' or ID == 'B014' or ID == 'B019'then
        call CreateDestructable('B01I', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01R' or ID == 'B015' or ID == 'B01A' then
        call CreateDestructable('B01J', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01S' or ID == 'B016' or ID == 'B01B' then
        call CreateDestructable('B01K', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01T' or ID == 'B017' or ID == 'B01C' then
        call CreateDestructable('B01L', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01U' or ID == 'B018' or ID == 'B01D' then
        call CreateDestructable('B01M', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01V' or ID == 'B013' or ID == 'B01E' then
        call CreateDestructable('B01N', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01W' or ID == 'B012' or ID == 'B01F' then
        call CreateDestructable('B01O', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01X' or ID == 'B011' or ID == 'B01G' then
        call CreateDestructable('B01P', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    endif
endfunction

function Interface_Night_Elf takes nothing returns nothing
    local integer ID = GetDestructableTypeId(GetEnumDestructable())
    local real x = GetWidgetX(GetEnumDestructable())
    local real y = GetWidgetY(GetEnumDestructable())
    //   -  Human       - Orc          - Undead
    if ID == 'B01I' or ID == 'B014' or ID == 'B019'then
        call CreateDestructable('B01Q', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01J' or ID == 'B015' or ID == 'B01A' then
        call CreateDestructable('B01R', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01K' or ID == 'B016' or ID == 'B01B' then
        call CreateDestructable('B01S', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01L' or ID == 'B017' or ID == 'B01C' then
        call CreateDestructable('B01T', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01M' or ID == 'B018' or ID == 'B01D' then
        call CreateDestructable('B01U', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01N' or ID == 'B013' or ID == 'B01E' then
        call CreateDestructable('B01V', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01O' or ID == 'B012' or ID == 'B01F' then
        call CreateDestructable('B01W', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01P' or ID == 'B011' or ID == 'B01G' then
        call CreateDestructable('B01X', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    endif
endfunction

function Interface_Orc takes nothing returns nothing
    local integer ID = GetDestructableTypeId(GetEnumDestructable())
    local real x = GetWidgetX(GetEnumDestructable())
    local real y = GetWidgetY(GetEnumDestructable())
    //   -  Human       - Night Elf          - Undead
    if ID == 'B01I' or ID == 'B01Q' or ID == 'B019'then
        call CreateDestructable('B014', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01J' or ID == 'B01R' or ID == 'B01A' then
        call CreateDestructable('B015', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01K' or ID == 'B01S' or ID == 'B01B' then
        call CreateDestructable('B016', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01L' or ID == 'B01T' or ID == 'B01C' then
        call CreateDestructable('B017', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01M' or ID == 'B01U' or ID == 'B01D' then
        call CreateDestructable('B018', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01N' or ID == 'B01V' or ID == 'B01E' then
        call CreateDestructable('B013', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01O' or ID == 'B01W' or ID == 'B01F' then
        call CreateDestructable('B012', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01P' or ID == 'B01X' or ID == 'B01G' then
        call CreateDestructable('B011', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    endif
endfunction

function Interface_Undead takes nothing returns nothing
    local integer ID = GetDestructableTypeId(GetEnumDestructable())
    local real x = GetWidgetX(GetEnumDestructable())
    local real y = GetWidgetY(GetEnumDestructable())
    //   -  Human       - Orc          - Night Elf
    if ID == 'B01I' or ID == 'B014' or ID == 'B01Q'then
        call CreateDestructable('B019', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01J' or ID == 'B015' or ID == 'B01R' then
        call CreateDestructable('B01A', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01K' or ID == 'B016' or ID == 'B01S' then
        call CreateDestructable('B01B', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01L' or ID == 'B017' or ID == 'B01T' then
        call CreateDestructable('B01C', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01M' or ID == 'B018' or ID == 'B01U' then
        call CreateDestructable('B01D', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01N' or ID == 'B013' or ID == 'B01V' then
        call CreateDestructable('B01E', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01O' or ID == 'B012' or ID == 'B01W' then
        call CreateDestructable('B01F', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    elseif ID == 'B01P' or ID == 'B011' or ID == 'B01X' then
        call CreateDestructable('B01G', x, y, 0.00, 1, 0)
        call RemoveDestructable(GetEnumDestructable())
    endif
endfunction

function UHPS_Settings_Button_Actions takes nothing returns nothing
    if GetUnitTypeId(GetSoldUnit()) == 'h002' then
        if GetLocalPlayer() == GetOwningPlayer(GetSoldUnit()) then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Human)
        endif
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h003' then
        if GetLocalPlayer() == GetOwningPlayer(GetSoldUnit()) then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Night_Elf)
        endif
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h004' then
        if GetLocalPlayer() == GetOwningPlayer(GetSoldUnit()) then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Orc)
        endif
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h005' then
        if GetLocalPlayer() == GetOwningPlayer(GetSoldUnit()) then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Undead)
        endif
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h007' then
        set udg_UHPSSFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        set udg_UHPSSFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h008' then
        set udg_UHPSSFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl"
        set udg_UHPSSFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h009' then
        set udg_UHPSSFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
        set udg_UHPSSFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    elseif GetUnitTypeId(GetSoldUnit()) == 'h00A' then
        set udg_UHPSSFX1[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
        set udg_UHPSSFX2[GetPlayerId(GetOwningPlayer(GetSoldUnit()))] = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        call RemoveUnit(GetSoldUnit())
    endif
endfunction

//===========================================================================
function InitTrig_UHPS_Settings_Button takes nothing returns nothing
    set gg_trg_UHPS_Settings_Button = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_UHPS_Settings_Button, EVENT_PLAYER_UNIT_SELL )
    call TriggerAddAction( gg_trg_UHPS_Settings_Button, function UHPS_Settings_Button_Actions )
endfunction

->

JASS:
// This code is simple system addon, created to show you how powerful it can be.
function Interface_Human takes nothing returns nothing
    local destructable u = GetEnumDestructable()
    local integer ID = GetDestructableTypeId(u)
    local real x = GetWidgetX(u)
    local real y = GetWidgetY(u)
    
    //   -  Night Elf       - Orc          - Undead
    if ID == 'B01Q' or ID == 'B014' or ID == 'B019'then
        call CreateDestructable('B01I', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01R' or ID == 'B015' or ID == 'B01A' then
        call CreateDestructable('B01J', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01S' or ID == 'B016' or ID == 'B01B' then
        call CreateDestructable('B01K', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01T' or ID == 'B017' or ID == 'B01C' then
        call CreateDestructable('B01L', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01U' or ID == 'B018' or ID == 'B01D' then
        call CreateDestructable('B01M', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01V' or ID == 'B013' or ID == 'B01E' then
        call CreateDestructable('B01N', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01W' or ID == 'B012' or ID == 'B01F' then
        call CreateDestructable('B01O', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01X' or ID == 'B011' or ID == 'B01G' then
        call CreateDestructable('B01P', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    endif
    
    set u = null
endfunction

function Interface_Night_Elf takes nothing returns nothing
    local destructable u = GetEnumDestructable()
    local integer ID = GetDestructableTypeId(u)
    local real x = GetWidgetX(u)
    local real y = GetWidgetY(u)
    
    //   -  Human       - Orc          - Undead
    if ID == 'B01I' or ID == 'B014' or ID == 'B019'then
        call CreateDestructable('B01Q', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01J' or ID == 'B015' or ID == 'B01A' then
        call CreateDestructable('B01R', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01K' or ID == 'B016' or ID == 'B01B' then
        call CreateDestructable('B01S', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01L' or ID == 'B017' or ID == 'B01C' then
        call CreateDestructable('B01T', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01M' or ID == 'B018' or ID == 'B01D' then
        call CreateDestructable('B01U', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01N' or ID == 'B013' or ID == 'B01E' then
        call CreateDestructable('B01V', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01O' or ID == 'B012' or ID == 'B01F' then
        call CreateDestructable('B01W', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01P' or ID == 'B011' or ID == 'B01G' then
        call CreateDestructable('B01X', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    endif
    
    set u = null
endfunction

function Interface_Orc takes nothing returns nothing
    local destructable u = GetEnumDestructable()
    local integer ID = GetDestructableTypeId(u)
    local real x = GetWidgetX(u)
    local real y = GetWidgetY(u)
    
    //   -  Human       - Night Elf          - Undead
    if ID == 'B01I' or ID == 'B01Q' or ID == 'B019'then
        call CreateDestructable('B014', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01J' or ID == 'B01R' or ID == 'B01A' then
        call CreateDestructable('B015', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01K' or ID == 'B01S' or ID == 'B01B' then
        call CreateDestructable('B016', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01L' or ID == 'B01T' or ID == 'B01C' then
        call CreateDestructable('B017', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01M' or ID == 'B01U' or ID == 'B01D' then
        call CreateDestructable('B018', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01N' or ID == 'B01V' or ID == 'B01E' then
        call CreateDestructable('B013', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01O' or ID == 'B01W' or ID == 'B01F' then
        call CreateDestructable('B012', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01P' or ID == 'B01X' or ID == 'B01G' then
        call CreateDestructable('B011', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    endif
    
    set u = null
endfunction

function Interface_Undead takes nothing returns nothing
    local destructable u = GetEnumDestructable()
    local integer ID = GetDestructableTypeId(u)
    local real x = GetWidgetX(u)
    local real y = GetWidgetY(u)
    
    //   -  Human       - Orc          - Night Elf
    if ID == 'B01I' or ID == 'B014' or ID == 'B01Q'then
        call CreateDestructable('B019', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01J' or ID == 'B015' or ID == 'B01R' then
        call CreateDestructable('B01A', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01K' or ID == 'B016' or ID == 'B01S' then
        call CreateDestructable('B01B', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01L' or ID == 'B017' or ID == 'B01T' then
        call CreateDestructable('B01C', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01M' or ID == 'B018' or ID == 'B01U' then
        call CreateDestructable('B01D', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01N' or ID == 'B013' or ID == 'B01V' then
        call CreateDestructable('B01E', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01O' or ID == 'B012' or ID == 'B01W' then
        call CreateDestructable('B01F', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    elseif ID == 'B01P' or ID == 'B011' or ID == 'B01X' then
        call CreateDestructable('B01G', x, y, 0.00, 1, 0)
        call RemoveDestructable(u)
    endif
    
    set u = null
endfunction

function UHPSSettingsButtonActions takes nothing returns nothing
    local unit u = GetSoldUnit()
    local integer i = GetUnitTypeId(u)
    local player p = GetOwningPlayer(u)
    local integer k = GetPlayerId(p)
    
    if i == 'h002' then
        if GetLocalPlayer() == p then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Human)
        endif
        call RemoveUnit(u)
    elseif i == 'h003' then
        if GetLocalPlayer() == p then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Night_Elf)
        endif
        call RemoveUnit(u)
    elseif i == 'h004' then
        if GetLocalPlayer() == p then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Orc)
        endif
        call RemoveUnit(u)
    elseif i == 'h005' then
        if GetLocalPlayer() == p then
            call EnumDestructablesInRect(gg_rct_SystemRegion, null, function Interface_Undead)
        endif
        call RemoveUnit(u)
    elseif i == 'h007' then
        set udg_UHPSSFX1[k] = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
        set udg_UHPSSFX2[k] = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
        call RemoveUnit(u)
    elseif i == 'h008' then
        set udg_UHPSSFX1[k] = "Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl"
        set udg_UHPSSFX2[k] = "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl"
        call RemoveUnit(u)
    elseif i == 'h009' then
        set udg_UHPSSFX1[k] = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
        set udg_UHPSSFX2[k] = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
        call RemoveUnit(u)
    elseif i == 'h00A' then
        set udg_UHPSSFX1[k] = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
        set udg_UHPSSFX2[k] = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
        call RemoveUnit(u)
    endif
    
    set u = null
    set p = null
endfunction

function InitTrig_UHPS_Settings_Button takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SELL)
    call TriggerAddCondition(t, Condition(function UHPSSettingsButtonActions))
    set t = null
endfunction
 
yeah an array or a hash would shorten that code tremendously...

Maggy, you know that with some additional array globals this whole elseif spam would be cleaned up ;<

I know, but before I tell him to use a hashtable, I need him to know that spamming functions like that is bad and slow :p

-Kobas-, you'd save the ID of the destructable you're going to create inside a hashtable with the key of the ID variable you're checking those Interface_ functions.


Your function would become like this:

JASS:
function Interface_Night_Elf takes nothing returns nothing
    local destructable u = GetEnumDestructable()
    
    call CreateDestructable(LoadInteger(udg_InterHash, GetDestructableTypeId(u), 0), GetWidgetX(u), GetWidgetY(u), 0.00, 1, 0)
    call RemoveDestructable(u)
    
    set u = null
endfunction

That's a HUGE improvement :D

Kudos to Adiktuz and Spinnaker for forcing me to do this xD
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
I have seen many other systems like this.. That all were the videos and photos only. But in fact they're totally weird I think!!! The interface was totally bad. Not like in the photo that you give... I don't know what's wrong with my pc but i think mine is normal. The models are not shown when I click any hero button.
But just keep going on! :) Good job..
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Ah, but that's so creative... There's a dialog box when we hover at the hero button.. That's cool.. Actually the interface or skin is not really important here.. The important is the system.. And you made it!
:goblin_yeah:
Rep++
_________________________________________
Oh and the model preview doesn't display too.. I think the resolution isn't the problem here....
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
You could disable entering the selection screen if the player already has a hero. You could consider repick option.

I'm not a fan of using a terrain type for the black. It limits the number of tiles available. Instead, try:
JASS:
local image i = CreateImage("Textures\\Black32.blp", 2000, 2000, 0, -3300, 1400, 0, 0, 0, 0, 2)
call SetImageRenderAlways(i , true)

And then show/hide it locally.

The 2000, 2000 is the width (x) and height (y). The -3300 and 1400 are the coordinates of the lower left corner of the image. 2 is image type. Don't use 1, since that gets drawn over effects I believe. You can test 3 and 4 also, but I believe 2 should work.

I can select the unit in the screen are, when not in the screen mode. I can get more heroes.

gg_trg_UHPS_Camera_Setup trigger loops even when no units are in the screen. That is a no-no.

Add call CameraSetupApplyForceDuration(udg_UHPSCamera, true, 0) to function Trig_UHPS_Progress_Actions so the camera pans instantly, and not over 0.1 seconds when the player enter the screen.

If I select Pick hero when no hero has been selected, a special effect is still created.

That's all for now, I'll take a look at the coding some more later. Keep on improving this, it is a great system.
 
Hmmmmm I started working on this once again, because lately a lot of people asked from me edited GUI version.

New one will be coded in vJass and so far code looks far more easier and faster than this one.
In just 1 day I re-coded 90% of whole system, simple library replaced all those triggers and shits.
Hmmm only thing left is to setup each hero, store stats and other values into variables and so on, but it should be finished in no time.
I will create GUI trigger as well so you can easily edit this even if you don't know jass.

It has 16 heroes, 1 interface for all players, you can still use multiboard with this, basic setup and so on...
 
Top