HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Help with lightning function

09-01-2009, 03:10 PM#1
Tom_Kazansky
I have a lightning attaching function:

Collapse JASS:
//tj_CoordinateZChecker = Location( 0., 0.) at map initialization
function GetLocZ takes real x, real y returns real
    call MoveLocation(tj_CoordinateZChecker,x,y)
    return GetLocationZ(tj_CoordinateZChecker)
endfunction

function GetPPX takes real x, real dist, real angle returns real
    local real X = x + dist * Cos(angle * bj_DEGTORAD)
    if X < tj_MapAreaMinX then
        set X = tj_MapAreaMinX
    endif
    if X > tj_MapAreaMaxX then
        set X = tj_MapAreaMaxX
    endif
    return X
endfunction

function GetPPY takes real y, real dist, real angle returns real
    local real Y = y + dist * Sin(angle * bj_DEGTORAD)
    
    if Y < tj_MapAreaMinY then
        set Y = tj_MapAreaMinY
    endif
    if Y > tj_MapAreaMaxY then
        set Y = tj_MapAreaMaxY
    endif

    return Y
endfunction

//----------------------

scope AttachLightning

private struct datax
    unit c
    real xc
    real yc
    real zc
    unit a
    real xa
    real ya
    real za
    lightning bolt
    real cx = 0.0
    real cy = 0.0
    real ax = 0.0
    real ay = 0.0
    real dur = 0.0
    real faderate = 0
    real elapsed = 0
    boolean vis = false
    boolean fade = false
    
    boolean movec = true
    boolean movea = true
    boolean reverse = false
endstruct 

function AddLightningUnitToUnit_Child takes nothing returns boolean
    local datax d = TT_GetData()
    local real x1
    local real y1
    local real z1
    local real x2
    local real y2
    local real z2
    local real f
    local boolean b = false
    if d.movec then
        if IsUnitHidden(d.c) then
            set d.movec = false
        else
            set d.cx = GetUnitX(d.c)
            set d.cy = GetUnitY(d.c)
        endif
    endif
    if d.movea then
        if IsUnitHidden(d.a) then
            set d.movea = false
        else
            set d.ax = GetUnitX(d.a)
            set d.ay = GetUnitY(d.a)
        endif
    endif
    set z1 = GetUnitFlyHeight(d.c) + GetLocZ(d.cx,d.cy)+d.zc
    set f = GetUnitFacing(d.c)
    set x1 = GetPPX( GetPPX( d.cx, d.xc, f-90.), d.yc, f )
    set y1 = GetPPY( GetPPY( d.cy, d.xc, f-90.), d.yc, f )
    
    set z2 = GetUnitFlyHeight(d.a) + GetLocZ(d.ax,d.ay)+d.za
    set f = GetUnitFacing(d.a)
    set x2 = GetPPX( GetPPX( d.ax, d.xa, f-90.), d.ya, f )
    set y2 = GetPPY( GetPPY( d.ay, d.xa, f-90.), d.ya, f )

    call MoveLightningEx(d.bolt, d.vis,x1,y1, z1, x2,y2, z2)

    set d.elapsed = d.elapsed + 0.04
    
    if d.fade then
        if d.elapsed >= d.dur then
            if GetLightningColorA(d.bolt) > d.faderate then
                call SetLightningColor( d.bolt, GetLightningColorR(d.bolt), GetLightningColorG(d.bolt), GetLightningColorG(d.bolt), ( GetLightningColorA(d.bolt) - d.faderate ) )
            elseif GetLightningColorA(d.bolt) <= d.faderate then
                call SetLightningColor( d.bolt, GetLightningColorR(d.bolt), GetLightningColorG(d.bolt), GetLightningColorG(d.bolt), 0)
                call DestroyLightning(d.bolt)
                call d.destroy()
                set b = true
            endif
        endif
    else
        if d.elapsed >= d.dur then
            call DestroyLightning(d.bolt)
            call d.destroy()
            set b = true
        endif
    endif
    return b
endfunction

