• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] "Freeze" when custom spell hits many targets

As the title says: this custom spell when it hits many targets causes unrecoverable lag which freezes the game

JASS:
scope LaserSweep

    private struct Missile extends Missiles

    static integer AID = 'A000'

    static real angleincrement = 9.0

    real angle

    static real distance = 1200.

    unit dummytarget

    real anglecovered

    static real anglecoveredmax = 45.

    group alreadyhit

    Lightning beam


        method onFinish takes nothing returns boolean

    call DummyAddRecycleTimer(dummytarget,0.5)

    set dummytarget=null

    if UnitAlive(source) and anglecovered < anglecoveredmax then

        set angle = angle + angleincrement

        set anglecovered = anglecovered + angleincrement      

        set .dummytarget = GetRecycledDummyAnyAngle(GetUnitX(source) + distance * Cos(angle * bj_DEGTORAD),GetUnitY(source) + distance * Sin(angle * bj_DEGTORAD),0)

        call deflectTarget(dummytarget)

        return false

    endif

    call DestroyGroup(alreadyhit)

    call beam.remove()

    return true

    endmethod


        method onPeriod takes nothing returns boolean

        local group g = CreateGroup()

        local unit u

        call LightningUtils.enumUnits(g, beam, 100.)

        loop

        set u=FirstOfGroup(g)

        exitwhen u==null

        if not IsUnitInGroup(u,alreadyhit) and IsUnitEnemy(u, owner) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and not BlzIsUnitInvulnerable(u) and UnitAlive(u) and not IsUnitType(u,UNIT_TYPE_STRUCTURE) then

            call GroupAddUnit(alreadyhit,u)

            call UnitDamageTarget(source, u, damage, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)

            call AddUnitBonusTimed(u,BONUS_ARMOR,-5,30.0)

        endif

        call GroupRemoveUnit(g,u)

        endloop

        set beam.targetX = .x

        set beam.targetY = .y

        call DestroyGroup(g)

        set g = null

            return false

        endmethod


        static method onCast takes nothing returns nothing

            local unit     c = GetTriggerUnit()

            local real     x = GetUnitX(c)

            local real     y = GetUnitY(c)

        local real startingangle = GetUnitFacing(c) - (anglecoveredmax / 2)

        local real startingx = x + distance * Cos(startingangle * bj_DEGTORAD)

        local real startingy = y + distance * Sin(startingangle * bj_DEGTORAD)

            local thistype this = thistype.create(startingx, startingy, 50.0, startingx,startingy, 50.0)


        set .dummytarget = GetRecycledDummyAnyAngle(startingx,startingy, 0.)

        set .target = dummytarget

            set source    = c

        set owner = GetOwningPlayer(c)

            set model     = ""

            set speed     = 1000

            set arc       = 0.

            set curve     = 0.

        set damage = 200 + (200 * GetUnitAbilityLevel(c,AID))

        set .angle = GetUnitFacing(c)

        set .anglecovered = 0.

        set .beam = Lightning.unitToPoint(c,startingx,startingy,50,50.,false,0.,"DRAL",0)

        set .alreadyhit = CreateGroup()

            call launch()

        set c=null

        endmethod


        static method onInit takes nothing returns nothing

            call RegisterSpellEffectEvent(AID, function thistype.onCast)

        endmethod

    endstruct

endscope

Systems used can be found here:

I suspect its call LightningUtils.enumUnits(g, beam, 100.) that's doing it since nothing else in my map uses that but idk why.
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Make sure to format the code so it's readable. You can click the three dots and then click this </> symbol to get it to paste properly, otherwise it will have those unnecessary return lines.
vJASS:
scope LaserSweep

    private struct Missile extends Missiles
 
        static integer AID = 'A000'
        static real angleincrement = 9.0
        real angle
        static real distance = 1200.
        unit dummytarget
        real anglecovered
        static real anglecoveredmax = 45.
        group alreadyhit
        Lightning beam

        method onFinish takes nothing returns boolean
            call DummyAddRecycleTimer(dummytarget, 0.5)
            set dummytarget = null

            if UnitAlive(source) and anglecovered < anglecoveredmax then
                set angle = angle + angleincrement
                set anglecovered = anglecovered + angleincrement
                set .dummytarget = GetRecycledDummyAnyAngle(GetUnitX(source) + distance * Cos(angle * bj_DEGTORAD), GetUnitY(source) + distance * Sin(angle * bj_DEGTORAD), 0)
                call deflectTarget(dummytarget)
                return false
            endif

            call DestroyGroup(alreadyhit)
            call beam.remove()
            return true
        endmethod

        method onPeriod takes nothing returns boolean
            local group g = CreateGroup()
            local unit u
            call LightningUtils.enumUnits(g, beam, 100.)

            loop
                set u = FirstOfGroup(g)
                exitwhen u == null

                if not IsUnitInGroup(u, alreadyhit) and IsUnitEnemy(u, owner) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and not BlzIsUnitInvulnerable(u) and UnitAlive(u) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
                    call GroupAddUnit(alreadyhit, u)
                    call UnitDamageTarget(source, u, damage, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
                    call AddUnitBonusTimed(u, BONUS_ARMOR, -5, 30.0)
                endif

                call GroupRemoveUnit(g, u)
            endloop

            set beam.targetX = .x
            set beam.targetY = .y
            call DestroyGroup(g)
            set g = null
            return false
        endmethod

        static method onCast takes nothing returns nothing
            local unit c = GetTriggerUnit()
            local real x = GetUnitX(c)
            local real y = GetUnitY(c)
            local real startingangle = GetUnitFacing(c) - (anglecoveredmax / 2)
            local real startingx = x + distance * Cos(startingangle * bj_DEGTORAD)
            local real startingy = y + distance * Sin(startingangle * bj_DEGTORAD)
            local thistype this = thistype.create(startingx, startingy, 50.0, startingx, startingy, 50.0)

            set .dummytarget = GetRecycledDummyAnyAngle(startingx, startingy, 0.)
            set .target = dummytarget
            set source = c
            set owner = GetOwningPlayer(c)
            set model = ""
            set speed = 1000
            set arc = 0.
            set curve = 0.
            set damage = 200 + (200 * GetUnitAbilityLevel(c, AID))
            set .angle = GetUnitFacing(c)
            set .anglecovered = 0.
            set .beam = Lightning.unitToPoint(c, startingx, startingy, 50, 50., false, 0., "DRAL", 0)
            set .alreadyhit = CreateGroup()
            call launch()
            set c = null
        endmethod

        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent(AID, function thistype.onCast)
        endmethod

    endstruct

endscope

Anyway, can you try to disable the lightning and see if that changes anything? It'd be much easier for you to test your suspicion instead of relying on us to import all of these systems into a map to test ourselves. Just // comment out any lines that mention lightning. Also, attaching a demo map would be very nice.
 
Top