HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Stun System not unit stackable?

05-20-2009, 02:56 PM#1
wraithseeker
Collapse JASS:

////! external ObjectMerger w3h BPSE STNB fnam "Custom Stun"
////! external ObjectMerger w3a AHtb STUN abuf 1 STNB alev 1 aher 1 ahdu 1 0 adur 1 0 Htb1 1 0 amat "" amcs 1 0 anam "Custom Stun"
library CustomStun initializer Init uses AutoIndex

    globals
        private constant real       INTERVAL    = 0.03125       //Interval of the timer, thus, delta value
        private constant integer    Dummy_Id    = 'h003'    //Dummy ID
        private constant integer    Bolt_Id     = 'STUN'    //Storm bolt ID
        private constant integer    Buff_Id     = 'B005'    //Stun buff ID
        private constant integer LOCUST = 'Aloc'
        private unit stunner = null
    endglobals
        
struct stun
    real Stunned = 0.
    unit target
    real duration
   static timer Timer = CreateTimer()
    static stun array D
    static integer Count = 0
        
    static method create takes unit target, real duration returns stun
        local stun d = stun.allocate()
        set d.target = target
        set d.duration = 0.
        set d.Stunned = duration
        if stun.Count == 0 then
            call TimerStart(stun.Timer,INTERVAL,true,function stun.Periodic)
        endif
        set stun.D[stun.Count] = d
        set stun.Count = stun.Count + 1
        return d
    endmethod
    
    static method Periodic takes nothing returns nothing
        local stun this
        local integer i = 0
        loop
            exitwhen i >= .Count
            set this = .D[i]
            if .duration >= .Stunned or GetWidgetLife(.target) < 0.405 then
                call .destroy()
                set .Count = .Count - 1
                if .Count > 0 then
                    set .D[i] = .D[.Count]
                    set i = i - 1
                else
                    call PauseTimer(.Timer)
                endif
            endif
            set .duration = .duration + INTERVAL
            set i = i + 1
        endloop
    endmethod
            
   private method onDestroy takes nothing returns nothing
        set .Stunned = 0
        call UnitRemoveAbility(.target, Buff_Id) 
    endmethod
    
    implement AutoData
endstruct
    
function IsStunned takes unit target returns boolean
    return stun[target] != 0
endfunction

function StopStun takes unit target returns nothing
    call UnitRemoveAbility(target,Buff_Id)
endfunction
    
function StunUnit takes unit target, real duration returns nothing
    local stun d = stun[target]
    call SetUnitX(stunner,GetUnitX(target))
    call SetUnitY(stunner,GetUnitY(target))
    call IssueTargetOrder(stunner, "thunderbolt", target )
    if d == 0 then
        set d = stun.create(target,duration)
        set stun[target] = d
    else
        set d = stun[target]
        set d.Stunned = duration
        set d.duration = 0.
    endif
endfunction

private function Init takes nothing returns nothing
    set stunner = CreateUnit(Player(12),Dummy_Id,0,0,0)
    call UnitAddAbility(stunner,Bolt_Id )
    call UnitAddAbility(stunner,LOCUST)
endfunction
endlibrary

Collapse JASS:
scope TidalWave initializer Init



globals
    private constant integer SPELL = 'A008'
    private constant integer STOMP = 'A009'
    private constant string EFFECT = "MDX\\TidalErruption.mdx"
    private boolexpr b
endglobals



private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction



private function LineFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit())) and GetWidgetLife(GetFilterUnit()) > 0.0451
endfunction

private function Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local location target = GetSpellTargetLoc()
    local unit dummy
    local group g = NewGroup()
    local group hitgroup = NewGroup()
    local integer i = 1
    local integer effects = 4
    local real dist = 600
    local real divdist = dist/effects
    local real cx = GetUnitX(caster)
    local real cy = GetUnitY(caster)
    local real tx = GetLocationX(target)
    local real ty = GetLocationY(target)
    local real angle = Atan2(ty-cy,tx-cx)
    local real x
    local real y
    local unit u
    local integer c = 0
    loop
        exitwhen i > effects
        call TriggerSleepAction(0.1)
        set x = GetUnitX(caster) + (divdist * i) * Cos(angle)
        set y = GetUnitY(caster) + (divdist * i) * Sin(angle)
        set dummy = CreateUnit(GetOwningPlayer(caster),DUMMY,x,y,GetUnitFacing(caster))
        call SetUnitScale(dummy,2,2,2)
        call AddTimedEffectTarget(EFFECT,dummy,"origin",3)
        call UnitApplyTimedLife(dummy,'BTLF',3.5)
        call GroupEnumUnitsInRangeOfSegment(g,cx,cy,x,y,100,b)
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            if not IsUnitInGroup(u,hitgroup) then
                call ThrowUnitToAir(u,28)
                call StunUnit(u,3)
                call GroupAddUnit(hitgroup,u)
            endif
            call GroupRemoveUnit(g,u)
        endloop
        set i = i + 1
        set c = c + 150
    endloop
        set u = null
    set caster = null
    set dummy = null
    call RemoveLocation(target)
    call ReleaseGroup(g)
    call ReleaseGroup(hitgroup)
    set target = null
endfunction



//===========================================================================

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction( t, function Actions )
    call TriggerAddCondition(t,Condition(function Conditions))
    set b = Filter(function LineFilter)
endfunction

endscope

Here when I use this spell 3 or 4 times stacking together, the stun buff never gets removed. I think it's not Multiple Unit Stackable?

I have checked that the dummy unit casting the spell is not dead throughout the instances.

Here's AutoData

Collapse JASS:
module AutoData 
  private static thistype array data 
     static method operator []= takes unit u, integer data returns nothing 
        set .data[GetUnitId(u)] = data 
     endmethod 
     static method operator [] takes unit u returns integer 
         return .data[GetUnitId(u)] 
     endmethod 
 endmodule 
05-20-2009, 03:57 PM#2
grim001
I only wrote that AutoData thing in notepad in about 10 seconds to show you how easy it is to use unit indexing for attachment. If you actually look at what it does you should see that there is no way it can be "not working" unless AutoIndex is completely not working. I would say first update AutoIndex, if that doesn't help, the bug is probably somewhere in your system. Anyway I'm going to be posting my own stun system in a day or two so maybe you should focus your efforts on something else rather than debugging this thing.