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

[JASS] CastBar Sytem

Status
Not open for further replies.
Level 11
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


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?
 
Level 3
Joined
Aug 9, 2008
Messages
60
I'm not sure how yours works, but what I'm gonna do is basically create a new function for cast spell on my caster system, call it Channel Spell, when you use it the rest of the stuff is gonna be done internally, it will detect when persons orders the unit to move, or when a stun spell hit the person, because all of my spells are entirely triggered, even the missiles generated by them.
 
Status
Not open for further replies.
Top