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

Wanderer - Submission

Status
Not open for further replies.
JASS:
function TimerExpires takes nothing returns nothing
  local integer timerID =  GetHandleId( GetExpiredTimer ())
  local unit u =  LoadUnitHandle (udg_Hash, timerID, 1)
  local location currentLoc
  local location newLoc
  //Break - Unit is doing something
  if (GetUnitCurrentOrder (u) == 0) then
   //Which Mod
   if ( LoadInteger(udg_Hash,timerID,0) == 0) then
       //Order Move + Snow
       set currentLoc = GetUnitLoc(u)
       set newLoc = PolarProjectionBJ (currentLoc, GetRandomReal(500, 1500), GetRandomReal(0,360))
       call IssuePointOrderLoc(u, "Move", newLoc)
       //Terain Change
       call SaveInteger(udg_Hash,timerID,3, GetTerrainType(GetLocationX(newLoc),GetLocationY(newLoc)) )
       call SaveLocationHandle(udg_Hash,timerID,2,newLoc)
       call SetTerrainType(GetLocationX(newLoc),GetLocationY(newLoc), 'Nsnw', 0, 1, 0)
       call RemoveLocation(currentLoc)
       call SaveInteger(udg_Hash,timerID,0,1)
   else
       //Point Reached
       set newLoc = LoadLocationHandle(udg_Hash,timerID,2)
       call SetTerrainType(GetLocationX(newLoc),GetLocationY(newLoc), LoadInteger(udg_Hash,timerID,3), 0, 1, 0)   
       call RemoveLocation(newLoc)   
       call SaveInteger(udg_Hash,timerID,0,0)
   endif
   set newLoc = null
   set currentLoc = null
  endif
  set u = null
endfunction

//===========================================================================
function InitTrig_Wanderer2 takes nothing returns nothing
   local timer t = CreateTimer()
   local integer timerID =  GetHandleId(t)
   set udg_Hash = InitHashtable()
   call TimerStart (t, 0.2, true, function TimerExpires)
   call SaveInteger(udg_Hash,timerID,0,0)
   call SaveUnitHandle(udg_Hash,timerID,1,CreateUnit ( Player(0), 'hgry', 0, 0, 270))
   set t = null
endfunction
 

Attachments

  • Wanderer.w3m
    16.7 KB · Views: 41
In JASS it's bad habit to use PolarProjection. Find out how to achieve similar goal with using only reals. :)

Others used "0.3" as timeout interval, which is very low already, but "0.2" is definitly not needed. I would recommend to use at least 0.3 for further similar missions, or even sligthly more.

Your applied method is interesting. Though, it has logical breaks (duration between change and new order) which is... let's say not 100% perfect.
It's solveable that when the unit reaches the target location, that it 'instantly' changes the terrain and receives a new order again to make it a round thing, without making a break.
 
Considered your Feedback
JASS:
function TimerExpires takes nothing returns nothing
  local integer timerID =  GetHandleId( GetExpiredTimer ())
  local unit u =  LoadUnitHandle (udg_Hash, timerID, 1)
  local integer mod
  local real x
  local real y
  local real angel
  //Break - Is Flying?
  if (GetUnitCurrentOrder (u) == 0) then
    set mod = LoadInteger(udg_Hash,timerID,0)
   if mod == 1 then
       //Point Reached
       set x = LoadReal(udg_Hash,timerID,2)
       set y = LoadReal(udg_Hash,timerID,3)
       call SetTerrainType(x,y, LoadInteger(udg_Hash,timerID,4), 0, 1, 0) 
       set mod = 0
       call SaveInteger(udg_Hash,timerID,0,0)
   endif 
   if  mod == 0 then
       //Order Move + Snow
       set angel = GetRandomReal(-bj_PI, bj_PI)
       set x = GetUnitX(u) + GetRandomReal(500, 1500) * Cos(angel)
       set y = GetUnitY(u) + GetRandomReal(500, 1500) * Sin(angel)
       call IssuePointOrder(u, "Move", x,y)
       //Terain Change
       call SaveInteger(udg_Hash,timerID,4, GetTerrainType(x,y) )
       call SaveReal(udg_Hash,timerID,2,x)
       call SaveReal(udg_Hash,timerID,3,y)
       call SetTerrainType(x,y, 'Nsnw', 0, 1, 0) 
       set mod = 1
   endif
   call SaveInteger(udg_Hash,timerID,0,mod)
  endif
  set u = null
