HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

JASS Trigger is making my WE freak out more than usual...

02-07-2007, 02:35 AM#1
Pyrogasm
So, I'm attempting to convert some of the triggers for my Nether Mage hero from GUI to JASS. However, I seem to have created a function that not only causes compile errors, but causes the trigger to no longer consist of anything (the "script code" box disappears). Then, after refreshing the window (switching to another map and back), the trigger doesn't even show up at all, but still "exists" (I can't name a trigger the same name as I was using for it).

The code compiles fine on the only compiler I've found for OS X, so I'm miffed.

Here it is (It's not complete):
Collapse JASS:
function Rift_Filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction

function Trig_Planar_Rift_JASS_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A009'
endfunction

function Trig_Planar_Rift_JASS_Actions takes nothing returns nothing
    local unit U = GetTriggerUnit()
    local unit U2
    local unit U3
    local real X = GetUnitX(GetTriggerUnit())
    local real Y = GetUnitY(GetTriggerUnit())
    local group G = CreateGroup()
    local boolexpr B = Condition( function Rift_Filter )
    local integer Level = GetUnitAbilityLevel(U, 'A009')
    call GroupEnumUnitsInRange( G, X, Y, 200.00, B )
    loop
        set U2 = FirstOfGroup(G)
        exitwhen U2 == null
        if IsUnitType(U2, UNIT_TYPE_ETHEREAL) == true then
            call UnitDamageTarget( U, U2, (16+Level*30.00) )
//            set U3 = CreateUnit(GetOwningPlayer(U), 'u00A', X, Y, 0)
//            call UnitApplyTimedLife(U3, 'BTLF', 1.00)
        endif
    endloop
endfunction

//===========================================================================
function InitTrig_Planar_Rift_JASS takes nothing returns nothing
    set gg_trg_Planar_Rift_JASS = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Planar_Rift_JASS, function Trig_Planar_Rift_JASS_Actions )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Planar_Rift_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT )
endfunction
Oh, and I should mention that if I "enable" it (which gives me the compile errors), I can then enable/disable it over and over again without the trigger giving any errors whatsoever. If I click on another trigger, WE crashes.
02-07-2007, 03:02 AM#2
Rising_Dusk
First of all, just so you know --
You're never registering your trigger condition as a condition for the trigger.

Also, your UnitDamageTarget() call is missing arguments.
And your FirstOfGroup() iterations were running an infinite loop.

One more thing, you were leaking a lot of handle references, and a group and a boolexpr.
I also went ahead and cleaned the trigger and made it easier to read, hopefully it helps.

See the red below for the issues.

Collapse JASS:
function Planar_Rift_JASS_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A009'
endfunction

function Rift_Filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction

function Planar_Rift_JASS_Actions takes nothing returns nothing
    local unit u1 = GetTriggerUnit()
    local unit u2
    local unit u3
    local group g = CreateGroup()
    local boolexpr b = Condition(function Rift_Filter)
    local integer lvl = GetUnitAbilityLevel(u1, 'A009')
    local real x = GetUnitX(GetTriggerUnit())
    local real y = GetUnitY(GetTriggerUnit())
    
    call GroupEnumUnitsInRange(g, x, y, 200., b)
    loop
        set u2 = FirstOfGroup(g)
        exitwhen u2 == null
        if IsUnitType(U2, UNIT_TYPE_ETHEREAL) == true then
            call UnitDamageTarget(u, u2, (16+Level*30.00), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
            //set U3 = CreateUnit(GetOwningPlayer(U), 'u00A', X, Y, 0)
            //call UnitApplyTimedLife(U3, 'BTLF', 1.00)
        endif
        call GroupRemoveUnit(g, u2)
    endloop
    
    call GroupClear(g)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set u1 = null
    set u2 = null
    set u3 = null
    set g = null
    set b = null
endfunction

function InitTrig_Planar_Rift_JASS takes nothing returns nothing
    set gg_trg_Planar_Rift_JASS = CreateTrigger()
    call TriggerAddAction(gg_trg_Planar_Rift_JASS, function Planar_Rift_JASS_Actions )
    call TriggerAddCondition(gg_trg_Planar_Rift_JASS, Condition(function Planar_Rift_JASS_Conditions))
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Planar_Rift_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT)
endfunction
02-07-2007, 03:26 AM#3
Pyrogasm
Quote:
Originally Posted by Me, in my above post
(It's not complete)
That's why everything leaks.

Thank you for fixing my DamageUnit() function, and adding that triggercondition. I could've sworn that I'd added that line in, else I wouldn't have put the conditions function in.
02-07-2007, 04:10 AM#4
Rising_Dusk
Sorry, when I get into the "Fix it" mood I'm very mechanical about it.
I always overlook the "Not complete" lines and just sort of fill in the blanks myself. xD

It works now though, right?
02-07-2007, 04:46 AM#5
Pyrogasm
Yes it does. I'm grateful for your support on this.

I do, however, have one more question. When I'm continually setting U3 and U2 to different things inside that loop like this:
Collapse JASS:
    loop
        set U2 = FirstOfGroup(G)
        exitwhen U2 == null
        if IsUnitType(U2, UNIT_TYPE_ETHEREAL) == true then
            call UnitDamageTarget( U, U2, (16+Level*30.00), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null )
            set U3 = CreateUnit(GetOwningPlayer(U), 'u00A', X, Y, 0)
            call UnitApplyTimedLife(U3, 'BTLF', 1.00)
            call UnitAddAbility(U3, 'A001')
            call SetUnitAbilityLevel(U3, 'A001', Level)
            call IssueTargetOrder(U3, "banish", U2)
        else
            set U3 = CreateUnit(GetOwningPlayer(U), 'u00A', X, Y, 0)
            call UnitApplyTimedLife(U3, 'BTLF', 1.00)
            call UnitAddAbility(U3, 'A00O')
            call SetUnitAbilityLevel(U3, 'A00O', Level)
            call IssueTargetOrder(U3, "banish", U2)
        endif
        call GroupRemoveUnit(G, U2)
    endloop
Do I have to set U3 = null and U2 = null at the end of the loop to avoid memory leaks, or can I just null it after the loop. If I don't, why? It seems like I would be creating a new handle every time I set U2 equal to NextOfGroup(G).
02-07-2007, 04:51 AM#6
Mythic Fr0st
I think you do, with loops, and locations, you have to do the same thing with call RemoveLocation(Loc), so i'd figure you'd have to set its data to null aswell

but im not 100% sure

Actually, im not 0.01% sure, lol
02-07-2007, 07:06 AM#7
grim001
you don't need to. setting a handle to null is to avoid a pointer leak; changing the pointer is the same as removing the reference and making it a reference to something else. you just have to null it once at the end of the function.
02-07-2007, 08:04 PM#8
wyrmlord
Might I also suggest using the unit variable for getting the unit's X/Y instead of GetTriggeringUnit? It may not make much of a difference performance-wise, but since you have the variable, why not use it?
02-08-2007, 12:51 AM#9
Pyrogasm
Quote:
Originally Posted by wyrmlord
Might I also suggest using the unit variable for getting the unit's X/Y instead of GetTriggeringUnit? It may not make much of a difference performance-wise, but since you have the variable, why not use it?
I already have; I optimized that code a lot.