HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Keeping a unit confined in a location...

03-16-2003, 06:37 PM#1
Ari
I'm trying to keep a unit temporarily within a certain distance of its current position. In effect, there's a unit at the middle of a circle, and I want them to stay within that circle (though they can move freely within the circle itself). There's two components to this:

first, I prevent any orders to points outside this circle from taking effect (don't worry about how). This works beautifully, and I'm happy with how it's implemented (for now).

But what about when the "shortest" point from point A to point B (both within the circle) takes the unit outside the circle? In other words, if a wall (for example) runs through the circle, and the unit is on one side, and the destination is on the other side, the unit will try to take the long way around. This can't be prevented as above, because the destination is a valid one. At the moment, I have a periodic trigger that checks every .5 seconds to see if a unit is still within this circle, and if not, sends them back in (using a unit - move instantly order). I'm beginning to suspect that this is the source of instabilities in my map, though, and I'd love to find a better way of doing this that doesn't involve periodic events.

Can anybody think of anything?
03-16-2003, 07:03 PM#2
Guest
How about unit leaves region, then move him back and order to stop or something. It's not a circle, but you could use some overlapping regions to almost get a circle. I would think 4 would do it.
Code:
 X
Y Z
 A

Then you would just have the event, Unit leaves Region X, and is not in Y,Z or A.
03-16-2003, 07:14 PM#3
Guest
I would very much like to know how you made him not accept orders telling him to go a certain distance.
03-16-2003, 07:23 PM#4
Guest
I'm sure he used DistanceBetweenPoints and canceled the order (issue stop) if it was farther than he wanted.
03-16-2003, 10:43 PM#5
Ari
For some reason (I can't even remember why anymore - this was at least 5 months ago now) stop orders weren't doing exactly what I wanted them to. Hmmmm, the engine has changed quite a bit since then - perhaps they would work for me. In any case, rather than stop orders, I used "unit - replace unit" actions, which have the advantage of completely negating any given orders (of course they're less than perfect if units have buffs, or have variables associated with them, but for me, that's not a problem).
03-16-2003, 11:41 PM#6
Iron_Ian
Make a single region for a circle\diamond. Then have a trigger if the unit leaves the region, order him to move to the center of the region.
03-17-2003, 12:09 AM#7
Guest
Quote:
I wrote:
How about unit leaves region, then move him back and order to stop or something.

Quote:
Iron_Ian Writes:
Make a single region for a circle\diamond. Then have a trigger if the unit leaves the region, order him to move to the center of the region.

Not poking fun of you, Ian. Just a bit baffled that you wrote the same thing 3 posts later.
03-17-2003, 12:10 AM#8
Electromancer
you could run a check, every 1 seconds, that does if (Real - Distance between 2 points) is equal to (whatever number is the limit) then move unit to point else do nothing. This keeps it were it should be.
03-17-2003, 01:18 AM#9
Aiursrage2k
The basic idea is to detect the event without a periodic one, I think this should work. Spawn 4 units (markers) using the polar projection of angles(0,90,180,270), record the origin, and the origin of the projection is the caster unit. Next add a trigger to detect when a unit comes within a range of the caster unit(condition: entering unit is a marker), check the distance between its current postion and the origin. If it (distance between caster and origin) is within your desired range, move the markers again (using projections listed above). Continue doing this check against until it is greater then your desired radius, if so move the caster unit back to the origin, and also move the markers back.

Note: I made a trigger to include spawned units for the function TriggerRegisterUnitInRangeSimple, if you need it you have to look for it (in one of these threads, as I have seemed to have lost it.)
03-17-2003, 02:39 AM#10
dataangel
Right after you give the order check their facing angle. If it isn't towards their order target, then they're walking around something, so stop 'em. This will stop them from moving around stuff even inside the circle though, so dunno if that'd help..

The periodic event shouldn't be causing any form of instability unless you're accessing array elements that haven't been defined yet inside them (the lag slowly adds up).
03-17-2003, 02:15 PM#11
Aiursrage2k
The good thing of this method, is it wont have to run the checks if the unit is idle.
Code:
//Four user defined variables (UDG)
//point origin, unit u, region region, trigger Detect
//updated it because rects were not getting destroyed
function myrectR takes nothing returns nothing
    local real array c

    //smaller more accurate, less efficent
    //greater less accurate, more efficent
    local real sz = 64.00 

    set c[0] =  GetLocationX(GetUnitLoc(udg_u)) - sz
    set c[1] =  GetLocationY(GetUnitLoc(udg_u)) - sz
    set c[2] =  GetLocationX(GetUnitLoc(udg_u)) + sz
    set c[3] =  GetLocationY(GetUnitLoc(udg_u)) + sz
    set udg_region = Rect(c[0],c[1] ,c[2],c[3])
endfunction

function DC takes nothing returns nothing
    local real dist
    call DestroyTrigger(udg_Detect)
    set udg_Detect = CreateTrigger(  )

    call myrectR()

    call DisplayTextToForce( GetPlayersAll(), "gah" )
    set dist = DistanceBetweenPoints(GetUnitLoc(udg_u), udg_Origin)
    if (dist > 500.00  ) then
        call SetUnitPositionLoc( udg_u, udg_Origin )
        call myrectR()
    endif
    call TriggerRegisterLeaveRectSimple( udg_Detect, udg_region  )
    call TriggerAddAction( udg_Detect, function DC )
endfunction

function init takes nothing returns nothing
    set udg_u = gg_unit_hhes_0000
    set udg_Origin = GetUnitLoc(udg_u)
    call DC()
endfunction

function InitTrig_region takes nothing returns nothing
    local code i = function init
    set gg_trg_region = CreateTrigger(  )
    call TriggerAddAction( gg_trg_region, i)
endfunction