• 🏆 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!

[Solved] IsUnitInRangeXY Issue

Status
Not open for further replies.
So I'm having an issue with IsUnitInRangeXY. It seems to be able to pick some units, but others just don't work, even if the unit is directly on top on it's target. What this code is suppose to do is that the unit 'mark' is supposed to deal damage to ground units around it.

The Setup trigger setups all the stuff that the unit will use. the onDamage Trigger will detect when a unit takes damage (uses Bribe's Damage Engine) and add a new instance of that unit to the trigger. The last trigger is the code that's giving me grief. For some reason, IsUnitInRangeXY (and I also test with IsUnitInRange, same problem) is not picking up some units.

Anyone ever encounter a problem like this before?


JASS:
    elseif GetUnitTypeId(udg_UDexUnits[udg_UDex]) == 'mark' then
        set SL_Uses_SL[udg_UDex]                = true
        set SL_LaserInterval[udg_UDex]          = 0
        set SL_LaserThreshold[udg_UDex]         = 32
        set SL_LaserDamageInterval[udg_UDex]    = 0
        set SL_LaserDamageThreshold[udg_UDex]   = 4
        set SL_LaserAttackType[udg_UDex]        = ATTACK_TYPE_PIERCE
        set SL_LaserAOE[udg_UDex]               = 200.
        set SL_LaserEffectStringBeam[udg_UDex]  = "war3mapImported\\LaserArcaneBeam.mdx"
        set SL_LaserEffectStringBase[udg_UDex]  = "war3mapImported\\LaserArcaneBase.mdx"
        set SL_IsSiegeLaserActive[udg_UDex]     = false
        call SetUnitPathing(udg_UDexUnits[udg_UDex], false)


JASS:
        elseif udg_DamageEventType == 0 and SL_Uses_SL[id] then
            set udg_DamageEventAmount = 0.
           
            set SL_LaserHits[id] = SL_LaserHits[id] + 1
            set SL_LaserDamageStacks[id] = SL_LaserDamageStacks[id] + GetFullDamage(udg_DamageEventPrevAmt, GetUnitArmor(udg_DamageEventTarget))
           
            if not SL_IsSiegeLaserActive[id] then
                set SL_LaserInstances = SL_LaserInstances + 1
                set SL_LaserSource[SL_LaserInstances] = udg_DamageEventSource
                set SL_LaserInterval[id] = 0
                set SL_LaserDamageInterval[id] = 0
                set SL_LaserEffectBeam[id] = AddSpecialEffectTarget(SL_LaserEffectStringBeam[id], udg_DamageEventSource, "origin")
                set SL_LaserDummy[id] = CreateUnit(GetOwningPlayer(udg_DamageEventSource), 'dumi', GetUnitX(udg_DamageEventSource), GetUnitY(udg_DamageEventSource), 270.)
                set SL_LaserEffectBase[id] = AddSpecialEffectTarget(SL_LaserEffectStringBase[id], SL_LaserDummy[id], "origin")
                set SL_LaserTarget[id] = udg_DamageEventTarget
                set SL_IsSiegeLaserActive[id] = true
                if not IsTriggerEnabled(gg_trg_Siege_Laser) then
                    call EnableTrigger(gg_trg_Siege_Laser)
                endif
            else
                set SL_LaserInterval[id] = 0
                if SL_LaserTarget[id] != udg_DamageEventTarget then
                    set SL_LaserTarget[id] = udg_DamageEventTarget
                endif
            endif


JASS:
scope SL
   
    globals
        public boolean array    Uses_SL
        public boolean array    IsSiegeLaserActive
        public group            LaserDamageGroup = CreateGroup()
       
        public unit array       LaserSource
        public unit array       LaserTarget
        public unit array       LaserDummy
        public effect array     LaserEffectBeam
        public effect array     LaserEffectBase
        public string array     LaserEffectStringBeam
        public string array     LaserEffectStringBase
        public integer          LaserInstances = 0
       
        public integer array    LaserInterval
        public integer array    LaserThreshold
        public integer array    LaserDamageInterval
        public integer array    LaserDamageThreshold
       
        public integer array    LaserHits
        public real array       LaserDamageStacks
        public real array       LaserAOE
        public attacktype array LaserAttackType
    endglobals

    function SiegeLaser takes nothing returns boolean
        local integer iLoop = 0
        local integer iRecycle = 0
        local integer id = 0
        local unit u = null
        local real damage = 0.
        local real SOURCE_X = 0.
        local real SOURCE_Y = 0.
        local real TARGET_X = 0.
        local real TARGET_Y = 0.
        local real angle = 0.
        local real distance = 0.
       
        loop
            set iLoop = iLoop + 1
            set id = GetUnitUserData(LaserSource[iLoop])
           
            set SOURCE_X = GetUnitX(LaserSource[iLoop])
            set SOURCE_Y = GetUnitY(LaserSource[iLoop])
            set TARGET_X = GetUnitX(LaserTarget[id])
            set TARGET_Y = GetUnitY(LaserTarget[id])
           
            //if SOURCE_X != TARGET_X and SOURCE_Y != TARGET_Y then
                set angle = Atan2(TARGET_Y - SOURCE_Y, TARGET_X - SOURCE_X)
                set distance = GetUnitMoveSpeed(LaserSource[iLoop]) / 32
                call SetUnitX(LaserSource[id], SOURCE_X + Cos(angle) * distance)
                call SetUnitY(LaserSource[id], SOURCE_Y + Sin(angle) * distance)
            //endif
           
            call SetUnitX(LaserDummy[id], SOURCE_X)
            call SetUnitY(LaserDummy[id], SOURCE_Y)
           
            set LaserDamageInterval[id] = LaserDamageInterval[id] + 1
            if LaserDamageInterval[id] >= LaserDamageThreshold[id] then
                set LaserDamageInterval[id] = 0
                call GroupEnumUnitsInRange(LaserDamageGroup, SOURCE_X, SOURCE_Y, LaserAOE[id] + Missile_MAXIMUM_COLLISION_SIZE, null)
                set damage = ( LaserDamageStacks[id] / LaserHits[id] ) 
                set LaserDamageStacks[id] = 0.
                set LaserHits[id] = 0
                loop
                    set u = FirstOfGroup(LaserDamageGroup)
                    call GroupRemoveUnit(LaserDamageGroup, u)
                    call BJDebugMsg("Player name: " + GetPlayerName(GetOwningPlayer(LaserSource[iLoop])))
                    call BJDebugMsg("Unit name: " + GetObjectName( GetUnitTypeId( u ) ))
                    call BJDebugMsg(R2S(LaserAOE[id]))
                    if IsUnitInRangeXY(u, SOURCE_X, SOURCE_Y, LaserAOE[id]) and IsUnitType(u, UNIT_TYPE_GROUND) then
                        /*call BJDebugMsg("Player name: " + GetPlayerName(GetOwningPlayer(LaserSource[iLoop])))
                        call BJDebugMsg("Unit name: " + GetObjectName( GetUnitTypeId( u ) ))
                        call BJDebugMsg(R2S(LaserAOE[id]))*/
                        if not IsUnitAlly(u, GetOwningPlayer(LaserSource[iLoop])) or ( not IsUnitEnemy(u, GetOwningPlayer(LaserSource[iLoop])) and u == LaserTarget[id] ) then
                            set udg_NextDamageType = udg_DamageTypeCode
                            call UnitDamageTarget(LaserSource[iLoop], u, damage, true, true, LaserAttackType[id], DAMAGE_TYPE_UNIVERSAL, null)
                            call TriggerEvaluate(udg_ClearDamageEvent)
                        endif
                    endif
                    exitwhen u == null
                endloop
            endif
           
            set LaserInterval[id] = LaserInterval[id] + 1
            if LaserInterval[id] >= LaserThreshold[id] or not UnitAlive(LaserSource[iLoop]) then
                set LaserInterval[id]       = 0
                set LaserDamageInterval[id] = 0
                set IsSiegeLaserActive[id]  = false
                call UnitApplyTimedLife(LaserDummy[id], 'BTLF', 0.01)
                set LaserDummy[id] = null
                set LaserTarget[id] = null
                call DestroyEffect(LaserEffectBeam[id])
                call DestroyEffect(LaserEffectBase[id])
                set iRecycle = iLoop
                loop
                    set LaserSource[iRecycle] = LaserSource[iRecycle + 1]
                    exitwhen iRecycle == LaserInstances
                    set iRecycle = iRecycle + 1
                endloop
                set LaserInstances = LaserInstances - 1
                if LaserInstances == 0 then
                    call DisableTrigger(gg_trg_Siege_Laser)
                endif
            endif
           
            exitwhen iLoop >= LaserInstances
        endloop
       
        return false
    endfunction

    //===========================================================================
    function InitTrig_Siege_Laser takes nothing returns nothing
        set gg_trg_Siege_Laser = CreateTrigger()
        call DisableTrigger( gg_trg_Siege_Laser )
        call TriggerRegisterTimerEvent( gg_trg_Siege_Laser, .03125, true )
        call TriggerAddCondition( gg_trg_Siege_Laser, function SiegeLaser )
    endfunction
   
endscope
 
Status
Not open for further replies.
Top