# Counting number of players in a rect

#### sethmachine

Level 15
Hi,

I am trying to write a function that returns the number of players in rect, based on whether their hero is in it (versus a peon/footman).

This function works when I enter a region, but when I leave a region and immediately enter another, it returns the wrong value (0). It flip flops every other region.

Thus if my hero entered regions in this order:

r1 --> r2 --> r3

it would display: 1, 0, 1 for the player count

JASS:
``````function getPlayerCountInRect takes rect r returns integer
local integer i = 0
local integer count = 0
loop
exitwhen i == TOTAL_PLAYERS
if isUnitInRect(playerDatum[i].pc.u, r) then
set count = count + 1
endif
set i = i + 1
endloop
return count
endfunction``````

JASS:
``````function isLocInRect2 takes location whichLoc, rect whichRect returns boolean
local real x = GetLocationX(whichLoc)
local real y = GetLocationY(whichLoc)
if x >= GetRectMinX(whichRect) and x <= GetRectMaxX(whichRect) and y >= GetRectMinY(whichRect) and y <= GetRectMaxY(whichRect) then
return true
endif
return false
endfunction

function isUnitInRect takes unit whichUnit, rect whichRect returns boolean
return isLocInRect2(GetUnitLoc(whichUnit), whichRect)
endfunction``````

JASS:
``````    static method leaveMain takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(GetTriggerUnit())
local integer pid = GetPlayerId(p)
local CreepRegion cr
if GetTriggerUnit() == playerDatum[pid].pc.u then
set cr = findCreepRegion(GetTriggeringRegion())
if playerDatum[pid].creepRegion == cr.creepTableId then
set playerDatum[pid].creepRegion = -1
set playerDatum[pid].creepFreq = 0
endif
set cr.totalPlayers = cr.totalPlayers - 1
endif
return false
endmethod

static method enterMain takes nothing returns boolean
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(GetTriggerUnit())
local integer pid = GetPlayerId(p)
local CreepRegion cr
if GetTriggerUnit() == playerDatum[pid].pc.u then
set cr = findCreepRegion(GetTriggeringRegion())
call print("players in rect: " + I2S(getPlayerCountInRect(cr.rRect)))
set playerDatum[pid].creepRegion = cr.creepTableId
set playerDatum[pid].creepFreq = cr.freq
set cr.totalPlayers = cr.totalPlayers + 1
endif
return false
endmethod``````

#### Zeatherann

Level 17
Try This

I simple function to brute force check it. It should work for your needs. If your rects are large and/or contain a large number of units and this function is called a lot then I suggest using a state based system with enters/leaves region events. However, since this works on rects and not regions you can get away with more dynamic use.
JASS:
``````function CountPlayersInRect takes rect R returns integer
local group G=CreateGroup()
local unit Unit
local integer Ret=0
local integer Pid
local boolean array Counted
call GroupEnumUnitsInRect(G,R,null)
loop
set Unit=FirstOfGroup(G)
exitwhen Unit==null
call GroupRemoveUnit(G,Unit)
if IsUnitType(Unit,UNIT_TYPE_HERO)then
set Pid=GetPlayerId(GetOwningPlayer(Unit))
if not Counted[Pid]then
set Counted[Pid]=true
set Ret=Ret+1
endif
endif
set Unit=null
endloop
call DestroyGroup(G)
set G=null
return Ret
endfunction``````

Replies
6
Views
617
Replies
4
Views
832
Replies
2
Views
426
Replies
3
Views
795
Replies
2
Views
539