• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Unit comes within range of other unit event

Level 6
Joined
May 31, 2008
Messages
218
I need help with a trigger that i don't seem to get right. If some1 just could explain how to start this trigger for me: A unit of a certain type comes within range of another certain unit type, then i know the rest myself. But the problem is that i can't find any good event option, since you can only choose to have a unit come within range of a specific unit, but i need a unit-type. Or can you use the no unit which is under preset, but that seems unlogical cause then conditions wont trigger.

Could someone tell me how to solve this?
 
Level 11
Joined
Feb 22, 2006
Messages
752
Let's say you want to detect whenever unit of type A comes within X distance of a unit of type B.

Make a timer that has a relatively short period, like 0.05. Every time the timer fires, loop through every unit in the map of type B, then do a groupenum of all units within X distance of each of those units. If any of the units enumerated are of type A, call a function that handles the event.
 
Level 9
Joined
Nov 4, 2007
Messages
931
Well I'll explain it GUI language how you could carry out a trigger like this:
Event:
Every # seconds of game time

Actions:
set MyUnitGroup = Pick Every Unit in Playable Map Area Matching(Matching unit is = YourCenterUnit)
Pick Every Unit in MyUnitGroup and do actions:
- set MyUnitGroup2 = Pick Every Unit in # range of Picked Unit Matching (your conditions for matching unit )
- Pick Every Unit in MyUnitGroup2 and do actions:
-Your actions for units that come within range of your units
- Remove Picked Unit From MyUnitGroup2
- Remove Picked Unit From MyUnitGroup
- Custom Script - call DestroyGroup(udg_MyUnitGroup2)
Custom Script - call DestroyGroup(udg_MyUnitGroup)


You should be able to work out the rest from there, I apologize for not being able to make it look like its GUI but i don't quite know how to format my replies yet, hope that helps.
 
Level 6
Joined
May 31, 2008
Messages
218
  • Untitled Trigger 004
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Set regional_capitol[0] = (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to (==) Region capitol))
      • Unit Group - Pick every unit in regional_capitol[0] and do (Actions)
        • Loop - Actions
          • Set gold[0] = (Units within 100.00 of (Position of (Picked unit)) matching ((Unit-type of (Matching unit)) Equal to (==) Gold Horse))
          • Unit Group - Pick every unit in gold[0] and do (Actions)
            • Loop - Actions
              • Unit - Remove (Picked unit) from the game
              • Unit Group - Remove all units of gold[0] from gold[0]
              • Custom script: call DestroyGroup (udg_gold[0])
          • Unit Group - Remove all units of regional_capitol[0] from regional_capitol[0]
          • Custom script: call DestroyGroup (udg_regional_capitol[0])
Now it seem to work, but this thing will happen maybe... hundreds or even a thousand times each time you play the map, so it it safe to keep it like this without any lagg occuring.
 
Level 11
Joined
Feb 14, 2009
Messages
884
Save the unit you want in a unit-type variable, and use that variable in the event
  • Events
    • Unit - A unit comes within x of (<your unit-type variable>)
 
Level 9
Joined
Nov 4, 2007
Messages
931
If you only have one or two units that you want to effect units that come within range of them, you should probably go with Kercyn's method, I can't say if it will lag or not judging from just that number of actions, but if you cover all your leaks it should minimize leaks, and by the way check to see if it only affects one unit at a time, because it appears that you destroy your group inside the unit group function, I'm not sure if that still carries out the actions for the rest of the units in that group so I can't say if you should move it or not.
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
It depends on what you are looking for. If you want to use the 'Unit comes within X of <other unit>' in a generic way (like a unit comes within range of any unit in some unit group), then that event with variable will not help you.

If you still want to do it using the 'Unit within range' event, then I think the only way possible is to do it via Jass/Lua:
  • Create trigger via jass/lua, register event, actions, etc. and then track the trigger's handle via variable of type 'Trigger'
  • Save the handle of the unit as a value in hashtable where the parent or child key is the handleId of the trigger
  • When the event fires, get handle of the fired trigger (the '(This trigger)' function) and load the approached unit from hashtable using the trigger's handleId
  • Since you create 1 trigger per 1 unit, the trigger's handleId should be a unique identifier of the approached unit
Basically, it would look something like
JASS:
//registration
function InitTrig_MyTrigger takes nothing returns nothing
    set gg_trg_MyTrigger = CreateTrigger(  )
    call TriggerRegisterUnitInRangeSimple( gg_trg_MyTrigger, 256, udg_MyUnitVariable )
    call TriggerAddAction( gg_trg_MyTrigger, function Trig_MyTrigger_Actions )

    call SaveUnitHandleBJ(udg_MyUnitVariable, 0, GetHandleIdBJ(gg_trg_MyTrigger), udg_MyHashtable )
endfunction

// loading the approached unit
set udg_ApproachedUnit = LoadUnitHandleBJ(0, GetHandleIdBJ(GetTriggeringTrigger()), udg_MyHashtable)

The above is just slightly modified GUI trigger that was converted to jass, but if you use the idea described there, then you can create a generic system that would allow you to reliably detect which unit from some set/group was approached by the trigger unit
 
Top