# [Solved]Checking if the units left the rect

Status
Not open for further replies.

#### maxodors

Level 7
What is the best way to check if the unit left the rect? I want to check whether the unit is still inside the rect or not. In this case, checking the distance does not work because it is rect.

Edit: here is my solution, but it does not look efficient
JASS:
``````            call LineSegment.EnumUnitsEx(temp_group, rect1X, rect1Y, rect2X, rect2Y, RECT_LENGTH , true)
loop
set u = FirstOfGroup(temp_group)
exitwhen u == null
if (BaseBool(u) and not IsUnitEnemy(u, this.owner)) then
if not IsUnitInGroup(u, this.barrierDef) then
//Turn on Immunities
endif
endif

call GroupRemoveUnit(temp_group, u)
endloop

set copy = CopyGroup(this.barrierDef)

loop
set u = FirstOfGroup(copy)
exitwhen u == null
if not IsUnitInGroup(u, check) then
//Turn off immunities
call GroupRemoveUnit(this.barrierDef, u)
endif

call GroupRemoveUnit(copy, u)

endloop

call GroupClear(check)``````

Last edited:

#### Elprede

Level 17
JASS:
``````function IsUnitInRect takes unit u, rect r returns boolean
return (GetRectMinX(r) <= GetUnitX(u)) and (GetUnitX(u) <= GetRectMaxX(r)) and (GetRectMinY(r) <= GetUnitY(u)) and (GetUnitY(u) <= GetRectMaxY(r))
endfunction``````

#### ThompZon

Level 23
JASS:
``````function IsUnitInRect takes unit u, rect r returns boolean
return (GetRectMinX(r) <= GetUnitX(u)) and (GetUnitX(u) <= GetRectMaxX(r)) and (GetRectMinY(r) <= GetUnitY(u)) and (GetUnitY(u) <= GetRectMaxY(r))
endfunction``````
Note that this checks unit-center to rect-edge. If you want the units collision to be taken into effect (such as "is unit completely inside" or "is unit at least touching the rect's edge") you'd have to add or subtract collision radius.

#### IcemanBo

Level 37
if called
JASS:
``call LineSegment.EnumUnitsEx(this.barrierDef, rect1X, rect1Y, rect2X, rect2Y, RECT_LENGTH , true)``
the group already only holds units that are inside rect.
As next step though, one iteration would be required to remove units that don't match BaseBool() and Enemy check.

Optimal solution would be passing a filter function to EnumUnitsEx(), which does BaseBool() and Enemy check, but we currently don't support it. It could avoid the removal iteration then, too. If you want to wait a couple of days I want to add this functionality.

Last edited:

#### IcemanBo

Level 37

JASS:
``````private static player g_player
static method myFilter takes nothing returns boolean
local unit u = GetFilterUnit()
return BaseBool(u) and not IsUnitEnemy(u, g_player)
endmethod

method updateImmunities takes nothing returns nothing
g_player = this.owner
call LineSegment.EnumUnitsEx(this.barrierDef, rect1X, rect1Y, rect2X, rect2Y, RECT_LENGTH , true, Filter(function thistype.myFilter)
endmethod``````

#### maxodors

Level 7

JASS:
``````private static player g_player
static method myFilter takes nothing returns boolean
local unit u = GetFilterUnit()
return BaseBool(u) and not IsUnitEnemy(u, g_player)
endmethod

method updateImmunities takes nothing returns nothing
g_player = this.owner
call LineSegment.EnumUnitsEx(this.barrierDef, rect1X, rect1Y, rect2X, rect2Y, RECT_LENGTH , true, Filter(function thistype.myFilter)
endmethod``````
So, are you saying the only improvement possible to my code is to add filter to reduce if statements?

Note that this checks unit-center to rect-edge. If you want the units collision to be taken into effect (such as "is unit completely inside" or "is unit at least touching the rect's edge") you'd have to add or subtract collision radius.
Since I do not have the "rect", I suppose this does not work (I use line segment system)

#### maxodors

Level 7
loops are gone...
Maybe I do not get something, but I need to give immunity status only to those who are in rect. So, with your code, I need to loop in order to check whether newly selected units in rect are the same and then stop the immunity on those who are not in the second group. How does it remove the need for looping?

#### IcemanBo

Level 37
"this.barrierDef" will only contain all units that are currently in new rect and pass the filter. I suppose that this is what you want and consider them to be in "immunity group". Old will be already removed from group.

#### maxodors

Level 7
"this.barrierDef" will only contain all units that are currently in new rect and pass the filter. I suppose that this is what you want and consider them to be in "immunity group". Old will be already removed from group.
I understand that. To give immunity, I use a boolean. So, I would need to set boolean off for those who are not in rect anymore. It is probably my bad because I didn't add booleans to my code, so it is not clear. Sorry

Edit: I guess your proposal is to set boolean off for all in the immunity group, clear the group, and then set boolean on for updated group? Won't this cause problems?

Last edited:

#### IcemanBo

Level 37
Ah, ok I see. Clearing before should work, and assigning boolean then to true again yes. It might happen even in filter function, to avoid extra loop if you want.

But IsUnitInGroup is a function which already does actually required check if unit is immune, or? It might check if unit is in immunity group and returns boolean. Not sure if separate boolean flag brings benefit.

#### maxodors

Level 7
Ah, ok I see. Clearing before should work, and assigning boolean then to true again yes. It might happen even in filter function, to avoid extra loop if you want.

But IsUnitInGroup is a function which already does actually required check if unit is immune, or? It might check if unit is in immunity group and returns boolean. Not sure if separate boolean flag brings benefit.
I just run immunity with a separate system of mine, but I see what you mean. Thank you.

Status
Not open for further replies.

Replies
2
Views
535
Replies
5
Views
496
Replies
9
Views
549
Replies
2
Views
630
Replies
16
Views
991