HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

JASS Spell Troubles

02-21-2006, 02:12 AM#1
emjlr3
trying to make an ability, you cast it, and it send waves rippling outwards, as the waves past the targets, if they are moving, they will take damage, this is what ive got

Collapse JASS:
function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006' 
endfunction

//function Quake_Group takes nothing returns boolean
    //return ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )
//endfunction

function Quake_Group takes nothing returns boolean
    return  ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )  
endfunction

function QuakeEffects takes unit Cast, unit Targ returns nothing    
    local location n = GetUnitLoc(Targ)
    local location l
    local real i
    local real i2

    if GetUnitAbilityLevel(Cast, 'A003') == 1 then
        set i = .1
    else
        set i = .15
    endif
    call TriggerSleepAction(.5)
    set l = GetUnitLoc(Targ)    
    if DistanceBetweenPoints(l,n) > 5 then 
        call DestroyEffect( AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",l ))
        set i2 =  DistanceBetweenPoints(l,n)*i
        if i2 > R2I(GetUnitState(Targ,UNIT_STATE_MAX_LIFE))/2 then
            set i2 = GetUnitState(Targ,UNIT_STATE_MAX_LIFE)/2
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )  
        else 
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )
        endif     
    endif

    call RemoveLocation(n)
    call RemoveLocation(l)
    set n = null
    set l = null
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local location l = GetUnitLoc(u)
    local location m
    local group g = CreateGroup() 
    local group h     
    local unit v   
    local integer i = 1
    local real r = 750      
    call TriggerSleepAction( 0.75 )
    
    loop
        exitwhen i > 36        
        set m = PolarProjectionBJ(l, 9999.00,  10.00 * i )
        call TerrainDeformationWaveBJ( 4.00, l, m, 500.00, 50.00, 0.00 )        
        set i = i + 1
    endloop   
    set i = 1
    call GroupEnumUnitsInRangeOfLoc(g, l, r, Condition(function Quake_Group)) 
    loop
        exitwhen i > 13
        loop
            set v = FirstOfGroup(g)
            exitwhen v == null
            call GroupRemoveUnit(g,v)
            if IsUnitInGroup(v, h) == false then 
                call GroupAddUnit(h,v)
                call QuakeEffects(u,v)
            endif
        endloop
        call TriggerSleepAction(.3)
        set i = i + 1
        set r = r + 750
    endloop
    
    call RemoveLocation(l)
    set l = null
    call RemoveLocation(m)
    set m = null
    call DestroyGroup(g)
    call DestroyGroup(h)
    set h = null
    set g = null    
    set u = null    
endfunction

//===========================================================================
function InitTrig_Quake takes nothing returns nothing
    set gg_trg_Quake = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Quake, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Quake, Condition( function Trig_Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_Quake, function Trig_Untitled_Trigger_001_Actions )
endfunction


now I expected QuakeEffects to do its thing no prob, and not wait for the whole thing to run before the next is run, but what it seems to be doing is waiting for the entire function to run, then it loops and does it for the next unit, and so on, I didnt want that wait to happen, but it is nesecarry to determine whether the unit has moved or not, any ideas?
02-21-2006, 02:17 AM#2
Vexorian
That's completelly normal function behaviour.

To accomplish what you want you need to create a new thread:

Collapse JASS:
function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006' 
endfunction

//function Quake_Group takes nothing returns boolean
    //return ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )
//endfunction

function Quake_Group takes nothing returns boolean
    return  ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )  
endfunction

function QuakeEffects_Thread takes nothing returns nothing
   local unit Cast=udg_Cast
   local unit Targ=udg_Targ
    local location n = GetUnitLoc(Targ)
    local location l
    local real i
    local real i2

    if GetUnitAbilityLevel(Cast, 'A003') == 1 then
        set i = .1
    else
        set i = .15
    endif
    call TriggerSleepAction(.5)
    set l = GetUnitLoc(Targ)    
    if DistanceBetweenPoints(l,n) > 5 then 
        call DestroyEffect( AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",l ))
        set i2 =  DistanceBetweenPoints(l,n)*i
        if i2 > R2I(GetUnitState(Targ,UNIT_STATE_MAX_LIFE))/2 then
            set i2 = GetUnitState(Targ,UNIT_STATE_MAX_LIFE)/2
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )  
        else 
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )
        endif     
    endif

    call RemoveLocation(n)
    call RemoveLocation(l)
    set n = null
    set l = null
    set Cast=null
    set Targ=null
