• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

How to search a region for a tileset?

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
I want to search a region for a tilesets of type how would I create such a function?

actually i want to search around a region

so if a given area is 3*3*(128) I want to search everything outside that in this case 5*5*(128) would be the outlying region. They have the same center.


Other examples: takes region 1*1*(128) search 5*5*(128), takes region 2*2*(128) search 4*4*(128)

Well, I began like this anyway: looks like a dumb way, and not sure how to loop through dubble, tripple rows and how to exit these loops :p

Basically it goes round the box. Not working yet Obviously.

JASS:
function SearchForTerrain takes real x, real y, real xDist, real yDist real searchRadian returns boolean
    set real x = x + searchRadian*128
    set real y = y - searchRadian*128

    loop // Something about the rows that I want to circle around this box.
    
        loop
          if GetTerrainType(x,y) == 'A000' then
            return TRUE
          endif
        set x = x - 128
        endloop
        loop
          if GetTerrainType(x,y) == 'A000' then
            return TRUE
          endif
        set y = y + 128
        endloop
        loop
          if GetTerrainType(x,y) == 'A000' then
            return TRUE
          endif
        set x = x + 128
        endloop
        loop
          if GetTerrainType(x,y) == 'A000' then
            return TRUE
          endif
        set y = y - 128
        endloop
    endloop
return FALSE
endfunction

The Image is what I had in mind. Each lap starts at the pink region and ends befor the following white, where next loop start seen above. Dunno exactly what parameters I need for these. The Red Regions I dont want to search. The black is the center and also not needed to be searched. (The regions are only to show you what I mean.)

I don't know how to keep track when it has gone 4 respectivly 2 regions distance (the distance changes depending on the lap it is on.)

Anyway, how would you do it?
 

Attachments

  • Boxes2.png
    Boxes2.png
    384.1 KB · Views: 110
Last edited:
Level 25
Joined
Jul 10, 2006
Messages
3,315
I don't quite understand; from your title it sounds like you want to check all terrain cells in a region for a given terrain tile, but your code tells a different story.

Which is it?

If you just want to check all cells for the terrain type, a simple nested loop is what you need.

(pseudocode)
Code:
integer minX, maxX, minY, maxY

loop i from minX to maxX
  loop j from minY to maxY
    if terrain type at (i*128, j*128) == (terrain type)
      return true
return false

This is how the above code will check all terrain cells in order:
attachment.php
 

Attachments

  • searchorder.png
    searchorder.png
    9.5 KB · Views: 180
Level 15
Joined
Nov 30, 2007
Messages
1,202
I only want to check around tthe region (the none black and red cells the rest are not interesting, and if it doesnt matter they might aswell be checked, this will run often. In your example its checking 8 tiles more then needed. I coppied you and it says that it is expecting returns?

JASS:
function CheckForRoad takes real minX, real maxX, real minY, real maxY returns boolean
local real y

   loop 
        set y = minY
        loop
          if GetTerrainType(minX,y) == 'A000' then
            return TRUE
          endif
        exitwhen y == maxY
        set y = y + 128
        endloop
    exitwhen minX == maxX
    set minX = minX + 128
    endloop
return FALSE    
endfunction
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
Will the border always be 1 terrain cell thick? If so, we can reduce it to take only a reduce, and calculate the extents from that.

You weren't supposed to copy my code; it's pseudocode, meaning "a code idea".

The boarder wont be longer then 2 rows, most of the times it will only be 1. But tbh, this check does the jobb so I dont know if its worth adding more lines just to remove 2-12 extra checks. However, how to make it work? ^^

Can I change the given parameter values like I did and why is it complaining at returns?

Hm, also we perhaps can take advantage of the pathing ground of the unit. The red cells and black from the screenshot above will most likely be a buildings pathing. Perhaps we can use that to retrive our min and max values?
 
Level 25
Joined
Jul 10, 2006
Messages
3,315
Now I'm even more confused.

Anyhow, to check the border only, you'll need these parameters:
minX
maxX
minY
maxY
centerMinX
centerMaxX
centerMinY
centerMaxY

The loops will have to change. I'm too tired right now to write proper code, so I'll try my best to explain it.
When you do the "x = x + 128" line, first check if the new value will be within centerMinX and centerMaxX; if it is, then set x = centerMaxX + 128. And the same for Y values.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
Now I'm even more confused.

Anyhow, to check the border only, you'll need these parameters:
minX
maxX
minY
maxY
centerMinX
centerMaxX
centerMinY
centerMaxY

The loops will have to change. I'm too tired right now to write proper code, so I'll try my best to explain it.
When you do the "x = x + 128" line, first check if the new value will be within centerMinX and centerMaxX; if it is, then set x = centerMaxX + 128. And the same for Y values.

So... like this:

JASS:
globals 
    real array bCenter_minX
    real array bCenter_maxX
    real array bCenter_minY
    real array bCenter_maxY
    real array bYard_minX
    real array bYard_maxX
    real array bYard_minY
    real array bYard_maxY
endglobals

function CheckForRoad takes integer index returns boolean
local real x = bYard_minX[index]
local real y
   loop 
        set y = bYard_minY[index] 
        loop
          if GetTerrainType(x,y) == 'Lrok' then
            return TRUE
          endif
        exitwhen y == bYard_maxY[index]
        
        if y > bCenter_minY[index] and y < bCenter_maxY[index] then
          set y = bCenter_maxY[index] + 128
            else 
              set y = y + 128
        endif     
        endloop
        
    exitwhen x == bYard_maxX[index]
    
    if x > bCenter_minX[index] and x < bCenter_maxX[index] then
      set x = bCenter_maxX[index] + 128
        else 
          set x = x + 128
    endif     
    endloop
return FALSE   
endfunction

Isn't it less extensive to just loop through all the blocks? ;p I'd be deducting 4 variables to set when the unit enters the map.

Also it it unwarrented to store these 8 variables when they are constant only depending on which unit_type it is? Example:

Functon 1 gives me the min to max x and y then function 2 checks for terrain, or is it smoother to just have function 2 check for terrain types as above? This might be used everytime the player removes the road or creates a building additionaly if it was created at a bad spot.

could also make it take unit type instead and then a bunch of ifs and then this check in the same function.

too bad not everything is squarre, some sides are longer then other if that were the case a inlined polarprojection would do the job. What if I want to compare shapes that are not rectangual, but angeled, or L shaped, or even, circular? :>

Okey, the wanted perimeter will be inside a region. A region that is combined my multiple rects still have a x-min, x-max, y-min, y-max or how does that work? Even if there are "gaps" in it? Another way would be to add the shapes to another variable

And you check them all but you go through multiple areas like this instead.

buildingA[x] = standard
buildingB[x] = second shape or null if there is none
buildingC[x] = third shape or null
...

This makes things way too complicated, figured out a workaround.
 
Last edited:
Status
Not open for further replies.
Top