Random points, but with distances in between.

Ivach

New Member
Reaction score
18
As the thread title suggests, I'm stumped on how to do this.

Basically, I have this trigger which creates 4 units at random points within 700 AoE of the caster. The problem is that I don't want any of these units to be close to each other. I want their positions to be random each time you cast it, yet they should at least be 200 distance apart from one another. Any ideas?
 

Exide

I am amazingly focused right now!
Reaction score
448
Start by setting a center point (Position of (Triggering Unit)).

Then set a real variable Degrees= random real between 1.0 and 360.0

Now loop this four times;
set SpawnPoint = CenterPoint offset by 700 towards Degrees.
Create 1 *Your_Unit* for ((Owner of (Triggering unit)) at spawnpoint facing 270.0 degrees
custom script call RemoveLocation(udg_SpawnPoint)
set Degrees = Degrees + 90 (360/4)

finally remove the CenterPoint
call RemoveLocation(udg_CenterPoint)

should work.
 

Rainther

I guess I should write something of value here...
Reaction score
61
That's not that random really :p That forms only a square if I read it right.
It's not a simple task to do.
 

Ivach

New Member
Reaction score
18
Yeah. That wasn't was I was talking about. Thanks anyway.

The units can be anywhere within the 700 AoE, but they can't be within 250 distance of each other.
 

Kuberr24

Well-Known Member
Reaction score
28
the square part is half the work though.

first you do as Exide suggested, but instead of distance 700 you take distance 450. and instead of creating a unit at that location, you pick another random point which is 250 away from that point in a circle. you do this 4 times and you have 4 random points, which will always be MINIMUM 136 distance from each other, but that is only 1% chance, other cases it will be 250-300 distance (pythagoras: Root(450²+450²) - (250+250) = 136), and WILL NEVER be closer to caster then 200 distance.

Picture:

naamlooszdb.jpg
 

Exide

I am amazingly focused right now!
Reaction score
448
Yeah. That wasn't was I was talking about. Thanks anyway.

The units can be anywhere within the 700 AoE, but they can't be within 250 distance of each other.

I see.
Creating them like that will take an ineffective piece of code, and will make it hard and probably confusing to use the ability.
You can also add a random value between 1 and 700, like this:

set SpawnPoint = CenterPoint offset by Random Integer Between 1 and 700 towards Degrees.

to gain a little bit more random-ness.
 

Ivach

New Member
Reaction score
18
Hmmm, damn. I guess such a degree of randomness isn't possible without a bunch of long triggers.

Thanks for all the ideas though, I might use them if I don't have a more suitable solution. +rep to everyone.
 

Kuberr24

Well-Known Member
Reaction score
28
Have you read my post? MY trigger is only 15 lines long :|... that's pretty short!
 

Ivach

New Member
Reaction score
18
Yeah I've seen it. Thanks for thanking out the time to draw such a detailed diagram.

The trigger does add more randomness to the points, but it still within the confines of several locations.

Again, thanks. I might use that solution though, as it's the closest proposed solution to my problem.
 

Summoned

New Member
Reaction score
51
Something like this?

Edit: Plugged leaks. Changed into a trigger.
JASS:
function Trig_Random_Summon_Actions takes nothing returns nothing

    local location castpoint
    local location point1
    local location point2
    local location point3
    local location point4
    local integer i
    
    if (GetSpellAbilityId() == 'A001') then
    
        set castpoint = GetUnitLoc(GetTriggerUnit())    
        set i = 1
    
        loop
            exitwhen i == 5
            if i == 1 then
                set point1 = PolarProjectionBJ(castpoint, GetRandomReal(0, 700), GetRandomReal(0, 360))
                set i = 2
            elseif i == 2 then
                set point2 = PolarProjectionBJ(castpoint, GetRandomReal(0, 700), GetRandomReal(0, 360))
                if DistanceBetweenPoints(point1, point2) > 250 then
                    set i = 3
                else
                    call RemoveLocation(point2)
                endif
            elseif i == 3 then
                set point3 = PolarProjectionBJ(castpoint, GetRandomReal(0, 700), GetRandomReal(0, 360))
                if (DistanceBetweenPoints(point1, point3) > 250) and (DistanceBetweenPoints(point2, point3) > 250) then
                    set i = 4
                else
                    call RemoveLocation(point3)
                endif
            elseif i == 4 then
                set point4 = PolarProjectionBJ(castpoint, GetRandomReal(0, 700), GetRandomReal(0, 360))
                if (DistanceBetweenPoints(point1, point4) > 250) and (DistanceBetweenPoints(point2, point4) > 250) and (DistanceBetweenPoints(point3, point4) > 250) then
                    set i = 5
                else
                    call RemoveLocation(point4)
                endif
            endif
        endloop
    
        call CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'n001', point1, 0)
        call CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'n001', point2, 0)
        call CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'n001', point3, 0)
        call CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'n001', point4, 0)
    
        call RemoveLocation(castpoint)
        call RemoveLocation(point1)
        call RemoveLocation(point2)
        call RemoveLocation(point3)
        call RemoveLocation(point4)
    
    endif
    
endfunction

