System CustomBar -> [TT] progressbar + Example

Anachron

New Member
Reaction score
53
Like the title says, I made an TextTag progress bar.

Sorry for the long code, but you can do everything you need with it!

The code:
JASS:
//******************************************************************************
//*
//* CustomBar 1.0 (Initial Release)
//* ====
//* For your CustomBar needs. / Thanks Vex for this sentence <3
//*
//* This library is used to give a fully functional Bar System
//* that provides you interfaces for setting the bar state and
//* for letting you fade the bar, and even let you decide which
//* fade Condition to use.
//*
//* If a Bar is fading (out) and its condition becomes false, its
//* changing its fading (to in).
//*
//* You can also disable fading, if you want.
//*
//* PLEASE NOTE: MY FADING OF MY SYSTEM DOES !NOT! USE
//* WC3S FADE SYSTEM! IT SIMPLY CHANGES THE COLOR OF THE
//* TEXTTAG WITH LESS ALPHA! YOU CAN USE BOTH TOGETHER,
//* BUT I DOUBT ITS A GOOD IDEA!
//*
//*
//* by dhk_undead_lord / aka Anachron
//*
//******************************************************************************
library CustomBar initializer init requires ARGB

    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
    //: Change anything below to what you need!
    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#

    //: The customizeable constants.
    //: I hope the names are self-explaining.
    //: (If not, check the CustomBar Documentation!
    globals
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: Texttag defaults.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        public constant string FADE_TYPE_IN = "IN"
        public constant string FADE_TYPE_OUT = "OUT"
        private constant real FADE_MIN = 0.
        private constant real FADE_MAX = 1.00
        private constant real TT_DEFAULT_AGE = 0.
        private ARGB TT_DEFAULT_COLOR
        private constant real TT_DEFAULT_FADEPOINT = 0.
        private constant boolean TT_DEFAULT_FADES = true
        private constant real TT_DEFAULT_FADE_STATE = FADE_MIN
        private constant real TT_DEFAULT_FADE_STRENGH = 0.75
        private constant string TT_DEFAULT_FADE_TYPE = FADE_TYPE_OUT
        private constant boolean TT_DEFAULT_FADING = false
        private constant texttag TT_DEFAULT_HANDLE = null
        private constant real TT_DEFAULT_LIFESPAN = 0.
        private constant boolean TT_DEFAULT_PERMANENT = true
        private constant real TT_DEFAULT_OFFSETX = 0.
        private constant real TT_DEFAULT_OFFSETY = 0.
        private constant real TT_DEFAULT_OFFSETZ = 0.
        private constant real TT_DEFAULT_POSX = 0.
        private constant real TT_DEFAULT_POSY = 0.
        private constant real TT_DEFAULT_POSZ = 0.
        private constant real TT_DEFAULT_SIZE = 7.5 * 0.023 / 10
        private constant boolean TT_DEFAULT_SUSPENDED = false
        private constant string TT_DEFAULT_TEXT = ""
        private constant real TT_DEFAULT_VELX = 0.
        private constant real TT_DEFAULT_VELY = 0.
        private constant boolean TT_DEFAULT_VISIBILITY = true

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: TextBar defaults.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        private constant string TB_DEFAULT_CHAR = "I"
        private constant integer TB_DEFAULT_CHAR_AMOUNT = 25
        private constant string TB_DEFAULT_CHAR_EMPTY = "*"
        private ARGB TB_DEFAULT_CHAR_COLOR
        private constant string TB_DEFAULT_FINISHEDBAR = ""
        private ARGB TB_DEFAULT_LIMITER_COLOR
        private constant string TB_DEFAULT_LIMITER_SYMBOL_LEFT = "["
        private constant string TB_DEFAULT_LIMITER_SYMBOL_RIGHT = "]"
        private constant boolean TB_DEFAULT_LIMITER_VISIBLE = true
        private constant real TB_DEFAULT_PERCENTAGE = 100.
        private constant integer TB_MAX_CHAR_AMOUNT = 100

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: CustomBar defaults.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        private constant boolean CB_DEFAULT_LOCKED = true
        private constant unit CB_DEFAULT_TARGET = null
        private constant force CB_DEFAULT_SHOW_FORCE = bj_FORCE_ALL_PLAYERS

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: TextBarStack defaults.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        private constant timer CBS_TIMER = CreateTimer()
        private constant real CBS_TICK = 0.0375

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: Information.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: For the ARGB declaration check the function init,
        //: at the total bottom of this library.
    endglobals

    //: The interfaces for the system
    public function interface iChange takes CustomBar cb returns nothing
    public function interface iFade takes CustomBar cb returns boolean
    public function interface iShow takes player owner, player cur returns boolean

    //: Default functions for this system
    public function defaultFadeCondition takes CustomBar cb returns boolean
        return GetUnitState(cb.target, UNIT_STATE_LIFE) == 0.
    endfunction

    public function defaultShowCondition takes player owner, player cur returns boolean
        return true
    endfunction

    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
    //: I don't recommend changing code below this!
    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#

    //==-=-=-=-=-=-=-
    //: Textmacros
    //==-=-=-=-=-=-=-
    //! textmacro varOp takes name, fname, type, method
    method operator $fname$ takes nothing returns $type$
        return .$name$
    endmethod

    method operator $fname$= takes $type$ val returns nothing
        set .$name$ = val
        $method$
    endmethod
    //! endtextmacro
    //==-=-=-=-=-=-=-

    //: A struct which contains all
    //: TextTag methods and members
    private struct TextTag
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: TextTag members. Sorted by name.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private real Age = TT_DEFAULT_AGE
        private ARGB Color = TT_DEFAULT_COLOR
        private boolean Fades = TT_DEFAULT_FADES
        private real FadeState = TT_DEFAULT_FADE_STATE
        private real FadeStrengh = TT_DEFAULT_FADE_STRENGH
        private string FadeType = TT_DEFAULT_FADE_TYPE
        private real Fadepoint = TT_DEFAULT_FADEPOINT
        private boolean Fading = TT_DEFAULT_FADING
        private iFade FadeCond = defaultFadeCondition
        private real Lifespan = TT_DEFAULT_LIFESPAN
        private texttag Handle = TT_DEFAULT_HANDLE
        private boolean Permanent = TT_DEFAULT_PERMANENT
        private real OffsetX = TT_DEFAULT_OFFSETX
        private real OffsetY = TT_DEFAULT_OFFSETY
        private real OffsetZ = TT_DEFAULT_OFFSETZ
        private real PosX = TT_DEFAULT_POSX
        private real PosY = TT_DEFAULT_POSY
        private real PosZ = TT_DEFAULT_POSZ
        private boolean Suspended = TT_DEFAULT_SUSPENDED
        private string Text = TT_DEFAULT_TEXT
        private real Size = TT_DEFAULT_SIZE
        private real VelX = TT_DEFAULT_VELX
        private real VelY = TT_DEFAULT_VELY
        private boolean Visibility = TT_DEFAULT_VISIBILITY

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: TextTag methods.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public static method create takes nothing returns thistype
            local thistype this = thistype.allocate()

            set .Handle = CreateTextTag()
            call .updAge()
            call .updColor()
            call .updFadepoint()
            call .updLifespan()
            call .updPermanent()
            call .updPos()
            call .updSuspended()
            call .updText()
            call .updVelocity()

            return this
        endmethod

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Update Methods.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private method updAge takes nothing returns nothing
            call SetTextTagAge(.Handle, .Age)
        endmethod

        private method updColor takes nothing returns nothing
            if not .fading then
                call SetTextTagColor(.Handle, .Color.red, .Color.green, .Color.blue, .Color.alpha)
            endif
        endmethod

        private method updFadepoint takes nothing returns nothing
            call SetTextTagFadepoint(.Handle, .Fadepoint)
        endmethod

        private method updLifespan takes nothing returns nothing
            call SetTextTagLifespan(.Handle, .Lifespan)
        endmethod

        private method updPermanent takes nothing returns nothing
            call SetTextTagPermanent(.Handle, .Permanent)
        endmethod

        private method updPos takes nothing returns nothing
            call SetTextTagPos(.Handle, .PosX, .PosY, .PosZ)
        endmethod

        private method updSuspended takes nothing returns nothing
            call SetTextTagSuspended(.Handle, .Suspended)
        endmethod

        private method updText takes nothing returns nothing
            call SetTextTagText(.Handle, .Text, .Size)
        endmethod

        private method updVelocity takes nothing returns nothing
            call SetTextTagVelocity(.Handle, .VelX, .VelY)
        endmethod

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Member setting / getting
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Variables that should update the texttag
        //==----------------------------------------
        //! runtextmacro varOp("Age", "age", "real", "call .updAge()")
        //! runtextmacro varOp("Color", "color", "ARGB", "call .updColor()")
        //! runtextmacro varOp("Fadepoint", "fadepoint", "real", "call .updFadepoint()")
        //! runtextmacro varOp("Lifespan", "lifespan", "real", "call .updLifespan()")
        //! runtextmacro varOp("Permanent", "permanent", "boolean", "call .updPermanent()")
        //! runtextmacro varOp("Suspended", "suspended", "boolean", "call .updSuspended()")
        //! runtextmacro varOp("Visibility", "visiblity", "boolean", "")

        //==--------------------------------------------
        //: Variables that shouldn't update the texttag
        //==--------------------------------------------
        //! runtextmacro varOp("Fades", "fades", "boolean", "")
        //! runtextmacro varOp("FadeCond", "fadeCond", "iFade", "")
        //! runtextmacro varOp("FadeState", "fadeState", "real", "")
        //! runtextmacro varOp("FadeStrengh", "fadeStrengh", "real", "")
        //! runtextmacro varOp("FadeType", "fadeType", "string", "")
        //! runtextmacro varOp("Fading", "fading", "boolean", "")
        //! runtextmacro varOp("Handle", "handle", "texttag", "")
        //! runtextmacro varOp("OffsetX", "offsetX", "real", "")
        //! runtextmacro varOp("OffsetY", "offsetY", "real", "")
        //! runtextmacro varOp("OffsetZ", "offsetZ", "real", "")

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Advanced members and their settings.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public method pos takes real x, real y, real z returns nothing
            set .PosX = x + .OffsetX
            set .PosY = y + .OffsetY
            set .PosZ = z + .OffsetZ
            call .updPos()
        endmethod

        public method posUnit takes unit u, real z returns nothing
            call .pos(GetUnitX(u), GetUnitY(u), z)
        endmethod

        public method text takes string t, real s returns nothing
            set .Text = t
            set .Size = s * 0.023 / 10
            call .updText()
        endmethod

        method operator textText takes nothing returns string
            return .Text
        endmethod

        method operator textText= takes string t returns nothing
            set .Text = t
            call .updText()
        endmethod

        method operator textSize takes nothing returns real
            return .Size
        endmethod

        method operator textSize= takes real s returns nothing
            set .Size = s
            call .updText()
        endmethod

        public method velocity takes real s, real angle returns nothing
            local real vel = s * 0.071 / 128
            set .VelX = vel * Cos(angle * bj_DEGTORAD)
            set .VelY = vel * Sin(angle * bj_DEGTORAD)
            call .updVelocity()
        endmethod

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Advanced Methods
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public method showPlayer takes player p returns nothing
            if GetLocalPlayer() == p then
                call SetTextTagVisibility(.Handle, .Visibility)
            endif
        endmethod

        public method fade takes CustomBar cb returns nothing
            local boolean c = false
            local boolean r = false
            local ARGB color = 0

            if .Fades then
                set c = .fadeCond.evaluate(cb)

                if c and .FadeState < FADE_MAX then
                    set .FadeType = FADE_TYPE_OUT
                    set .Fading = true
                    set r = true
                elseif not(c) and .FadeState > FADE_MIN then
                    set .FadeType = FADE_TYPE_IN
                    set .Fading = true
                    set r = true
                endif

                if .Fading then
                    //: Lets calculate the fading!
                    if .FadeType == FADE_TYPE_OUT then
                        set .FadeState = .FadeState + .FadeStrengh * CBS_TICK
                        if .FadeState >= FADE_MAX then
                            set .FadeState = FADE_MAX
                            set .Fading = false
                        endif
                    elseif .FadeType == FADE_TYPE_IN then
                        set .FadeState = .FadeState - .FadeStrengh * CBS_TICK
                        if .FadeState <= FADE_MIN then
                            set .FadeState = FADE_MIN
                            set .Fading = false
                        endif
                    endif

                    if .Fading then
                        call SetTextTagAge(.Handle, .FadeState)
                    endif
                endif

                if r then
                    if .Fading then
                        call SetTextTagAge(.Handle, .FadeState)
                        call SetTextTagFadepoint(.Handle, 0.)
                        call SetTextTagLifespan(.Handle, FADE_MAX + CBS_TICK * 2)
                        call SetTextTagPermanent(.Handle, false)
                        call cb.showCB()
                    else
                        call SetTextTagAge(.Handle, .Age)
                        call SetTextTagLifespan(.Handle, .Lifespan)
                        call SetTextTagFadepoint(.Handle, .Fadepoint)
                        call SetTextTagPermanent(.Handle, .Permanent)

                        if .FadeType == FADE_TYPE_OUT then
                            call SetTextTagVisibility(.Handle, false)
                        endif
                    endif
                endif
            endif
        endmethod

        private method onDestroy takes nothing returns nothing
            call DestroyTextTag(.Handle)
        endmethod
    endstruct

    //: A struct which contains all
    //: Textbar methods and members
    private struct TextBar
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: TextBar members. Sorted by name.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private string Char = TB_DEFAULT_CHAR
        private integer CharAmount = TB_DEFAULT_CHAR_AMOUNT
        private ARGB CharColor = TB_DEFAULT_CHAR_COLOR
        private ARGB array CharColors [TB_MAX_CHAR_AMOUNT]
        private string CharEmpty = TB_DEFAULT_CHAR_EMPTY
        private string FinishedBar = TB_DEFAULT_FINISHEDBAR
        private ARGB LimiterColor = TB_DEFAULT_LIMITER_COLOR
        private string LimiterSymbolLeft = TB_DEFAULT_LIMITER_SYMBOL_LEFT
        private string LimiterSymbolRight = TB_DEFAULT_LIMITER_SYMBOL_RIGHT
        private boolean LimiterVisible = TB_DEFAULT_LIMITER_VISIBLE
        private real Percentage = TB_DEFAULT_PERCENTAGE

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: TextBar methods
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public static method create takes nothing returns thistype
            local thistype this = thistype.allocate()

            return this
        endmethod
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Member setting / getting
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Variables that should'nt update the texttag
        //==--------------------------------------------
        //! runtextmacro varOp("Char", "char", "string", "")
        //! runtextmacro varOp("CharAmount", "charAmount", "integer", "")
        //! runtextmacro varOp("CharEmpty", "charEmpty", "string", "")
        //! runtextmacro varOp("FinishedBar", "finishedBar", "string", "")
        //! runtextmacro varOp("LimiterColor", "limiterColor", "ARGB", "")
        //! runtextmacro varOp("LimiterSymbolLeft", "limiterSymbolLeft", "string", "")
        //! runtextmacro varOp("LimiterSymbolRight", "limiterSymbolRight", "string", "")
        //! runtextmacro varOp("LimiterVisible", "limiterVisible", "boolean", "")
        //! runtextmacro varOp("Percentage", "percentage", "real", "")

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Advanced Methods
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public method addGradient takes ARGB left, ARGB right, integer start, integer end returns nothing
            local integer i = start - 1
            local boolean e = false
            local real s = 0.
            local string test = ""
            local real m = 100 / .CharAmount
            set m = m / 100

            loop
                exitwhen e

                if i < end then
                    set s = i * m
                    set test = "i :" + I2S(i) + "\n" + " 1 / " + I2S(.CharAmount) + " = " + R2S(s)
                    set .CharColors<i> = ARGB.mix(left, right, s)

                    set i = i + 1
                else
                    set e = true
                endif
            endloop
        endmethod

        public method generateBar takes nothing returns nothing
            local integer i = 0
            local string char = &quot;&quot;

            set .FinishedBar = &quot;&quot;

            loop
                exitwhen i &gt;= .CharAmount

                if i &lt; (.Percentage / 100) * .CharAmount then
                    if .CharColors<i> != 0 then
                        set char = .CharColors<i>.str(.Char)
                    else
                        set char = .CharColor.str(.Char)
                    endif
                else
                    set char = .CharEmpty
                endif

                set .FinishedBar = .FinishedBar + char

                set i = i + 1
            endloop

            if .LimiterVisible then
                set .FinishedBar = .LimiterColor.str(.LimiterSymbolLeft) + .FinishedBar + .LimiterColor.str(.LimiterSymbolRight)
            endif
        endmethod
    endstruct

    //: A struct which contains all
    //: Custom methods and members
    struct CustomBar
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: CustomBar members
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private unit Target = CB_DEFAULT_TARGET
        private boolean Locked = CB_DEFAULT_LOCKED
        private iChange UpdateMethod

        private iShow ShowCond = defaultShowCondition
        private force ShowForce = CB_DEFAULT_SHOW_FORCE

        private TextBar TxtBar
        private TextTag TxtTag

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: CustomBar methods
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public static method create takes unit target, iChange updMeth returns thistype
            local thistype this = thistype.allocate()

            set .Target = target
            set .TxtBar = TextBar.create()
            set .TxtTag = TextTag.create()
            set .UpdateMethod = updMeth

            call CBStack.addCustomBar(this)

            return this
        endmethod

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Member setting / getting
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Variables that should&#039;nt update the texttag
        //==--------------------------------------------
        //! runtextmacro varOp(&quot;Locked&quot;, &quot;locked&quot;, &quot;boolean&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;ShowCond&quot;, &quot;showCond&quot;, &quot;iShow&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;ShowForce&quot;, &quot;showForce&quot;, &quot;force&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;Target&quot;, &quot;target&quot;, &quot;unit&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;TxtTag&quot;, &quot;txtTag&quot;, &quot;TextTag&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;TxtBar&quot;, &quot;txtBar&quot;, &quot;TextBar&quot;, &quot;&quot;)
        //! runtextmacro varOp(&quot;UpdateMethod&quot;, &quot;updateMethod&quot;, &quot;iChange&quot;, &quot;&quot;)

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Advanced methods.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        public method Show takes force f, iShow c returns nothing
            set .ShowForce = f
            set .ShowCond = c
        endmethod

        public method checkP takes player p returns nothing
            if .ShowCond.evaluate(GetOwningPlayer(.Target), p) then
                call .TxtTag.showPlayer(p)
            endif
        endmethod

        public method showCB takes nothing returns nothing
            local integer i = 0
            local boolean e = false

            loop
                exitwhen e

                if i &lt; 15 then
                    if IsPlayerInForce(Player(i), .ShowForce) then
                        call .checkP(Player(i))
                    endif

                    set i = i + 1
                else
                    set e = true
                endif
            endloop
        endmethod

        public method updateBar takes nothing returns nothing
            if .Locked then
                call .TxtTag.posUnit(.Target, 0.)
            endif

            call .UpdateMethod.execute(this)
            call .TxtBar.generateBar()
            set .TxtTag.textText = .TxtBar.finishedBar
        endmethod

        public method update takes nothing returns nothing
            call .updateBar()
            call .TxtTag.fade(this)
        endmethod

        private method onDestroy takes nothing returns nothing
            call CBStack.remCustomBar(this)
            call .TxtTag.destroy()
            call .TxtBar.destroy()
        endmethod
    endstruct

    //: A struct which is used to
    //: update CustomBars
    struct CBStack
        static CustomBar array CBars
        static integer index = 0

        public static method addCustomBar takes CustomBar cb returns nothing
            set thistype.CBars[thistype.index] = cb
            set thistype.index = thistype.index + 1

            if thistype.index == 1 then
                call TimerStart(CBS_TIMER, CBS_TICK, true, function thistype.updateBars)
            endif
        endmethod

        public static method remCBByIndex takes integer i returns nothing
            set thistype.CBars<i> = thistype.CBars[thistype.index]
            set thistype.index = thistype.index - 1

            if thistype.index &lt;= 0 then
                call PauseTimer(CBS_TIMER)
            endif
        endmethod

        public static method remCustomBar takes CustomBar cb returns nothing
            local integer i = 0
            local boolean e = false

            loop
                exitwhen e

                if i &lt; thistype.index then
                    if thistype.CBars<i> == cb then
                        call .remCBByIndex(i)
                        set e = true
                    else
                        set i = i + 1
                    endif
                else
                    set e = true
                endif
            endloop
        endmethod

        public static method updateBars takes nothing returns nothing
            local integer i = 0
            local boolean e = false

            loop
                exitwhen e

                if i &lt; thistype.index then

                    if thistype.CBars<i> == 0 then
                        call thistype.remCBByIndex(i)
                        set i = i - 1
                    else
                        call thistype.CBars<i>.update()
                    endif

                    set i = i + 1
                else
                    set e = true
                endif
            endloop
        endmethod
    endstruct

    //: The init method, initialisates
    //: a few default objects
    private function init takes nothing returns nothing
        set TB_DEFAULT_CHAR_COLOR = ARGB.create(255, 255, 255, 255)
        set TB_DEFAULT_LIMITER_COLOR = ARGB.create(255, 255, 255, 255)
        set TT_DEFAULT_COLOR = ARGB.create(255, 255, 255, 255)
    endfunction
