• 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] Spell that bugg after the first cast :S

Status
Not open for further replies.
Level 11
Joined
Apr 6, 2008
Messages
760
hi i have some problems with this spell i have tried many things but nothing seems to help. ok here is the problem, when i cast this spell for the first time it works perfectly, but when i cast it the second time it just blows up then it stop channeling(wont even start moving), any1 know why this bugg like i missed a leak or trying to move a lightning that dont exist(even if i have checked that sometimes)?

JASS:
scope OrbofZeus initializer Init
//!=============================================================================!\\
//! Orb of Zeus by Ciebron.                                                     !\\
//! Give Credits is you use this in your map                                    !\\
//! --------------------------------------------------------------------------- !\\
//! Channels a orb made from the god Zeus him self. the long u channel          !\\
//! the more the ball will grow, when release it will be such force that the    !\\
//! ball will fly up in the air and strike lighting from above and when         !\\
//! it lands it will deal damage to nearby units                                !\\
//! --------------------------------------------------------------------------- !\\
//! Requires:                                                                   !\\
//! ¯¯¯¯¯¯¯¯¯                                                                   !\\
//! - Object Editor  - A hero                                                   !\\
//! - Object Editor  - The Orb of Zeuz ability                                  !\\
//! - Object Editor aadada - The Orb Dummy Unit                                 !\\
//! - Trigger Editor - This Trigger                                             !\\
//! - Trigger Editor - CSData - by Vexorian                                     !\\
//! - Trigger Editor - CSSaftey - by Vexorian                                   !\\
//! - Trigger Editor - Table - by Vexorian                                      !\\
//!   ([url=http://www.wc3campaigns.net/showthread.php?t=80534]CS15.2 - Wc3campaigns[/url])                      !\\
//! --------------------------------------------------------------------------- !\\
//!=============================================================================!\\
//!=================================Setup Starts================================!\\
//!=============================================================================!\\
globals
private constant integer Abil_id = 'A000' //!Ability rawcode
private constant integer Dum_id = 'h000' //!Dummy rawcode
private constant string ESFX = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl" //!SFX when the lightning hit the target
private constant string GSFX = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" //! Effect that gets created @ the ground when the ball hits it
private constant string Lighttype = "FORK" //!lightning type
private constant real LightningRange = 400. //! Range of the lightnings
private constant integer MaximumTargets = 3 //! Maximum nr of target allowed (cant be 0 duh)
private constant real Maxdist = 1500. //! distance the orb will move
private constant real Time = 3. //! Time to Travel Maxdist
private constant real Curve = 6. //! adjust this if the ball goes to high or to low for ur taste (lower, the higher the ball will get and the other way around)
private constant string AttachPoint = "origin"

    //! dont touch these
    private group OrbofZeus = CreateGroup()
    private HandleTable activeTable
endglobals

private function SetDamage takes real a returns real
    return a*1.5 //!damage formula, a is based b.size (atm it deals 1.5*b.size)
endfunction
//!=============================================================================!\\  
//!=================================Setup Ends==================================!\\
//!=============================================================================!\\

private struct Data
unit caster
unit dummy
unit array victims [MaximumTargets]

real cos
real sin
real size
real z
real dist
real fulltime
real time
real dmg
real distance
real Movedist

real lightningtime

lightning array Lightning [MaximumTargets]

integer count

player play

