HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Optimizing Jass Spell

01-28-2008, 06:57 AM#1
shadowange1
Hello everyone,
I have started learning Jass and i created this spell that teleports a unit to a targeted unit and damages all in an area.

The spell works in moving the unit from one place to another and created the effect, however no damage is done and i don't know why.I was also wondering if there was anyway i could optimize my code.

Jass Code
Hidden information:
[
Collapse JASS:
function Trig_Charge_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A021' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Charge_Actions takes nothing returns nothing
    local unit cas = GetSpellAbilityUnit()
    local unit tar = GetSpellTargetUnit()
    local location p1 = GetUnitLoc(tar)
    local group g1
    local effect e1
    local unit n
    local unit f
    local group g2
    call TriggerSleepAction( 0.25 )
    call SetUnitPositionLoc( cas, p1 )
    call MoveRectToLoc( gg_rct_Region_015, p1 )
    call TriggerSleepAction( 0.10 )
    set g1 = GetUnitsInRectAll(gg_rct_Region_015)
    set g2 = g1
    loop
        set f=FirstOfGroup(g2)
        exitwhen f==null
        if ( ( IsUnitType(f, UNIT_TYPE_STRUCTURE) == true ) ) then
            call GroupRemoveUnit( g1, f )
        endif
        if ( ( IsUnitDeadBJ(f) == true ) ) then
            call GroupRemoveUnit( g1, f )
        endif
        if ( ( IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) == true ) ) then
            call GroupRemoveUnit( g1, f )
        endif
        if ( ( IsUnitAlly(f, GetOwningPlayer(cas)) == true ) ) then
            call GroupRemoveUnit( g1, f )
        endif
        if ( ( f == cas )==true ) then
            call GroupRemoveUnit( g1, f )
        endif
        call GroupRemoveUnit( g2, f )
    endloop
    if (IsUnitAliveBJ(tar) == true) then        
        if (IsUnitAliveBJ(cas) == true) then
             call IssueTargetOrderBJ( cas, "attack", tar )
        endif
    endif
    call AddSpecialEffectLocBJ( p1, "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" )
    set e1 = GetLastCreatedEffectBJ()
    set g2=g1
    loop
        set f=FirstOfGroup(g2)
        exitwhen f==null
        if ( IsUnitAliveBJ(f) == true ) then
        call UnitDamageTargetBJ( cas, f, ( I2R(GetHeroStatBJ(bj_HEROSTAT_STR, cas, true)) + ( 25.00 * I2R(GetUnitAbilityLevelSwapped('A021', cas)) ) ), ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL )
        endif
        call GroupRemoveUnit( g2, f )
    endloop
    call TriggerSleepAction( 1.00 )
    call DestroyGroup (g1)
    call DestroyGroup (g2)
    call RemoveLocation (p1)
    call DestroyEffectBJ( e1 )
    set cas = null
    set tar = null
    set f = null
endfunction

//===========================================================================
function InitTrig_Charge takes nothing returns nothing
    set gg_trg_Charge = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Charge, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Charge, Condition( function Trig_Charge_Conditions ) )
    call TriggerAddAction( gg_trg_Charge, function Trig_Charge_Actions )
endfunction

01-28-2008, 08:39 AM#2
The Elite
for a star you can change:
Collapse JASS:
    if ( not ( GetSpellAbilityId() == 'A021' ) ) then
        return false
    endif
    return true
to
Collapse JASS:
return GetSpellAbilityId() == 'A021
will post more when i see them
01-28-2008, 12:23 PM#3
Deaod
Collapse JASS:
function Trig_Charge_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021'
endfunction

