HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

JASS code "changed" by a JASS noob could use a check please...

07-23-2006, 04:57 AM#1
darkwulfv
Alright, I tried to expand my limited understanding of JASS by changing a trigger straight from GUI to a more compact, clean JASS trigger... For those who know me, congradulations should be in order *The)TideHunter( cough cough* Unfortunatly, I know very little about JASS, so I could only do so much without threatening to turn my computer into a pile of sludge... So I need somebody to please check it over. It's still probably very crappy, but it gives me feeling of satisfaction that I now know a little more about JASS. So, in all it's limited glory, here's a before and after. +REP to anyone who helps out (unless I need to spread it :p) Also, I'll credit you in my WC3C sections of my credits.

BEFORE!
Collapse JASS:
function Trig_Turn_on_Damage_Copy_Copy_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00E' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Turn_on_Damage_Copy_Copy_Func008001002 takes nothing returns boolean
    return ( UnitHasBuffBJ(GetFilterUnit(), 'B002') == true )
endfunction

function Trig_Turn_on_Damage_Copy_Copy_Func008Func003001001 takes nothing returns boolean
    return ( TimerGetRemaining(udg_TempTimer) == 0.00 )
endfunction

function Trig_Turn_on_Damage_Copy_Copy_Func008A takes nothing returns nothing
    call StartTimerBJ( udg_TempTimer, false, udg_Real )
    loop
    exitwhen(Trig_Turn_on_Damage_Copy_Copy_Func008Func003001001())
    call UnitDamageTargetBJ( udg_TempUnit, GetEnumUnit(), udg_Real, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE )
    endloop
endfunction

function Trig_Turn_on_Damage_Copy_Copy_Actions takes nothing returns nothing
    local integer udg_TempInteger
    local unit udg_TempUnit
    local timer udg_TempTimer
    set udg_FlameStompUnit[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))] = GetTriggerUnit()
    set udg_TempInteger = GetUnitAbilityLevelSwapped('A00E', udg_FlameStompUnit[GetConvertedPlayerId(GetOwningPlayer(GetTriggerUnit()))])
    call CreateNUnitsAtLoc( 1, 'e001', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING )
    set udg_TempUnit = GetLastCreatedUnit()
    call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_Turn_on_Damage_Copy_Copy_Func008001002)), function Trig_Turn_on_Damage_Copy_Copy_Func008A )
endfunction

AFTER!
Collapse JASS:
function Trig_Turn_on_Damage_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00E' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Turn_on_Damage_Func008A takes nothing returns nothing
    call StartTimerBJ( TempTimer, false, TempReal )
    loop
    exitwhen( TimerGetRemaining(TempTimer) == 0.00 )
    call UnitDamageTargetBJ( TempUnit, GetEnumUnit(), TempReal, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE )
    endloop
endfunction

function Trig_Turn_on_Damage_Actions takes nothing returns nothing
    local integer TempInteger
    local unit TempUnit
    local timer TempTimer
    local unit u = GetTriggerUnit
    local real TempReal = TempInteger * 2
    set udg_FlameStompUnit[GetConvertedPlayerId(GetOwningPlayer(u))] = u
    set TempInteger = GetUnitAbilityLevelSwapped('A00E', udg_FlameStompUnit[GetConvertedPlayerId(GetOwningPlayer(u))])
    call CreateNUnitsAtLoc( 1, 'e001', GetOwningPlayer(u), GetUnitLoc(u), bj_UNIT_FACING )
    set TempUnit = GetLastCreatedUnit()
    call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition( UnitHasBuffBJ(GetFilterUnit(), 'B002') == true ), function Trig_Turn_on_Damage_Func008A )
endfunction

Sorry for the very crappy codes, I'm sure half of this could be packed into 3 natives :p. Please, don't lecture me on the shittyness of BJ's and stuff, I just want this to work.
07-23-2006, 06:35 AM#2
BertTheJasser
Collapse JASS:
Condition( UnitHasBuffBJ(GetFilterUnit(), 'B002') == true )
A Condition must be a function, and can not be inserted directly.
07-23-2006, 06:51 AM#3
darkwulfv
soooo... How exactly would I put it in? The way it was before?
07-23-2006, 07:01 AM#4
BertTheJasser
Mm yes, but remember that the whole func leaks as hell and is infected with holy BJ shit.
07-23-2006, 07:07 AM#5
darkwulfv
greaaat, just when I thought I'd fixed leakage... Well, any way to fix that? Or is the leak major? becuase if not I think I can let it slide...
07-23-2006, 10:09 AM#6
Captain Griffen
Here:

Collapse JASS:
function Trig_Turn_on_Damage_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00E'
endfunction

function HasB002Buff takes nothing returns boolean
    return GetUnitAbilityLevel(GetFilterUnit(), 'B002') > 0
endfunction