endfunction

function QuakeEffects takes unit Cast, unit Targ returns nothing    
   //We often look for bj globals we could set so we don't have to create variables with the variable editor
   //and all that annoyance. I am leaving them as defined globals because I don't have the time to take blizzard.j
   //and look for them right now
   set udg_Cast=Cast
   set udg_Targ=Targ
   call ExecuteFunc("QuakeEffects_Thread")
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local location l = GetUnitLoc(u)
    local location m
    local group g = CreateGroup() 
    local group h     
    local unit v   
    local integer i = 1
    local real r = 750      
    call TriggerSleepAction( 0.75 )
    
    loop
        exitwhen i > 36        
        set m = PolarProjectionBJ(l, 9999.00,  10.00 * i )
        call TerrainDeformationWaveBJ( 4.00, l, m, 500.00, 50.00, 0.00 )        
        set i = i + 1
    endloop   
    set i = 1
    call GroupEnumUnitsInRangeOfLoc(g, l, r, Condition(function Quake_Group)) 
    loop
        exitwhen i > 13
        loop
            set v = FirstOfGroup(g)
            exitwhen v == null
            call GroupRemoveUnit(g,v)
            if IsUnitInGroup(v, h) == false then 
                call GroupAddUnit(h,v)
                call QuakeEffects(u,v)
            endif
        endloop
        call TriggerSleepAction(.3)
        set i = i + 1
        set r = r + 750
    endloop
    
    call RemoveLocation(l)
    set l = null
    call RemoveLocation(m)
    set m = null
    call DestroyGroup(g)
    call DestroyGroup(h)
    set h = null
    set g = null    
    set u = null    
endfunction

//===========================================================================
function InitTrig_Quake takes nothing returns nothing
    set gg_trg_Quake = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Quake, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Quake, Condition( function Trig_Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_Quake, function Trig_Untitled_Trigger_001_Actions )
endfunction

02-21-2006, 02:24 AM#3
emjlr3
awesome ill give it a try ty for the past response....




hmmm I tried, and it does not seem to be working, I got exactly what you have written there too, it is doing nothing at all

Collapse JASS:
function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006' 
endfunction

//function Quake_Group takes nothing returns boolean
    //return ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )
//endfunction

function Quake_Group takes nothing returns boolean
    return  ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true )  
endfunction

function QuakeEffects_Thread takes nothing returns nothing
    local unit Cast = udg_Caster
    local unit Targ = udg_Target    
    local location n = GetUnitLoc(Targ)
    local location l
    local real i
    local real i2

    if GetUnitAbilityLevel(Cast, 'A003') == 1 then
        set i = .1
    else
        set i = .15
    endif
    call TriggerSleepAction(.5)
    set l = GetUnitLoc(Targ)    
    if DistanceBetweenPoints(l,n) > 5 then 
        call DestroyEffect( AddSpecialEffectLoc("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",l ))
        set i2 =  DistanceBetweenPoints(l,n)*i
        if i2 > R2I(GetUnitState(Targ,UNIT_STATE_MAX_LIFE))/2 then
            set i2 = GetUnitState(Targ,UNIT_STATE_MAX_LIFE)/2
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )  
        else 
            call UnitDamageTarget( Cast, Targ, i2,false, true, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL,WEAPON_TYPE_AXE_MEDIUM_CHOP )
        endif     
    endif

    call RemoveLocation(n)
    call RemoveLocation(l)
    set n = null
    set l = null
    set Cast = null
    set Targ = null
endfunction