timer t

    static method create takes nothing returns Data
        local Data d = Data.allocate()
        local location loc = GetSpellTargetLoc()
        local real tx = GetLocationX(loc)
        local real ty = GetLocationY(loc)
        local real x
        local real y
        local real angle
        local real scale
        local integer index = 0
        
        //! just for debugging
        loop
            exitwhen index >= MaximumTargets
            set d.Lightning[index] = null
            set index = index + 1
        endloop
        
        //! setup stuff
        set d.caster = GetTriggerUnit()
        set x = GetUnitX(d.caster)
        set y = GetUnitY(d.caster)
        set angle = Atan2(ty-y,tx-x)
        set d.play = GetOwningPlayer(d.caster)
        set d.cos = Cos(angle)
        set d.sin = Sin(angle)
        set d.dummy = CreateUnit(d.play,Dum_id,x+100*d.cos,y+100*d.sin,0.)
        set d.size = 1
        set scale = 1+(0.25*d.size)
        set d.Movedist = (Maxdist/Time)/(1./.035)
        set d.t = NewTimer()
        set d.count = 0
        call SetUnitScale(d.dummy,scale,scale,scale)
        call SetCSData(d.t, d)
        call TimerStart(d.t,1.,true,function Data.OrbGrow)
        
        call RemoveLocation(loc)
        set loc = null
        
        return d
    endmethod
    
    static method OrbGrow takes nothing returns nothing
    local Data d = GetCSData(GetExpiredTimer())
    local real scale
    
    //! make's the orb grow
    set d.size = d.size + 1
    set scale = 1+(0.25*d.size)
    call SetUnitScale(d.dummy,scale,scale,scale)
    endmethod
    
    static method Move takes nothing returns nothing
        local Data d = GetCSData(GetExpiredTimer())
        local real x = GetUnitX(d.dummy)+d.Movedist*d.cos // New Y cord
        local real y = GetUnitY(d.dummy)+d.Movedist*d.sin // New X cord
        local group g //group for picking units
        local unit victim //used in the loop to damage and create lightnings
        local integer index = 0 //used in the group to set array index
        
        set d.dist = d.dist + d.Movedist
        set d.z = JumpParabola(d.dist,Maxdist,Curve)
    
        call SetUnitFlyHeight(d.dummy,d.z,0.)
        
        //! check if the unit is @ the ground, if it is we make it blow up
        if d.z > 0. then
            //! if the lightning have been alive for .25 sec we destroy them else we move them
            if d.lightningtime >= .25 then
                loop
                    exitwhen index >= d.count
                    if d.Lightning[index] != null then
                        call DestroyLightning(d.Lightning[index])
                        set d.Lightning[index] = null
                    else
                        call BJDebugMsg("Tried to destroy a lightning that dont exist")
                    endif
                    set index = index + 1
                endloop
                set d.count = 0
                set index = 0
            else
                loop
                    exitwhen index >= d.count
                    call MoveLightningEx(d.Lightning[index],true,x,y,GetUnitFlyHeight(d.dummy)+50,GetUnitX(d.victims[index]),GetUnitY(d.victims[index]),GetUnitFlyHeight(d.victims[index])+50)
                    set index = index + 1
                endloop
                set index = 0
            endif
            
            
            //! check if they x & y cords isnt outside the mapbounds
            if MinX < x and MaxX > x and MinY < y and MaxY > y then
                call SetUnitX(d.dummy,x)
                call SetUnitY(d.dummy,y)
            endif
            
            //! if .5 sec have gone since the last lightning we make new ones
            if d.lightningtime >= .5 then
                set g = NewGroup()
            
                call GroupEnumUnitsInRange(g,x,y,500,Filter(function Data.filter))
                
                set d.count = 0
                
                loop
                    set victim = FirstOfGroup(g)
                    exitwhen victim == null or index >= MaximumTargets
                    call GroupRemoveUnit(g,victim)
                    set d.victims[index] = victim
                    set d.Lightning[index] = AddLightningEx("FORK",true,x,y,GetUnitFlyHeight(d.dummy)+50,GetUnitX(victim),GetUnitY(victim),GetUnitFlyHeight(victim)+50)
                    call UnitDamageTarget(d.caster,victim,100.,false,false,ATTACK_TYPE_MAGIC,null,null)
                    call DestroyEffect(AddSpecialEffectTarget(ESFX,victim,AttachPoint))
                    set index = index + 1
                endloop
                
                set d.count = index
                set d.lightningtime = 0.
                call ReleaseGroup(g)
            endif
        else
            set g = NewGroup()
            
            call GroupEnumUnitsInRange(g,x,y,500,Filter(function Data.filter))
            call DestroyEffect(AddSpecialEffect(GSFX,x,y))
            
            //! dmg units where the orb blew up
            loop
                set victim = FirstOfGroup(g)
                exitwhen victim == null
                call GroupRemoveUnit(g,victim)
                call UnitDamageTarget(d.caster,victim,100.,false,false,ATTACK_TYPE_MAGIC,null,null)
            endloop
            
            call ReleaseGroup(g)
            
            call d.destroy()
        endif
        
        set d.time = d.time + .035
        set d.lightningtime = d.lightningtime + .035
        set g = null
        
    endmethod
    
    static method filter takes nothing returns boolean
        local Data d = GetCSData(GetExpiredTimer())
        local unit f = GetFilterUnit()
        local boolean ok = GetWidgetLife(f) > .405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(f,GetOwningPlayer(d.caster))
        set f = null
        return ok
    endmethod
    
    method onDestroy takes nothing returns nothing
        local integer index = 0
        
        //! destroys the lightning    
        loop
            exitwhen index >= .count
            if .Lightning[index] != null then
                call DestroyLightning(.Lightning[index])
                set .Lightning[index] = null
            else
                call BJDebugMsg("Tried to destroy a lightning that dont exist")
            endif
            set index = index + 1
        endloop
        
        call KillUnit(.dummy)
        
        call ReleaseTimer(.t)
    endmethod
