HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

[JASS] Lagging Spell

11-04-2008, 05:15 PM#1
DeathRing
Hey, I'm finally starting to get the hang of using JASS, and I wanted to use one of Vexorian's functions GroupAddUnitsInTriangle() for a cone-like spell I'm working on. Everything within the spell works correctly, but upon using it on any units, the game lags. The Lag is only really noticable when this spell is being casted more than once at the same time or targets a lot of units. Could someone possibly take a look at what I did wrong? Thank you in advance .
Collapse JASS:
globals
    constant real area = 100.00
    constant real dis = 800.00
    constant real fin = 400.00
endglobals

function Barbed_Shards_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A0AD'
endfunction

//Some of Vexorian's Cone-coding mixed with a bit of tweaking.
function Barbed_Shards_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local location loc = GetSpellTargetLoc()
    local real x = GetUnitX(caster)
    local real y = GetUnitY(caster)
    local real alpha = Atan2( GetLocationY(loc)-GetUnitY(caster) , GetLocationX(loc)-GetUnitX(caster) )
    local real beta = alpha+bj_PI/2
    local real x1 = x+area*Cos(beta)/2
    local real y1 = y+area*Sin(beta)/2
    local real x2
    local real y2
    local real x3 =( x+dis*Cos(alpha) ) + fin*Cos(beta)/2
    local real y3 =( y+dis*Sin(alpha) ) + fin*Sin(beta)/2
    local real x4
    local real y4
    local group g = CreateGroup()
    local unit picked
    local player p = GetOwningPlayer(caster)
        set beta = alpha-bj_PI/2
        set x2 = x+area*Cos(beta)/2
        set y2 = y+area*Sin(beta)/2
        set x4 = ( x+dis*Cos(alpha) ) + fin*Cos(beta)/2
        set y4 = ( y+dis*Sin(alpha) ) + fin*Sin(beta)/2
    call GroupAddUnitsInTriangle(g, x1, y1, x2, y2, x3, y3 )
    call GroupAddUnitsInTriangle(g, x2, y2, x3, y3, x4, y4 )
    loop
        set picked = FirstOfGroup(g)
        exitwhen picked == null
        if IsUnitEnemy(picked,p) then
            call UnitDamageTarget(caster, picked, 100.00,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null) 
        endif
        call GroupRemoveUnit(g, picked)
    endloop
    call DestroyGroup(g)
    call RemoveLocation(loc)
    set loc = null
    set g = null
    set picked = null
    set caster = null
endfunction

