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

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
JASS:
scope Wanderer initializer Init

    globals
        private hashtable hash
    endglobals

    private function Move takes nothing returns nothing
   
        local unit u = LoadUnitHandle(hash,0,0)
        local real x0 = GetUnitX(u)
        local real y0 = GetUnitY(u)
       
        local real x1
        local real y1
        local real distance = GetRandomReal(500, 1500)
        local real angle = GetRandomReal(0, 2*bj_PI)
       
        //I don't know if we have to deal with exceptions, but here it is in case the point is not within
        //the playable map area.
        //It's a bad algorithm, but since the minimum chance of succes is 25% (in a corner),
        //it should be sufficient for only one unit.
        loop
            set x1 = x0 + distance * Cos(angle)
            set y1 = y0 + distance * Sin(angle)  
            exitwhen RectContainsCoords(bj_mapInitialPlayableArea, x1, y1)
        endloop
       
       
       
        call SaveInteger(hash, 0, 2, GetTerrainType(x1,y1))
        call SaveReal(hash, 0, 3, x1)
        call SaveReal(hash, 0, 4, y1)
        call SaveInteger(hash, 0, 5, GetTerrainVariance(x1, y1))
        call SetTerrainType(x1, y1, 'Nsnw', -1, 1, 0)
        call IssuePointOrder(u,"move",x1,y1)
        set u = null
    endfunction
   
    private function Check takes nothing returns nothing
        local unit u = LoadUnitHandle(hash,0,0)
        local real x0 = GetUnitX(u)
        local real y0 = GetUnitY(u)
        local real x1 = LoadReal(hash, 0, 3)
        local real y1 = LoadReal(hash, 0, 4)
       
        if(IsUnitInRangeXY(u, x1, y1, 20)) then
            call SetTerrainType(x1, y1, LoadInteger(hash, 0, 2), LoadInteger(hash, 0, 5), 1, 0)
            call Move()
        endif
        set u = null
    endfunction
   
    private function Init takes nothing returns nothing
        local timer t = CreateTimer()
        set hash = InitHashtable()
        call SaveUnitHandle(hash, 0, 0, CreateUnit(GetLocalPlayer(), 'hgry', GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea), 0))
        call TimerStart(t, 0.03, true, function Check)
        call SaveTimerHandle(hash, 0, 1, t)
        call Move()
        set t = null
    endfunction
endscope

I was not sure, if we need to deal with exceptions, that are not specified in the mission description, so I used a very bad algorithm to make the target point always be within the playable map area.
 

Attachments

  • JASS Class Mission 2.w3m
    24.7 KB · Views: 37
The safety check is good, but I wouldn't explicitly force it here already. You might let it, though, of course.

The principle looks good, though one thing I don't like; the not dynamic binding into hashtable. Using only static keys like "0" AND "0" for example is not senseful even it might work. I hope you understand what I mean. :)
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
You would prefer if I used GetHandleId?
I did it like this, because in the other submission you stated, that it should only work for one gryphon, not for multiple units. I will update it, once I finished the next mission. ;)
 
Yes. Well I then stated it wrong. What I wanted to say is that the code by alone should not order other units to move around, too, with for example picking always all units on map, but I didn't want to emphazize that it must restrictivly only work for one unit. (Then the hashtable logis makes less sense.)