endstruct

private function PreLoad takes nothing returns nothing
    call Preload(GSFX)
    call Preload(ESFX)
    call RemoveUnit(CreateUnit(Player(15),Dum_id,0,0,0))
endfunction

private function onend takes nothing returns boolean
    local Data d
    local unit u = GetTriggerUnit()

    if IsUnitInGroup(u,OrbofZeus) then
        set d = activeTable[u]
        set d.dmg = SetDamage(d.size)
        call PauseTimer(d.t)
        call TimerStart(d.t,.035,true,function Data.Move)
        //! remove the caster from the group
        call GroupRemoveUnit(OrbofZeus,u)
        //! flush the caster's table
        call activeTable.flush(d.caster)
    endif

    set u = null
    return false
endfunction
    
private function conds takes nothing returns boolean
    local Data d
    
    if GetSpellAbilityId() == Abil_id then
        set d = Data.create()
        //! set a table to the caster
        set activeTable[d.caster] = d
        //! add the caster to a group for "caster"
        call GroupAddUnit(OrbofZeus,d.caster)
    endif
    return false
endfunction

private function Init takes nothing returns nothing
    local trigger t =CreateTrigger()
    local integer index = 0

    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition( function conds ) )

    set t = CreateTrigger()
    set index = 0

    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_ENDCAST,null)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function onend))
    
    //! this spell use table to get rid of dynamic triggers
    set activeTable = Table.create()
    call PreLoad()
endfunction

endscope


EDIT:

Lightning dont cuase the bugg, i think it is the table


JASS:
call PauseTimer(d.t)
call TimerStart(d.t,.035,true,function Data.Move)
maybe this? it was not it..
 
Last edited:
Level 11
Joined
Apr 6, 2008
Messages
760
ok i rewrote it BUT i have the same fucking problem! (sry for dubble post it like a *bump* :p)


