• 🏆 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!

[vJass] Heath & Mana bar system v2.1

-------------------------------------------
**
**M A N A**
**
**B A R S**
**
**S Y S T E M**

I/ How to use and how to import
JASS:
//               H O W   T O   I M P O R T
//    1: Export LightningData.slk, nhocklanhox6-Elphis.blp, nhocklanhox6-Nyuu.blp, Elphis-Nyuu and import it into your map
//    2: Change path of LightningData.slk = Splats\LightningData.slk
//    3: Change path of nhocklanhox6-Nyuu.blp = ReplaceableTextures\Manabar\nhocklanhox6-Nyuu.blp
//    4: Change path of nhocklanhox6-Elphis.blp = ReplaceableTextures\Manabar\nhocklanhox6-Elphis.blp
//    5: Change path of Elphis-Nyuu = ReplaceableTextures\HitPointBar\Elphis-Nyuu.blp
//    WARNING: DO NOT CHANGE THIS PATH, IF YOU CHAGE THIS PATH, ALL LIGHTNING WILL CRASH
//    5: Copy trigger Mana bars and all trigger of folder Resources into your map
//    6: Read how to use
//    7: Enjoy :D
JASS:
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//         M A N A & H E A T H    B A R    S Y S T E M
//                    =======
//         System created by: 
//                           - Elphis
//                           - Special thanks to Bowser499 for help me improve this system.
//  What system does:
//                   This system allow you to create a mana bars on unit :)
//
//                   HOW TO USES:
//!                                 novjass
    struct Manabars......
    //===========================ALL ABOUT HELPING METHOD===========================
    //**This method help you to hide mana bars for player**
    method hideBarsToPlayer takes /*
    */player p /* Which player you want to hide
    */boolean hide /* Boolean hide bars
    */ returns nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToPlayer(Player(0),true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarstoPlayer(Player(0),false) /*
    //This method help to hide bars to all enemies of this player, that mean, only you and your allies can see this bars
    */method hideBarsToEnemies takes /*
    */boolean hide /* Boolean hide bars
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToEnemies(true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToEnemies(false) /*
    //This method help to hide bars to all player, that mean, only you can see this bars
    */method hideBarsAllPlayers takes /*
    */boolean hide /* Boolean hide bars
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsAllPlayers(true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsAllPlayers(false) /*
    **This method help you to destroy data and also destroy bars**
    */ method removeBars takes nothing returns nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.removeBars()
    //******************************************************************************
    //                      MAIN SYSTEM
    //******************************************************************************
    //This method add bars to unit
    static method add takes /*
    */ unit u /* Which unit you want to add
    */ real scale /* Scale (Size) of unit
    */ integer data /* Save data of bars with number, very important ( Like Hastable )
    */ boolean hpbaractivator /* Allow to create hp bar to unit
    */ boolean mpbaractivator /* Allow to create mana bar to unit
    */ boolean hidebars /* if = true, only you can see this bars 
    */ boolean hidebarsenemies /* if = true, only you and your allies can see this bars
    */ returns nothing
    //NOW FOR EXAMPLE
                    call Manabars.add(udg_u,1.,50,false,true /*that mean, only you and your allies can see this bars :)*/)
                    /*Save this bars with number 50, when you want to destroy this bars or stuff, you need to use this number*/
    //This method help you chage data of bars to another unit.
    method changeData takes /*
    */ unit u /* Which unit you want to change bars
    */ real scale /* Scale (Size) of unit
    */ integer savenumber /* With data number
    */ return nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call changeData(GetTriggerUnit(),GetHandleId(GetTriggerUnit())
    //
//!                                 endnovjass
II/ System Code:
JASS:
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//         M A N A & H E A T H    B A R     S Y S T E M
//                    =======
//         System created by: 
//                           - Elphis
//                           - Special thanks to Bowser499 for help me improve this system.
//  What system does:
//                   This system allow you to create a mana bars on unit :)
//
//                   HOW TO USES:
//!                                 novjass
    struct Manabars......
    //===========================ALL ABOUT HELPING METHOD===========================
    //**This method help you to hide mana bars for player**
    method hideBarsToPlayer takes /*
    */player p /* Which player you want to hide
    */boolean hide /* Boolean hide bars
    */ returns nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToPlayer(Player(0),true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarstoPlayer(Player(0),false) /*
    //This method help to hide bars to all enemies of this player, that mean, only you and your allies can see this bars
    */method hideBarsToEnemies takes /*
    */boolean hide /* Boolean hide bars
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToEnemies(true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToEnemies(false) /*
    //This method help to hide bars to all player, that mean, only you can see this bars
    */method hideBarsAllPlayers takes /*
    */boolean hide /* Boolean hide bars
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsAllPlayers(true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsAllPlayers(false) /*
    **This method help you to destroy data and also destroy bars**
    */ method removeBars takes nothing returns nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.removeBars()
    //******************************************************************************
    //                      MAIN SYSTEM
    //******************************************************************************
    //This method add bars to unit
    static method add takes /*
    */ unit u /* Which unit you want to add
    */ real scale /* Scale (Size) of unit
    */ integer data /* Save data of bars with number, very important ( Like Hastable )
    */ boolean hpbaractivator /* Allow to create hp bar to unit
    */ boolean mpbaractivator /* Allow to create mana bar to unit
    */ boolean hidebars /* if = true, only you can see this bars 
    */ boolean hidebarsenemies /* if = true, only you and your allies can see this bars
    */ returns nothing
    //NOW FOR EXAMPLE
                    call Manabars.add(udg_u,1.,50,false,true /*that mean, only you and your allies can see this bars :)*/)
                    /*Save this bars with number 50, when you want to destroy this bars or stuff, you need to use this number*/
    //This method help you chage data of bars to another unit.
    method changeData takes /*
    */ unit u /* Which unit you want to change bars
    */ real scale /* Scale (Size) of unit
    */ integer savenumber /* With data number
    */ return nothing /*
    //NOW FOR EXAMPLE:
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call changeData(GetTriggerUnit(),GetHandleId(GetTriggerUnit())
    //
//!                                 endnovjass
//
//
//               H O W   T O   I M P O R T
//    1: Export LightningData.slk, nhocklanhox6-Elphis.blp, nhocklanhox6-Nyuu.blp, Elphis-Nyuu and import it into your map
//    2: Change path of LightningData.slk = Splats\LightningData.slk
//    3: Change path of nhocklanhox6-Nyuu.blp = ReplaceableTextures\Manabar\nhocklanhox6-Nyuu.blp
//    4: Change path of nhocklanhox6-Elphis.blp = ReplaceableTextures\Manabar\nhocklanhox6-Elphis.blp
//    5: Change path of Elphis-Nyuu = ReplaceableTextures\HitPointBar\Elphis-Nyuu.blp
//    WARNING: DO NOT CHANGE THIS PATH, IF YOU CHAGE THIS PATH, ALL LIGHTNING WILL CRASH
//    5: Copy trigger Mana bars and all trigger of folder Resources into your map
//    6: Read how to use
//    7: Enjoy :D
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
//********************************************************************************
library Manabars/*
                                */ requires /*
                                */          CTL        /*
                                */          Table      /*
                                */          Alloc
    //
    globals
        //===================================CONFIGURATION===================================
        //***********************************SYSTEM SETTINGS*********************************
        //System Periodic
        private         constant            real            PERIODIC            =           0.031250000
        //Location you want to move when unit dead
        private         constant            real            DEAD_LOC            =           0.
        //
        //==================================NON-CONFIGURATION=================================
        private                             location        barLocation         =           Location(0.,0.)
        //
        private         constant            string          MP_MODEL            =           "ELPH"
        private         constant            string          HP_MODEL            =           "ICEF"
        private         constant            string          MP_EMPTY            =           "NYUU"
        //
        private         constant            real            Z_OFFSET            =           181.
        private         constant            real            MP_LONG             =           66.
        private         constant            real            SAFE_MP             =           20.
        private         constant            real            Z_HP_OFFSET         =           21.
        //
                                            Table           BARS_TAB
        //*************************************************************************************
    endglobals
    //====================================DO NOT CHANGE ANYTHING BELOW====================================
    struct Manabars extends array
        implement Alloc
        private boolean         release
        private unit            caster
        private integer         barsData
        private real            unitScale
        private lightning       firstLightning
        private lightning       secondLightning
        private lightning       thirdLightning
        private lightning       fourthLightning
        private static boolean   array barsHidden

        method changeData takes unit whichUnit, real newScale, integer saveNumber returns boolean
            local boolean dataExist = BARS_TAB.has(barsData)
            
            if dataExist then
                call BARS_TAB.remove(barsData)
                set unitScale          = newScale
                set caster             = whichUnit
                set BARS_TAB[barsData] = this
            else
                debug call BJDebugMsg("Can't change data.")
            endif
            
            return dataExist
        endmethod
        
        method removeBars takes nothing returns boolean
            local boolean barsRemoved = caster != null
        
            if barsRemoved then
                set release = true
                call BARS_TAB.remove(barsData)
                call DestroyLightning(firstLightning)
                call DestroyLightning(secondLightning)
                call DestroyLightning(thirdLightning)
                call DestroyLightning(fourthLightning)
                set firstLightning  = null
                set secondLightning = null
                set caster          = null
                call this.deallocate()
            else
                debug call BJDebugMsg("Can't remove bars: the unit does not exist.")
            endif

            return barsRemoved
        endmethod
        
        method isHidden takes player whichPlayer returns boolean
            return barsHidden[GetPlayerId(whichPlayer)]
        endmethod
        
        method hideBarsToPlayer takes player whichPlayer, boolean doHide returns nothing
            local real    alphaNum = 1
            local integer playerId = GetPlayerId(whichPlayer)
            
            if caster != null then
                set barsHidden[playerId] = doHide
                
                // Special case: hidden units.
                if not doHide and IsUnitHidden(caster) then
                    debug call BJDebugMsg("Can't show bars: the unit is hidden.")
                else
                    if doHide then
                        set alphaNum = 0
                    endif
                    
                    if GetLocalPlayer() == whichPlayer then
                        call SetLightningColor(firstLightning ,1.,1.,1.,alphaNum)
                        call SetLightningColor(secondLightning,1.,1.,1.,alphaNum)
                        call SetLightningColor(thirdLightning,1.,1.,1.,alphaNum)
                        call SetLightningColor(fourthLightning,1.,1.,1.,alphaNum)
                    endif  
                endif
            else
                debug call BJDebugMsg("Can't operate bars: the unit does not exist.")
            endif
        endmethod
        
        method hideBarsAllPlayers takes boolean doHide returns nothing
            local integer i           = 0
            local player  casterOwner = GetOwningPlayer(caster)
            local player  curPlayer

            if caster != null then
                loop
                    exitwhen i > 11
                    set curPlayer = Player(i)
                    call hideBarsToPlayer(curPlayer,curPlayer != casterOwner)
                    set i = i + 1
                endloop
            else
                debug call BJDebugMsg("Can't operate bars: the unit does not exist.")
            endif
        endmethod
        
        method hideBarsToEnemies takes boolean doHide returns nothing
            local integer i           = 0
            local player  casterOwner = GetOwningPlayer(caster)
            local player  curPlayer

            if caster != null then
                loop
                    exitwhen i > 11
                    set curPlayer = Player(i)
                    call hideBarsToPlayer(curPlayer,IsPlayerEnemy(curPlayer,casterOwner))
                    set i = i + 1
                endloop
            else
                debug call BJDebugMsg("Can't operate bars: the unit does not exist.")
            endif
        endmethod

            //Periodic of this system.
            implement CTL
                local real locX  = 0.
                local real locY  = 0.
                local real locZ  = 0.
                local real barX  = 0.
                local real barZ  = 0.
                local real indX  = 0.
                local real ind2X = 0.
                local real percentage
            implement CTLExpire
                if GetUnitTypeId(caster) == 0 or release then
                    call removeBars()
                elseif IsUnitType(caster,UNIT_TYPE_DEAD) then
                    call MoveLightning(firstLightning ,true,DEAD_LOC,DEAD_LOC,DEAD_LOC,DEAD_LOC)
                    call MoveLightning(secondLightning,true,DEAD_LOC,DEAD_LOC,DEAD_LOC,DEAD_LOC)
                    call MoveLightning(thirdLightning,true,DEAD_LOC,DEAD_LOC,DEAD_LOC,DEAD_LOC)
                    call MoveLightning(fourthLightning,true,DEAD_LOC,DEAD_LOC,DEAD_LOC,DEAD_LOC)
                else
                    set locX = GetWidgetX(caster)
                    set locY = GetWidgetY(caster)

                    call MoveLocation(barLocation,locX,locY)
                    
                    set locZ = GetLocationZ(barLocation)
                    
                    set percentage = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)/(bj_CAMERA_DEFAULT_DISTANCE+250)

                    set barX = locX - MP_LONG*percentage
                    set barZ = locZ + GetUnitFlyHeight(caster) + Z_OFFSET*unitScale - SAFE_MP
                    
                    set indX  = barX + percentage*MP_LONG*2*GetUnitState(caster,UNIT_STATE_MANA)/GetUnitState(caster,UNIT_STATE_MAX_MANA)
                    set ind2X = locX + MP_LONG*percentage
                    
                    call MoveLightningEx(secondLightning,true,ind2X,locY,barZ,barX,locY,barZ)
                    call MoveLightningEx(thirdLightning,true,ind2X,locY,barZ+Z_HP_OFFSET,barX,locY,barZ+Z_HP_OFFSET)
                    call MoveLightningEx(firstLightning,true,barX,locY,barZ,indX,locY,barZ)
                    call MoveLightningEx(fourthLightning,true,barX,locY,barZ+Z_HP_OFFSET,indX,locY,barZ+Z_HP_OFFSET)
                endif
            implement CTLEnd
        
        static method add takes unit u,real scale,integer data,boolean hpbaractivator,boolean mpbaractivator,boolean hidebars,boolean hidebarsenemies returns nothing
            local thistype this 
            local real     x    
            local real     y    
            local player   p    
            local integer  i    = 0
            //
            if not hpbaractivator and not mpbaractivator then
                return
            endif
            //
            if BARS_TAB.has(data) then
                debug call BJDebugMsg("Can't add bars")
            else
                set this = create()
                set p = GetOwningPlayer(u)
                //Save data with number
                set BARS_TAB[data] = this

                set caster = u
                set barsData = data
                set unitScale = scale

                set release = false

                set x = GetWidgetX(caster)
                set y = GetWidgetY(caster)
                if mpbaractivator then
                    set firstLightning  = AddLightning(MP_MODEL,true,x,y,x,y)
                    set secondLightning = AddLightning(MP_EMPTY,true,x,y,x,y)
                else
                    set firstLightning = null
                    set secondLightning = null
                endif
                //
                if hpbaractivator then
                    set thirdLightning = AddLightning(MP_EMPTY,true,x,y,x,y)
                    set fourthLightning = AddLightning(HP_MODEL,true,x,y,x,y)
                else
                    set thirdLightning = null
                    set fourthLightning = null
                endif
                if hidebars then
                    call hideBarsAllPlayers(hidebars)
                elseif hidebarsenemies then
                    call hideBarsToEnemies(hidebarsenemies)
                endif
            endif
        endmethod

        private static method onInit takes nothing returns nothing
            //Table install
            set BARS_TAB = Table.create()
        endmethod
    endstruct
endlibrary
[/HIDDEN]
III/ System Screen Shot
untit192.jpg

IV/ Credits:
Click to view CTL
Click to view ErrorMessages
Click to view Alloc
Click to view Table
-------------------------------------------


v1.0: First release version.
v1.1: Optimized, add new method, bars color changed.
v1.2: A REAL MP BARS.
v1.3: Optimized, fix method.
v1.4: Add new data.
v1.5: Optimized.
v1.6: Bugs fixed.
v1.7: Using CTL instead of TimerUtils.
v1.8: Optimized.
v1.9: Fixed the bar has incorrect height offset on uneven ground.
v1.20: - Improved changeData's method structure. It also returns a boolean now that will identify if the data was changed or not.
- Improved removeBars's method structure. It now contains a debug message if bar removal failed and also returns a boolean that will indicate such a situation.
- Optimized hideBarsToPlayer method: minimized the local data amount, making the overall code safer.
- Added isHidden method that allows to track if the bar is hidden or shown.
- Added barsHidden boolean array to the struct for tracking if the bar is hidden or shown.
- Variables got decent names.
v2.1: Hp bar added


Keywords:
mana, bars, lightning
Contents

Mana bars (Map)

Reviews
Mana bars system v1.9 | Reviewed by Maker | 19th October 2013 Concept[/COLOR]] People are always looking for ways to differentiate their maps from others. Adding customization is one way to do it an you provide a nice system that many people...

Moderator

M

Moderator


Mana bars system v1.9 | Reviewed by Maker | 19th October 2013

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

Concept[/COLOR]]
126248-albums6177-picture66521.png

