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

Wanderer - Submission

Status
Not open for further replies.
Okay, so,
using a hashtable like a multitype array did not make too much sense to me, so I made it able to support more gryphons.

The issue though, is that I keep getting an exception or something I could not debug, so I tweaked it using a hack. This is by no means a way to go, but it works, so yay I guess.

The exception causes rest of the code not to execute, therefore, not all gryphons are passed through the loop, and they are left out of the group. It works fine, save for an infrequent loop skip, but it is not that visible.

Also, question considering child keys, 't', 'v', 'x', 'y' promote code readability, but how much do they really impact resource-wise? If hashtables actually used hash, it should not make any difference. Should I change it or leave it?

I'm grateful for any pointed out mistakes/leaks or suggestions.

JASS:
scope Wanderer initializer Init
    globals
        hashtable wanderersHash = InitHashtable()
    endglobals
   
    private function IssueMoveOrder takes unit u returns nothing
        local integer id = GetHandleId(u)
        local real distance = GetRandomReal(500, 1500)
        local real angle = GetRandomReal(-bj_PI, bj_PI)
        local real mapHeight = GetRectMaxY(GetPlayableMapRect())
        local real mapWidth = GetRectMaxX(GetPlayableMapRect())
        local real x
        local real y
       
        // Calculate x within map bounds
        loop
            set x = distance * Cos(angle) + GetUnitX(u)
            exitwhen x < mapWidth and x > - mapWidth
        endloop
        // Calculate y within map bounds
        loop
            set y = distance * Sin(angle) + GetUnitY(u)
            exitwhen y < mapHeight and y > - mapHeight
        endloop
       
        // Save new issued order's variables into hashtable
        call SaveReal(wanderersHash, id, 'x', x)
        call SaveReal(wanderersHash, id, 'y', y)
        call SaveInteger(wanderersHash, id, 't', GetTerrainType(x, y))
        call SaveInteger(wanderersHash, id, 'v', GetTerrainVariance(x, y))
       
        // Change the target tile to snow and issue the order
        call SetTerrainType(x, y, 'Wsnw', -1, 1, 0)
        call IssuePointOrder(u, "move", x, y)
    endfunction
   
    private function GetNewGryphon takes nothing returns unit u
        local unit u = CreateUnit(Player(0),'hgry',0,0,0)
       
        local integer id = GetHandleId(u)
        local integer terrainType = GetTerrainType(0, 0)
        local integer terrainVariance = GetTerrainVariance(0, 0)
       
        call SaveReal(wanderersHash, id, 'x', GetUnitX(u))
        call SaveReal(wanderersHash, id, 'y', GetUnitY(u))
        call SaveInteger(wanderersHash, id, 't', terrainType)
        call SaveInteger(wanderersHash, id, 'v', terrainVariance)
       
        call IssueMoveOrder(u)
       
        return u
    endfunction
   
    private function HasArrived takes unit u returns boolean
        local integer unitId = GetHandleId(u)
       
        // Load target coordinates
        local real x = LoadReal(wanderersHash, unitId, 'x')
        local real y = LoadReal(wanderersHash, unitId, 'y')
       
        // Return true if target has arrived
        if (IsUnitInRangeXY(u, x, y, 15)) then
            return TRUE
        else
            return FALSE
        endif
    endfunction

    private function PeriodicCheck takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local group wanderersGroup = LoadGroupHandle(wanderersHash, GetHandleId(t), 0)
        local group swapGroup = CreateGroup()
        local group enumGroup = CreateGroup()
        local unit u
        local integer unitId
        local real x
        local real y
        local integer terrainType
        local integer terrainVariance
        local real targetX
        local real targetY
       
        /*NEEDS TO CHANGE ========================================*/
        // Copying to preserve the group hack
        loop
            set u = FirstOfGroup(wanderersGroup)
            exitwhen u == null
           
            call GroupAddUnit(swapGroup, u)
            call GroupAddUnit(enumGroup, u)
            call GroupRemoveUnit(wanderersGroup, u)
        endloop
        call SaveGroupHandle(wanderersHash, GetHandleId(t), 0, swapGroup)
        /* =======================================================*/
       
        // Enumerate through group of Gryphon units and check for arrival
        loop
            /* Exception probably happens within this loop */
            set u = FirstOfGroup(enumGroup)
            exitwhen u == null
           
            set unitId = GetHandleId(u)
            set x = GetUnitX(u)
            set y = GetUnitY(u)
           
            if (HasArrived(u)) then
                // Change the terrain back to previous type
                set targetX = LoadReal(wanderersHash, unitId, 'x')
                set targetY = LoadReal(wanderersHash, unitId, 'y')
                set terrainType = LoadInteger(wanderersHash, unitId, 't')
                set terrainVariance = LoadInteger(wanderersHash, unitId, 'v')
                call SetTerrainType(targetX, targetY, terrainType, terrainVariance, 1, 0)
                   
                // Calculate the next moving point and issue an order
                call IssueMoveOrder(u)
            endif
           
            call GroupRemoveUnit(enumGroup, u)
        endloop
       
        call DestroyGroup(wanderersGroup)
        call DestroyGroup(enumGroup)
        set t = null
        set u = null
        set wanderersGroup = null
        set swapGroup = null
        set enumGroup = null
    endfunction
   
    private function Init takes nothing returns nothing
        local timer t = CreateTimer()
        local group wanderersGroup = CreateGroup()
       
        call GroupAddUnit(wanderersGroup, GetNewGryphon())
        call GroupAddUnit(wanderersGroup, GetNewGryphon())
        call GroupAddUnit(wanderersGroup, GetNewGryphon())
        call GroupAddUnit(wanderersGroup, GetNewGryphon())
       
        call TimerStart(t, 0.3, true, function PeriodicCheck)
        call SaveGroupHandle(wanderersHash, GetHandleId(t), 0, wanderersGroup)
       
        set t = null
        set wanderersGroup = null
    endfunction
endscope
 

Attachments

  • Wanderer.w3m
    19 KB · Views: 53
Just to emphasize this again. --
People who maybe already solved missions are very welcome to give feedback/recommend to mark as solved, too.
Of course I will try to give Input, too, lastly when it comes to status change, but other opinions do for sure weight much, especially from people who undertsood/solved already the mission.
 
Status
Not open for further replies.
Top