Snippet Text Tag

MyPad

Member
Reaction score
0
A text tag snippet that allows you to create local text tags worry-free.

If you have any suggestions for any features, feel free to add them:

JASS:
library TextTag uses/*

    */ optional OneTimer,/*   - A truly optional resource. If not found, the system attempts to generate a hashtable
                            in order to store the timers to be generated, which will handle the checking of instances.
    */

    //==========================//
    //  TextTag                 //
    //      -   By  MyPad       //
    //                          //
    //  Version:                //
    //      v.1.3.01            //
    //==========================//
 
    //  Description:    //

    //======================================================================================//
    //  TextTag is a snippet that provides convenience for the creation of local text tags. //
    //  Thus, it is lightweight in usage and grants the user a bit of ease in coding.       //
    //======================================================================================//
 
    //  API (Application Programming Interface) //
    //      Note: Section is in vJASS...        //
 
    //! novjass
        struct TextTag
     
            Creation and destruction:
         
            call TextTag.create(playerId)
                //  Creates a local texttag for a certain player.
             
                //  Note that the playerId parameter takes the actual number of the player,
                //  not the player itself
           
                //  To create a global instance, request 17 or higher (Must be bigger than bj_MAX_PLAYER_SLOTS)
            local TextTag tag = TextTag.create(playerId)
         
            ..
         
            call tag.destroy()
                //  This destroys a TextTag instance. How it manages to destroy an instance
                //  for a player is determined mathematically.
         
            method operator:
         
                set tag.permanent = bool
                    //  Sets the permanence of a TextTag
                 
                set tag.duration = r
                    //  If it is not permanent, a TextTag's duration is reset to the requested (r).
                 
                set tag.msg = somevar
                    //  Sets the message of a texttag
                 
                set tag.Red = int
                set tag.Blue = int
                set tag.Green = int
                set tag.Alpha = int
                    //  These are self-explanatory
                 
                set tag.widget = wid
                set tag.unit = uni
                    //  Attaches a text tag to a widget or a unit.
                 
            method /(s):
                call tag.setPos(x, y, heightOffset)
                    //  Sets the position of a TextTag instance to the requested coordinates
                    //  with a z-offset of heightOffset
             
                call tag.setVeloc(xvel, yvel)
                    //  Sets the pace at which the tag moves at a certain direction.
             
                call tag.setVelocEx(speed, angle)
                    //  Wrapper function for setVeloc
                 
        endstruct
     
        function CreateTextTagBJ takes player p, real x, real y, real offset, integer red, integer green, integer blue, string msg returns TextTag
            //  Creates a TextTag instance with the default settings.
    //! endnovjass
 
    globals
        //  This determines the check rate of the timers..
        private constant real INTERVAL = 1/32.
    endglobals
 
    //  A minor rewrite of a double-linked list module.
    private module DoubleLink_Mod
        thistype next
        thistype prev
     
        method pop takes nothing returns nothing
            set next.prev = prev
            set prev.next = next
        endmethod
     
        method push takes integer head returns nothing
            set next = head
            set prev = next.prev
            set next.prev = this
            set prev.next = this
        endmethod
    endmodule
 
    private module TextTag_Mod
        //  How many texttags are possible (+1)
        readonly static constant integer ALLOC_MULTIPLIER = 101
     
        //  These are the default settings for heights
        readonly static constant real DEFAULT_HEIGHT = 10.
        readonly static constant real HEIGHT_OFFSET = 0.023 / 10.
     
        //  Default offset value for velocity
        readonly static constant real VELOCITY_OFFSET = 0.071 / 128.
     
        //  Default duration of a texttag instance
        readonly static constant real DEFAULT_DURATION = 2.
     
        //  Default speed and angle of a texttag
        readonly static constant real DEFAULT_VELOC_SPEED = 80.
        readonly static constant real DEFAULT_VELOC_ANGLE = 90.
     
        //  The list of deallocated instances.
        readonly thistype recCount
     
        //  When the text tag is a global text tag...
        readonly thistype local_next
        readonly thistype local_prev
     
        method local_pop takes nothing returns nothing
            set local_prev.local_next = local_next
            set local_next.local_prev = local_prev
            set local_prev = 0
            set local_next = 0
        endmethod
     
        method local_push takes integer head returns nothing
            set local_prev = head
            set local_next = local_prev.local_next
            set local_prev.local_next = this
            set local_next.local_prev = this
        endmethod
     
        static if LIBRARY_OneTimer then
            readonly Timer instanceCheck
        else
            //  Too lazy to do an array search...
            readonly static constant hashtable DATA_HASH = InitHashtable()
         
            readonly timer instanceCheck
            readonly integer instanceData
        endif
     
        method deallocate takes nothing returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set recCount = thistype(pIndex*ALLOC_MULTIPLIER).recCount
            set thistype(pIndex*ALLOC_MULTIPLIER).recCount = this
        endmethod
     
        static method allocate takes integer pIndex returns thistype
            local thistype this = thistype(pIndex*ALLOC_MULTIPLIER).recCount
            if this.recCount == pIndex*ALLOC_MULTIPLIER then
                if integer(this) < (pIndex+1)*ALLOC_MULTIPLIER then
                    //  From indices pIndex*ALLOC_MULTIPLIER to (pIndex+1)*ALLOC_MULTIPLIER - 1
                    set this = this + 1
                    set thistype(pIndex*ALLOC_MULTIPLIER).recCount = this
                    set this.recCount = pIndex*ALLOC_MULTIPLIER
                else
                    //  Error, text tag count exceeded...
                    set this = -1
                endif
            else
                //  Recycling; it is impossible for the allocate method to go over the max.
                set thistype(pIndex*ALLOC_MULTIPLIER).recCount = this.recCount
                set this.recCount = pIndex*ALLOC_MULTIPLIER
            endif
            return this
        endmethod
     
        private static method onSecInit takes nothing returns nothing
            local thistype this = 0
         
            static if LIBRARY_OneTimer then
                //  This recycles the expired timer instead.
                call Timer.getExpired().destroy()
            else
                //  This actually destroys the initialization timer.
                call DestroyTimer(GetExpiredTimer())
            endif
         
            loop
                exitwhen integer(this) > bj_MAX_PLAYER_SLOTS + 1
             
                call thistype(this*ALLOC_MULTIPLIER).push(this*ALLOC_MULTIPLIER)
                set thistype(this*ALLOC_MULTIPLIER).recCount = this*ALLOC_MULTIPLIER
               
                static if LIBRARY_OneTimer then
                    set thistype(this*ALLOC_MULTIPLIER).instanceCheck = Timer.create()
                    set thistype(this*ALLOC_MULTIPLIER).instanceCheck.data = this*ALLOC_MULTIPLIER
                else
                    set thistype(this*ALLOC_MULTIPLIER).instanceCheck = CreateTimer()
                    call SaveInteger(DATA_HASH, 0, GetHandleId(thistype(this*ALLOC_MULTIPLIER).instanceCheck), this*ALLOC_MULTIPLIER)
                    call SaveBoolean(DATA_HASH, 1, GetHandleId(thistype(this*ALLOC_MULTIPLIER).instanceCheck), true)
                endif
             
                set this = this + 1
            endloop
        endmethod
     
        private static method onInit takes nothing returns nothing
            static if LIBRARY_OneTimer then
                call Timer.create().start(0., false, function thistype.onSecInit)
            else
                call TimerStart(CreateTimer(), 0., false, function thistype.onSecInit)
            endif
        endmethod
    endmodule
 
    struct TextTag extends array
        private texttag texttag
     
        private widget wid_targ
        private unit uni_targ
     
        private boolean isPermanent
        private real dur
     
        private string s
        private real size
     
        private real fadepoint
     
        private integer red
        private integer green
        private integer blue
        private integer alpha
     
        implement DoubleLink_Mod
       
        implement TextTag_Mod
       
        method destroy takes nothing returns nothing
            local thistype that = this.local_next
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call DestroyTextTag(texttag)
                set texttag = null
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call DestroyTextTag(texttag)
                    set texttag = null
                endif
            endif
         
            if that != 0 then
                loop
                    exitwhen that == this
                    call that.local_pop()
                    call that.deallocate()
                    set that = this.local_next
                endloop
            endif
         
            set wid_targ = null
            set uni_targ = null
         
            set isPermanent = false
            set dur = 0.
         
            set red = 0
            set green = 0
            set blue = 0
            set alpha = 0
         
            set s = ""
         
            call pop()
            call deallocate()
        endmethod
     
        //============================================================//
        //          Methods                                           //
        //============================================================//
        method setPos takes real x, real y, real heightOffset returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagPos(texttag, x, y, heightOffset)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagPos(texttag, x, y, heightOffset)
                endif
            endif
        endmethod
     
        method setVeloc takes real xvel, real yvel returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagVelocity(texttag, xvel * VELOCITY_OFFSET, yvel * VELOCITY_OFFSET)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagVelocity(texttag, xvel * VELOCITY_OFFSET, yvel * VELOCITY_OFFSET)
                endif
            endif
        endmethod
     
        method setVelocEx takes real speed, real angle returns nothing
            call setVeloc(Cos(angle * bj_DEGTORAD) * speed, Sin(angle * bj_DEGTORAD) * speed)
        endmethod
     
        //============================================================//
        //          Method operators                                  //
        //============================================================//
     
        method operator permanent takes nothing returns boolean
            return isPermanent
        endmethod
        method operator permanent= takes boolean b returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set isPermanent = b
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagPermanent(texttag, isPermanent)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagPermanent(texttag, isPermanent)
                endif
            endif
        endmethod
     
        method operator duration takes nothing returns real
            if not isPermanent then
                return dur
            endif
         
            //  If permanent, the text tag will always endure. Thus, its' duration is -1
            return -1.
        endmethod
        method operator duration= takes real r returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            if isPermanent then
                return
            endif
         
            set dur = r
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagLifespan(texttag, dur)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagLifespan(texttag, dur)
                endif
            endif
        endmethod
     
        method operator msg takes nothing returns string
            return s
        endmethod
        method operator msg= takes string str returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set s = str
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagText(texttag, s, size * HEIGHT_OFFSET)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagText(texttag, s, size * HEIGHT_OFFSET)
                endif
            endif
        endmethod
     
        method operator height takes nothing returns real
            return size
        endmethod
        method operator height= takes real h returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set size = h
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagText(texttag, s, size * HEIGHT_OFFSET)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagText(texttag, s, size * HEIGHT_OFFSET)
                endif
            endif
        endmethod
     
        method operator fade takes nothing returns real
            return fadepoint
        endmethod
        method operator fade= takes real fader returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            if not isPermanent then
                set fadepoint = RMinBJ(RAbsBJ(fader), dur)
            else
                return
            endif
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagFadepoint(texttag, fadepoint)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagFadepoint(texttag, fadepoint)
                endif
            endif
        endmethod
     
        method operator Red takes nothing returns integer
            return red
        endmethod
        method operator Red= takes integer r returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set red = r
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
                endif
            endif
        endmethod
     
        method operator Green takes nothing returns integer
            return green
        endmethod
        method operator Green= takes integer r returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set green = r
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
                endif
            endif
        endmethod
     
        method operator Blue takes nothing returns integer
            return blue
        endmethod
        method operator Blue= takes integer r returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set blue = r
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
                endif
            endif
        endmethod
     
        method operator Alpha takes nothing returns integer
            return alpha
        endmethod
        method operator Alpha= takes integer r returns nothing
            local integer pIndex = this/ALLOC_MULTIPLIER
         
            set alpha = r
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
            else
                if GetLocalPlayer() == Player(pIndex) then
                    call SetTextTagColor(texttag, red, green, blue, 255 - alpha)
                endif
            endif
        endmethod
     
        method operator widget takes nothing returns widget
            return wid_targ
        endmethod
        method operator widget= takes widget wid returns nothing
            if wid == null then
                //  Must not attach to null instance...
                return
            endif
         
            set uni_targ = null
            set wid_targ = wid
         
            call setPos(GetWidgetX(wid_targ), GetWidgetY(wid_targ), 0)
            call setVeloc(0,0)
        endmethod
     
        method operator unit takes nothing returns unit
            return uni_targ
        endmethod
        method operator unit= takes unit uni returns nothing
            if unit == null then
                //  Must not attach to null instance...
                return
            endif
         
            set wid_targ = null
            set uni_targ = uni
         
            call setPos(GetWidgetX(uni_targ), GetWidgetY(uni_targ), GetUnitFlyHeight(uni_targ))
            call setVeloc(0,0)
        endmethod
     
        //  =================================   //
        //  Create and onTick methods           //
        //  =================================   //
     
        private static method onTick takes nothing returns nothing
            static if LIBRARY_OneTimer then
                local Timer tick
            else
                local timer tick
            endif
            local integer pIndex
            local thistype head
            local thistype this
         
            static if LIBRARY_OneTimer then
                set tick = Timer.getExpired()
                set pIndex = tick.data
            else
                set tick = GetExpiredTimer()
                set pIndex = LoadInteger(DATA_HASH, 0, GetHandleId(tick))
            endif
         
            set head = pIndex
            set this = head.next
         
            set pIndex = pIndex/ALLOC_MULTIPLIER
         
            if this == head then
             
                static if LIBRARY_OneTimer then
                    set tick.pause = true
                else
                    call SaveBoolean(DATA_HASH, 1, GetHandleId(this.instanceCheck), true)
                    call PauseTimer(tick)
                endif
            endif
         
            loop
                exitwhen this == head
                if this.uni_targ != null or this.wid_targ != null then
                    if this.wid_targ != null then
                        set this.widget = wid_targ
                    else
                        set this.unit = uni_targ
                    endif
                endif
                if not this.isPermanent then
                    set this.dur = this.dur - INTERVAL
                 
                    if this.dur <= 0. then
                        call this.destroy()
                    endif
                endif
                set this = this.next
            endloop
        endmethod
     
        static method create takes integer pIndex returns thistype
            local thistype this = 0
            local integer i = 0
            local thistype array that
           
            if pIndex > bj_MAX_PLAYER_SLOTS + 1 then
                set pIndex = bj_MAX_PLAYER_SLOTS + 1
            elseif pIndex < 0 then
                //  Apply modulo...
                set pIndex = pIndex - pIndex/(bj_MAX_PLAYER_SLOTS + 1)*(bj_MAX_PLAYER_SLOTS + 1) + (bj_MAX_PLAYER_SLOTS + 1)
            endif
         
            if pIndex > bj_MAX_PLAYER_SLOTS then
                loop
                    exitwhen i > bj_MAX_PLAYER_SLOTS
                    set that<i> = allocate(i)
                 
                    if that<i> == -1 then
                        exitwhen true
                    endif
                    set i = i + 1
                endloop
             
                if i &lt;= bj_MAX_PLAYER_SLOTS then
                    //  Creation failed, sadly...
                    loop
                        exitwhen i &lt;= 0
                        call that<i>.deallocate()
                        set i = i - 1
                    endloop
                else
                    //  Creation success..
                    set this = allocate(pIndex)
                 
                    call this.push(pIndex*ALLOC_MULTIPLIER)
                 
                    set this.texttag = CreateTextTag()
                 
                    set i = 0
                    loop
                        exitwhen i &gt; bj_MAX_PLAYER_SLOTS
                        call that<i>.local_push(this)
                        set i = i + 1
                    endloop
                 
                    static if LIBRARY_OneTimer then
                        if thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck.paused then
                            call thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck.start(INTERVAL, true, function thistype.onTick)
                        endif
                    else
                        if LoadBoolean(DATA_HASH, 1, GetHandleId(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck)) then
                            call RemoveSavedBoolean(DATA_HASH, 1, GetHandleId(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck))
                            call TimerStart(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck, INTERVAL, true, function thistype.onTick)
                        endif
                    endif
                endif
            else
                set this = allocate(pIndex)
                if this != -1 then
                    call BJDebugMsg(&quot;Allocated! \n&quot; + I2S(this))
                    //  Allocation Successful..
                    call this.push(pIndex*ALLOC_MULTIPLIER)
                 
                    if GetLocalPlayer() == Player(pIndex) then
                        set this.texttag = CreateTextTag()
                    endif
                 
                    static if LIBRARY_OneTimer then
                        if thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck.paused then
                            call thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck.start(INTERVAL, true, function thistype.onTick)
                        endif
                    else
                        if LoadBoolean(DATA_HASH, 1, GetHandleId(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck)) then
                            call RemoveSavedBoolean(DATA_HASH, 1, GetHandleId(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck))
                            call TimerStart(thistype(pIndex*ALLOC_MULTIPLIER).instanceCheck, INTERVAL, true, function thistype.onTick)
                        endif
                    endif
                endif
            endif
            return this
        endmethod
     
    endstruct
 
    globals
        TextTag vj_lastCreatedTextTag = 0
    endglobals
   
    function CreateTextTagBJ takes player p, real x, real y, real offset, integer red, integer green, integer blue, string msg returns TextTag
        local TextTag this
     
        if p == null then
            set this = TextTag.create(bj_MAX_PLAYER_SLOTS + 1)
        else
            set this = TextTag.create(GetPlayerId(p))
        endif
     
        if this == -1 then
            return this
        endif
     
        call this.setPos(x, y, offset)
        call this.setVelocEx(TextTag.DEFAULT_VELOC_SPEED, TextTag.DEFAULT_VELOC_ANGLE)
     
        set this.permanent = false
     
        set this.height = TextTag.DEFAULT_HEIGHT
        set this.duration = TextTag.DEFAULT_DURATION
        set this.fade = TextTag.DEFAULT_DURATION - 0.5
     
        set this.Red = red
        set this.Green = green
        set this.Blue = blue
        set this.Alpha = 0
     
        set this.msg = msg
     
        set vj_lastCreatedTextTag = this
        return vj_lastCreatedTextTag
    endfunction
endlibrary
</i></i></i></i>


Parallel Link:
HIVE
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top