• 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.
  • It's time for the first HD Modeling Contest of 2025. Join the theme discussion for Hive's HD Modeling Contest #7! Click here to post your idea!

[Trigger] Spawning Unit Location

Status
Not open for further replies.
Level 8
Joined
Sep 10, 2013
Messages
372
If I made 2 regions, a bigger region and a smaller one inside it, and I want to spawn units using triggers in a random location in the bigger region, but not in the smaller region, how can I do that?
 
Level 29
Joined
Feb 18, 2014
Messages
3,599
Unit - Create "Unit" at random point of "Region".
Condition - Created unit is in "small region" equal to true
Action - Move created unit to random point of "Large region"

I don't know but it's probably possible to use "different than region" action.
 
You can always trial and error. Just try, and if condition does not met, try again.

scratch it, i rushed. see Wietlol's suggestion.
Idk if it's good to make in gui, but you could use coordinates:

Code:
rect_1 = smaller rect, inside
rect_2 = bigger rect, surrounding

(Now some help variables, for our bounds)
minX = maxX(rect_1) - centerX(rect_1)
maxX = maxX(rect_2) - minX
minY = maxY(rect_1) - centerY(rect_1)
maxX = maxY(rect_2) - minY

// Now random values. So here we decide if he go in positive, or negative direction from our center.

if Random(1, 2) == 1 then[INDENT]
randX = Random(minX, maxX)[/INDENT]
else
[INDENT]randX = -1* Random(minX, maxX)[/INDENT]

if Random(1, 2) == 1 then
[INDENT]randY = Random(minY, maxY)[/INDENT]
else
[INDENT]randY = -1* Random(minY, maxY)[/INDENT]

x = CenterXOf(rect_1)
y = CenterYOf(rect_1)

myRandomLocation = Location(x + randX, y + randY)
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,658
The best way is to do it one at a time.

RlaPzRp.png

you want a spot anywhere in the grey area, where every spot has the same chance as another to appear.

You first do a random real for the x axis. (Random point between 'a' and 'b', these are points)
Then you check where that position is:
YO4xpkb.png

If your X point is lower than 'c' or larger than 'd', it is simple, and you can do a random number for the y as a normal rectangle.

But if your random number is between 'c' and 'd', you need to do something else.
QSRRV1a.png

You create a random real between 0 and 'e' + 'f' (these are lengths).
If that number is larger than 'e', then you add 'g' to it and add the position (Y-Max in this case, but you could also do it from down to top if you like).
If it is smaller than or equal to 'e', you can just add the position of the green rect to it.

Pros:
- this doesnt include loops
- this only uses two random generated numbers
- this is fairly simple to code
- this is pretty do-able in GUI

Cons:
- You have to admit that I am a genius
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
JASS code with the calculation: (untested)
JASS:
function GetRandomPointInRectFilteringRect takes rect r1, rect r2, location l returns location
    //resulting position
    local real resultX
    local real resultY
    
    //rect1 data
    local real r1_minX = GetRectMinX(r1)
    local real r1_maxX = GetRectMaxX(r1)
    local real r1_minY = GetRectMinY(r1)
    local real r1_maxY = GetRectMaxY(r1)
    
    //rect2 data
    local real r2_minX = GetRectMinX(r2)
    local real r2_maxX = GetRectMaxX(r2)
    local real r2_minY //not necessarily used
    local real r2_maxY //not necessarily used
    
    //temporary data variable
    local real r
    
    set resultX = GetRandomReal(r1_minX, r1_maxX)
    if resultX < r2_minX or resultX > r2_maxX then
        //x position is outside inner rect x range
        set resultY = GetRandomReal(r1_minY, r1_maxY)
        
    else
        //not used outside this block
        set r2_minY = GetRectMinY(r2)
        set r2_maxY = GetRectMaxY(r2)
        
        //x position is inside inner rect x range
        set r = r2_maxY - r2_minY
        set resultY = GetRandomReal(r1_minY, r1_maxY - r)
        
        if resultY > r2_minY then
            //y position is in block after the inner rect
            set resultY = resultY + r
        endif
    endif
    
    //create new location or move existing
    if l == null then
        set l = Location(resultX, resultY)
    else
        call MoveLocation(l, resultX, resultY)
    endif
    return l
endfunction
(I do have to credit KILLCIDE for beating me at wether it is better to start at 0 or at minY in the Y calculation+comparison.)

EDIT:
Tested it and changed
"if resultY > r2_maxY then"
to
"if resultY > r2_minY then"

EDIT:
Changed to MoveLocation as suggested by KILLCIDE
 
Last edited:
Status
Not open for further replies.
Top