1. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  2. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  3. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

UI: 3x3 Custom Unit Stats

Discussion in 'The Lab' started by Tasyen, Jul 5, 2019.

  1. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    That was requested on hive discord. Its an custom UI that "hides" the default unit infos and instead shows a 3 x 3 custom stats grid. It is written in Lua (not requested but no one said otherwise). The Custom stats do also support showing Tooltips and each of the frames can be changed during the game.
    CustomStat Hero 3x3.jpg


    Code (Lua):

    --[[
    CustomStatFrame 1.2a
    By Tasyen
    That are the stuff one uses to access the customstat frames.
        CustomStatFrames.BoxS a parent for simpleframes hide it to easyly hide all of them
        CustomStatFrames.BoxF parent of the frames
        CustomStatFrames[index].Frame
        CustomStatFrames[index].FrameIcon = The icon of that CustomStat
        CustomStatFrames[index].FrameText = The Text of that CustomStat
        CustomStatFrames[index].FrameHover = Handle the mousehovering
        CustomStatFrames[index].ToolTipBox = The box of the tooltip
        CustomStatFrames[index].ToolTipTitle = The Title of the tooltip
        CustomStatFrames[index].ToolTipText = The text of the tooltip

    --]]


    CustomStatFrames = {Count = 0}
    CustomStatSelectedUnit = {}
    function CustomStatAdd(icon, text)
        CustomStatFrames.Count = CustomStatFrames.Count + 1
       
        local fh = BlzCreateSimpleFrame("CustomStat", CustomStatFrames.BoxS, CustomStatFrames.Count)
        local tooltipBox = BlzCreateFrame("BoxedText", CustomStatFrames.BoxF,0, CustomStatFrames.Count)
        local fhHover = BlzCreateFrameByType("FRAME", "CustomStatHover", CustomStatFrames.BoxF, "", CustomStatFrames.Count)
       
        BlzFrameSetPoint(fhHover, FRAMEPOINT_BOTTOMLEFT, fh, FRAMEPOINT_BOTTOMLEFT, 0, 0)
        BlzFrameSetPoint(fhHover, FRAMEPOINT_TOPRIGHT, BlzGetFrameByName("CustomStatText", CustomStatFrames.Count), FRAMEPOINT_TOPRIGHT, 0, 0)
        BlzFrameSetTooltip(fhHover, tooltipBox) --when faceHover is hovered with the mouse frame tooltip becomes visible.
       
        BlzFrameSetAbsPoint(tooltipBox, FRAMEPOINT_BOTTOM, 0.6, 0.2)
        BlzFrameSetSize(tooltipBox, 0.15, 0.08)

        BlzFrameSetText(BlzGetFrameByName("CustomStatText", CustomStatFrames.Count), text)
        BlzFrameSetText(BlzGetFrameByName("BoxedTextTitle", CustomStatFrames.Count), "TooltipTitle")
        BlzFrameSetText(BlzGetFrameByName("BoxedTextValue", CustomStatFrames.Count), text)
        BlzFrameSetTexture(BlzGetFrameByName("CustomStatIcon", CustomStatFrames.Count), icon, 0, true)
       
       
        --Dissallow having the TEXT-Tooltip-Frames gaining mouse control. This might produce problems, if the TEXT Frame has an disabled Color.
        BlzFrameSetEnable(BlzGetFrameByName("BoxedTextValue", CustomStatFrames.Count), false)
        BlzFrameSetEnable(BlzGetFrameByName("BoxedTextTitle", CustomStatFrames.Count), false)

        --[[ 4x3
        if CustomStatFrames.Count == 1 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
        elseif CustomStatFrames.Count == 5 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.375, 0.08)
        elseif CustomStatFrames.Count == 9 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.435, 0.08)
        else
            BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", CustomStatFrames.Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, 0)
        end
        --]]

        --[[ 4x4
        if CustomStatFrames.Count == 1 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
        elseif CustomStatFrames.Count == 5 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.36, 0.08)
        elseif CustomStatFrames.Count == 9 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.41, 0.08)
        elseif CustomStatFrames.Count == 13 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.46, 0.08)
        else
            BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", CustomStatFrames.Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, 0)
        end
        --]]


        --3x3
        if CustomStatFrames.Count == 1 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
        elseif CustomStatFrames.Count == 4 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.375, 0.08)
        elseif CustomStatFrames.Count == 7 then
            BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.435, 0.08)
        else
            BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", CustomStatFrames.Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, -0.005)
        end
       
        --save into table
        CustomStatFrames[CustomStatFrames.Count] = {}
        CustomStatFrames[CustomStatFrames.Count].Frame = fh
        CustomStatFrames[CustomStatFrames.Count].FrameIcon = BlzGetFrameByName("CustomStatIcon", CustomStatFrames.Count)
        CustomStatFrames[CustomStatFrames.Count].FrameText = BlzGetFrameByName("CustomStatText", CustomStatFrames.Count)
        CustomStatFrames[CustomStatFrames.Count].FrameHover = fhHover
        CustomStatFrames[CustomStatFrames.Count].ToolTipBox = tooltipBox
        CustomStatFrames[CustomStatFrames.Count].ToolTipTitle = BlzGetFrameByName("BoxedTextTitle", CustomStatFrames.Count)
        CustomStatFrames[CustomStatFrames.Count].ToolTipText = BlzGetFrameByName("BoxedTextValue", CustomStatFrames.Count)
    end

    function CustomStatUpdate()
        local isVisible = BlzFrameIsVisible(CustomStatFrames.BoxS)
       
        BlzFrameSetText(CustomStatFrames[1].FrameText, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))) --copy normal damage text
        BlzFrameSetText(CustomStatFrames[2].FrameText, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 2))) --copy normal armor field
       
        BlzFrameSetText(CustomStatFrames[6].FrameText, GetUnitMoveSpeed(CustomStatSelectedUnit[GetLocalPlayer()]))
        BlzFrameSetVisible(CustomStatFrames.BoxF, BlzFrameIsVisible(CustomStatFrames.BoxS))
    end

    function CustomStatInit()

        --move the default unit infos out of the screen and scale it down
        local function CustomStatMoveOutOfScreen(frame)
            BlzFrameClearAllPoints(frame)
            BlzFrameSetAbsPoint(frame, FRAMEPOINT_CENTER, 3, 0)
        end
        for index = 0, 5, 1 do
            CustomStatMoveOutOfScreen(BlzGetFrameByName("InfoPanelIconBackdrop", index))      
        end
        CustomStatMoveOutOfScreen(BlzGetFrameByName("InfoPanelIconHeroIcon", 6))
        CustomStatMoveOutOfScreen(BlzGetFrameByName("InfoPanelIconAllyTitle", 7))
        CustomStatMoveOutOfScreen(BlzGetFrameByName("InfoPanelIconAllyGoldIcon", 7))

        --Create a Selection Trigger thats a pretty naive approach.
        local trig = CreateTrigger()
        TriggerAddAction(trig, function () CustomStatSelectedUnit[GetTriggerPlayer()] = GetTriggerUnit() end)
       
        local index = 0
        repeat
            TriggerRegisterPlayerSelectionEventBJ(trig, Player(index), true)
            --TriggerRegisterPlayerSelectionEventBJ(trig, Player(index), false)
            index = index + 1
        until index == bj_MAX_PLAYER_SLOTS


        --create a Parent for the Stats so you can easyly hide/show them-
        --Stats use SimpleUnitStatsPanel as parent that way they are only shown when an unit is selected which does not build.
        CustomStatFrames.BoxS = BlzCreateFrameByType("SIMPLEFRAME", "CustomStatFrames.BoxSBoss", BlzGetFrameByName("SimpleUnitStatsPanel",0), "", 0)
        CustomStatFrames.BoxF = BlzCreateFrameByType("FRAME", "CustomStatFrames.BoxFBoss", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
       
       
       
        BlzLoadTOCFile("war3mapimported\\CustomStat.toc")
        BlzLoadTOCFile("war3mapimported\\BoxedText.toc")
       
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test1")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test2")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test3")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test4")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test5")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test6")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test7")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test8")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test9")
        --[[
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test10")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test11")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test12")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test13")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test14")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test15")
        CustomStatAdd(udg_UnitStatIcon[CustomStatFrames.Count + 1],"Test16")
        --]]

        TimerStart(CreateTimer(), 0.1, true, CustomStatUpdate)
        print("Done")
    end
     


    Changes:
    V1.2a The Tooltip TEXT Frames are now disabled with thay they can not fight for mouse control anymore.
    V1.2 The default UnitInfos are now moved using their Icon instead of the container Frame. Does not scale them down anymore.
     

    Attached Files:

    Last edited: Nov 2, 2019
  2. Hatuyk

    Hatuyk

    Joined:
    Jul 8, 2019
    Messages:
    2
    Resources:
    0
    Resources:
    0
    Hey Tasyen, I just made an account to thanks you for your amazing job.
    That's exactly what I was looking for. Keep going !

    If you have time I would love a JASS version I struggle trying to convert it in JASS.
     
    Last edited: Jul 8, 2019
  3. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    Added a Vjass version.
     
  4. Hatuyk

    Hatuyk

    Joined:
    Jul 8, 2019
    Messages:
    2
    Resources:
    0
    Resources:
    0
    Thanks you very much ! :)
     
  5. xorkatoss

    xorkatoss

    Joined:
    Jul 12, 2010
    Messages:
    1,602
    Resources:
    7
    Models:
    5
    Maps:
    1
    Spells:
    1
    Resources:
    7
    wow dude keep up the awesome UI stuff! If I may ask...why isn't this uploaded in the spell section?

    I'll wait for an answer before I bring down the storm of questions I have for this :p
     
  6. The_Spellweaver

    The_Spellweaver

    Joined:
    Feb 20, 2013
    Messages:
    107
    Resources:
    4
    Models:
    4
    Resources:
    4
    Ermergherd. I will use this. Thank very much for contributions
     
  7. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    Somehow I think its not ready for the spellsection. Although it should work as it is but misses in my opinion a nice hook in feature, currently one has to change the function CustomStatUpdate to show custom data.
     
  8. pOke

    pOke

    Joined:
    Mar 24, 2013
    Messages:
    1,103
    Resources:
    1
    Maps:
    1
    Resources:
    1
    I am fully updated and both the vjass and lua versions crash on test startup for me, I can open and save the map without issue
     
  9. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    That is bad, then it might crash probably for other people, too.
    You could try changing that line maybe this line inside "function MouveOutOfScreen" is more dangerous then I thought. It moves the default unit info ui out of the screen.
    Code (Lua):

    BlzFrameSetAbsPoint(fh, FRAMEPOINT_CENTER, 3, 3)
    ->
    BlzFrameSetAbsPoint(fh, FRAMEPOINT_CENTER, 0, 0)
     
     
  10. pOke

    pOke

    Joined:
    Mar 24, 2013
    Messages:
    1,103
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Sorry! It seems I gave a false alarm. Turns out I had a sound card issue causing the crash.

    Test map working correctly for me now.

    Apologize for the confusion.
     
  11. ToolorDie

    ToolorDie

    Joined:
    Jan 23, 2015
    Messages:
    155
    Resources:
    0
    Resources:
    0
    I'm gonna do some tinkering with this, looks amazing. Was hoping to make a quasi-stat for an "endurance" system, this might be it. Bit late to this party but I wanted to not replace the entire interface but just add 1x1 stat grid, that would be on every unit instead of just hero units.
     
  12. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    First you would have to thinker were you place your new stat on the screen.
    After that you have to choose how to display the new stat, should it looke like Agi/Str/Int fields (only text), like Attack/Armor infos, like the custom fields of this system or be a bar that is filled to x% or something other fancy.

    You have to save your values unit based, so you can display them when only that unit selected.
    Create the frames needed to display the custom stat.

    In this post the shown way to detect the current selected unit is quite naive, but works in single selection gameplay.
    Might be better with something like this:
    Code (Text):

    SelectedUnitsGroup = CreateGroup() --should not be destroyed
    TimerStart(CreateTimer(), 0.1, true, function()
       
        if BlzFrameIsVisible(BlzGetFrameByName("SimpleUnitStatsPanel",0)) then --Single unit  selection unit stats frame shown
            GroupEnumUnitsSelected(SelectedUnitsGroup, GetLocalPlayer(), nil) --get the units selected of the local player
            local unit = FirstOfGroup(SelectedUnitsGroup) --only the first one we need
            if unit then --unit is not null
                -- do something that can be async, like changing text of frames icons....
            end
        end
    end)
     
     
  13. ToolorDie

    ToolorDie

    Joined:
    Jan 23, 2015
    Messages:
    155
    Resources:
    0
    Resources:
    0
    Taysen!

    This is a bit off but I couldn't use tags in profile msg, sry.

    You helped me with a mana = stamina system and I am now trying to further develop it. Whereas I was using Mana, now I am using custom UI "Stamina" from your now deprecated system "MyResources" which I found more convenient for my needs.

    I need help! I'm trying to configure the same mana loss equation to the new UI Stamina but it isn't working. Attached a map, the only thing that doesn't matter is "Equipment" triggers at top.

    I got the Temperature and Fatigue to work, I am certain I can get the other fields, but "Stamina" field is very stubborn. Hope you have time, and sorry this wasn't in a better spot

    -Edit 1: Tried to clean up

    -Edit 2: So, so sorry, I connected too many systems through variables.

    *
    Only have to worry about (to the best of my ability)

    -------- My Resource bar


    >Demo >ResourceBar Changes >Stamina Change

    The stuff under >Stamina Change is all I'm worried about. Sorry for bad navigation!
     

    Attached Files:

    Last edited: Oct 16, 2019
  14. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    UDex is used inside the if - condition, but not set in the same trigger.
    Set UDex = (Custom value of (Picked unit))​

    Same with PlayerIndex, has to be set to the correct index before writing onto that array otherwise -> some random players get displayed the values.
    Set PlayerIndex = (100 x (Player number of (Owner of (Picked unit))))

    But, you should ask such map specific questions not directly connected to this Thread, in a pm/conversation or in a trigger Help Thread.
     
  15. ToolorDie

    ToolorDie

    Joined:
    Jan 23, 2015
    Messages:
    155
    Resources:
    0
    Resources:
    0
    I promise I meant to do a DM, I couldn't get my upload or link tags to work when I tried DM preview. Thank you so much
     
  16. Khaletsky

    Khaletsky

    Joined:
    Oct 13, 2017
    Messages:
    10
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Sadly first 3 vertical icons (top ones) and sometimes 2-nd vertical icons have non-stop blinking tooltip when I hover a mouse on them, can't find what I did wrong. Can you help me figure it out?
    vJass version btw
     
    Last edited: Oct 31, 2019
  17. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    Can't say anything about your code without seeing, But I think the error comes from my inefficent removage of the default Unit Infos (attack, armor, etc). The default Unit Infos are reposed quite often, when such an repos happens the default Unit Info can take over the Control of that place.
    Some time after I published this I found out that when one moves the UnitInfo Icons directly and clears their points the reposing stops.

    But I kinda think it was a misstake to remove attack and armor Unit Info, it probably would be better to compress them.

    Uploaded: V1.2 moving the Icons or the ones being relative to the container instead of the containers.
     
    Last edited: Nov 1, 2019
  18. Khaletsky

    Khaletsky

    Joined:
    Oct 13, 2017
    Messages:
    10
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Ok, I fixed it by moving tooltip up a little bit, seems like it was overlapping the actual stats and it was blinking cuz of updates. But that's my guess.
     
    Last edited: Nov 1, 2019
  19. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,721
    Resources:
    37
    Tools:
    2
    Maps:
    3
    Spells:
    11
    Tutorials:
    20
    JASS:
    1
    Resources:
    37
    Oh you are right that also could be the problem. The tooltip text can take the mouse focus which would hide itself (cause it is a tooltip only visible when a specific frame is hovered with the mouse) with that the owner would regain the focus making the tooltip visible again, that repeats and would produce that blinking. Solution either move the tooltip away or one disables the texts can be done inside the code or in fdf.

    I think that happen to me aswell when I was doing some tests with some other UI-Frame-System.
     
  20. Teo_omant

    Teo_omant

    Joined:
    Nov 4, 2019
    Messages:
    28
    Resources:
    0
    Resources:
    0
    Tasyen, hi. Im noob in jass, understand a bit. How can I make the stats appear only for the red player, and for the rest only attack and armor?