JASS:
scope OrbofZeus initializer Init
//!=============================================================================!\\
//! Orb of Zeus by Ciebron.                                                     !\\
//! Give Credits is you use this in your map                                    !\\
//! --------------------------------------------------------------------------- !\\
//! Channels a orb made from the god Zeus him self. the long u channel          !\\
//! the more the ball will grow, when release it will be such force that the    !\\
//! ball will fly up in the air and strike lighting from above and when         !\\
//! it lands it will deal damage to nearby units                                !\\
//! --------------------------------------------------------------------------- !\\
//! Requires:                                                                   !\\
//! ¯¯¯¯¯¯¯¯¯                                                                   !\\
//! - Object Editor  - A hero                                                   !\\
//! - Object Editor  - The Orb of Zeuz ability                                  !\\
//! - Object Editor aadada - The Orb Dummy Unit                                 !\\
//! - Trigger Editor - This Trigger                                             !\\
//! - Trigger Editor - CSData - by Vexorian                                     !\\
//! - Trigger Editor - CSSaftey - by Vexorian                                   !\\
//! - Trigger Editor - Table - by Vexorian                                      !\\
//!   ([url=http://www.wc3campaigns.net/showthread.php?t=80534]CS15.2 - Wc3campaigns[/url])                      !\\
//! --------------------------------------------------------------------------- !\\
//!=============================================================================!\\
//!=================================Setup Starts================================!\\
//!=============================================================================!\\
globals
private constant integer Abil_id = 'A000' //!Ability rawcode
private constant integer Dum_id = 'h000' //!Dummy rawcode
private constant string ESFX = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl" //!SFX when the lightning hit the target
private constant string GSFX = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" //! Effect that gets created @ the ground when the ball hits it
private constant string Lighttype = "FORK" //!lightning type
private constant real LightningRange = 400. //! Range of the lightnings
private constant integer MaximumTargets = 3 //! Maximum nr of target allowed (cant be 0 duh)
private constant real Maxdist = 1500. //! distance the orb will move
private constant real Time = 3. //! Time to Travel Maxdist
private constant real Curve = 6. //! adjust this if the ball goes to high or to low for ur taste (lower, the higher the ball will get and the other way around)
private constant string AttachPoint = "origin"

    //! dont touch these
    private group OrbofZeus = CreateGroup()
    private HandleTable activeTable
endglobals

private function SetDamage takes real a returns real
    return a*1.5 //!damage formula, a is based b.size (atm it deals 1.5*b.size)
endfunction
//!=============================================================================!\\  
//!=================================Setup Ends==================================!\\
//!=============================================================================!\\

private struct Data
unit caster
unit dummy
unit array victims [MaximumTargets]

real cos
real sin
real size
real z
real dist
real fulltime
real time
real dmg
real Movedist

real lightningtime

lightning array Lightning [MaximumTargets]

integer count

player play

trigger trig

timer t

    static method create takes nothing returns Data
        local Data d = Data.allocate()
        local location tloc = GetSpellTargetLoc()
        local real x
        local real y
        local real tx = GetLocationX(tloc)
        local real ty = GetLocationY(tloc)
        local real angle
        
        set d.caster = GetTriggerUnit()
        set x = GetUnitX(d.caster)
        set y = GetUnitY(d.caster)
        set angle = Atan2(ty-y,tx-x)
        set d.cos = Cos(angle)
        set d.sin = Sin(angle)
        set d.play = GetOwningPlayer(d.caster)
        set d.Movedist = (Maxdist/Time)/(1./.035)
        set d.dummy = CreateUnit(d.play,Dum_id,x+75*d.cos,y+75*d.sin,0.)
        set d.t = NewTimer()
        
        call SetCSData(d.t,d)
        call TimerStart(d.t,.5,true,function Data.OrbGrow)
        
        return d
    endmethod

    static method OrbGrow takes nothing returns nothing
        local Data d = GetCSData(GetExpiredTimer())
        local real scale
        
        set d.size = d.size + 1
        set scale = 1+(.25*d.size)
        call SetUnitScale(d.dummy,scale,scale,scale)
    endmethod
    
    static method Move takes nothing returns nothing
        local Data d = GetCSData(GetExpiredTimer())
        local real x = GetUnitX(d.dummy)
        local real y = GetUnitY(d.dummy)
        
        set d.dist = d.dist + d.Movedist
        set d.z = JumpParabola(d.dist,Maxdist,Curve)
        
        call SetUnitFlyHeight(d.dummy,d.z,0.)
        
        if d.z > 0 then
            call SetUnitX(d.dummy,x+d.Movedist*d.cos)
            call SetUnitY(d.dummy,y+d.Movedist*d.sin)
        else
            call d.destroy()
        endif
    endmethod
    
    method onDestroy takes nothing returns nothing
        local integer index = 0
            
        call KillUnit(.dummy)
        
        call ReleaseTimer(.t)
    endmethod
endstruct

private function PreLoad takes nothing returns nothing
    call Preload(GSFX)
    call Preload(ESFX)
    call RemoveUnit(CreateUnit(Player(15),Dum_id,0,0,0))