function Trig_Turn_on_Damage_Actions takes nothing returns nothing
    local unit ut
    local unit uloop
    local unit u = GetTriggerUnit()
    local integer i = GetUnitAbilityLevel(udg_FlameStompUnit[GetPlayerId(GetOwningPlayer(u))], 'A00E')
    local real r = i * 2
    local group g = CreateGroup()
    local boolexpr b = Condition(function HasB002Buff)

    set ut = CreateUnit(GetOwningPlayer(u), 'e001', GetUnitX(u), GetUnitY(u), 270)
    call GroupEnumUnitsInRect(g, GetPlayableMapRect(), b)

    call DestroyBoolExpr(b)
    set b = null

    call PolledWait(r)

    loop
        set uloop = FirstOfGroup(g)
        exitwhen uloop == null
        call UnitDamageTarget(ut, uloop, r, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
    loop

    set ut = null
    set uloop = null
    set u = null
    call DestroyGroup(g)
    set g = null
endfunction

Could have used a timer, but then you'd need to use local handle variables.

Also, this may not be exactly what you want, because your origional code made absolutely no sense in places, mainly that loop with no wait in it, with a function that called non-existant variables.
07-23-2006, 12:43 PM#7
darkwulfv
erm... My trigger is supposed to do this:
Unit casts spell == Flame Stomp (A00E)
create a dummy unit (e001)
unit group, units being those with flame stomp buff (B002)
-loop
start timer (TempTimer)
damage target (dummy unit damages picked unit) for r damage (which would be integer * 2, which is spell level * 2 of the triggering unit, u)
everything is then set to null. Is that what yours does? Pardon that it didnt make sense, I had an updated code that may have made the slightest bit more sense but it was late last night and Inever got around to it...
07-23-2006, 01:05 PM#8
Captain Griffen
Why start TempTimer? I see no point.
07-23-2006, 01:46 PM#9
darkwulfv
The unit takes damage every second for r (the real = integer 2) seconds, guess I forgot to mention that, sorry :/. The loop is supposed to keep looping until the remaining time of the timer = zero. I've been changing and fixing the code almost non-stop for the past hour, so here's an updated version. I did use some of your code, so don't feel like I blew your effort off. NOTE: I know nothing is nulled, thats after this code works. But 1 question. Do local variables have to be nulled in the function they were declared in, or can they be nulled elsewhere?
Collapse JASS:
function Trig_Turn_on_Damage_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A00E' )
endfunction

function HasB002Buff takes nothing returns boolean
    return GetUnitAbilityLevel(GetFilterUnit(), 'B002') > 0
endfunction

function StartTimer takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer i = GetUnitAbilityLevelSwapped('A00E', u )
    local real r = i * 2 
    local timer t = CreateTimerBJ(false, r)
    local unit tu = CreateNUnitsAtLoc( 1, 'e001', GetOwningPlayer(u), GetUnitLoc(u), bj_UNIT_FACING )   
    loop
    call StartTimerBJ( t, false, r )
    exitwhen( TimerGetRemaining(t) == 0.00 )
    call UnitDamageTargetBJ( tu, GetEnumUnit(), r, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
    call PolledWait( 1 )
    endloop
endfunction

function Trig_Turn_on_Damage_Actions takes nothing returns nothing
    call ForGroupBJ( GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function HasB002Buff)), function StartTimer )
endfunction
In hopes that this new code will be better and closer to a solution,
-Darkwulfv
07-23-2006, 06:51 PM#10
The)TideHunter(
I changed a few BJ's and stuff, yes local handles need to be nulled, but not in the function they was created in.
Heres your code from your last post updated:

Collapse JASS:
function Trig_Turn_on_Damage_Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == 'A00E')
endfunction

function HasB002Buff takes nothing returns boolean
    return GetUnitAbilityLevel(GetFilterUnit(), 'B002') > 0
endfunction

