• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!
  • ✅ The POLL for Hive's Texturing Contest #33 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!

[JASS] trouble with dummy casting

Not open for further replies.
Level 6
Sep 9, 2006
So, this ability shoots an orb out.. the orb shoots shockwaves back as it travels, 45 degrees off the travel line behind it, then all units between the 2 shockwaves SHOULD get slowed.. that last part is not happening for some reason.

Also, is there a more efficient way of doing the conditions and other function besides using global temp variables?
scope Orb

    private constant integer ABILITY_ID = 'A003'           //ability id of Spark Jump
    private constant integer DUMMY_ABILITY_PULSE = 'A004'  //ability id of the pulse damaging ability (i.e. shockwave)
    private constant integer DUMMY_ABILITY_SLOW = 'A006'   //ability id of the slow ability (slow)
    private constant integer DUMMY_ORB_ID = 'h001'         //orb id
    private constant integer DUMMY_ID = 'h000'             //dummy unit id
    private constant integer PULSE_TIMER = 25              // .01's of sec between pulses
    private constant real DUMMY_OFFSET = 6.                //amount dummy is offset by each time
    private constant real PULSE_WIDTH = 45.                //how wide the pulse lines are (degrees from center travel line)
    private unit tempU
    private real tempR
    private unit tempD
    private group g //unit group used for units that get slowed

private struct data
    static hashtable h = InitHashtable()
    unit c
    unit array dummy [3] //dummy units (orb and casters)
    integer lvl
    integer PT = PULSE_TIMER - 15 //subtract some to get the pulses to start a bit earlier
    integer count
    timer tim = CreateTimer()
    real Fx //final position
    real Fy
    real Sx //pulse spell target point
    real Sy
    real angle //from origin of spell to target point
    real Pangle
    real maxdist
    real curdist
    static method matching takes nothing returns boolean
        local real angle = bj_RADTODEG*Atan2(GetWidgetY(tempD)-GetWidgetY(GetFilterUnit()),GetWidgetX(tempD)-GetWidgetX(GetFilterUnit()))
        return (angle>(tempR-45.))and(angle<(tempR+45.))and(IsUnitAlly(GetFilterUnit(),GetOwningPlayer(tempU))==false)and(GetWidgetLife(GetFilterUnit())>0)and(IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false)
    static method slow_group takes nothing returns nothing
        local unit d = CreateUnit(GetOwningPlayer(tempU), 'h000', GetWidgetX(tempD), GetWidgetY(tempD), 0)
        call UnitAddAbility(d, DUMMY_ABILITY_SLOW)
        call IssueTargetOrder( d, "slow", GetEnumUnit() )
        call UnitApplyTimedLife(d, 'BTLF', .4)
        set d = null
    static method periodic takes nothing returns nothing
        local integer id = GetHandleId(GetExpiredTimer())
        local data this = LoadInteger(.h,id,0)
        local real Dx = GetWidgetX(.dummy[1])
        local real Dy = GetWidgetY(.dummy[1])
        local real Tx = (Dx + DUMMY_OFFSET * Cos(.angle * bj_DEGTORAD))
        local real Ty = (Dy + DUMMY_OFFSET * Sin(.angle * bj_DEGTORAD))
        set .curdist = .curdist + DUMMY_OFFSET
        call SetUnitPosition(.dummy[1], Tx, Ty)
        if .PT > 0 then
            set .PT = .PT - 1
            set .PT = PULSE_TIMER
            set .count = 3
            set .Pangle = .angle + 135
                exitwhen .count == 1
                set .Sx = (Tx + 10 * Cos(.Pangle * bj_DEGTORAD))
                set .Sy = (Ty + 10 * Sin(.Pangle * bj_DEGTORAD))
                set .dummy[.count] = CreateUnit(GetOwningPlayer(.c), DUMMY_ID, Tx, Ty, .Pangle)
                call UnitAddAbility(.dummy[.count], DUMMY_ABILITY_PULSE)
                call SetUnitAbilityLevel(.dummy[.count], DUMMY_ABILITY_PULSE, .lvl)
                call IssuePointOrder(.dummy[.count], "shockwave", .Sx, .Sy)
                call UnitApplyTimedLife(.dummy[.count], 'BTLF', .3)
                set .Pangle = .Pangle + 90
                set .count = .count - 1
            set tempU = .c
            set tempR = .angle
            set tempD = .dummy[1]
            call GroupEnumUnitsInRange(g, Tx, Ty, (200. + 100. * I2R(.lvl)), Condition(function data.matching))
            call ForGroup(g, function data.slow_group)
            call GroupClear(g)
            set tempU = null
            set tempD = null
            //send pulse; slow units and shoot shockwaves
        if .curdist > .maxdist then
            call RemoveUnit(.dummy[1])
            call DestroyTimer(.tim)
            call FlushChildHashtable(.h,id)
            call .destroy(id)
            //end spell

    static method create takes nothing returns data
        local data this = data.allocate()
        local real Dx
        local real Dy
        set .c = GetTriggerUnit()
        set Dx = GetWidgetX(.c)
        set Dy = GetWidgetY(.c)
        set .lvl = GetUnitAbilityLevel(.c, ABILITY_ID)
        set .angle = bj_RADTODEG * Atan2(GetSpellTargetY() - Dy, GetSpellTargetX() - Dx)
        set .maxdist = 600. + (200. * I2R(.lvl))
        set .curdist = 0.
        set .dummy[1] = CreateUnit(GetOwningPlayer(.c), DUMMY_ORB_ID, Dx, Dy, 0)
        call SaveInteger(.h,GetHandleId(.tim),0,this)
        call TimerStart(.tim,.01,true,function data.periodic)
        return this

    static method Conditions takes nothing returns nothing
        if GetSpellAbilityId() == ABILITY_ID then
            call .create()
    static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddAction( t, function data.Conditions )
Level 6
Sep 9, 2006
Those UnitApplyTimedLife calls are very low. You shouldn't have .4 or something, you should have it at maybe 1.5 or 2.0. If they are too low, the dummy will die before it can actually cast the ability :p

ok thats what i was thinking, becaues i did some testing and found out that its enough time fo rthe shockwave but apparently not for the slow
Level 6
Sep 9, 2006
ok so i think something is wrong with setting up the group that will be slowed; currently, using a side script, i see no dummies on the map, except for the 2 (sometimes 4 because of the .3 sec duration on those units vs .25sec pulse rate), when the ability is ran

edit: forgot to actually create the group.. testing now :p

anddd it works; now to tweak some numbers
Last edited:
Not open for further replies.