endfunction

//===========================================================================
function InitTrig_Wanderer2 takes nothing returns nothing
   local timer t = CreateTimer()
   local integer timerID =  GetHandleId(t)
   set udg_Hash = InitHashtable()
   call TimerStart (t, 0.3, true, function TimerExpires)
   call SaveInteger(udg_Hash,timerID,0,0)
   call SaveUnitHandle(udg_Hash,timerID,1,CreateUnit ( Player(0), 'hgry', 0, 0, 270))
   set t = null
endfunction
 

Attachments

  • Wanderer.w3m
    16.8 KB · Views: 37
JASS:
        //Order Move + Snow
        set angel = GetRandomReal(-bj_PI, bj_PI)
        set x = GetUnitX(u) + GetRandomReal(500, 1500) * Cos(angel)  
        set y = GetUnitY(u) + GetRandomReal(500, 1500) * Sin(angel)
        call IssuePointOrder(u, "Move", x,y)
        //Terain Change
        call SaveInteger(udg_Hash,timerID,4, GetTerrainType(x,y) )
        call SaveReal(udg_Hash,timerID,2,x)
        call SaveReal(udg_Hash,timerID,3,y)
        call SetTerrainType(x,y, 'Nsnw', 0, 1, 0)   
        set mod = 1
^This part of coding runs practicaly always. No matter what value "mod" initialy has.

JASS:
//Point Reached
        set x = LoadReal(udg_Hash,timerID,2)
        set y = LoadReal(udg_Hash,timerID,3)
        call SetTerrainType(x,y, LoadInteger(udg_Hash,timerID,4), 0, 1, 0)  
        set mod = 0
        call SaveInteger(udg_Hash,timerID,0,0)
^This part of coding runs practicaly always, except the very first time.

Do you know what I mean? Because, yes, it works, but from the architecture it's maybe not prefered.

I see this as pretty much 'Completed' but I just wanted to ask if you share my critique view on it. :)
 
Yes both Action-Blocks are executed each timeout except the first time, that's the plan.
-> But you are right checking every time to avoid in first-timeout an Action-Block, sounds inefficient.
Solution: Remove mod and its if, save the Terrain at 0/0 to reset it correctly even on first timeout
JASS:
function TimerExpires takes nothing returns nothing
  local integer timerID =  GetHandleId( GetExpiredTimer ())
  local unit u =  LoadUnitHandle (udg_Hash, timerID, 1)
  local real x
  local real y
  local real angel
  //Break - GreifenReiter Fliegt
  if (GetUnitCurrentOrder (u) == 0) then
   //Reset Terain
   set x = LoadReal(udg_Hash,timerID,2)
   set y = LoadReal(udg_Hash,timerID,3)
   call SetTerrainType(x,y, LoadInteger(udg_Hash,timerID,4), LoadInteger(udg_Hash,timerID,5), 1, 0)  
   //Order Move + Snow
   set angel = GetRandomReal(-bj_PI, bj_PI)
   set x = GetUnitX(u) + GetRandomReal(500, 1500) * Cos(angel) 
   set y = GetUnitY(u) + GetRandomReal(500, 1500) * Sin(angel)
   call IssuePointOrder(u, "Move", x,y)
   //Terain Change
   call SaveInteger(udg_Hash,timerID,4, GetTerrainType(x,y) )
   call SaveInteger(udg_Hash,timerID,5, GetTerrainVariance(x,y) )  
   call SaveReal(udg_Hash,timerID,2,x)
   call SaveReal(udg_Hash,timerID,3,y)
   call SetTerrainType(x,y, 'Nsnw', 0, 1, 0)  
  endif
  set u = null
endfunction