endlibrary
</i></i></i></i></i></i></i>


Documentation:
JASS:
//******************************************************************************
// =-=-=-=-=-=-=-
// THE CONSTANTS
// =-=-=-=-=-=-=-
/*
    //: Sets the identifier
    //: for the fade type in.
    FADE_TYPE_IN = &quot;IN&quot;

    //: Sets the identifier
    //: for the fade type out.
    FADE_TYPE_OUT = &quot;OUT&quot;

    //: Sets the boundaries
    //: for the fading
    FADE_MIN = 0.
    FADE_MAX = 1.00

    //: Sets the default age
    //: of the texttag.
    TT_DEFAULT_AGE = 0.

    //: Sets the default angle
    //: of the texttag.
    TT_DEFAULT_ANGLE = 90.

    //: Sets the default color
    //: of the texttag.
    //: (INITIALIZED IN INIT METHOD)
    TT_DEFAULT_COLOR

    //: Sets the default fadepoint
    //: of the texttag.
    TT_DEFAULT_FADEPOINT = 0.

    //: Sets the default boolean
    //: of the texttag if its able
    //: to fade.
    TT_DEFAULT_FADES = true

    //: Sets the default fade color
    //: of the texttag.
    //: (INITIALIZED IN INIT METHOD)
    TT_DEFAULT_FADE_COLOR

    //: Sets the default fadestate
    //: of the texttag.
    TT_DEFAULT_FADE_STATE = FADE_MIN

    //: Sets the default fadestrengh
    //: of the texttag.
    TT_DEFAULT_FADE_STRENGH = 0.75

    //: Sets the default fade type
    //: of the texttag.
    TT_DEFAULT_FADE_TYPE = FADE_TYPE_OUT

    //: Sets the default boolean
    //: of the texttag if its fading
    //: or not.
    TT_DEFAULT_FADING = false

    //: Sets the default handle
    //: of the texttag.
    TT_DEFAULT_HANDLE = null

    //: Sets the default lifespan time
    //: of the texttag.
    TT_DEFAULT_LIFESPAN = 0.

    //: Sets the default boolean
    //: of the texttag if its permanent.
    TT_DEFAULT_PERMANENT = true

    //: Sets the default offsets
    //: of the texttag.
    TT_DEFAULT_OFFSETX = 0.
    TT_DEFAULT_OFFSETY = 0.
    TT_DEFAULT_OFFSETZ = 0.

    //: Sets the default location
    //: of the texttag.
    TT_DEFAULT_POSX = 0.
    TT_DEFAULT_POSY = 0.
    TT_DEFAULT_POSZ = 0.

    //: Sets the default textsize
    //: of the texttag.
    //: Note: This is the wc3 size,
    //: not the normal word one,
    //: so we recalculate it with
    //: the formula.
    TT_DEFAULT_SIZE = 7.5 * 0.023 / 10

    //: Sets the default boolean
    //: of the texttag if its suspended
    //: or not.
    TT_DEFAULT_SUSPENDED = false

    //: Sets the default speed
    //: of the texttag.
    TT_DEFAULT_SPEED = 10 * (0.071 / 128)

    //: Sets the default text
    //: of the texttag.
    TT_DEFAULT_TEXT = &quot;&quot;

    //: Sets the default velocity
    //: of the texttag.
    TT_DEFAULT_VELX = TT_DEFAULT_SPEED * Cos(TT_DEFAULT_ANGLE * bj_DEGTORAD)
    TT_DEFAULT_VELY = TT_DEFAULT_SPEED * Sin(TT_DEFAULT_ANGLE * bj_DEGTORAD)

    //: Sets the default boolean
    //: of the texttag if its shown
    //: or not.
    TT_DEFAULT_VISIBILITY = true
*/
/*
    //: Sets the default char symbol
    //: of the TextBar.
    TB_DEFAULT_CHAR = &quot;||&quot;

    //: Sets the default char amount
    //: of the TextBar.
    TB_DEFAULT_CHAR_AMOUNT = 25

    //: Sets the default empty char symbol
    //: of the TextBar.
    TB_DEFAULT_CHAR_EMPTY = &quot; &quot;

    //: Sets the default char color
    //: of the TextBar.
    //: (INITIALIZED IN INIT METHOD)
    TB_DEFAULT_CHAR_COLOR

    //: Sets the default bar string
    //: of the TextBar.
    TB_DEFAULT_FINISHEDBAR = &quot;&quot;

    //: Sets the default limiter color
    //: of the TextBar.
    //: (INITIALIZED IN INIT METHOD)
    TB_DEFAULT_LIMITER_COLOR

    //: Sets the default limiter symbol
    //: on the left of the TextBar.
    TB_DEFAULT_LIMITER_SYMBOL_LEFT = &quot;[&quot;

    //: Sets the default limiter symbol
    //: on the right of the TextBar.
    TB_DEFAULT_LIMITER_SYMBOL_RIGHT = &quot;]&quot;

    //: Sets the default boolean if limiters
    //: are shown in the TextBar.
    TB_DEFAULT_LIMITER_VISIBLE = true

    //: Sets the default percentage
    //: of the TextBar.
    TB_DEFAULT_PERCENTAGE = 100.

    //: Sets the maximum amount of chars
    //: in a TextBar.
    TB_MAX_CHAR_AMOUNT = 100
*/
/*
    //: Sets the default boolean
    //: of the CustomBar if its locked
    //: to the unit or not.
    CB_DEFAULT_LOCKED = true

    //: Sets the default target
    //: of the CustomBar.
    CB_DEFAULT_TARGET = null

    //: Sets the default force
    //: of the CustomBar to which its
    //: displayed.
    CB_DEFAULT_SHOW_FORCE = bj_FORCE_ALL_PLAYERS

*/
/*
    //: Sets the timer for the CBStack.
    CBS_TIMER = CreateTimer()

    //: Sets the update interval
    //: for timer above.
    CBS_TICK = 0.0375
*/
//******************************************************************************


