HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Determining Approached Unit

02-13-2009, 03:28 AM#1
fX_
How to determine the approached unit associated with the triggerevent: TriggerRegisterInRange()?
02-13-2009, 04:08 AM#2
Bobo_The_Kodo
Attach the unit to the trigger?
02-13-2009, 08:46 AM#3
Captain Griffen
Mmm...try and find the unit at exactly the right distance?
02-13-2009, 08:49 AM#4
xombie
fX_, what are you using it for? The way in which you do this strongly depends on what it is being used for.
02-13-2009, 10:55 AM#5
fX_
What this does is detects when a hero comes in range of a subject unit, which is supposed to be a member of a 'creep wave' (as in AOS') for some AI system I am putting together - yes, motivated by an AOS I am making. It is supposed to make creeps rally to heroes that come in range of them if there is not yet a hero close to them.

I implemented Bobo's suggestion.

Collapse JASS:
    scope Rally

        globals
            private constant real APPROACH_RANGE = 1000.00
            private constant real GATHER_DISTANCE_MIN = 100.00
            private constant real GATHER_DISTANCE_MAX = 500.00
           
            private player gP = null
            private group gUG = CreateGroup()
        endglobals

        private function DestroyTriggerDelayed takes trigger t returns nothing
            call TriggerSleepAction(0.00)
            call DestroyTrigger(t)
        endfunction
       
        private function AllyHeroFilter takes nothing returns boolean
            return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.00 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) and IsUnitAlly(GetFilterUnit(), gP)
        endfunction

        struct Rally extends UnitAction

            private static method Prompt takes nothing returns boolean
                local trigger TRIG = GetTriggeringTrigger()
                local integer INT_Index = 0
                local unit U_Patron = GetTriggerUnit()
                local integer INT_CountPatron = 0

                loop
                    exitwhen Rally.Inst[INT_Index].trig == TRIG
                    set INT_Index = INT_Index + 1
                endloop

                set gP = GetOwningPlayer(Rally.Inst[INT_Index].uSubject)
                if GetUnitState(U_Patron, UNIT_STATE_LIFE) > 0.00 and IsUnitType(U_Patron, UNIT_TYPE_HERO) and IsUnitAlly(U_Patron, gP) then
                    call GroupEnumUnitsInRange(gUG, GetUnitX(Rally.Inst[INT_Index].uSubject), GetUnitY(Rally.Inst[INT_Index].uSubject), APPROACH_RANGE, Filter(function AllyHeroFilter))
                    loop
                        set U = FirstOfGroup(gUG)
                        exitwhen U == null
                        set INT_CountPatron = INT_CountPatron + 1
                        call GroupRemoveUnit(gUG, U)
                    endloop
                    if INT_CountPatron == 1 then
                        set Rally.Inst[INT_Index].uPatron = U_Patron
                        call Rally.Inst[INT_Index].mind.PromptAction(Rally.Inst[INT_Index])
                    endif

                    call GroupClear(gUG)
                endif

                set TRIG = null
                set gP = null
                set U_Patron = null
                return false
            endmethod

            public unit uSubject
            public UnitMind mind
            public integer intOrderId = OrderId("move")
            public integer intPriority
            public unit uPatron = null
            public trigger trig = CreateTrigger()

            public static method Create takes unit subject, UnitMind mind, integer priority returns boolean
                if subject != null and mind != 0 and priority >= 0 and Rally.intCountInst < UNIT_ACTION_MAX_INSTANCES and Rally.Get(subject) == 0 then
                    set Rally.Inst[Rally.intCountInst] = Rally.allocate()
                    set Rally.Inst[Rally.intCountInst].uSubject = subject
                    set Rally.Inst[Rally.intCountInst].mind = mind
                    set Rally.Inst[Rally.intCountInst].intPriority = priority
                    call TriggerRegisterUnitInRange(Rally.Inst[Rally.intCountInst].trig, subject, APPROACH_RANGE)
                    call TriggerAddCondition(Rally.Inst[Rally.intCountInst].trig, Condition(function Rally.Prompt))

                    set Rally.Inst[Rally.intCountInst].intInstIndex = Rally.intCountInst
                    set Rally.intCountInst = Rally.intCountInst + 1

                    return true
                endif

                return false
            endmethod

            public method SetPriority takes integer priority returns boolean
                if priority >= 0 then
                    set .intPriority = priority
                    return true
                endif
                return false
            endmethod

            public method Destroy takes nothing returns nothing
                set .uSubject = null
                call .mind.RemoveAction(this)
                set .uPatron = null
                call DestroyTriggerDelayed.execute(.trig)
                set .trig = null

                set Rally.intCountInst = Rally.intCountInst - 1
                set Rally.Inst[Rally.intCountInst].intInstIndex = .intInstIndex
                set this = 0
                set Rally.Inst[.intInstIndex] = Rally.Inst[Rally.intCountInst]
                set Rally.Inst[Rally.intCountInst] = 0
            endmethod

            public method Evaluate takes nothing returns integer
                if .uPatron != null then
                    return .intPriority
                endif
                return -1
            endmethod

            public method Execute takes nothing returns nothing
                local real R_X = GetUnitX(.uPatron)
                local real R_Y = GetUnitY(.uPatron)
                local real R_Distance = GetRandomReal(GATHER_DISTANCE_MIN, GATHER_DISTANCE_MAX)
                local real R_Angle = Atan2(GetUnitY(.uSubject) - R_Y, GetUnitX(.uSubject) - R_X)

                set R_X = R_X + R_Distance * Cos(R_Angle)
                set R_Y = R_Y + R_Distance * Sin(R_Angle)

                call IssuePointOrder(.uSubject, "move", R_X, R_Y)
            endmethod

            private integer intInstIndex
            private static Rally array Inst[UNIT_ACTION_MAX_INSTANCES]
            private static integer intCountInst = 0

            public static method Get takes unit subject returns Rally
                local integer INT_Index = 0

                loop
                    exitwhen INT_Index == Rally.intCountInst
                    if Rally.Inst[INT_Index].uSubject == subject then
                        return Rally.Inst[INT_Index]
                    edif
                    set INT_Index = INT_Index + 1
                endloop

                return 0
            endmethod

        endstruct

    endscope
02-13-2009, 11:27 AM#6
DioD
Attach unit to trigger, use separete trigger for every unit.

There is no "clean vJass way"
02-13-2009, 12:56 PM#7
fX_
By attaching do you mean associating like I did? Or what?