People are always looking for ways to differentiate their maps from others.
Adding customization is one way to do it an you provide a nice system
that many people can find useful

There could be a health bar added to the system
Triggers[/COLOR]]
126248-albums6177-picture66521.png
  • The code is leakless an MUI
  • The code is neat and clean and efficient
126248-albums6177-picture66523.png
  • Instead of the unit group working as a boolean,
    use method has from Table
  • You could check if the unit is hidden
  • The height of the bar is bugged on flying units, but that can prove
    to be difficult to fix
Effects[/COLOR]]
126248-albums6177-picture66521.png
  • Both the empty and the full bars look sufficiently good, however
    I think they could be slightly sharper or higher resolution
Rating[/COLOR]]
CONCEPTTRIGGERSEFFECTSRATINGSTATUS
5444APPROVED

[COLOR="gray"

[/TD]



Mana bars system v1.7 | Reviewed by Maker | 18th Oct 2013
NEEDS FIX


126248-albums6177-picture66522.png


  • The bar has incorrect height offset on uneven ground
126248-albums6177-picture66523.png


  • Instead of the unit group working as a boolean,
    use method has from Table
  • You do not need to null local player p
  • Organize the checks like this
    JASS:
    if GetUnitTypeId(caster) == 0 or release then
        Remove
    elseif IsUnitType(caster,UNIT_TYPE_DEAD) then
        MoveToDeadLoc
    else
        Update
    endif
  • Don't call MoveLocation or get the x/y if you don't go to the update block
[tr]
 
It's pretty much nice idea about these bars :)
Review for v1.6.

Originality: 4.5/5. This system isn't something that can be called a breakthrough, but it's still nice idea to make custom mana bar displaying. It is handy for many players and actual for many map makers that want to make players' life a bit more easier. Talking about originality, similar system can be seen in Invasion in Duskwood map. I am also providing some examples of similar 'bar' systems:
Execution: 4.2/5. Some problems that I've pointed out:
  • Bad variable naming. Here this naming is especially bad. I think that you must read JPAG for many tips about the proper variable naming. That must help you in writing your code and making it more readable!
  • if not IsUnitType(caster,UNIT_TYPE_DEAD) and GetUnitTypeId(caster) != 0 and not release then is the bright example of very bad condition block forming. The thing is that not is an operator aswell and it consumes some resources while executing the code. In many cases you can just invert this block with else to get more performance. The correct condition must look like that: if IsUnitType(caster,UNIT_TYPE_DEAD) and GetUnitTypeId(caster) == 0 and release then Please keep it in mind. Same with if not IsUnitInGroup(u,G) then and many others.
  • I strictly advise you to use LightningUtils there. There is absolutely no need for fatal errors from this system.

Usability: 5/5. Very nice system for the map of any genre. Nothing more to say.

Overall: (4.5+4.2+5)/3 = 4.5 = 4/5. Nice and easy to use system. I can not give Highly Recommended rating because of not very clean execution there, so until it's changed and improved, I will place Recommended here.

4/5: Recommended
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
Since there is no difference between the bars (aside from their color), you could just use one lightning type, which would be white. There are natives to change the color of lightnings, so with white you'd have endless options for the bar colors (like different color for enemies, or different color of mana bars to allow custom resources, like Rage, Energy, for example). That's what I did to (but with dummy units) and it's working perfectly.

Thumbs up for the idea of using lightning effects, and for doing it in vJASS, BTW :)
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Yes I know, but somehow it looks very confusing here. The structure of the example is horrible ... But that's just my opinion.
JASS:
    method hideBarsToPlayer takes /*
    */player p /* Which player you want to hide
    */boolean hide /* Boolean hide bars
    */ returns nothing /*
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarsToPlayer(Player(0),true) /*
                        //if you want to show again
                        */ local Manabars m = BARS_TAB[<whichdata>] /*
                        */ call m.hideBarstoPlayer(Player(0),false) /*
vs
JASS:
 method hideBarsToPlayer takes player p, boolean hide returns nothing
    /*
    *   Comment (What is BARS_TAB and whichdata)
    */
    local Manabars m = BARS_TAB[<whichdata>]
    /*
    *   Comment 
    */
    call m.hideBarsToPlayer(Player(0),true)
 
Level 3
Joined
Jun 13, 2010
Messages
43
Great system, however its lacking more configuration option. For example : Unit with different scales size cause inconsistency of the hp bars/mana bars height. Make it configurable for each and different units to add their own height value of the bars
 
Level 3
Joined
May 28, 2012
Messages
32
I don't know if it's just me but the system has a little bug. If you cast a spell your manabar as well as your health bar are getting decreased.
 
Top