- Joined
- Feb 20, 2013
- Messages
- 136
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.
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