endfunction

private function OnEnd takes nothing returns boolean
    local Data d
    local unit u = GetTriggerUnit()
    
    if IsUnitInGroup(u,OrbofZeus) then
        set d = activeTable[u]
        call PauseTimer(d.t)
        call TimerStart(d.t,.035,true,function Data.Move)
        call activeTable.flush(u)
    endif
    
    set u = null
    
    return false
endfunction

private function conds takes nothing returns boolean
    local Data d
    
    if GetSpellAbilityId()==Abil_id then
        set d = Data.create()
        call GroupAddUnit(OrbofZeus,d.caster)
        set activeTable[d.caster] = d
    endif
    
    return false
endfunction

private function Init takes nothing returns nothing
    local trigger t =CreateTrigger()
    local integer index = 0

    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddCondition(t,Filter(function conds))
    
    set t = CreateTrigger()
    set index = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_ENDCAST,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddCondition(t,Filter(function OnEnd))
    
    //! this spell use table to get rid of dynamic triggers
    set activeTable = Table.create()
    
    call PreLoad()
    
    set t = null
endfunction

endscope



EDIT:

its like we use the first struct over and over again


i think my JNGP is bugged or something

this wont even work!

JASS:
scope OrbofZeus initializer Init

globals
    private constant integer Abil_id = 'A000'
    private constant integer Dum_id = 'h000'
endglobals

private struct Data
unit caster
unit dummy

real cos
real sin
real dist

timer t
    
    method onDestroy takes nothing returns nothing
        call PauseTimer(.t)
        call DestroyTimer(.t)
    endmethod
endstruct

private function Move takes nothing returns nothing
    local Data d = GetCSData(GetExpiredTimer())
    local real x = GetUnitX(d.dummy)+30*d.cos
    local real y = GetUnitY(d.dummy)+30*d.sin
        
    set d.dist = d.dist + 30
        
    if d.dist < 1500 then
        call SetUnitX(d.dummy,x)
        call SetUnitY(d.dummy,y)
    else
        call KillUnit(d.dummy)
        call d.destroy()
    endif
endfunction

private function Action takes nothing returns nothing
    local Data d = Data.create()
    local location targetloc = GetSpellTargetLoc()
    local real tx = GetLocationX(targetloc)
    local real ty = GetLocationY(targetloc)
    local real x
    local real y
    local real angle
        
    set d.caster = GetTriggerUnit()
    set x = GetUnitX(d.caster)
    set y = GetUnitY(d.caster)
    set angle = Atan2(ty-y,tx-x)
    set d.cos = Cos(angle)
    set d.sin = Sin(angle)
    set d.dummy = CreateUnit(GetOwningPlayer(d.caster),Dum_id,x+75*d.cos,y+75*d.sin,0.)
    set d.t = CreateTimer()
    
    call SetCSData(d.t,d)
    call TimerStart(d.t,.035,true,function Move)
    
    call RemoveLocation(targetloc)
    set targetloc = null
endfunction

private function conds takes nothing returns boolean
    return GetSpellAbilityId()==Abil_id
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddAction(t,function Action)
    call TriggerAddCondition(t,Filter(function conds))
    
endfunction

endscope
 
Last edited:
Level 11
Joined
Apr 6, 2008
Messages
760
that would be great :D

hmm doing made it work^^ so why do i need 2 do this never needed that before :eek:

JASS:
    method onDestroy takes nothing returns nothing
        set .caster = null
        set .dummy = null
        set .cos = 0
        set .sin = 0
        set .dist = 0
        set .t = null
    endmethod
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
As you have assumed, I have not looked at this(too precious time to waste ^^ ), but I do not forget such things.
I am not certain why not doing that would cause problems(other than leaks) - yes I still haven't examined the code.
But yes - you have to null every handle variable you have. The destroy() function does not destroy the variables in the struct. If there are leaks in the struct, destroy() will not clear them. destroy() only frees the index of the struct.
 
Status
Not open for further replies.
Top