1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS/AI] UI: Creating a Bar

Discussion in 'Tutorial Submission' started by Tasyen, Jun 12, 2019.

Tags:
  1. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,441
    Resources:
    18
    Tools:
    2
    Maps:
    3
    Spells:
    8
    Tutorials:
    4
    JASS:
    1
    Resources:
    18

    What is a SIMPLESTATUSBAR


    A SIMPLESTATUSBAR is a simple frame that shows a blp texture partly (from left to right) based on the SIMPLESTATUSBAR current value vs its max value. The blp Texture is stretched to the total frames size. On default the value can be from 0 to 100 (0 beeing empty, 100 full). 40 would show 40% of the blp.
    Its also possible to have a border an overlay text and adding a background blp texture. The barTexture is above the background and will hide more of it as nearer the value is to the max value.

    Bar.jpg

    Functions



    This 3 functions are the ones you should use when alterting the bars Value.
    Code (vJASS):

    native BlzFrameSetValue takes framehandle frame, real value returns nothing
    native BlzFrameGetValue takes framehandle frame returns real
    native BlzFrameSetMinMaxValue takes framehandle frame, real minValue, real maxValue returns nothing
     

    BlzFrameSetValue
    sets the current value.
    BlzFrameGetValue
    gets the local current value
    BlzFrameSetMinMaxValue
    sets the min max values of the bar.

    You also might use
    BlzFrameSetTexture takes framehandle frame, string texFile, integer flag, boolean blend
    to change the used textures during the game.

    The Frame Definition File


    There is no mainframe SIMPLESTATUSBAR in the default fdf, aka not createable without unwanted other frames. Therefore one has to write a custom one and load that custom one over a custom written toc.
    Thats the fdf text for 3 SIMPLESTATUSBAR all beeing mainFrames. MyBarEx has a border while MyBar does not. The last has no additional features (background, border, text).
    Without the border it is more suited for Faces. One could have the idea to hide or destroy the child but that is in that case no good idea, cause it would crash the game (its a String, Texture thing when one deals with simple frames).
    TOC and FDF

    MyBar.TOC
    Code (Text):

    war3mapImported\myBar.fdf

     
    MyBar.fdf
    Code (Text):

    String "MyBarTextTemplate" {
       //FontColor 0.99 0.427 0.0705 1.0, //Red Green Blue Alpha 0.0 to 1.0
       FontColor 1.0 1.0 1.0 1.0,
       FontShadowColor 0.0 0.0 0.0 0.9,
       FontShadowOffset 0.001 -0.001,
       Font "MasterFont", 0.01, //MasterFont is only valid with "DecorateFileNames,"
    }
    Frame "SIMPLESTATUSBAR" "MyBarEx" {
       Width 0.07, //Default Width
       Height 0.012, //Default Height
       BarTexture "Replaceabletextures\Teamcolor\Teamcolor00.blp", //Default BarTexture
       Layer "BACKGROUND" { //A simpleFrames thing, where this is placed layer wise
           Texture "MyBarExBackground"{ //the BACKGROUND Texture named "MyBarExBackground" its also a frame and a child
               File "Replaceabletextures\Teamcolor\Teamcolor27.blp", //Default Texture for "MyBarExBackground"
           }
       }
       Frame "SIMPLEFRAME" "MyBarExFrame" { //Child of "MyBarEx"
           DecorateFileNames, //Lookup FileNames in a StringList
           SetAllPoints, //copy "MyBarEx"
           Layer "ARTWORK" {
               Texture "MyBarExBorder" {
                   File "SimpleXpBarBorder", //Default Texture for "MyBarExBorder"
               }
               String "MyBarExText" INHERITS "MyBarTextTemplate" {
                   Text "MyBarEx", //Default Text for "MyBarExText" which takes over Data from "MyBarTextTemplate"
               }
           }
       }
    }

    Frame "SIMPLESTATUSBAR" "MyBar" {
       Width 0.07,
       Height 0.012,
       BarTexture "Replaceabletextures\Teamcolor\Teamcolor00.blp",
       Layer "BACKGROUND" {
           Texture "MyBarBackground" {
               File "Replaceabletextures\Teamcolor\Teamcolor27.blp",
           }
       }
       Frame "SIMPLEFRAME" "MyBarFrame" {
           SetAllPoints,
           DecorateFileNames,
           Layer "ARTWORK" {
               String "MyBarText" INHERITS "MyBarTextTemplate" {
                   Text "MyBar",
               }
           }
       }
    }
    Frame "SIMPLESTATUSBAR" "MySimpleBar" {
       Width 0.07,
       Height 0.012,
    }
     

    Example MyBar


    This jass code creates 3 simpleStatusBars 2 "MyBarEx" and 1 "MyBar". The "MyBarEx" will show the % life and mana of the unit selected. "MyBar" shows the 2 background bar usage with paladin enabled and paladin disabled icon.
    Paladin 35 2 Bars.jpg
    Cause a SIMPLESTATUSBAR can only show blp one uses teamcolors to give a bar a color.
    Code (vJASS):

    function UpdateBars takes nothing returns nothing
       local unit u = GetTriggerUnit()
      call BlzFrameSetValue(BlzGetFrameByName("MyBarEx",1), GetUnitLifePercent(u)) //Load the Frame at ("MyBarEx",1) and set its value to the %HP
       call BlzFrameSetValue(BlzGetFrameByName("MyBarEx",2), GetUnitManaPercent(u))
       set u = null
    endfunction

    function MyBarCreate takes nothing returns nothing
      local framehandle bar = BlzCreateSimpleFrame("MyBarEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 1) //Create Bar at createContext 1
       local framehandle bar2 = BlzCreateSimpleFrame("MyBarEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 2) //createContext 2
      local framehandle bar4 = BlzCreateSimpleFrame("MyBar", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 4) //createContext 4, other names so would not be needed.
       call BlzFrameSetAbsPoint(bar, FRAMEPOINT_CENTER, 0.5, 0.3) // pos the bar
       call BlzFrameSetPoint(bar2, FRAMEPOINT_TOP, bar, FRAMEPOINT_BOTTOM, 0.0, 0.0) // pos bar2 below bar
       call BlzFrameSetPoint(bar4, FRAMEPOINT_BOTTOM, bar, FRAMEPOINT_TOP, 0.0, 0.0) // pos bar4 above bar
       call BlzFrameSetSize(bar4, 0.04, 0.04) //change the size of bar4

       call BlzFrameSetValue(bar4, 35) //Starting value for bar 4.

      call BlzFrameSetTexture(bar, "Replaceabletextures\\Teamcolor\\Teamcolor00.blp", 0, true) //change the BarTexture of bar to color red
       call BlzFrameSetTexture(bar2, "Replaceabletextures\\Teamcolor\\Teamcolor01.blp", 0, true) //color blue for bar2
       call BlzFrameSetTexture(bar4, "Replaceabletextures\\CommandButtons\\BTNHeroPaladin.blp", 0, true) //bar4 to Paladin-Face
      call BlzFrameSetTexture(BlzGetFrameByName("MyBarBackground",4), "Replaceabletextures\\CommandButtonsDisabled\\DISBTNHeroPaladin.blp", 0, true) //Change the background to DisabledPaladin-Face. ("MyBarBackground", 4) belongs to Bar4. would Bar4 be a "MyBarEx" one would have to write "MyBarExBackground" cause they are named differently in fdf.

       call BlzFrameSetText(BlzGetFrameByName("MyBarExText",1), "Life")
       call BlzFrameSetText(BlzGetFrameByName("MyBarExText",2), "Mana")
       call BlzFrameSetText(BlzGetFrameByName("MyBarText",4), I2S(R2I(BlzFrameGetValue(bar4)))+"%")

       call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 99999, "Select an unit to update the Bars")
    endfunction

    //===========================================================================
    function InitTrig_MyBar takes nothing returns nothing
       local trigger trig = CreateTrigger()
        set gg_trg_MyBar = CreateTrigger()
        call TriggerRegisterTimerEventSingle( gg_trg_MyBar, 0.00 )
        call TriggerAddAction( gg_trg_MyBar, function MyBarCreate )
       call BlzLoadTOCFile("war3mapimported\\mybar.toc")
       call TriggerRegisterPlayerSelectionEventBJ(trig, Player(0), true )
       call TriggerAddAction(trig, function UpdateBars)
    endfunction
     


    There is also the SimpleStatusbar_face2 map which randomly changes the face of arthas between living and deathknight.
    Code (vJASS):

    function Change takes nothing returns nothing
       local framehandle fh = BlzGetFrameByName("MyBar",0)
       call BlzFrameSetValue(fh, BlzFrameGetValue(fh) + GetRandomReal(-3,3))
       set fh = null
    endfunction
    function Trig_Nahkampf_Initialisierung_Actions takes nothing returns nothing
       local framehandle fh = BlzCreateSimpleFrame("MyBar", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0)
       call BlzFrameSetAbsPoint(fh, FRAMEPOINT_CENTER, 0.5, 0.4)
       call BlzFrameSetValue(fh, 50)
       call BlzFrameSetText(BlzGetFrameByName("MyBarText",0), "")
       call BlzFrameSetTexture(BlzGetFrameByName("MyBarBackground",0), "Replaceabletextures\\CommandButtons\\BTNHeroDeathKnight.blp", 0,true)
       call BlzFrameSetTexture(fh, "Replaceabletextures\\CommandButtons\\BTNArthas.blp", 0,true)
       call BlzFrameSetSize(fh, 0.08, 0.08)
       call TimerStart(CreateTimer(), 0.08, true, function Change)
    endfunction

    //===========================================================================
    function InitTrig_MyBar takes nothing returns nothing
        set gg_trg_MyBar = CreateTrigger(  )
        call TriggerRegisterTimerEventSingle( gg_trg_MyBar, 0.00 )
        call TriggerAddAction( gg_trg_MyBar, function Trig_Nahkampf_Initialisierung_Actions )
       call LoadToc("war3mapimported\\mybar.toc")
    endfunction
     

    ArthasFace2.gif

    It is also possible to use a white Texture and change the color of the bar using
    Code (vJASS):
    BlzFrameSetTexture(bar, "ui\\feedback\\progressbar\\human-statbar-color", 0, true)
    BlzFrameSetVertexColor(bar, BlzConvertColor(255, 255, 255, 1))
    This lines crashed for me in 1.31.1, but work fine in 1.32.1 (reforged).
     

    Attached Files:

    Last edited: Feb 12, 2020
  2. xorkatoss

    xorkatoss

    Joined:
    Jul 12, 2010
    Messages:
    1,573
    Resources:
    7
    Models:
    5
    Maps:
    1
    Spells:
    1
    Resources:
    7
    Awesome example of how to make hp/mana bars!

    Can I just leave this here for people that want the bars to show numbers? :)
    Code (vJASS):

    function UpdateBars takes nothing returns nothing
       local unit u = GetTriggerUnit()
       local string h = I2S(R2I(GetUnitStateSwap(UNIT_STATE_LIFE, u)))
       local string mh = I2S(BlzGetUnitMaxHP(u))
       local string m = I2S(R2I(GetUnitStateSwap(UNIT_STATE_MANA, u)))
       local string mm = I2S(BlzGetUnitMaxMana(u))
       call BlzFrameSetValue(BlzGetFrameByName("MyBarEx",1), GetUnitLifePercent(u))
       call BlzFrameSetValue(BlzGetFrameByName("MyBarEx",2), GetUnitManaPercent(u))
       call BlzFrameSetText(BlzGetFrameByName("MyBarExText",1), h + "/" + mh)
       call BlzFrameSetText(BlzGetFrameByName("MyBarExText",2), m + "/" + mm)
       set u = null
       set h = null
       set mh = null
       set m = null
       set mm = null
    endfunction
    p.s I'm not sure if this the best and more efficient way to do it but it gets the job done.

    HP Bar Numbers.jpg
     
  3. deepstrasz

    deepstrasz

    Map Reviewer

    Joined:
    Jun 4, 2009
    Messages:
    12,656
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Could this be converted to GUI one day? I direly hope so.
     
  4. FeelsGoodMan

    FeelsGoodMan

    Joined:
    Dec 13, 2018
    Messages:
    1,026
    Resources:
    2
    Maps:
    2
    Resources:
    2
    I dream of that too, for us normal GUI peasants.
     
  5. WyrmSlayer

    WyrmSlayer

    Joined:
    Apr 18, 2010
    Messages:
    86
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Do this hp mp bar apply for all players?
    (After changing the event of unit selecting to apply for all players?)
     
  6. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,441
    Resources:
    18
    Tools:
    2
    Maps:
    3
    Spells:
    8
    Tutorials:
    4
    JASS:
    1
    Resources:
    18
    When one would add more selection Events, then each selection would overwrite the shown value of the Frame, which is shown to everyone.
    To not have this happen one either surrounds the updating of the Frame in GetLocalPlayer so it differs or create 1 Frame for each Player and make them right after the creation invisible for other players which again needs GetLocalPlayer, but only once at the creation, not in the writing.
     
  7. Rhobox

    Rhobox

    Joined:
    Jul 31, 2019
    Messages:
    5
    Resources:
    0
    Resources:
    0
    I attempted to port this over to Lua to no avail. I have it initalize in a map init function and I've tried a very short timer (0.1s and 1s) and nothing makes the bars actually show up.

    Code (Text):

    function MyBarCreate()
        local framehandle bar = BlzCreateSimpleFrame("MyBarEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 1)
        local framehandle bar2 = BlzCreateSimpleFrame("MyBarEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 2)
        local framehandle bar4 = BlzCreateSimpleFrame("MyBar", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), 4)

        BJDebugMsg("Variables created")

        BlzFrameSetAbsPoint(bar, FRAMEPOINT_CENTER, 0.5, 0.3)
        BlzFrameSetPoint(bar2, FRAMEPOINT_TOP, bar, FRAMEPOINT_BOTTOM, 0,0, 0.0)
        BlzFrameSetPoint(bar4, FRAMEPOINT_BOTTOM, bar, FRAMEPOINT_TOP, 0.0, 0.0)
        BlzFrameSetSize(bar4, 0.04, 0.04)

        BJDebugMsg("Locations assigned")

        BlzFrameSetValue(bar4, 35)
        BJDebugMsg("Values Assigned")

        BlzFrameSetTexture(bar, "Replaceabletextures\\Teamcolor\\Teamcolor00.blp", 0, true)
        BlzFrameSetTexture(bar2, "Replaceabletextures\\Teamcolor\\Teamcolor01.blp", 0, true)
        BlzFrameSetTexture(bar4, "Replaceabletextures\\CommandButtons\\BTNHeroPaladin.blp", 0, true)
        BlzFrameSetTexture(BlzGetFrameByName("MyBarBackground", 4), "Replaceabletextures\\CommandButtonsDisabled\\DISBTNHeroPaladin.blp", 0, true)
        local framehandle fh = BlzGetFrameByName("MyBarExText",1)
        BlzFrameSetText(fh, "Life")
        fh = BlzGetFrameByName("MyBarExText",2)
        BlzFrameSetText(fh, "Mana")
        fh = BlzGetFrameByName("MyBarText",4)
        BlzFrameSetText(fh, tostring(R2I(BlzFrameGetValue(bar4))).."%")
        BJDebugMsg("Bars Initialized")
    end

    function UpdateBars()
        local unit u = GetTriggerUnit()
        BlzFrameSetValue(BlzGetFrameByName("MyBarEx", 1), GetUnitLifePercent(u))
        BlzFrameSetValue(BlzGetFrameByName("MyBarEx", 2), GetUnitManaPercent(u))
        u = nil
        BJDebugMsg("Wow!")
    end

    function InitTrig_MyBar()
        local trigger trig = CreateTrigger()
        BlzLoadTOCFile("war3mapimported\\MyBar.toc")
        TriggerRegisterPlayerSelectionEventBJ(trig, Player(0), true)
        TriggerAddAction(trig, UpdateBars)
    end
     
    For some reason it was erroring when I wasn't calling the BlzGetFrameByName outside the BlzFrameSetText area...

    If you are curious here is the other piece:
    Code (Text):

    function Initialize_Lua()
        InitTrig_MyBar()
        SpawnHero()
        InitTrig_Change_Hero_Stats()
        InitTrig_Damage_tags()
        InitTrig_Override_Damage()
        InitTrig_Prevent_Death()
    end

    TimerStart(CreateTimer(), 1.00, false, function()
        BJDebugMsg("Attempting to create bars")
        MyBarCreate()
    end)
    Hey so I found my issue. I was working on my map having it saved as a folder. This seems to have a bug where it can't save properly using the save command and it deletes the contents of said folder and creates a backup file. Saving again saves properly, however it was clearing my war3mapImported folder every time, so imports just weren't happening.

    When I no longer use the folder saves it now works fine. Thanks!
     
    Last edited by a moderator: Sep 24, 2019