Zwiebelchen
You can change this now in User CP.
- Reaction score
- 60
This System creates a floating text style Casting bar below (or above) your unit via using a simple function call.
Features:
- Automaticly cancels the bar progression when the unit gets a different order (you can deactivate this feature if you wish)
- 3 visibility options (Player only, all friendlys, all players)
- easy to use and adjust
- 100% leak free
- ordinary and channeled cast (inverted) settings
Requires:
- Newgen (http://www.thehelper.net/forums/showthread.php?t=73936)
- TTbars (Modular version)
- ARGB (Modular version)
- TimerUtils (Modular version)
Pros:
- Easy to implement and adjust
- MUI and GUI-accessable
Cons:
- May slow down your map on heavy use due to masses of string calls (mostly unavoidable)
Implementation:
- Create a new trigger called "CastingBar"
- Convert it to custom text
- Replace everything in the trigger with the Jass Code below
Use
Custom Script: call Castingbar(Castingtime, orderstring, unit, visibilityInt, ChanneledBool)
when you want to attach a casting bar to a unit.
For example:
Custom Script: call Castingbar(2.50, "heal", GetTriggerUnit(), 2, false)
Note: This Casting Bar system only works properly, if the unit maintains the order during the execution. This means it works only during the "casting" time or the "channeling" time of the ability. If you wish to apply the Casting bar without having the unit ordered a spell, you can disable the orderstring checking.
Thanks to Deaod for the modular version:
JASS:
library CastingBar uses TTBARS, ARGB
// Zwiebelchen's Casting Bar System
// redone.
// Requires NewGen, such as Warcraft III Patch 1.24b
globals
private constant integer NUMBER_OF_BAR_BITS = 40 // The number of the commas/apostrophes/whatever you use to fill an entire bar
// It's not recommended to set this higher than 100, since it will cause lag due to the bad string handling of Warcraft III
// Use a bigger Size instead.
// Never set this to 0, since it will create a divide by 0 error.
private constant string BAR_BIT = "039;" // The letter used for the Bar
private constant integer COLOR = 0xFF33CCFF // The hex color code for the bar - Leave out the "|r" at the end!
private constant integer COLOR_CHANNEL = 0xFF00FF00 // The hex color code for the Channeling bar - Leave out the "|r" at the end!
private constant integer BACKGROUND_COLOR = 0xFF000033 // The hex color codes for the Background of the Bar
private constant integer BACKGROUND_COLOR_CHANNEL = 0xFF003300 // The hex color codes for the Background of the Channeling Bar
private constant real CASTING_BAR_X_OFFSET = 0 // The X Offset of the bar position to the unit. + being east
private constant real CASTING_BAR_Y_OFFSET = 0 // The Y Offset of the bar position to the unit. + being north
// Set these values to 0 if you want to use a third person camera or do the math
// and get an equation depending on the camera angle if you want to use a 3D camera.
// It may need a little bit of trying to find good values for these
private constant real CASTING_BAR_Z_OFFSET = 0 // The Z Offset of the bar position to the unit.
private constant real CASTING_BAR_SIZE = 8 // The size of the bar font
private constant real CASTING_BAR_FADE_OUT = 0.5
private constant real TICK = 0.02 // The frequency the bars get updated - recommended value: 0.02
endglobals
//----------------------------------------------------------------------------------------
//Use call Castingbar(Castingtime, Orderstring, Casterunit, VisiblyModifier, ChannelingBool) to attach a casting bar to a unit.
// variables: real Castingtime --> Only use casting times above 0.3 seconds, otherwise it will look strange
// string Orderstring --> The Orderstring of the ability. Used to determine wether the unit moves
// during the casting. Set this to "_" to disable the orderstring check.
// unit Casterunit --> Obviously the caster
// integer Visibly Modifier --> Changes Visibility of the Casting bar
// 0: Only the owner of the casting unit sees the bar
// 1: All Allies of the Player can see the bar
// 2: All Players can see the bar
// boolean Channeled --> false: ordinary cast; true: channeled cast
private struct Data
TTBar bar
unit c
real t
real tt
string order
private integer i
private static thistype array Structs
private static timer T=CreateTimer()
private static integer Count=0
method onDestroy takes nothing returns nothing
call .bar.FadeOut(CASTING_BAR_FADE_OUT, true, 0,0)
// clean your struct here
set .Count=.Count-1
set .Structs[.i]=.Structs[.Count]
set .Structs[.i].i=.i
if .Count==0 then
call PauseTimer(.T)
endif
endmethod
private static method Callback takes nothing returns nothing
local integer i=.Count-1
local thistype s
loop
exitwhen i<0
set s=.Structs<i>
//
if GetUnitCurrentOrder(s.c)==OrderId(s.order) or s.order=="_" then
set s.t=s.t+TICK
set s.bar.Value=100*s.t/s.tt
if s.t>=s.tt then
call s.destroy()
endif
else
call s.destroy()
endif
// do your things here, dont forget to call s.destroy() somewhen
//
set i=i-1
endloop
endmethod
static method create takes unit caster, real time, string order, force disp, boolean channel returns thistype
local thistype s=.allocate()
set s.bar=TTBar.create(BAR_BIT, NUMBER_OF_BAR_BITS, CASTING_BAR_SIZE, GetUnitX(caster)+CASTING_BAR_X_OFFSET,GetUnitY(caster)+CASTING_BAR_Y_OFFSET,CASTING_BAR_Z_OFFSET)
call s.bar.ChangeVisibility(disp)
call s.bar.LockToUnit(caster, CASTING_BAR_X_OFFSET, CASTING_BAR_Y_OFFSET, CASTING_BAR_Z_OFFSET)
if channel then
call s.bar.SetBackground(ARGB(BACKGROUND_COLOR_CHANNEL))
call s.bar.SetForeground(ARGB(COLOR_CHANNEL))
else
call s.bar.SetBackground(ARGB(BACKGROUND_COLOR))
call s.bar.SetForeground(ARGB(COLOR))
endif
set s.c=caster
set s.t=0
set s.tt=time
set s.order=order
// initialize the struct here
set .Structs[.Count]=s
set s.i=.Count
if .Count==0 then
call TimerStart(.T, TICK, true, function thistype.Callback)
endif
set .Count=.Count+1
return s
endmethod
endstruct
function Castingbar takes real Casttime, string Order, unit Caster, integer ShowCastingBar, boolean Channeled returns nothing
local force TextTagForce=null
local player LocalPlayer = GetOwningPlayer(Caster)
if ShowCastingBar == 0 then
set TextTagForce = CreateForce()
call ForceAddPlayer(TextTagForce, LocalPlayer)
elseif ShowCastingBar == 1 then
set TextTagForce = CreateForce()
call ForceEnumAllies(TextTagForce, LocalPlayer, null)
endif
call Data.create(Caster, Casttime, Order, TextTagForce, Channeled)
if TextTagForce!=null then
call DestroyForce(TextTagForce)
set TextTagForce = null
endif
endfunction
endlibrary
</i>
If you don't like modularity and prefer a stand-alone version, use this code:
JASS:
library CastingBar initializer InitCastingBar
// Zwiebelchen's Casting Bar System
// Requires NewGen, such as Warcraft III Patch 1.24b
globals
private constant integer NumberOfBarBits = 40 // The number of the commas/apostrophes/whatever you use to fill an entire bar
// It's not recommended to set this higher than 100, since it will cause lag due to the bad string handling of Warcraft III
// Use a bigger Size instead.
// Never set this to 0, since it will create a divide by 0 error.
private constant string BarBit = "039;" // The letter used for the Bar
private constant string Colorcode = "|cff33ccff" // The hex color code for the bar - Leave out the "|r" at the end!
private constant string ColorcodeCh = "|cff00ff00" // The hex color code for the Channeling bar - Leave out the "|r" at the end!
private constant string ColorcodeBG = "|cff000033" // The hex color codes for the Background of the Bar
private constant string ColorcodeBGCh = "|cff003300" // The hex color codes for the Background of the Channeling Bar
private constant real CastingBarXOffset = 0 // The X Offset of the bar position to the unit. + being east
private constant real CastingBarYOffset = 0 // The Y Offset of the bar position to the unit. + being north
// Set these values to 0 if you want to use a third person camera or do the math
// and get an equation depending on the camera angle if you want to use a 3D camera.
// It may need a little bit of trying to find good values for these
private constant real CastingBarZOffset = 0 // The Z Offset of the bar position to the unit.
private constant real CastingBarSize = 8 // The size of the bar font
private constant real ZCBTimerIntervall = 0.02 // The frequency the bars get updated - recommended value: 0.02
//Do not edit the following variables!
private boolexpr b = null
private texttag array ZCBarray
private integer NumberOfBars = 0
private hashtable ZCBHash = InitHashtable()
private timer ZCBTimer = CreateTimer()
endglobals
//----------------------------------------------------------------------------------------
//Use call Castingbar(Castingtime, Orderstring, Casterunit, VisiblyModifier, ChannelingBool) to attach a casting bar to a unit.
// variables: real Castingtime --> Only use casting times above 0.3 seconds, otherwise it will look strange
// string Orderstring --> The Orderstring of the ability. Used to determine wether the unit moves
// during the casting. Set this to "_" to disable the orderstring check.
// unit Casterunit --> Obviously the caster
// integer Visibly Modifier --> Changes Visibility of the Casting bar
// 0: Only the owner of the casting unit sees the bar
// 1: All Allies of the Player can see the bar
// 2: All Players can see the bar
// boolean Channeled --> false: ordinary cast; true: channeled cast
private function CommaMultiplier takes integer Number returns string // This function seems poorly triggered, but it's like this for a reason
local string CommaString = ""
// Ordinary Loopcalls would totally fuck off the performance on heavy duty cause of the awkward string handling of Warcraft III
// If you want to use more than 50 Barbits (though I don't recommend that), feel free to add more ifs here.
// It's highly recommended to hardcode the Barbits here (replace them with "''''''''''" for example) - it will greatly improve performance
//example:
// if Number >= 25 then
// set CommaString = CommaString+"'''''''''''''''''''''''''"
// set Number = Number - 25
// endif
// if Number >= 15 then
// set CommaString = CommaString+"'''''''''''''''"
// set Number = Number - 15
// endif
// if Number >= 5 then
// set CommaString = CommaString+"'''''"
// set Number = Number - 5
// endif
loop
exitwhen Number <= 0
set CommaString = CommaString+BarBit
set Number = Number - 1
endloop
return CommaString
endfunction
private function BarTimerLoop takes nothing returns nothing
local integer i = 0
local texttag Tag
local real Casttime
local real CurrentTime
local string Order
local unit Caster
local boolean Channeled
local integer a = 0
if NumberOfBars > 0 then
loop
if ZCBarray<i> == null then //Fill up empty array positions
if ZCBarray[NumberOfBars-1] != null then
set ZCBarray<i> = ZCBarray[NumberOfBars-1]
set ZCBarray[NumberOfBars-1] = null // Cleanup: Take the last entry of the list and move it to the empty slot
set NumberOfBars = NumberOfBars - 1
else
set NumberOfBars = NumberOfBars - 1
endif
else //The bar tag exists
if HaveSavedReal(ZCBHash, GetHandleId(ZCBarray<i>), 0) then
set Tag = ZCBarray<i>
set Casttime = LoadReal(ZCBHash, GetHandleId(Tag), 0)
set CurrentTime = LoadReal(ZCBHash, GetHandleId(Tag), 1)
set Order = LoadStr(ZCBHash, GetHandleId(Tag), 2)
set Caster = LoadUnitHandle(ZCBHash, GetHandleId(Tag), 3)
set Channeled = LoadBoolean(ZCBHash, GetHandleId(Tag), 4)
set CurrentTime = CurrentTime + ZCBTimerIntervall
call SaveReal(ZCBHash, GetHandleId(Tag), 1, CurrentTime) //Store the Bar progress time
set a = R2I((CurrentTime/Casttime) * I2R(NumberOfBarBits)) //Calculate the number of "filled" bar bits
if CurrentTime < Casttime then
if (GetUnitCurrentOrder(Caster) == OrderId(Order)) then
if Channeled == false then
call SetTextTagText(Tag, Colorcode+CommaMultiplier(a)+"|r"+ColorcodeBG+CommaMultiplier(NumberOfBarBits-a)+"|r", (CastingBarSize * 0.023 / 10))
else
call SetTextTagText(Tag, ColorcodeCh+CommaMultiplier(NumberOfBarBits-a)+"|r"+ColorcodeBGCh+CommaMultiplier(a)+"|r", (CastingBarSize * 0.023 / 10))
endif
else
if Order == "_" then
if Channeled == false then
call SetTextTagText(Tag, Colorcode+CommaMultiplier(a)+"|r"+ColorcodeBG+CommaMultiplier(NumberOfBarBits-a)+"|r", (CastingBarSize * 0.023 / 10))
else
call SetTextTagText(Tag, ColorcodeCh+CommaMultiplier(NumberOfBarBits-a)+"|r"+ColorcodeBGCh+CommaMultiplier(a)+"|r", (CastingBarSize * 0.023 / 10))
endif
else
call SetTextTagFadepoint(Tag, CurrentTime) //casting bar cancelled - fade out instantly
call SetTextTagLifespan(Tag, CurrentTime+0.5 )
call FlushChildHashtable(ZCBHash, GetHandleId(Tag)) //clear the hashtable entry
set ZCBarray<i> = null
endif
endif
else
call FlushChildHashtable(ZCBHash, GetHandleId(Tag)) //casting bar expired - clear the hashtable entry
set ZCBarray<i> = null
endif
endif
endif
set i = i + 1
set a = 0
exitwhen i >= NumberOfBars
endloop
set Caster = null
set Tag = null
endif
endfunction
function Castingbar takes real Casttime, string Order, unit Caster, integer ShowCastingBar, boolean Channeled returns nothing
local force TextTagForce
local texttag FloatingText
local real X = (GetUnitX(Caster) + CastingBarXOffset)
local real Y = (GetUnitY(Caster) + CastingBarYOffset)
local player LocalPlayer = GetOwningPlayer(Caster)
set FloatingText = CreateTextTag()
if FloatingText == null then
call BJDebugMsg("|cffff0000ERROR: Maximum number of Texttags reached. Bar not created.|r")
return
endif
if ShowCastingBar == 0 then
set TextTagForce = CreateForce()
call ForceAddPlayer(TextTagForce, LocalPlayer)
endif
if ShowCastingBar == 1 then
set TextTagForce = CreateForce()
call ForceEnumAllies(TextTagForce, LocalPlayer, b)
endif
set LocalPlayer = null
call SetTextTagPos(FloatingText, X, Y, CastingBarZOffset)
if Channeled == false then
call SetTextTagText(FloatingText, Colorcode+CommaMultiplier(NumberOfBarBits)+"|r", (CastingBarSize * 0.023 / 10))
else
call SetTextTagText(FloatingText, ColorcodeCh+CommaMultiplier(NumberOfBarBits)+"|r", (CastingBarSize * 0.023 / 10))
endif
call SetTextTagPermanent( FloatingText, false )
call SetTextTagFadepoint( FloatingText, Casttime )
call SetTextTagLifespan( FloatingText, (Casttime + 0.5) )
if IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS) then
call SetTextTagVisibility(FloatingText, false)
endif
if ShowCastingBar == 2 then
if IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS) then
call SetTextTagVisibility(FloatingText, true)
endif
else
if IsPlayerInForce(GetLocalPlayer(), TextTagForce) then
call SetTextTagVisibility(FloatingText, true)
endif
endif
call SaveReal(ZCBHash, GetHandleId(FloatingText), 0, Casttime) //
call SaveReal(ZCBHash, GetHandleId(FloatingText), 1, 0.0) //
call SaveStr(ZCBHash, GetHandleId(FloatingText), 2, Order) //Save all required variables to the Floating Text
call SaveUnitHandle(ZCBHash, GetHandleId(FloatingText), 3, Caster) //
call SaveBoolean(ZCBHash, GetHandleId(FloatingText), 4, Channeled) //
set ZCBarray[NumberOfBars] = FloatingText //Add The created casting-bar to the list of active bars
set NumberOfBars = NumberOfBars + 1 //Update the number of bars
set FloatingText = null
if ShowCastingBar < 2 then
call DestroyForce(TextTagForce)
endif
set TextTagForce = null
endfunction
function InitCastingBar takes nothing returns nothing
call TimerStart(ZCBTimer,ZCBTimerIntervall,true, function BarTimerLoop)
endfunction
endlibrary
</i></i></i></i></i></i>
Special Thanks to N-a-z-g-u-l for his HandleCount System.