//===========================================================================
function InitTrig_Wanderer2 takes nothing returns nothing
   local timer t = CreateTimer()
   local integer timerID =  GetHandleId(t)
   set udg_Hash = InitHashtable()
   call TimerStart (t, 0.3, true, function TimerExpires)
   call SaveUnitHandle(udg_Hash,timerID,1, CreateUnit ( Player(0), 'hgry', 0, 0, 270))
   //Pre Change Terain Change
   call SaveInteger(udg_Hash,timerID,4, GetTerrainType(0,0) )  
   call SaveInteger(udg_Hash,timerID,5, GetTerrainVariance(0,0) )  
   set t = null
endfunction
 
Last edited:
I think that's a good way you do.
Though, I would keep with comments in english, and also "angel" could be "angle". ;p

Good job!
full
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Just wanna add something, using random number from Rmin to Rmax and applying polar projection based on random angle won't give a uniform distribution because the is area element is 2πrdr hence more will end up closer to the origin. If you want uniformly distributed random point in a circle, use a different approach I mentioned here. There are other ways to achieve this but it requires using SquareRoot so I think this is the best approach.
 
Thanks for that information i reproduced your tests in Warcraft 3. The cluster formating in near distance was detect, too.



Test Circle Random - 2 x 0 to 1 x Radius smaller.jpg

JASS:
function RandomU takes nothing returns nothing
  local real x
  local real y
  local real angel
  local real radius = 800
  local real random = radius * GetRandomReal(0, 1) + radius * GetRandomReal(0, 1)
  if random > radius then
     set random = 2 * radius - random
  endif
  set angel = GetRandomReal(-bj_PI, bj_PI)
  set x = random * Cos(angel)  
  set y = random * Sin(angel)
  call CreateUnit(Player(0),'h000',x,y,0)
endfunction


Test Circle Random - 800 x 0 to 1 smaller.jpg

JASS:
function RandomU takes nothing returns nothing
  local real x
  local real y
  local real angel
  local real random = GetRandomReal(10, 800)
  set angel = GetRandomReal(-bj_PI, bj_PI)
  set x = 0 + random * Cos(angel)  
  set y = 0 + random * Sin(angel)
  call CreateUnit(Player(0),'h000',x,y,0)
endfunction



Hmm i expirmented a little bit with your code to fit for donats:
I come to this three but first a default setup
maxRadius = 800
minRadius = 300
1.

Donat Clustered 5000 smaller1.jpg

JASS:
function RandomU takes nothing returns nothing
  local real x
  local real y
  local real angel
  local real radius = 800
  local real minradius = 300
  local real random = GetRandomReal(minradius, radius)
  set angel = GetRandomReal(-bj_PI, bj_PI)
  set x = random * Cos(angel) 
  set y = random * Sin(angel)
  call CreateUnit(Player(0),'h000',x,y,0)
endfunction


2.

Donat Clustered OuterRing 5000.jpg

JASS:
function RandomU takes nothing returns nothing
  local real x
  local real y
  local real angel
  local real radius = 800
  local real minradius = 300
  local real random = GetRandomReal(minradius/2, radius) + GetRandomReal(minradius/2, radius)
  if random > radius  then
     set random =  radius - ( radius - minradius) * ( ( random - radius) / radius)
  endif
  set angel = GetRandomReal(-bj_PI, bj_PI)
  set x = random * Cos(angel) 
  set y = random * Sin(angel)
  call CreateUnit(Player(0),'h000',x,y,0)
endfunction

3.

Donat Unclustered 5000 new.jpg

JASS:
function RandomU takes nothing returns nothing
  local real x
  local real y
  local real angel
  local real radius = 800
  local real minradius = 300
  local real random = GetRandomReal(minradius/2, radius) + GetRandomReal(minradius/2, radius)
  if random > radius  then
     set random = random - ( GetRandomReal(random - radius , random - minradius))
  endif
  set angel = GetRandomReal(-bj_PI, bj_PI)
  set x = random * Cos(angel) 
  set y = random * Sin(angel)
  call CreateUnit(Player(0),'h000',x,y,0)
endfunction


 
Status
Not open for further replies.
Top