• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Help me improve this buffapplystruct

Status
Not open for further replies.
Level 22
Joined
Nov 14, 2008
Messages
3,256
Yeah this is just a struct which adds an ability to the unit and therefore adds a buff (usually abilities based on Tornado Slow Aura). It checks if the unit already has the current buff and if so, it extends the time instead of some other crap which would bug the UnitMakeAbilityPermanent.

Uses AIDS for some lock issue with a group. More info inside the JASS tag

JASS:
library BuffApplyStruct requires AIDS

//no I don't have any API functions yet and yes the struct is private, live with it I wont release it
//anyway

/* The lock part works like this,
    if the unit is already in the hit group, we only increase the lock amount
    of the unit "GetUnitId" and when the loop is fired and an instance is off
    we reduce the lock and if the lock is 0 we remove the unit from the hit group */

    private struct BuffStruct
    
        unit    u //unit member
        real    t //duration member
        integer abilid //ability id 
        integer buffid //buff id
        
        private static integer array lock // this static uses aids
        private static group hit = CreateGroup() //filtering
        private static integer array index// basic indexing
        private static integer total = 0 //above
        private static timer tim = CreateTimer() //above
        
        //dunno if this actually works but hey I just made it quickly
        static method GetInstance takes unit u returns thistype
            local integer i = 0
            local thistype this
            local integer array ii
            local boolean b = false
            loop
                exitwhen b == true
                set this = ii[i]
                if .u == u then
                    set b = true
                    return this
                endif
                set i = i + 1
            endloop
            return 0
        endmethod
        
        static method Loop takes nothing returns nothing
            local integer i = 0
            local integer id
            local thistype this
            loop
                exitwhen i >= total
                set this = index[i]
                set .t = .t - PERIOD
                if .t <= 0. and GetWidgetLife(.u) < 0.405 and IsUnitType(.u, UNIT_TYPE_DEAD) then
                    set id = GetUnitId(.u)
                    call UnitMakeAbilityPermanent(.u, false, .abilid)
                    call UnitRemoveAbility(.u, .abilid)
                    call UnitRemoveAbility(.u, .buffid)
                    call .destroy()
                    set lock[id] = lock[id] - 1
                    if lock[id] == 0 then
                        call GroupRemoveUnit(hit, .u)
                    endif
                    set total = total - 1
                    set index[i] = index[total]
                    set i = i - 1
                    if total == 0 then
                        call PauseTimer(tim)
                    endif
                endif
                set i = i + 1
            endloop
        endmethod
        
        static method create takes unit u, real t, integer abilid, integer buffid returns thistype
            local thistype this
            local integer id = GetUnitId(u)
            
    /* Now this is complicated.
            First we check if the unit is in any struct instance (not buff dependable)
                if so we check if the unit has any buff going on with our buffplacer
                    and if not we start a new instance else we just increase the time
                     below the else part */
            if IsUnitInGroup(u, hit) then
                if GetUnitAbilityLevel(u, abilid) == 0 then
                    set this = .allocate()
                    set .u = u
                    set .t = t
                    set .abilid = abilid
                    set .buffid = buffid
                    set lock[id] = lock[id] + 1
                    call UnitAddAbility(u, abilid)
                    call UnitMakeAbilityPermanent(u, true, abilid)
                    if total == 0 then
                        call TimerStart(tim, PERIOD, true, function thistype.Loop)
                    endif
                    set index[total] = this
                    set total = total + 1
                else
                    set this = GetInstance(u)
                    set .t = .t + t
                endif
                
        /* Or if the unit isn't in any struct instance at all we fire the below off and adds
                the unit into our group */
            else
                set this = .allocate()
                set .u = u
                set .t = t
                set .abilid = abilid
                set .buffid = buffid
                set lock[id] = lock[id] + 1
                call UnitAddAbility(u, abilid)
                call UnitMakeAbilityPermanent(u, true, abilid)
                call GroupAddUnit(hit, u)
                if total == 0 then
                    call TimerStart(tim, PERIOD, true, function thistype.Loop)
                endif
                set index[total] = this
                set total = total + 1
            endif
            return this
        endmethod
    endstruct
endlibrary

So give me some constructive critism about this, feel free to use it if you want to, I'm not going to release it public as there are lots of better buffstructs out there, credit me if you want to but don't take credit for it please.

I tried to apply T32 but hey it just adds the struct instances ...
 
Status
Not open for further replies.
Top