//===========================================================================
function InitTrig_Random_Summon takes nothing returns nothing
    set gg_trg_Random_Summon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Random_Summon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Random_Summon, function Trig_Random_Summon_Actions )
endfunction
 

Kuberr24

Well-Known Member
Reaction score
28
Something like this?

Unless I'm misreading, your trigger will simply stop creating units if it gets to close to another unit? I think he wants a solution to when that problem happens, not just stop :p

You COULD edit your code to instead of "set I = 3" to "loop - recalculate a new point - exitwhen (point matches all conditons) - endloop" but that CAN cause major lag if your PC gets unlucky with random points ;)
 

Summoned

New Member
Reaction score
51
The loop doesn't end until all 4 points are created, because i doesn't get set to the next value until the distance is greater than 250. But yes, there might be lag if you're EXTREMELY EXTREMELY EXTREMELY unlucky (by extremely unlucky, I mean so improbable it's almost impossible). I just finished writing up a GUI version.

EDIT: Shorter version, requires the point variable to be a point array. Also can be configured to a value of more than 4 easily just by changing the two 4's to whatever.
Trigger:
  • Random Summon 3
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Summon Hellbeasts
    • Actions
      • Set castpoint = (Position of (Triggering unit))
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Set point[(Integer A)] = (castpoint offset by (Random real number between 0.00 and 700.00) towards (Random real number between 0.00 and 360.00) degrees)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Integer A) Greater than 1
            • Then - Actions
              • For each (Integer B) from 1 to ((Integer A) - 1), do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Distance between point[(Integer A)] and point[(Integer B)]) Greater than 250.00
                    • Then - Actions
                      • Do nothing
                    • Else - Actions
                      • Custom script: call RemoveLocation(udg_point[bj_forLoopAIndex])
                      • Custom script: set bj_forLoopBIndex = bj_forLoopAIndex
                      • Custom script: set bj_forLoopAIndex = bj_forLoopAIndex - 1
            • Else - Actions
              • Do nothing
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Unit - Create 1 Summoned Hellbeast for (Owner of (Triggering unit)) at point[(Integer A)] facing 0.00 degrees
          • Custom script: call RemoveLocation(udg_point[bj_forLoopAIndex])
      • Custom script: call RemoveLocation(udg_castpoint)



(EDIT: long version... also hard to configure, ignore this unless you like bleeding eyes)
Trigger:
  • Random Summon 2
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Summon Hellbeasts
    • Actions
      • Set castpoint = (Position of (Triggering unit))
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Integer A) Equal to 1
            • Then - Actions
              • Set point1 = (castpoint offset by (Random real number between 0.00 and 700.00) towards (Random real number between 0.00 and 360.00) degrees)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Integer A) Equal to 2
                • Then - Actions
                  • Set point2 = (castpoint offset by (Random real number between 0.00 and 700.00) towards (Random real number between 0.00 and 360.00) degrees)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Distance between point1 and point2) Greater than 250.00
                    • Then - Actions
                      • Do nothing
                    • Else - Actions
                      • Custom script: call RemoveLocation(udg_point2)
                      • Custom script: set bj_forLoopAIndex = 1
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Integer A) Equal to 3
                    • Then - Actions
                      • Set point3 = (castpoint offset by (Random real number between 0.00 and 700.00) towards (Random real number between 0.00 and 360.00) degrees)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Distance between point1 and point3) Greater than 250.00
                          • (Distance between point2 and point3) Greater than 250.00
                        • Then - Actions
                          • Do nothing
                        • Else - Actions
                          • Custom script: call RemoveLocation(udg_point3)
                          • Custom script: set bj_forLoopAIndex = 2
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Integer A) Equal to 4
                        • Then - Actions
                          • Set point4 = (castpoint offset by (Random real number between 0.00 and 700.00) towards (Random real number between 0.00 and 360.00) degrees)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Distance between point1 and point4) Greater than 250.00
                              • (Distance between point2 and point4) Greater than 250.00
                              • (Distance between point3 and point4) Greater than 250.00
                            • Then - Actions
                              • Do nothing
                            • Else - Actions
                              • Custom script: call RemoveLocation(udg_point4)
                              • Custom script: set bj_forLoopAIndex = 3
                        • Else - Actions
      • Unit - Create 1 Summoned Hellbeast for (Owner of (Triggering unit)) at point1 facing 0.00 degrees
      • Unit - Create 1 Summoned Hellbeast for (Owner of (Triggering unit)) at point2 facing 0.00 degrees
      • Unit - Create 1 Summoned Hellbeast for (Owner of (Triggering unit)) at point3 facing 0.00 degrees
      • Unit - Create 1 Summoned Hellbeast for (Owner of (Triggering unit)) at point4 facing 0.00 degrees
      • Custom script: call RemoveLocation(udg_castpoint)
      • Custom script: call RemoveLocation(udg_point1)
      • Custom script: call RemoveLocation(udg_point2)
      • Custom script: call RemoveLocation(udg_point3)
      • Custom script: call RemoveLocation(udg_point4)
 

Ivach

New Member
Reaction score
18
Whoa thanks, that's pretty much what I was looking for, and yet the trigger doesn't seem as long as I thought it would be.

Based on just looking and it, it pretty much should work as how I want it. But I'll try it out when I get home. +rep.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top