Steel
Software Engineer
- Reaction score
- 109
Version History:
Version 2.4:
-Greatly Simplified Code
-Fixed a string concatenation issue causing the system to crash
Version 2.3:
-Better map cleanup
-Better unit indexation
-Added in function RemoveBarUnit
-Modified existing functions for better leak / crash protection
-Split Gradient functions and Floating Bars into separate libraries
-Speed optimized
Version 2.2:
-Map properly cleans memory leaks.
-Mana bar properly disappears.
-Changed the syntax for AddBar, it takes in a boolean now. Example: call AddBar(u, true). The boolean of true or false tells the function if we want the mana bar added or not.
-Combined the Config trigger with the globals with the main structure of the system
Version 2.1:
-Map now tracks mana.
Version 2.0:
-Initial Release
FAQ
Q: Can this work for heroes/specific units exclusively?
A: Yes! You as the user determine which units have the bars above them. Please read the How to Use section below. It will be very useful.
Q: What is use? The game can have health bars already!
A: This was originally designed to show the HP bar without having to hold alt. The WC3 Engine now supports showing the health bar forever, but my system now also shows mana above the unit. You also are not required to have both the health and mana bar, you can have just the mana bar shown without the health. It's up to you.
Q: How does it work?
A: This system uses the ability of structs to house information. The older system used handles which made it very slow. This new system is much faster since it uses globals. The system doesn't use multiple timers to track each texttag, this is highly inefficient and extremely slow. The system uses 1 timer that traverses over every unit in the array and updates the texttags this way.
Requirements
-vJASS
Implementation
Step 1a - Copy the Category Floating Bars
Step 1b - Paste what you just copied into your map
Step 1c - Save your Map, any compile errors mean that you have pasted improperly or you do not use vJASS
Advanced Users Only
Step 2a - You can change the variables in the Configurables if you know how they will react
Functions to Use:
You should only ever use the following 2 functions
Basic Users:
AddBar(u, life, mana)
RemoveBarUnit(u)
Advanced Users:
function Addbar takes unit u, boolean life, boolean mana returns nothing
function RemoveBarUnit takes unit u returns boolean //If boolean returns false, unit is not found and it has no bars on it.
AddBar will create a bar ontop of the unit you deem. The boolean life and mana tell the system what you want to track.
For example say we just created a unit, you want to track the unit's life and mana you would do this DIRECTLY after you create the unit
//Track the last created unit's life and mana
call AddBar(bj_lastCreatedUnit, true, true)
//Track the last created unit's mana only
call AddBar(bj_lastCreatedUnit, false, true)
//Track the last created unit's life only
call AddBar(bj_lastCreatedUnit, true, false)
Starting to see the picture?
Now that you know how to add a bar, let me show you how to Add a bar....lets remove:
call RemoveBarUnit(GetTriggerUnit())
Very simple.
Floating Bars v2.4
Gradient v2.4
Screenshot:
Download Me (v2.4)!
Download Me (v2.3)!
Download Me (v2.2)!
Download Me (v2.1)!
Download Me (v2.0)!
Version 2.4:
-Greatly Simplified Code
-Fixed a string concatenation issue causing the system to crash
Version 2.3:
-Better map cleanup
-Better unit indexation
-Added in function RemoveBarUnit
-Modified existing functions for better leak / crash protection
-Split Gradient functions and Floating Bars into separate libraries
-Speed optimized
Version 2.2:
-Map properly cleans memory leaks.
-Mana bar properly disappears.
-Changed the syntax for AddBar, it takes in a boolean now. Example: call AddBar(u, true). The boolean of true or false tells the function if we want the mana bar added or not.
-Combined the Config trigger with the globals with the main structure of the system
Version 2.1:
-Map now tracks mana.
Version 2.0:
-Initial Release
FAQ
Q: Can this work for heroes/specific units exclusively?
A: Yes! You as the user determine which units have the bars above them. Please read the How to Use section below. It will be very useful.
Q: What is use? The game can have health bars already!
A: This was originally designed to show the HP bar without having to hold alt. The WC3 Engine now supports showing the health bar forever, but my system now also shows mana above the unit. You also are not required to have both the health and mana bar, you can have just the mana bar shown without the health. It's up to you.
Q: How does it work?
A: This system uses the ability of structs to house information. The older system used handles which made it very slow. This new system is much faster since it uses globals. The system doesn't use multiple timers to track each texttag, this is highly inefficient and extremely slow. The system uses 1 timer that traverses over every unit in the array and updates the texttags this way.
Requirements
-vJASS
Implementation
Step 1a - Copy the Category Floating Bars
Step 1b - Paste what you just copied into your map
Step 1c - Save your Map, any compile errors mean that you have pasted improperly or you do not use vJASS
Advanced Users Only
Step 2a - You can change the variables in the Configurables if you know how they will react
Functions to Use:
You should only ever use the following 2 functions
Basic Users:
AddBar(u, life, mana)
RemoveBarUnit(u)
Advanced Users:
function Addbar takes unit u, boolean life, boolean mana returns nothing
function RemoveBarUnit takes unit u returns boolean //If boolean returns false, unit is not found and it has no bars on it.
AddBar will create a bar ontop of the unit you deem. The boolean life and mana tell the system what you want to track.
For example say we just created a unit, you want to track the unit's life and mana you would do this DIRECTLY after you create the unit
//Track the last created unit's life and mana
call AddBar(bj_lastCreatedUnit, true, true)
//Track the last created unit's mana only
call AddBar(bj_lastCreatedUnit, false, true)
//Track the last created unit's life only
call AddBar(bj_lastCreatedUnit, true, false)
Starting to see the picture?
Now that you know how to add a bar, let me show you how to Add a bar....lets remove:
call RemoveBarUnit(GetTriggerUnit())
Very simple.
Floating Bars v2.4
JASS:
library FloatingBars initializer FloatingInit requires Gradient
globals
//========================================================================
//********************** Configurable Settings! ********************
//========================================================================
string DisplayCharacter = "039;" //Character intended for display
integer BarLength = 30 //How many DisplayCharacters are used
real BarSize = 11.00 //Size of the text
real XOffSet = -35.00//Offset over the unit by X
real YOffSet = -40.00//Offset over the unit by Y
real XOffSetM = -35. //Offset over the unit by X (Mana version)
real YOffSetM = -55. //Offset over the unit by Y (Mana version)
real Frequency = .04 //Recurrence of the timer that tracks the system
//========================================================================
//**********************DO NOT MODIFY BELOW THIS LINE!********************
//========================================================================
integer FS_MAX_BARS = 100
integer FS_CURR_BARS = 0
FloatingStruct array structlink
integer FS_COUNT = 0
endglobals
struct FloatingStruct
unit u
texttag t
texttag tm
static method create takes unit whichUnit, boolean life, boolean mana returns FloatingStruct
local FloatingStruct fs = FloatingStruct.allocate()
set fs.u = whichUnit
if life then
if FS_CURR_BARS<=100 then
set fs.t = CreateTextTag()
set FS_CURR_BARS=FS_CURR_BARS+1
call SetTextTagText(fs.t, "|c0000FF00", BarSize * 0.023 / 10)
call SetTextTagPos(fs.t,GetUnitX(whichUnit)+XOffSet,GetUnitY(whichUnit)+YOffSet,200)
call SetTextTagPermanent(fs.t,true)
call SetTextTagColor(fs.t,255,255,255,255)
call SetTextTagVisibility(fs.t,IsUnitVisible(fs.u,GetLocalPlayer()))
debug else
debug call BJDebugMsg("Text tax limit reached")
endif
endif
if ((GetUnitState(whichUnit, UNIT_STATE_MANA)>1) and mana) then
if FS_CURR_BARS<=100 then
set fs.tm = CreateTextTag()
debug call BJDebugMsg("Text Tag Created")
set FS_CURR_BARS=FS_CURR_BARS+1
call SetTextTagText(fs.tm, "|c000000FF", BarSize * 0.023 / 10)
call SetTextTagPos(fs.tm,GetUnitX(whichUnit)+XOffSetM,GetUnitY(whichUnit)+YOffSetM,200)
call SetTextTagPermanent(fs.tm,true)
call SetTextTagColor(fs.tm,255,255,255,255)
call SetTextTagVisibility(fs.tm,IsUnitVisible(fs.u,GetLocalPlayer()))
debug else
debug call BJDebugMsg("Text tax limit reached")
endif
endif
return fs
endmethod
private method onDestroy takes nothing returns nothing
set this.u = null
if (not(this.t==null)) then
call DestroyTextTag(this.t)
set FS_CURR_BARS=FS_CURR_BARS-1
set this.t=null
endif
if (not(this.tm==null)) then
call DestroyTextTag(this.tm)
set FS_CURR_BARS=FS_CURR_BARS-1
set this.tm=null
endif
set FS_COUNT=FS_COUNT-1
endmethod
endstruct
function RecycleIndex takes integer i returns nothing
loop
exitwhen i>FS_COUNT
set structlink<i>=structlink[i+1]
set i = i + 1
endloop
endfunction
function RemoveBarInt takes integer i returns nothing
call structlink<i>.destroy()
call RecycleIndex(i)
endfunction
function FindUnitIndex takes unit u returns integer
local integer i = 1
loop
exitwhen ((i>FS_COUNT) or (structlink<i>.u==null))
if structlink<i>.u==u then
return i
endif
set i = i + 1
endloop
return -1
endfunction
function RemoveBarUnit takes unit u returns boolean
local integer i = FindUnitIndex(u)
if (i==-1) then
debug call BJDebugMsg("Error unit not in index")
return false
else
call RemoveBarInt(i)
endif
return true
endfunction
function UpdateBar takes integer in, string barstr, texttag t, unitstate curr, unitstate max returns nothing
local integer i = 0
local integer j = 0
local boolean update = false
loop
exitwhen i==BarLength
if (not update) and (GetUnitState(structlink[in].u, curr) < (i * ((GetUnitState(structlink[in].u, max))/BarLength))+1) then
set update = true
set barstr = barstr+"|r|cFF000000"
else
set barstr = barstr+DisplayCharacter
endif
set i = i + 1
endloop
set barstr = barstr+"|r"
call SetTextTagText(t, barstr, BarSize * 0.023 / 10)
call SetTextTagVisibility(t,IsUnitVisible(structlink[in].u,GetLocalPlayer()))
endfunction
function BarTimer takes nothing returns nothing
local integer i=0
loop
exitwhen (i>FS_COUNT or structlink<i>.u==null)
if (not(structlink<i>.t==null)) then
call UpdateBar(i,"|c00"+gradientchild(GetUnitState(structlink<i>.u, UNIT_STATE_LIFE),GetUnitState(structlink<i>.u, UNIT_STATE_MAX_LIFE)), structlink<i>.t, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
call SetTextTagPos(structlink<i>.t,GetUnitX(structlink<i>.u)+XOffSet,GetUnitY(structlink<i>.u)+YOffSet,180)
debug else
debug call BJDebugMsg("structlink<i>.t == null")
endif
//Mana
if (not(structlink<i>.tm==null)) then
call UpdateBar(i,"|c000000FF", structlink<i>.tm, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
call SetTextTagPos(structlink<i>.tm,GetUnitX(structlink<i>.u)+XOffSetM,GetUnitY(structlink<i>.u)+YOffSetM,180)
debug else
debug call BJDebugMsg("structlink<i>.tm == null")
endif
if GetUnitState(structlink<i>.u, UNIT_STATE_LIFE) <= 0 then
call RemoveBarInt(i)
endif
set i=i+1
endloop
endfunction
function AddBar takes unit u, boolean life, boolean mana returns nothing
if (not(FindUnitIndex(u)==-1)) then
debug call BJDebugMsg("Error: Duplicate Floating Bar Creation Called")
return
endif
set structlink[FS_COUNT] = FloatingStruct.create(u, life, mana)
set FS_COUNT = FS_COUNT + 1
endfunction
function FloatingInit takes nothing returns nothing
local timer t = CreateTimer()
set FS_COUNT = 0
call TimerStart(t,Frequency,true,function BarTimer)
endfunction
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Gradient v2.4
JASS:
library Gradient
function s2hex takes string str returns integer
if (str == "F") then
return 15
elseif (str=="E") then
return 14
elseif (str=="D") then
return 13
elseif (str=="C") then
return 12
elseif (str=="B") then
return 11
elseif (str=="A") then
return 10
endif
return S2I(str)
endfunction
function hex2s takes integer i returns string
if (i == 15) then
return "F"
elseif (i==14) then
return "E"
elseif (i==13) then
return "D"
elseif (i==12) then
return "C"
elseif (i==11) then
return "B"
elseif (i==10) then
return "A"
elseif (i>15) then
return "F"
elseif (i<0) then
return "0"
endif
return I2S(i)
endfunction
function gradient takes string str returns string
local integer i = 1
local string r1 = SubString(str,0,1)
local string r2 = SubString(str,1,2)
local string g1 = SubString(str,2,3)
local string g2= SubString(str,3,4)
local string b1 = SubString(str,4,5)
local string b2 = SubString(str,5,6)
local integer x
set x = s2hex(r1)+2
set r1 = hex2s(x)
set x = s2hex(r2)+2
set r2 = hex2s(x)
set x = s2hex(g1)-2
set g1 = hex2s(x)
set x=s2hex(g2)-2
set g2 = hex2s(x)
set str = r1+r2+g1+g2+b1+b2
return str
endfunction
function gradientchild takes real curr, real max returns string
local integer i = 1
local string str = "00FF00"
local real percent = (curr/max)*100
local integer x = R2I((100-percent)/12.5)
loop
exitwhen i>x
set str = gradient(str)
set i = i +1
endloop
return str
endfunction
endlibrary
Screenshot:
Download Me (v2.4)!
Download Me (v2.3)!
Download Me (v2.2)!
Download Me (v2.1)!
Download Me (v2.0)!