function QuakeEffects takes unit Cast, unit Targ returns nothing   
   set udg_Caster=Cast
   set udg_Target=Targ
   call ExecuteFunc("QuakeEffects_Thread")
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local location l = GetUnitLoc(u)
    local location m
    local group g = CreateGroup() 
    local group h     
    local unit v   
    local integer i = 1
    local real r = 750      
    call TriggerSleepAction( 0.75 )
    
    loop
        exitwhen i > 36        
        set m = PolarProjectionBJ(l, 9999.00,  10.00 * i )
        call TerrainDeformationWaveBJ( 4.00, l, m, 500.00, 50.00, 0.00 )        
        set i = i + 1
    endloop   
    set i = 1
    call GroupEnumUnitsInRangeOfLoc(g, l, r, Condition(function Quake_Group)) 
    loop
        exitwhen i > 13
        loop
            set v = FirstOfGroup(g)
            exitwhen v == null
            call GroupRemoveUnit(g,v)
            if IsUnitInGroup(v, h) == false then 
                call GroupAddUnit(h,v)
                call QuakeEffects(u,v)
            endif
        endloop
        call TriggerSleepAction(.3)
        set i = i + 1
        set r = r + 750
    endloop
    
    call RemoveLocation(l)
    set l = null
    call RemoveLocation(m)
    set m = null
    call DestroyGroup(g)
    call DestroyGroup(h)
    set h = null
    set g = null    
    set u = null    
endfunction

//===========================================================================
function InitTrig_Quake takes nothing returns nothing
    set gg_trg_Quake = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Quake, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Quake, Condition( function Trig_Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_Quake, function Trig_Untitled_Trigger_001_Actions )
endfunction

02-21-2006, 02:41 AM#4
Vexorian
what exactly do you mean by 'Does not seem to be working'?
02-21-2006, 02:45 AM#5
emjlr3
well, the ripple is created, but the enemy untis are never damage, nor is the thunder clap effect created
02-21-2006, 02:49 AM#6
Vexorian
hmnn add BJDebugMsg's after and before the call TriggerSleepAction(.5) and see if they show messages
02-21-2006, 03:15 AM#7
emjlr3
nothing at all, no messages are ever displayed
02-21-2006, 06:35 AM#8
Anitarf
What is the h unit group supposed to do (I don't even see you create it anywhere)? You also loop through the g group 13 times even though it is empty already after the first time you loop through it.
02-21-2006, 11:47 AM#9
Vexorian
you are not initializing the h group, so when you use it it crashes the thread.

Also that part with the PolarProjections is leaking you have to remove m after making the terrain deform

Btw terrain deformations have to be destroyed too
02-21-2006, 12:08 PM#10
Blade.dk
By the way, this function is often very useful for me when debugging thread crashes and stuff, because it not only displays a message (with this function always a number), but also makes the trigger stop executing until player 0 presses escape. Also useful when you are debugging spells where you don't know exactly where a bug happens.

Collapse JASS:
function Debug takes integer id returns nothing
    local trigger t = CreateTrigger()
    call BJDebugMsg(I2S(id))
    call TriggerRegisterPlayerEventEndCinematic(t, Player(0))
    loop
        exitwhen GetTriggerExecCount(t) > 0
        call TriggerSleepAction(0)
    endloop
    call DestroyTrigger(t)
    set t = null
endfunction
02-21-2006, 06:58 PM#11
emjlr3
well u were right, local group h = CreateGroup() solved the problem

that and my unit group g creation was not inside my loop

ty for the help
02-21-2006, 07:16 PM#12
Vexorian
when any variable doesn't have any value assigned to it and you try to use it it causes the thraed to crash.

h never had anything assigned to it so a call that uses it makes the trigger stop
02-21-2006, 07:26 PM#13
emjlr3
btw how do you destroy terrain deforms?

im looking through JSC and cant find anything under "destroy" or "remove"
02-21-2006, 07:55 PM#14
Vexorian
For twisted reasons it is TerrainDeform stop http://jass.sourceforge.net/doc/api/...ormation.shtml