//===========================================================================
function InitTrig_Barbed_Shards takes nothing returns nothing
    local trigger shards = CreateTrigger( )
    call Preload("Abilities\\Spells\\NightElf\\FanOfKnives\\FanOfKnivesMissile.mdl")
    call TriggerRegisterAnyUnitEventBJ( shards, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( shards, Condition( function Barbed_Shards_Conditions ) )
    call TriggerAddAction( shards, function Barbed_Shards_Actions )
endfunction
11-04-2008, 06:14 PM#2
Vexorian
Does the lag remain if you comment out the damage part?
11-04-2008, 06:34 PM#3
DeathRing
Little to no lag remains, but definately not as much with the damage part on.
11-04-2008, 06:46 PM#4
Vexorian
  • How many units does it hit?
  • Do you have any triggers that fire when damage is done?
11-04-2008, 06:56 PM#5
DeathRing
Well I placed no constraints on how many units it can hit, I tested the spell on a group of about 20 peasants just to see how well the spell functioned. As for answering your 2nd question, the Barb Arrow Spell actucally activates during one of my other triggered spells. Basically it shoots an arrow like the trajectory shown below:
O = Hero casting
/ _ \ = Trajectory
X = Target Spell Point
-----> = Barbed Arrow Spell
_ _ _
/ \
/ \
/ \
O <---- X ---->

Once it lands, arrows are shot out in 8 different angles "0,45,90....360", hence making the Barb Arrow spell shoot 8 times and cause lag when theres multiple units getting hit. I hope I explained that well.
11-04-2008, 07:06 PM#6
Vexorian
That doesn't really answer my second question.

Does ANY of your other triggers fire on unit damage?
11-04-2008, 07:21 PM#7
DeathRing
Not at all. O dang, didnt know the diagram messed up, crap.
11-04-2008, 07:35 PM#8
Vexorian
Hmnn , could you post the version of GroupAddUnitsInTriangle?

How about you recycled the group instead of destroying it?
11-04-2008, 07:41 PM#9
DeathRing
Collapse JASS:
function GroupAddUnitsInTriangle_AngleCheck takes real angle, real angle1, real angle2, real PI2 returns boolean
 local real x
    if (angle1>angle2) then
        set x=angle1
        set angle1=angle2
        set angle2=x
    endif
    if (angle2-angle1>angle1 - (angle2-PI2)) then
        set angle2=angle2-PI2
        if (angle < bj_PI) then
            set angle=angle-PI2
        endif
        return (angle>=angle2) and (angle<=angle1)
    endif
 return (angle>=angle1) and (angle<=angle2)
endfunction

function GetRectThatLimitsTriangle takes real x1, real y1, real x2, real y2, real x3, real y3 returns rect
 local real maxx
 local real minx
    if (x1>x2) then
        if (x2>x3) then     //x1>x2>x3
            set maxx=x1
            set minx=x3
        elseif (x3>x1) then //x3>x1>x2
            set maxx=x3
            set minx=x2
        else                //x3>x1>x2
            set maxx=x1
            set minx=x2
        endif
    elseif (x1>x3) then //x2>x1>x3
        set maxx=x2
        set minx=x3
    elseif (x3>x2) then //x3>x2>x1
        set maxx=x3
        set minx=x1
    else                //x2>x3>x1
        set maxx=x2
        set minx=x1
    endif

    if (y1>y2) then
        if (y2>y3) then     //y1>y2>y3
            return Rect(minx,y3,maxx,y1)
        elseif (y3>y1) then //y3>y1>y2
            return Rect(minx,y2,maxx,y3)
        else                //y3>y1>y2
            return Rect(minx,y2,maxx,y1)
        endif
    elseif (y1>y3) then //y2>y1>y3
        return Rect(minx,y3,maxx,y2)
    elseif (y3>y2) then //y3>y2>y1
        return Rect(minx,y1,maxx,y3)
    endif
 //y2>y3>y1
 return Rect(minx,y1,maxx,y2)
endfunction



function GroupAddUnitsInTriangle takes group whichGroup, real x1, real y1, real x2, real y2, real x3, real y3 returns nothing
 local rect semi=GetRectThatLimitsTriangle(x1,y1,x2,y2,x3,y3)
 local group inrect=CreateGroup()
 local unit picked
 local real x
 local real y
 local real alpha=Atan2(y2-y1,x2-x1)
 local real beta =Atan2(y3-y1,x3-x1)
 local real gama =Atan2(y1-y2,x1-x2)
 local real delta=Atan2(y3-y2,x3-x2)
 local real PI2=bj_PI+bj_PI

    call GroupEnumUnitsInRect( inrect, semi,null)
    loop
        set picked=FirstOfGroup(inrect)
        exitwhen picked==null
        set x=GetUnitX(picked)
        set y=GetUnitY(picked)
        if IsUnitInGroup(picked,whichGroup) then
        elseif (GroupAddUnitsInTriangle_AngleCheck(Atan2(y-y1,x-x1),alpha,beta,PI2) and GroupAddUnitsInTriangle_AngleCheck( Atan2(y-y2,x-x2) ,gama,delta,PI2)) then
            call GroupAddUnit( whichGroup, picked)
        endif
        call GroupRemoveUnit(inrect,picked)
    endloop
 call RemoveRect(semi)
 call DestroyGroup(inrect)
 set whichGroup=null
 set picked=null
 set semi=null
 set inrect=null
endfunction
Theres the function I used.
11-04-2008, 08:44 PM#10
Vexorian
Try this one: http://www.wc3campaigns.net/showthread.php?t=101247 should be faster .
11-04-2008, 08:53 PM#11
DeathRing
Alrighty then, I'll try that function, thanks a bunch Vexorian!
11-04-2008, 11:27 PM#12
DeathRing
Hmm, odd, I havent given you rep before and won't let me give you some now... : /
11-14-2008, 04:03 AM#13
Pyrogasm
If that's still too laggy, you can always approximate your triangle as a sector of a circle.