HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Chain Lightning, Doesn't.

12-12-2009, 05:59 PM#1
Panto
Greetings,

I am trying to make a simple custom chain lightning and am struggling to make the art line up right.

I have done some research in the forum and learned that others have found that caster units casting chain lightning spells need a tiny bit of time to actually cast it, so I am creating a caster (uCast) for each instance of the art.

I have implemented this using casters instead of lightning art because the units in the map have widely varying flying heights.

However, in practice this code doesn't seem to connect one unit to the next. The debug in the If section outputs reasonable X and Y coordinates for the source of each lightning caster, but the lightning art seems to either work or not, with no pattern that I could discern for why it works between some units and not others.

My conclusion is that I must have made some logical error in the code, but so far I haven't been able to suss out what that is. If you see it, please just let me know.

Thanks!

Note, this code doesn't do anything but art; there is no effect on the targeted units yet.

Code:
A01T: Lightning art spell, single target
A011: Lightning dummy spell
u003: Caster unit

Collapse JASS:
function Trig_Laser_Refract_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A011'
endfunction

function Trig_Laser_Refract_Pick takes nothing returns boolean
    return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit()))) and not(IsUnitDead(GetFilterUnit()))
endfunction

function Trig_Laser_Refract_Actions takes nothing returns nothing
    local unit uAge = GetTriggerUnit()
    local unit uPat = GetSpellTargetUnit()
    local unit uCast = null
    local group gNear = CreateGroup()
    local integer iL = 0
    local boolexpr xprEnemy = Condition(function Trig_Laser_Refract_Pick)
    local real rXPat = GetUnitX(uPat)
    local real rYPat = GetUnitY(uPat)

    call BJDebugMsg("Runs: Laser Refract")

    set iL = 0
    loop
        exitwhen iL >= 5 // number of bounces

        call GroupEnumUnitsInRange(gNear, rXPat, rYPat, 1200, xprEnemy)

        call GroupRemoveUnit(gNear, uPat) // so it doesn't bounce right back
        set uPat = GroupPickRandomUnit(gNear)

        if uPat != null then
            set rXPat = GetUnitX(uPat)
            set rYPat = GetUnitY(uPat)

            call BJDebugMsg("Inside If, x = "+R2S(rXPat)+", y = "+R2S(rYPat))
            set uCast = CreateUnit(GetOwningPlayer(uAge), 'u003', rXPat, rYPat, 0)
            call UnitAddAbility(uCast, 'A01T')
            call IssueTargetOrder(uCast, "chainlightning", uPat)
            call UnitApplyTimedLife(uCast, 'BTLF', 0.25)

            set iL = iL + 1

            call GroupClear(gNear)
        else
            call BJDebugMsg("Inside Else")
            set iL = 5
        endif

    endloop

    call DestroyBoolExpr(xprEnemy)
    set uAge = null
    set uPat = null
    set uCast = null
    call DestroyGroup(gNear)
    set gNear = null
endfunction

//===========================================================================
function InitTrig_Laser_Refract takes nothing returns nothing
    set gg_trg_Laser_Refract = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Laser_Refract, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Laser_Refract, Condition(function Trig_Laser_Refract_Conditions))
    call TriggerAddAction(gg_trg_Laser_Refract, function Trig_Laser_Refract_Actions)
endfunction
12-12-2009, 09:35 PM#2
Anitarf
If it doesn't work for some units, perhaps it is because the dummy caster fails to cast it for some reason (invalid target, target out of range etc.).

I don't understand why you don't use lightning art, though, you can set it's z value so flying heights should not be an issue.

Also, WC3 chain spells aren't instant, they actually have a certain projectile speed even if the projectile itself is not there because it is replaced with the lightning effects.
12-13-2009, 02:55 PM#3
Panto
Unfortunately the lightning spell has max range and all of the possible targets are the same unit-type and belong to the same owner. There's no discernible reason why some would work and some wouldn't.

I will go learn more about lightning effects, I suppose. Thanks.
12-14-2009, 07:41 AM#4
Tot
Quote:
Originally Posted by Panto
I have implemented this using casters instead of lightning art because the units in the map have widely varying flying heights.

no problem, use
Collapse JASS:
globals
     private location TEMP_LOC
endglobals

function GetUnitZ takes unit u returns real
     if TEMP:LOC==null then
          set TEMP_LOC=Location(GetUnitX(u),GetUnitY(u))
     else
          call MoveLocation(TEMP_LOC,GetUnitX(u),GetUnitY(u))
     endif
     return GetLocationZ(TEMP_LOC)+GetUnitFlyHeight(u)
endfunction

to get an units height
and move the lightings to it viaMoveLightningEx(...)
12-15-2009, 05:02 AM#5
Deaod
Collapse JASS:
globals
     private location TEMP_LOC=Location(0,0)
endglobals

function GetPointZ takes real x, real y returns real
    call MoveLocation(TEMP_LOC,x,y)
    return GetLocationZ(TEMP_LOC)
endfunction

function GetUnitZ takes unit u returns real
    return GetPointZ(GetUnitX(u), GetUnitY(u))+GetUnitFlyHeight(u)
endfunction