function StartTimer takes nothing returns nothing
    local unit TriggerUnit = GetTriggerUnit()
    local integer AbilLevel = GetUnitAbilityLevelSwapped('A00E', TriggerUnit)
    local real r = AbilLevel * 2 
    local timer t = CreateTimer()
    local unit Dummy = CreateUnit(GetOwningPlayer(TriggerUnit), 'e001', GetUnitX(TriggerUnit), GetUnitY(TriggerUnit), bj_UNIT_FACING )   
    loop
        call TimerStart(t, r, false, null)
        exitwhen(TimerGetRemaining(t) == 0.00)
        call UnitDamageTarget(Dummy, GetEnumUnit(), r, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
        call PolledWait(1)
    endloop
    set TriggerUnit = null
    call DestroyTimer(t)
    set t = null
    set Dummy = null
endfunction

Sorry for renaming the locals, i couldent understand what they meant at first.
EDIT: I realised you used poll wait, in a loop, in a looped loop, Forgroup is a loop too.
Thats bad because it will only damage 1 unit a time until its finished then go on to the next 1, polling will poll the intire trigger and not just that function. TriggerSleepAction would have the same effect.
07-23-2006, 07:50 PM#11
darkwulfv
I knew that my locals needed to be nulled, I hadn't gotten around to it yet... So does this work? Oh, and np for changing local var. names, I was just trying to get it done... However, I must ask. Is that the whole trigger, or is it missing the Trig_Turn_on_ actions function? Also, will this work for what I'd like it to? (damaging multiple units multiple times? If this won't, is there a buff or something that does damage over time that I can give to those units, thus making the timer loop uneeded?) So what you were saying is that this won't work for what I want it to due to the polled waits?
07-23-2006, 09:43 PM#12
The)TideHunter(
Well, that was everything but the Init_Trig function.
And, unfortunatly, this wont work =(.
The polled waits will make it damage 1 unit at a time instead of damaging multiple units at multiple times.
To be perfectly honest, i would use a DoT method and the return bug for a good method.

Heres what i just wrote up:

Collapse JASS:
function GC takes nothing returns gamecache
    if(udg_GC == null) then
        call FlushGameCache(InitGameCache("GC"))
        set udg_GC = InitGameCache("GC")
    endif
    return udg_GC
endfunction

function H2I takes handle H returns integer
    return H
    return 0
endfunction

function I2Unit takes integer I returns unit
    return I
    return null
endfunction

function DamageOverTime_Update takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local string tS = I2S(H2I(t))
    local unit Target = I2Unit(GetStoredInteger(GC(), "DamageOverTime_Target", tS))
    local unit Credit = I2Unit(GetStoredInteger(GC(), "DamageOverTime_Credit", tS))
    local real Damage = GetStoredReal(GC(), "DamageOverTime_DPI", tS)
    local integer Intervals = GetStoredInteger(GC(), "DamageOverTime_Intervals", tS) - 1
    local real Dur = GetStoredReal(GC(), "DamageOverTime_Duration", tS)
    if(Intervals != 0) then
        call UnitDamageTarget(Credit, Target, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
        call StoreInteger(GC(), "DamageOverTime_Intervals", tS, Intervals)
        call TimerStart(t, Dur, false, function DamageOverTime_Update)
    else
        call FlushStoredMission(GC(), tS)
        call DestroyTimer(t)
        set t = null
        set Target = null
        set Credit = null
    endif
endfunction

function DamageOverTime takes unit whichUnit, unit Credit,  real DamagePerInterval, integer Intervals, real IntervalDuration returns nothing
    local timer t = CreateTimer()
    local string tS = I2S(H2I(t))
    call StoreInteger(GC(), "DamageOverTime_Target", tS, H2I(whichUnit))
    call StoreInteger(GC(), "DamageOverTime_Credit", tS, H2I(Credit))
    call StoreReal(GC(), "DamageOverTime_DPI", tS, DamagePerInterval)
    call StoreInteger(GC(), "DamageOverTime_Intervals", tS, Intervals)
    call StoreReal(GC(), "DamageOverTime_Duration", tS, IntervalDuration)
    call TimerStart(t, IntervalDuration, false, function DamageOverTime_Update)
endfunction

Put it in your main map script section, BTW, this requires a gamecache called GC (udg_GC).
Then to use, type:
Collapse JASS:
call DamageOverTime(Target, Credit, DamagePerInterval, integer DamageIntervalCount, IntervalDuration)

So lets say you wanted to do 50 damage per second every 1 second for 10 seconds, type:

Collapse JASS:
call DamageOverTime(Target, Credit, 50., 10, 1.)

Anyway, to put this into your trigger, just do:

Collapse JASS:
function Trig_Turn_on_Damage_Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == 'A00E')
endfunction

function HasB002Buff takes nothing returns boolean
    return GetUnitAbilityLevel(GetFilterUnit(), 'B002') > 0
endfunction

function Trig_Turn_on_Damage_Actions takes nothing returns nothing
    local unit TriggerUnit = GetTriggerUnit()
    local integer AbilLevel = GetUnitAbilityLevel(TriggerUnit, 'A00E')
    local real Fixer = AbilLevel * 2
    local group Enum = GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function HasB002Buff))
    local unit CurrentUnit
    loop
        set CurrentUnit = FirstOfGroup(Enum)
        exitwhen CurrentUnit == null
        call DamageOverTime(CurrentUnit, TriggerUnit, Fixer, R2I(Fixer), 1.)
        call GroupRemoveUnit(Enum, CurrentUnit)
    endloop
    set TriggerUnit = null
    call DestroyGroup(Enum)
    set Enum = null
endfunction
I hope that works anyway.
07-23-2006, 11:12 PM#13
darkwulfv
Wow... Thanks Tide... I'll insert this when I can and give it a try. The spell itself kicks ass (imagine the firelord with flames all around him and then war stomp...) I just hope the damage over time works. If it doesn't, then I don't think the world will end, but you know.