Example:
JASS:
library CustomBarExample initializer init requires CustomBar

    //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    //: Update Functions
    //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    public function setLifePer takes CustomBar cb returns nothing
        set cb.txtBar.percentage = GetUnitStatePercent(cb.target, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
    endfunction

    public function setManaPer takes CustomBar cb returns nothing
        set cb.txtBar.percentage = GetUnitStatePercent(cb.target, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
    endfunction

    public function showCheck takes player owner, player cur returns boolean
        return IsPlayerAlly(owner, cur) or owner == cur
    endfunction

    private function init takes nothing returns nothing
        local CustomBar cb = 0
        local unit u = CreateUnit(Player(0), &#039;Hamg&#039;, 0., 0., 0.)
        local ARGB left = 0
        local ARGB right = 0

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: CustomBar Creation - Hitpoint Bar
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Lets initialize colors!
        //: Parameters: Alpha, red, green, blue
        set left = ARGB.create(255, 8, 74, 16)
        set right = ARGB.create(255, 214, 255, 230)

        //: Create a new CustomBar!
        //: Parameters:
        //: u -&gt; Unit that actually owns the bar
        //: setLifePer -&gt; Function that changes the par Percentage
        set cb = CustomBar.create(u, CustomBar_iChange.setLifePer)

        //: Add a few offsets
        set cb.txtTag.offsetX = -92.
        set cb.txtTag.offsetY = -32.

        //: Add Gradients
        //: Parameters:
        //: left -&gt; Left Gradient
        //: right -&gt; Right Gradient
        //: 1 -&gt; Start from position
        //: 25 -&gt; End at position
        call cb.txtBar.addGradient(left, right, 1, 25)

        //: Set the texttag showing for players
        //: Parameters:
        //: bj_FORCE_ALL_PLAYERS -&gt; A player force that could see the textag
        //: CustomBar_iShow.showCheck -&gt; Method that must return true
        //: in order that player is allowed to see the texttag.
        call cb.Show(bj_FORCE_ALL_PLAYERS, CustomBar_iShow.showCheck)

        //: This actually shows it.
        call cb.showCB()

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: CustomBar Creation - Mana Bar
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Lets initialize colors!
        //: Parameters: Alpha, red, green, blue
        set left = ARGB.create(255, 8, 66, 90)
        set right = ARGB.create(255, 239, 239, 239)

        //: Create a new CustomBar!
        //: Parameters:
        //: u -&gt; Unit that actually owns the bar
        //: setLifePer -&gt; Function that changes the par Percentage
        set cb = CustomBar.create(u, CustomBar_iChange.setManaPer)

        //: Add a few offsets
        set cb.txtTag.offsetX = -92.
        set cb.txtTag.offsetY = -64.

        //: Add Gradients
        //: Parameters:
        //: left -&gt; Left Gradient
        //: right -&gt; Right Gradient
        //: 1 -&gt; Start from position
        //: 25 -&gt; End at position
        call cb.txtBar.addGradient(left, right, 1, 25)

        //: Set the texttag showing for players
        //: Parameters:
        //: bj_FORCE_ALL_PLAYERS -&gt; A player force that could see the textag
        //: CustomBar_iShow.showCheck -&gt; Method that must return true
        //: in order that player is allowed to see the texttag.
        call cb.Show(bj_FORCE_ALL_PLAYERS, CustomBar_iShow.showCheck)

        //: This actually shows it.
        call cb.showCB()

        //: Finished! Can life be easier?
    endfunction
endlibrary


Systems using this:
JASS:
//*|------------------------------------------------------------------------------------|&gt;
//*| SpellBar v.1.00 |&gt;
//*| by dhk_undead_lord aka Anachron |&gt;
//*| |&gt;
//*| ABOUT: |&gt;
//*| This system provides you with the ability to create RPG cast |&gt;
//*| bars, such as in World of Warcraft. |&gt;
//*| |&gt;
//*| WHAT YOU NEED: |&gt;
//*| You need JassNewGenPack to use this vJASS system. |&gt;
//*| (Download it here: <a href="http://www.wc3c.net/showthread.php?goto=newpost&amp;t=90999" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?goto=newpost&amp;t=90999</a>) |&gt;
//*| |&gt;
//*| STEPS TO IMPORT: |&gt;
//*| I.) Copy this code. |&gt;
//*| II.) Paste it into the head of your map. |&gt;
//*| (Therefor go to the Trigger Editor, select the mapname and paste |&gt;
//*| into the area on the right) |&gt;
//*| III.) Save your map! |&gt;
//*| (With File - Save Map (S) or control + S. DO NOT SAVE WITH SAVE AS!) |&gt;
//*| IV.) You got it! You imported the system. |&gt;
//*| |&gt;
//*| To make sure this system works, you should try a few tests! |&gt;
//*|------------------------------------------------------------------------------------|&gt;
library SpellBar initializer init requires CustomBar

    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
    //: Change anything below to what you need!
    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#

    //: The customizeable constants.
    //: I hope the names are self-explaining.
    globals
        private constant real TIMER_TICK = 0.03
    endglobals

    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
    //: I don&#039;t recommend changing code below this!
    //=!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
    globals
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        //: System data.
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        private hashtable SpellBarInstances = InitHashtable()
        private trigger SystemTrigger = CreateTrigger()

    endglobals

    public function updateSpellBar takes CustomBar cb returns nothing
        local SpellBar sb = SpellBar(LoadInteger(SpellBarInstances, GetHandleId(cb.target), 0))
        set cb.txtBar.percentage = (sb.elapsed / sb.max) * 100
    endfunction

    public function showCheck takes player owner, player cur returns boolean
        return IsPlayerAlly(owner, cur) or owner == cur
    endfunction

    //: A struct which contains all SpellBar
    //: information we need.
    struct SpellBar
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: SpellBar members
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private CustomBar cb = 0
        public real elapsed = 0.
        public real max = 0.
        public unit han = null

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: Static members
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private static timer TIMER = CreateTimer()
        private static thistype array INSTANCES[8191]
        private static integer INDEX = 0

        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        //: SpellBar methods
        //==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        private static method drainInst takes thistype this returns boolean
            if .elapsed &lt; .max then
                set .elapsed = .elapsed + TIMER_TICK
                return false
            else
                call .destroy()
                return true
            endif
        endmethod

        private static method drain takes nothing returns nothing
            local integer i = 0

            loop
                exitwhen i &gt;= thistype.INDEX

                if thistype.drainInst(thistype.INSTANCES<i>) then
                    set i = i - 1
                endif

                set i = i + 1
            endloop

            if thistype.INDEX &lt;= 0 then
                call PauseTimer(thistype.TIMER)
            endif
        endmethod

        public static method create takes unit u, integer i, real dur, CustomBar b returns thistype
            local thistype this = thistype.allocate()
            local ARGB left = 0
            local ARGB right = 0
            local CustomBar c = 0

            //: Set variables
            set .han = u
            set .max = dur

            //: Save the CustomBar
            set .cb = b

            set thistype.INSTANCES[.INDEX] = this
            set thistype.INDEX = thistype.INDEX + 1
            if thistype.INDEX == 1 then
                call TimerStart(thistype.TIMER, TIMER_TICK, true, function thistype.drain)
            endif
            call SaveInteger(SpellBarInstances, GetHandleId(u), 0, integer(this))

            return this
        endmethod

        private method onDestroy takes nothing returns nothing
            set thistype.INSTANCES[integer(this)] = thistype.INSTANCES[thistype.INDEX]
            set thistype.INDEX = thistype.INDEX - 1
            call FlushChildHashtable(SpellBarInstances, GetHandleId(.han))
            call .cb.destroy()
        endmethod
    endstruct

//: Handles the SpellBar removing
//: if unit gets an new order while casting.
    private function eventHandler takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer i = GetHandleId(u)
        local integer sbID = LoadInteger(SpellBarInstances, i, 0)
        local SpellBar sb = SpellBar(sbID)

        if sb.han != null then
            call sb.destroy()
        endif
    endfunction

    //: This function now registers any order which is able to
    //: interrupt the spell cast. Default is everything.
    private function init takes nothing returns nothing
        local integer i = 0

        call TriggerAddAction(SystemTrigger, function eventHandler)

        loop
            exitwhen i &gt;= 15

            call TriggerRegisterPlayerUnitEvent(SystemTrigger, Player(i), EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(SystemTrigger, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
            call TriggerRegisterPlayerUnitEvent(SystemTrigger, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)

            set i = i + 1
        endloop
    endfunction

endlibrary
</i>


SpellBar example:
JASS:
scope SpellBarTest initializer init

    private function newSpellBar takes nothing returns nothing
        local CustomBar c = 0
        local ARGB left = 0
        local ARGB right = 0

        //: =-------------------=
        //: Initialize CustomBar
        //: =-------------------=
        //: Add Colors
        set left = ARGB.create(255, 8, 74, 16)
        set right = ARGB.create(255, 214, 255, 230)
        //: I Highly suggest to not touch this-&gt;
        set c = CustomBar.create(GetTriggerUnit(), CustomBar_iChange.SpellBar_updateSpellBar)
        //: Add a gradient
        call c.txtBar.addGradient(left, right, 1, 25)
        //: Show the CustomBar to this playergroup
        call c.Show(bj_FORCE_ALL_PLAYERS, CustomBar_iShow.SpellBar_showCheck)
        //: Display the CustomBar.
        call c.showCB()
        //: Now change our CustomBar to display the Spellname aswell.
        set c.txtBar.limiterVisible = true
        set c.txtBar.limiterSymbolRight = &quot;&quot;
        set c.txtBar.limiterSymbolLeft = GetObjectName(&#039;AHhb&#039;) + &quot;\n&quot;

        //: Actually creates the SpellBar
        call SpellBar.create(GetTriggerUnit(), &#039;AHhb&#039;, 2.00, c)
    endfunction

    private function holyLightOnly takes nothing returns boolean
        return GetSpellAbilityId() == &#039;AHhb&#039;
    endfunction

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0

        call TriggerAddAction(t, function newSpellBar)
        call TriggerAddCondition(t, Condition(function holyLightOnly))

        loop
            exitwhen i &gt;= 15

            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_CHANNEL, null)
            set i = i + 1
        endloop

        set t = null
    endfunction

endscope
 

Attachments

  • SpellBar.v.1.01.w3x
    39.4 KB · Views: 315
  • UserBar_v.1.00.w3m
    36 KB · Views: 316
  • spells_2855_screenshot_tnb.jpg
    spells_2855_screenshot_tnb.jpg
    25.1 KB · Views: 573
  • spells_2926_screenshot_tnb.jpg
    spells_2926_screenshot_tnb.jpg
    19.2 KB · Views: 525

Troll-Brain

You can change this now in User CP.
Reaction score
85
I would have said depends how many text tags you layer on top of each other...
Ofc but you shouldn't use spaces between them anyway.
Without any space between them, if you take a low resolution you will see the texttags.
 

Azlier

Old World Ghost
Reaction score
461
Using the | character results in nice, smooth text tag bars.
 

Anachron

New Member
Reaction score
53
You can change any values you want at any time.
I know that | is better, however the I is supported even at russian keyboards.
 

Anachron

New Member
Reaction score
53
W/E. Can this resource be approved now? :p I don't get any feedback to the code, just about the | thing.
 

Azlier

Old World Ghost
Reaction score
461
You want code comments? I'll give ya code comments.

First of all, why not use T32? Would be better that way.

Second, you haven't replaced 'I' with '|" yet.

Third, [lJASS]showPlayer[/lJASS] is a horrible name for that method.

Fourth, your varOp textmacro needs a name that won't conflict with other stuff. A good rule of thumb is to make internal textmacros "private" by make them named things like LIBRARYNAME__Textmacro.

Fifth, you shouldn't use forces.

Sixth, making those function interfaces private would be nice.
 

Anachron

New Member
Reaction score
53
First of all, why not use T32? Would be better that way.
Whats do you mean with T32?

Second, you haven't replaced 'I' with '|" yet.
Yes, because its not supported on asian keyboard at all.

Third, showPlayer is a horrible name for that method.
So, to what should I rename it?

Fourth, your varOp textmacro needs a name that won't conflict with other stuff. A good rule of thumb is to make internal textmacros "private" by make them named things like LIBRARYNAME__Textmacro.
Textmacros are made to be public everywhere in the script, that is what they are thought for. You can even ask Vex, I told him the same as you tell me now.

Fifth, you shouldn't use forces.
Whats so bad about them? They make life easier.

Sixth, making those function interfaces private would be nice.
Ok, I guess that is a good point.
 

BlackRose

Forum User
Reaction score
239
T32 is Timer32

[ljass]private constant real TT_DEFAULT_SIZE = 7.5 * 0.023 / 10[/ljass]
Why not 7.5 * 0.0023? Or even 0.01725? You could have have a note saying only the first real should be modified.

JASS:
public method velocity takes real s, real angle returns nothing
      local real vel = s * 0.071 / 128
      set .VelX = vel * Cos(angle * bj_DEGTORAD)
      set .VelY = vel * Sin(angle * bj_DEGTORAD)
      call .updVelocity()
endmethod


Same with that.
 

Anachron

New Member
Reaction score
53
Timer32 is a waste of time and space. Its useless, I only use approved scripts from wc3c.net.

About the X * 0.023 / 10 stuff:
I took the wc3 native function parameters, and I think it shouldn't be that hard to get a rid of what you have to change, if there is only one number that something is multiplied with.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Timer32 is a waste of time and space. Its useless, I only use approved scripts from wc3c.net.
Well, i wouldn't say it like that ...
There are some good scripts here, some could be better but *shrugs*.
At least here we have less pretentious guys which care about suggestions from other users.
I mean, read scripts before saying statements.

For Timer32 i still have no proof that a player can notice the difference with TimerUtils and X timers instead though.
 

Anachron

New Member
Reaction score
53
If I use Timer32 it can't be approved on wc3c.net anymore, and I personally think they are good enough to know whats good and what not.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
If I use Timer32 it can't be approved on wc3c.net anymore, and I personally think they are good enough to know whats good and what not.
The first sentence is true, but the second is really sad, you can't make your own opinion, just believe in some others ones, and proclaim it as a fact, how lame ...
 

Anachron

New Member
Reaction score
53
Well, I have my own opinion, and that is, even if they are pretentious, they mostly are right, in whatever situation.

I personally think they are not the best, but they can help me getting better.
I also use my own stuff, for example Vexorian did not implemented a static if for modules, which I had to find workouts for because he didn't want to add it (yet).
 

Laiev

Hey Listen!!
Reaction score
188
just make T32 optional in your system, may help people here and don't will fuc* with your system in wc3c.

If people don't like T32, just don't use and the system still working on without any problem :rolleyes:
 
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