Grouping Units Fails Sometimes

WolfieeifloW

WEHZ Helper
Reaction score
372
My spell is a simple dash, but it also does damage and creates an illusion at every enemy hit.

My problem is that sometimes (Usually when going diagonal), units won't get grouped by the spell.
My hero goes right through the middle of them, but still doesn't create an illusion sometimes.
Here's the code:
JASS:
library PhantomDash initializer Init requires TimerUtils optional GTrigger

    globals
        private constant integer ABILITY_ID = 'PHAN'
        private constant integer ILLUSION_ID = 'ILLU'
        private constant integer DUMMY_ID = 'dUMM'
        private constant integer HIT_RANGE = 50
        private constant real SPEED = 500.
        private constant real RADIUS = 50.
        private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MELEE
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
        private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
    endglobals
    
    private function Damage takes integer level returns real
        return level * 50.
    endfunction
    
    struct data
        unit caster
        real casterX
        real casterY
        real targetX
        real targetY
        real facing
        group hit = CreateGroup()
        timer t
        
        method destroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call GroupClear(.hit)
            call .deallocate()
        endmethod
    endstruct
    
    globals
        private constant real PERIOD = 0.03125
        private constant real DSPEED = SPEED * PERIOD
        private group GROUP = CreateGroup()
        private location loc
        private real x
        private real y
        private integer CurrentInstance
    endglobals
    
    private function Conditions takes nothing returns boolean
        local unit u = GetFilterUnit()
        local unit dummy
        local data d = CurrentInstance
        
        call BJDebugMsg("Conditions")
        if IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and GetWidgetLife(u) >= 0.405 and IsUnitEnemy(u, GetOwningPlayer(d.caster)) and IsUnitInGroup(u, d.hit) == false then
            call BJDebugMsg("Passed")
            call UnitDamageTarget(d.caster, u, Damage(GetUnitAbilityLevel(d.caster, ABILITY_ID)), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
            set dummy = CreateUnit(GetOwningPlayer(d.caster), DUMMY_ID, GetUnitX(u), GetUnitY(u), bj_UNIT_FACING)
            call UnitAddAbility(dummy, ILLUSION_ID)
            call SetUnitAbilityLevel(dummy, ILLUSION_ID, GetUnitAbilityLevel(d.caster, ABILITY_ID))
            call IssueTargetOrderById(dummy, 852274, d.caster)
            call UnitApplyTimedLife(dummy, 'BTLF', 1.)
            call GroupAddUnit(d.hit, u)
        endif
        set dummy = null
        set u = null
        return false
    endfunction
    
    private function Callback takes nothing returns nothing
        local data d = GetTimerData(GetExpiredTimer())
        
        set d.casterX = GetUnitX(d.caster)
        set d.casterY = GetUnitY(d.caster)
        set x = d.targetX - d.casterX
        set y = d.targetY - d.casterY
        if SquareRoot(x * x + y * y) >= HIT_RANGE then
            call BJDebugMsg("Callback")
            set d.facing = Atan2(d.targetY - d.casterY, d.targetX - d.casterX)
            set d.casterX = d.casterX + DSPEED * Cos(d.facing)
            set d.casterY = d.casterY + DSPEED * Sin(d.facing)
            call SetUnitX(d.caster, d.casterX)
            call SetUnitY(d.caster, d.casterY)
            set CurrentInstance = d
            call GroupEnumUnitsInRange(GROUP, GetUnitX(d.caster), GetUnitY(d.caster), RADIUS, Condition(function Conditions))
        else
            call BJDebugMsg("Ending")
            call BJDebugMsg("---------------")
            call SetUnitAnimation(d.caster, "stand")
            call PauseUnit(d.caster, false)
            call d.destroy()
        endif
    endfunction
    
    private function Actions takes nothing returns boolean
        local data d
        
        if GetSpellAbilityId() == ABILITY_ID then
            call BJDebugMsg("Actions")
            set d = data.create()
            set d.caster = GetTriggerUnit()
            set loc = GetSpellTargetLoc()
            set d.casterX = GetUnitX(d.caster)
            set d.casterY = GetUnitY(d.caster)
            set d.targetX = GetLocationX(loc)
            set d.targetY = GetLocationY(loc)
            set d.t = NewTimer()
            call SetTimerData(d.t, d)
            call SetUnitAnimation(d.caster, "walk")
            call PauseUnit(d.caster, true)
            call TimerStart(d.t, PERIOD, true, function Callback)
            set loc = null
        endif
        return false
    endfunction
        
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        
        static if(LIBRARY_GTrigger) then
            call TriggerAddCondition(GT_RegisterStartsEffectEvent(trig, ABILITY_ID), Condition(function Actions))
        else
            call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(trig, Condition(function Actions))
        endif
        set trig = null
    endfunction
    
endlibrary

The speed is quite low, for testing purposes, but even at a normal speed (1500), it still errors.

In fact, I just tested it back at 1500, and now it just fails to group, more often then not, even when going in a straight X line.
Oh, and the dummy has 0.00 backswing and cast point; And the illusion wand ability has 0 cooldown and mana cost.
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
Maybe you are ordering too many actions for 0.03215 seconds, but I think that's impossible...

TIP: Try creating group on struct creation to avoid some leaks.
Another one: You may use T32 and see where you made any mistake with yor current timer system, I am on vacation now and I don't have Newgen WE with me, if you wait I will create exactly what you need. Tommorow I'm coming
 

Jedi

New Member
Reaction score
63
50 is very small radius imo, even you touch unit with your hero there is a chance it can't be enumed(depends on unit collisions).

Proof edit:I am picking units in 50 range of left paladin and display it's name.
 
Reaction score
456
Good idea is to go to terrain editor and display grid. Smallest cells have size of 32, then 128, and finally 256.
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
omg now I saw it, 50 radius is nothing, you should use melee range values, like 120-130 to check.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top