function Trig_Charge_Actions takes nothing returns nothing
    local unit cas = GetSpellAbilityUnit()
    local unit tar = GetSpellTargetUnit()
    local real xtar = GetUnitX(tar)
    local real ytar = GetUnitY(tar)
    local group g1
    local effect e1
    local unit f
    local group g2
    call TriggerSleepAction( 0.25 )
    call SetUnitX(cas, xtar)
    call SetUnitY(cas, ytar)
    call TriggerSleepAction( 0.10 )
    call GroupEnumUnitsInRange(g1, GetUnitX(cas), GetUnitY(cas), 200, null)
    set g2 = g1
    
    loop
        set f=FirstOfGroup(g2)
        exitwhen f==null
        if ( (IsUnitType(f, UNIT_TYPE_STRUCTURE)==true) or (IsUnitDeadBJ(f)==true) or (IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE)==true) or (IsUnitAlly(f, GetOwningPlayer(cas))==true) or (f==cas)) then
            call GroupRemoveUnit( g1, f )
        endif
        call GroupRemoveUnit( g2, f )
    endloop
    
    if (GetUnitState(tar, UNIT_STATE_LIFE) > 0.405) and (GetUnitState(cas, UNIT_STATE_LIFE) > 0.405) then
        call IssueTargetOrder( cas, "attack", tar )
    endif
    
    set e1 = AddSpecialEffect( "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", xtar, ytar )
    set g2=g1
    
    loop
        set f=FirstOfGroup(g2)
        exitwhen f==null
        if ( GetUnitState(f, UNIT_STATE_LIFE) > 0.405 ) then
            call UnitDamageTargetBJ( cas, f, (GetHeroStr(cas, true)+(25.0*GetUnitAbilityLevel(cas, 'A021'))), ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC )
        endif
        call GroupRemoveUnit( g2, f )
    endloop
    
    call TriggerSleepAction(1.00)
    call DestroyGroup(g1)
    call DestroyGroup(g2)
    call DestroyEffect(e1)
    set g1=null
    set g2=null
    set e1=null
    set cas = null
    set tar = null
    set f = null
endfunction

//===========================================================================
function InitTrig_Charge takes nothing returns nothing
local trigger trig = CreateTrigger(  )
local integer index=0

    loop
        call TriggerRegisterPlayerUnitEvent( trig,Player(index), EVENT_PLAYER_UNIT_SPELL_CAST, Condition( function Trig_Charge_Conditions ) )
    set index=index+1
    exitwhen index>11
    endloop
    
    call TriggerAddAction( trig, function Trig_Charge_Actions )
endfunction

i shortened your code a bit and replaced most of the BJs you used with natives.
Reworked your trigger to use coordinates instead of locations, and replaced IsUnitAliveBJ with GetUnitState(u, life)>0.405.

just try out if it works for you now.
01-28-2008, 04:11 PM#4
chobibo
Try reading the jass introduction tutorials specially blade.dk's "Making Your Own Stomp Spell", I learned a lot from that.
Use this inittrig if you like.
Collapse InitTrig:
function InitTrig_Charge takes nothing returns nothing
local trigger trig = CreateTrigger(  )
local integer index=0
local player p = null
    call Preload("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl") // Caches the effect so it won't lag the first time it's used.
    loop
        set p = Player(index)
        call TriggerRegisterPlayerUnitEvent( trig,p, EVENT_PLAYER_UNIT_SPELL_CAST, Condition( function Trig_Charge_Conditions ) )
        set index = index + 1
        exitwhen index >= 11
    endloop
    call TriggerAddAction( trig, function Trig_Charge_Actions )
    set p = null
    set trig = null
endfunction
I'll also try editing the action function just wait ok. thanks
01-28-2008, 08:18 PM#5
burningice95
For starters, you can replace IsUnitAlive with IsUnitAliveBJ

Also, you can remove the TriggerSleepAction (unless you want a small delay for some reason)
01-29-2008, 04:54 AM#6
shadowange1
okay guys thanks for the help i will look over them so i can understand what and why you guys did the things.

Also is using x,y coordinates better thatn using loc?
And this part of the code
call GroupEnumUnitsInRange(g1, GetUnitX(cas), GetUnitY(cas), 200, null)
is meant to get units in a range of the caster correct and store it in g1. In addition i will no longer need to move the region to that point right?
01-29-2008, 03:04 PM#7
Deaod
afaik using X/Y coords is a heap faster than using locations.

and yes, that groupenum function stores all units in a certain range of a location in the specified variable, so you dont have to move a rect to that point, since this method is more accurate and really as fast or even faster.