I will update it, once I finished the next mission. ;)
ok. :)
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
JASS:
scope Wanderer initializer Init

    globals
        private hashtable hash
    endglobals

    private function Move takes unit u returns nothing
  
        local integer h = GetHandleId(LoadTimerHandle(hash, GetHandleId(u), 0))
        local real x0 = GetUnitX(u)
        local real y0 = GetUnitY(u)
      
        local real x1
        local real y1
        local real distance = GetRandomReal(500, 1500)
        local real angle = GetRandomReal(0, 2*bj_PI)
      
        //I don't know if we have to deal with exceptions, but here it is in case the point is not within
        //the playable map area.
        //It's a bad algorithm, but since the minimum chance of succes is 25% (in a corner),
        //it should be sufficient for only one unit.
        loop
            set x1 = x0 + distance * Cos(angle)
            set y1 = y0 + distance * Sin(angle) 
            exitwhen RectContainsCoords(bj_mapInitialPlayableArea, x1, y1)
        endloop
      
      
      
        call SaveInteger(hash, h, 2, GetTerrainType(x1,y1))
        call SaveReal(hash, h, 3, x1)
        call SaveReal(hash, h, 4, y1)
        call SaveInteger(hash, h, 5, GetTerrainVariance(x1, y1))
        call SetTerrainType(x1, y1, 'Nsnw', -1, 1, 0)
        call IssuePointOrder(u,"move",x1,y1)
        set u = null
    endfunction
  
    private function Check takes nothing returns nothing
        local integer h = GetHandleId(GetExpiredTimer())
        local unit u = LoadUnitHandle(hash, h, 0)
        local real x0 = GetUnitX(u)
        local real y0 = GetUnitY(u)
        local real x1 = LoadReal(hash, h, 3)
        local real y1 = LoadReal(hash, h, 4)
      
        if(IsUnitInRangeXY(u, x1, y1, 20)) then
            call SetTerrainType(x1, y1, LoadInteger(hash, h, 2), LoadInteger(hash, h, 5), 1, 0)
            call Move(u)
        endif
        set u = null
    endfunction
  
    private function Init takes nothing returns nothing
        local timer t = CreateTimer()
        local integer h
        local unit u
        set hash = InitHashtable()
        set u = CreateUnit(GetLocalPlayer(), 'hgry', GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea), 0)
        call TimerStart(t, 0.03, true, function Check )
        set h = GetHandleId(t)
        call SaveUnitHandle(hash, h, 0, u)
        call SaveTimerHandle(hash, GetHandleId(u), 0, t)
        call Move(u)
        set t = null
    endfunction
endscope

I think it should be better now.
It's a bit complicated, because no globals other than the hashtable were allowed.
 

Attachments

  • JASS Class Mission 2.w3m
    24.7 KB · Views: 32
Hm, you seem to do similar approach like Chaosy does.

No offense, but I would like to know why exactly you chose this tequnique and require a unit parameter as arugment?
Also, have you read the crash course? I just want to understand why you don't attach unit to the timer, as it's the clearest way imo; maybe I should improve some description.
Or was there an other reason? Simply wanna follow you guys.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
No offense, but I would like to know why exactly you chose this tequnique and require a unit parameter as arugment?
For me it's kind of obvious, if you have a function, that moves a unit to a random location, that the unit is used as a parameter.

Also, have you read the crash course?
Yes.

I just want to understand why you don't attach unit to the timer, as it's the clearest way imo; maybe I should improve some description.
I think this is mostly, because I changed the trigger from only focusing on one unit to making it more generic as you suggested. I did attach the unit to the timer though, but I also attached the timer to the unit. :D
I originally intended to make the Check function have a parameter as well, but that's not possible, if I use at with a timer.
So the only way to get the unit in the Check function was using GetExpiredTimer and the hashtable.
To get to the hashtable data in the Move function I need to get the timer again, which makes it a bit complicated.
I think the code would be lot more structured, if I had the plan to make it generic from the beginning.
I could rewrite it, but I wanted to save time, so I kept most of the system and only changed it a bit.
 
To get to the hashtable data in the Move function I need to get the timer again, which makes it a bit complicated.
Yes, and I wonder why there is this seperate move function at all, honestly. I would do it directly only in the callback function I guess, because I have everything there what I need.

But I kind of understand your thinking, too, thanks for explainations. I believe I will accept then @Chaosy 's attempt, too, with yours.

Really cool, guys, you're great!

full


By the way, to all who maybe read this, too; you're all encouraged to comment each other always, and try to suggest what to change, or saying all is good.^^
 
Status
Not open for further replies.
Top