- Joined
- Apr 6, 2008
- Messages
- 760
I've been player around little try to make a castbar system but im not happy with it. Its works fine but i think my method is abit unefficent. I think the best is to use channel spells so we can detect when it stopcasting and check for how long it have casted the spell
Anyone know a better way to do this?
JASS:
library CastBar
globals
public constant real FadeTime = 0.5
public string INACTIVE = ""
public constant string Green = "|CFF00FF00"
public constant string Red = "|CFFED1C24"
public constant string Yellow = "|CFFFFF200"
public constant string ColorEnd = "|r"
endglobals
//! textmacro CastBar
globals
private HandleTable Table
endglobals
private struct CastBar
private unit Carrier
private timer Timer
private integer Count
private texttag BarText
private string Text
private string TextI
private player Owner
private real Time
static method onInit takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= CastBar_BarCount //Makes the creation of the bar faster so we dont have to loop when we create it
set CastBar_INACTIVE = CastBar_INACTIVE + CastBar_BarType
set i = i + 1
endloop
set Table = HandleTable.create()
endmethod
static method CreateBar takes unit u returns nothing
local thistype Dat = thistype.allocate()
local integer index = 0
set Dat.BarText = CreateTextTag()
set Dat.Timer = NewTimer()
set Dat.Text = ""
set Dat.Carrier = u
set Dat.Owner = GetOwningPlayer(Dat.Carrier)
set Dat.Count = 0
set Dat.TextI = ""
set Dat.Time = 0
call SetTextTagVisibility(Dat.BarText,false)
call SetTextTagPermanent(Dat.BarText,true)
call SetTextTagText(Dat.BarText,CastBar_INACTIVE,CastBar_Size)
call SetTextTagPosUnit(Dat.BarText,Dat.Carrier,CastBar_ZHeight)
if GetLocalPlayer() == Dat.Owner then
call SetTextTagVisibility(Dat.BarText,true)
endif
set Table[Dat.Carrier] = Dat
call SetTimerData(Dat.Timer,Dat)
call TimerStart(Dat.Timer,CastBar_Interval,true,function thistype.Callback)
endmethod
static method Callback takes nothing returns nothing
local timer Time = GetExpiredTimer()
local thistype Dat = GetTimerData(Time)
local integer index = 0
set Dat.Count = Dat.Count + 1
set Dat.Text = Dat.Text + CastBar_BarType
set Dat.TextI = ""
loop //SLOWWWW LOOP
exitwhen index >= (CastBar_BarCount-Dat.Count)
set Dat.TextI = Dat.TextI + CastBar_BarType // Gief substraction to strings :P
set index = index + 1
endloop
call SetTextTagText(Dat.BarText,CastBar_Yellow+Dat.Text+CastBar_ColorEnd+Dat.TextI,CastBar_Size)
call SetTextTagPosUnit(Dat.BarText,Dat.Carrier,CastBar_ZHeight)
set Time = null
endmethod
static method Success takes unit u returns boolean
local thistype Dat = Table[u]
call Dat.BarFade()
if Dat.Count >= CastBar_BarCount then
call SetTextTagText(Dat.BarText,CastBar_Green+Dat.Text+Dat.TextI+CastBar_ColorEnd,CastBar_Size)
return true
else
call SetTextTagText(Dat.BarText,CastBar_Red+Dat.Text+Dat.TextI+CastBar_ColorEnd,CastBar_Size)
return false
endif
endmethod
method BarFade takes nothing returns nothing
call PauseTimer(this.Timer)
call TimerStart(this.Timer,CastBar_FadeTime,false,function thistype.Fade)
call SetTextTagPermanent(this.BarText,false)
call SetTextTagFadepoint(this.BarText,CastBar_FadeTime)
endmethod
static method Fade takes nothing returns nothing
local timer Time = GetExpiredTimer()
local thistype Dat = GetTimerData(Time)
call Table.flush(Dat.Carrier)
call Dat.destroy()
set Time = null
endmethod
method onDestroy takes nothing returns nothing
set .Carrier = null
set .Owner = null
call ReleaseTimer(.Timer)
set .Timer = null
call DestroyTextTag(.BarText)
set .BarText = null
endmethod
endstruct
//! endtextmacro
endlibrary
JASS:
scope Test
globals
private constant integer SPELL_ID = 'A000'
private constant real SPELL_RANGE = 500.
private constant integer CastBar_BarCount = 100
private constant real CastBar_BarTime = 2.5
private constant string CastBar_BarType = "||"
private constant real CastBar_ZHeight = 0.01
private constant real CastBar_Size = 0.01
private constant real CastBar_Interval = CastBar_BarTime/CastBar_BarCount
private group Spell_Group = CreateGroup()
private real a
private real b
private HandleTable HT
endglobals
//! runtextmacro CastBar()
private struct Data
unit Caster
unit Target
static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function thistype.OnCast))
set trig = CreateTrigger()
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(trig,Player(index),EVENT_PLAYER_UNIT_SPELL_ENDCAST,null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(trig,Condition(function thistype.OnEnd))
set HT = HandleTable.create()
set trig = null
endmethod
static method OnCast takes nothing returns boolean
local unit u
local unit t
if GetSpellAbilityId()==SPELL_ID then
set u = GetTriggerUnit()
set t = GetSpellTargetUnit()
call thistype.Create(u,t)
set u = null
set t = null
endif
return false
endmethod
static method OnEnd takes nothing returns boolean
local unit u = GetTriggerUnit()
local thistype Dat
if IsUnitInGroup(u,Spell_Group) then
set Dat = HT[u]
if CastBar.Success(Dat.Caster) then //im not happy with this
debug call BJDebugMsg("Success")
else
debug call BJDebugMsg("Fail")
endif
call GroupRemoveUnit(Spell_Group,Dat.Caster)
endif
set u = null
return false
endmethod
static method Create takes unit u,unit t returns nothing
local thistype D = thistype.allocate()
set D.Caster = u
set D.Target = t
call GroupAddUnit(Spell_Group,D.Caster)
set HT[D.Caster] = D
call CastBar.CreateBar(D.Caster)
endmethod
method onDestroy takes nothing returns nothing
set this.Caster = null
set this.Target = null
endmethod
endstruct
endscope
Anyone know a better way to do this?