function AddLightningUnitToUnit takes string codeName, boolean checkVisibility, unit c, real xc, real yc, real zc, unit a, real xa, real ya, real za, real dur, boolean checkfade, real faderate returns lightning
    local datax d
    local real z1
    local real z2
    local real x1
    local real y1
    local real x2
    local real y2
    local real f
    if codeName == "" or c== null or a == null then
        return null
    endif
    set d = datax.create()
    set d.c = c
    set d.xc = xc
    set d.yc = yc
    set d.zc = zc
    set d.a = a
    set d.xa = xa
    set d.ya = ya
    set d.za = za
    
    set d.fade = checkfade
    set d.faderate = faderate/100.
    set d.vis = checkVisibility
    set d.cx = GetUnitX(d.c)
    set d.cy = GetUnitY(d.c)
    set d.ax = GetUnitX(d.a)
    set d.ay = GetUnitY(d.a)
    set d.dur = dur
    set z1 = GetUnitFlyHeight(d.c) + GetLocZ(d.cx,d.cy)+d.zc
    set z2 = GetUnitFlyHeight(d.a) + GetLocZ(d.ax,d.ay)+d.za
    set f = GetUnitFacing(d.c)
    set x1 = GetPPX( GetPPX( d.cx, xc, f-90.), yc, f )
    set y1 = GetPPY( GetPPY( d.cy, xc, f-90.), yc, f )
    
    set f = GetUnitFacing(d.a)
    set x2 = GetPPX( GetPPX( d.ax, xa, f-90.), ya, f )
    set y2 = GetPPY( GetPPY( d.ay, xa, f-90.), ya, f )
    
    set d.bolt = AddLightningEx(codeName, checkVisibility, x1,y1, z1, x2,y2, z2)
    
    call TT_Start( function AddLightningUnitToUnit_Child ,d )
    set bj_lastCreatedLightning = d.bolt
    return bj_lastCreatedLightning
endfunction

endscope

the problem is: when I play my map with friends (online, on Garena with patch 1.24b) and when a hero casts spell that use the above function, my friend and I got "kicked" out of the game , no error reported; War3 just exit, it just like I have an infinite loop or something alike

The above function work fine in Single Player.

I just know the problem is the above function because I only comment the line calls that function and then I didn't get "kick".

I really can't find anything odd

please help.
09-01-2009, 06:44 PM#2
0zyx0
Terrain deformations and GetLocationZ can cause desyncs. If you use shockwave or earthquake, that can happen.
09-01-2009, 07:50 PM#3
Anitarf
Quote:
Originally Posted by 0zyx0
Terrain deformations and GetLocationZ can cause desyncs. If you use shockwave or earthquake, that can happen.
Only if you use the z value for something that must be synchronised. If you use it for visual stuff such as lightning z, it doesn't matter.
09-02-2009, 01:09 AM#4
Tom_Kazansky
it's weird, the spell works like this:
pick units in range of caster, create a dummy unit and create lightnining effect from the dummy to picked units and damages them after a short delay

the only thing I change in the spell is commenting the line calls the lightning function but I can't find anything that can cause bug in that func.

if you can, please see this: [Arena] HAVOK, pick the hero: Thunder Bird (East Team's hero area) and use Static Spread. Neutral creep will spawn after 1 minutes

if you get the error and you think you can help, please PM me and I will send you a non-protected version.


EDIT: here is the code for the spell:

Expand JASS:



Collapse JASS:
scope ThunderBirdSkills

private struct data
    unit c
    unit a
    real dmg
    boolean blk
    boolean rfl
endstruct

private function Des takes nothing returns boolean
    local data d = TT_GetData()
    local boolean b = false
    call DestroyEffect( AddSpecialEffectTarget("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",d.a,"origin"))
    if d.rfl and CanUnitReflectSpell(d.a) then
        call StaticSpreadSingle.execute( d.a, d.c, d.a, d.dmg, true, false )
        set b = true
    endif
    if not b then
        if d.blk and not CanUnitResistSpell( d.a ) then
            call UnitHitBySpell( d.c, d.a, "" )
            call UnitDamageUnit( d.c, d.a, d.dmg, 4, false, true )
        endif
    endif
    call d.destroy()
    return true
endfunction

function StaticSpreadSingle takes unit c, unit a, unit s, real dmg, boolean blk, boolean rfl returns nothing
    local data d = data.create()
    local tjunit ad = GetUnitUserData(a)
    set d.c = c
    set d.a = a
    set d.dmg = dmg
    set d.blk = blk
    set d.rfl = rfl
    call TT_StartEx( function Des, d , 0.25 )
    
    //call AddLightningUnitToUnit( "FORK", true, s, 0., 0., 0., a, 0.,0., ad.unitconst.pimpact, 0., true, 4 )
endfunction

function StaticSpread takes unit c, real cx, real cy, integer lvl returns nothing
    local unit p
    local real dmg =  GetUnitSpellDamage( c,20+45.*lvl, 4 )
    local real tr = 600.
    local unit d = CreateUnit( Player(15),'n00Q',cx,cy,270.)
    if SPELLCRIT then
        call UnitSpellCritShow( c, dmg )
    endif
    call SetUnitZ( d, GetUnitFlyHeight(c)+100. )
    call UnitApplyTimedLife(d,'BTLF',0.5 )
    
    call EnumNearestUnits( ENUM_GROUP, 2+lvl, cx, cy, tr, GeneralBoolExprGet( c, 0, null, "001000001100001010" ) ) //<- this belongs to my filter system
    loop
        set p = FirstOfGroup(ENUM_GROUP)
        exitwhen p == null
        call GroupRemoveUnit(ENUM_GROUP,p)
        call StaticSpreadSingle( c, p, d, dmg, true , true )
    endloop
    
    set d = null
endfunction

endscope