• 🏆 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!

How to check if the x, y is inside any of 100 regions

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
I need to check if a building is created inside any of say 100 regions

Do I do it like this? or is there a way to combine these regions to one?

JASS:
function CheckForTownRect takes real x, real y returns boolean
  local integer i = 0
    loop  
        if  IsLocationInRegion(townArea[i], Location(x, y) then
            return TRUE
        endif
      set i = i + 1
      exitwhen i > MAX_TOWN_COUNT
    endloop
return FALSE
endfunction
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
I need to check if a building is created inside any of say 100 regions

Do I do it like this? or is there a way to combine these regions to one?

JASS:
function CheckForTownRect takes real x, real y returns boolean
  local integer i = 0
    loop  
        if  IsLocationInRegion(townArea[i], Location(x, y) then
            return TRUE
        endif
      set i = i + 1
      exitwhen i > MAX_TOWN_COUNT
    endloop
return FALSE
endfunction

I would use one region only, so that I pick every unit that's a town hall, then move the region there and check if the location is in that region. This should make things easier.

The other way is creating a region around every town hall and remove it if the town hall is destroyed. If destroying the halls is even possible.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
The town can be destroyed, but I also want different sized town areas so I prefer to create 100 regions in a setup trigger and attach it to a town.

Otherwise the decoration would have to be adjusted to be completly similar.

Changed to this so I also can use it to compare it to the owner of the town later.

JASS:
function LookForTownRect takes real x, real y returns integer
  local integer i = 0
    loop  
      if  IsLocationInRegion(townArea[i], Location(x, y) then
        return i
      endif
      set i = i + 1
      exitwhen i > MAX_TOWN_COUNT
    endloop
  return -1
endfunction

I suppose this is the way I'll be using.

Another way to compare the owning town would be to pick every unit in TownGroup and check for the closest one but I wouldn't think its faster.
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
JASS:
    function LookForTownRect takes unit town returns integer
        local integer i = 0
        loop
            if IsUnitInRegion(townArea[i], town) then
                return i
                //if you wanted to return rect directly, just do
                //return townArea[i]
            endif
            exitwhen i >= MAX_TOWN_COUNT
            set i = i + 1
        endloop
        return -1
        //if you are returning rect:
        //return null
    endfunction

or

JASS:
    function LookForTownInRect takes real x, real y returns integer
        local integer i = 0
        loop
            if IsPointInRegion(townArea[i], x, y) then
                return i
                //if you want to return rect directly just do
                //return townArea[i]
            endif
            exitwhen i >= MAX_TOWN_COUNT
            set i = i + 1
        endloop
        return -1
        //if you are returning rect:
        //return null
    endfunction
 
Level 15
Joined
Nov 30, 2007
Messages
1,202

Thanks didn't think of that.

I also realized that one could create fly pathing blockers on the country side build locations and make a building requirment for air-pathability. Best would be if you could create a custom pathing ground for blight and then just use that there so that air can still walk over farm buildable areas.

Any ideas how to create invisible blight?

Edit 2, it apears I have to convert rect2region to be able to use that condition, any other way? Could do it in the setup though.

This should also work, then I could skip looping through it for checking town area. (If I dont't find a way to create two different buildables. Or I scratch air units all together.

call RegionAddRect(townRegion, gg_rct_TownRegion000 )

Looks like this now:

JASS:
function InsideTown takes nothing returns nothing
* * // Do stuff
endfunction

function Building takes nothing returns nothing
  local integer i = 0
// Could place these inside the condition, but that might look messy?
  local real x = GetLocationX(GetUnitLoc(GetConstructingStructure()))
  local real y = GetLocationY(GetUnitLoc(GetConstructingStructure())) 
  
    // Checks if it's building inside a town
    loop
        if IsPointInRegion(townArea[i], x, y) then  
          call InsideTown()
          return // Could also do all the stuff here but that might look messy?
        endif
        set i = i + 1
      exitwhen i > MAX_TOWN_COUNT
    endloop
    
    // The building is not inside a town!
    // Do stuff
 

endfunction

function InitTrig_Construction takes nothing returns nothing
  local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_CONSTRUCT_START )
    call TriggerAddAction(t, function Building )
  set t = null
endfunction

Have one issue remaining though....

JASS:
 local real x = GetLocationX(GetUnitLoc(GetTriggerUnit()))
  local real y = GetLocationY(GetUnitLoc(GetTriggerUnit())) // Could place these inside the condition, but that might look messy?
  call BJDebugMsg("You are building atleast...")
    // Checks if it's building inside a town
    loop
/*THIS WORK >>>*/ if RectContainsUnit(townArea[i], GetTriggerUnit()) == TRUE then <<< THIS WORKS
/*DOESN'T WORK >>>*/ if IsPointInRegion(townArea[i], x, y) then     <<< THIS DOESN'T
// Continues...

JASS:
  //Working Option!
 set townArea[0] = gg_rct_TA000
//Not Working Option!
   call RegionAddRect(townArea[0], gg_rct_TA000)
 
Last edited:

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,540
Hi, let me clear up some confusion about rects and regions.

  • A region is a set of rects - you can for example have a region which is shaped like a + by adding two rects to it with opposite size.
  • region and rect are both datatypes which are objects in their own sense - they can be created and destroyed.
  • If a rect is added to a region and then transformed/destroyed, the region's contents will not change to match that.

Using this information you'll probably want to approach the problem differently.

Here's what you're looking at:

  • You do/don't want something to be possible to create within some range of a "town" construct.
  • "Town"s are dynamic (they are created and destroyed during the game)

Therefore, the best way to solve this will look something like this:

  1. Create an initialization function which checks all pre-placed "town"s and defines their areas as "unsafe" building areas by adding a surrounding rect to a global region.
  2. Create a trigger which registers any new towns' unsafe building areas for the system by adding its surrounding rect to that region.
  3. Create a trigger which rebuilds the unsafe region whenever a "town" is destroyed.
  4. Create a trigger that checks building locations for that unsafe region whenever a new construct is going to begin building.

I have a few other thoughts though - is a "town" a unit, or some abstract idea? If the town is a specific type or types of unit, you can just enumerate units around the new building and look for a "town" - this is better in every aspect.

Also: local real x = GetLocationX(GetUnitLoc(GetConstructingStructure())) -> local real x=GetUnitX(GetConstructingStructure())
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
Awesome so basically I can add rect to a playerTownRegion and then check compare it later. This also solves how I'm gonna detect resources on ground. If a player loses a town his townrect is removed from the region.

GoldRegion
IronRegion
FoodRegion
e.t.c.

*Deleted* I Didn't Create the region properly.

Edit; Trying to do one or the other; The building can't be placed there, order cancel or; worker issued build order order stop. Can't get either to work decently. Also the rect dont seem to be removed and it keeps detecting townArea[0-1] as unbuildable.

Edit: I hate it when I dont set my integers to 0 when im looping them, sorry.
 
Last edited:
Status
Not open for further replies.
Top