124 lignes
4.3 KiB
Lua
124 lignes
4.3 KiB
Lua
|
|
local GetTime = QuestHelper_GetTime
|
|
|
|
QuestHelper_File["collect_location.lua"] = "4.0.1.$svnversion$"
|
|
QuestHelper_Loadtime["collect_location.lua"] = GetTime()
|
|
|
|
-- little endian two's complement
|
|
local function signed(c)
|
|
QuestHelper: Assert(not c or c >= -127 and c < 127)
|
|
if not c then c = -128 end
|
|
if c < 0 then c = c + 256 end
|
|
return c
|
|
--return strchar(c)
|
|
end
|
|
|
|
local dec2hex = {[0] = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
|
|
|
|
local hex2dec = {}
|
|
|
|
for k, v in pairs(dec2hex) do hex2dec[v] = k end
|
|
|
|
local function tohex(c)
|
|
return dec2hex[c]
|
|
end
|
|
|
|
local function lgToDec(c, pos)
|
|
if not c or c == "" then return 0 end
|
|
|
|
local ret = 0
|
|
|
|
pos = pos or 0
|
|
|
|
if pos == 0 then c = string.reverse(c) end
|
|
|
|
ret = todec(string.sub(c,1,1)) * math.pow(16, pos) + lgToDec(string.sub(c, 2), pos + 1)
|
|
|
|
return ret
|
|
end
|
|
|
|
local function lgToHex(c, pos)
|
|
local ret, rem, hex
|
|
|
|
pos = pos or 0
|
|
c = c or 0
|
|
local minVal = math.pow(16, pos)
|
|
local maxVal = math.pow(16, pos+1) - 1
|
|
|
|
if c > maxVal then
|
|
rem, hex = lgToHex(c, pos + 1)
|
|
else
|
|
rem, hex = c, ""
|
|
end
|
|
|
|
local mult = 0
|
|
|
|
while rem >= minVal do
|
|
mult = mult + 1
|
|
rem = rem - minVal
|
|
end
|
|
|
|
return rem, hex .. tohex(mult)
|
|
end
|
|
|
|
local function todec(c)
|
|
return hex2dec[c]
|
|
end
|
|
|
|
local function float(c)
|
|
-- if not c then c = -128 end
|
|
-- QuestHelper: Assert( c >= -128, string.format("c is too small. It is %s.", tostring(c)))
|
|
-- QuestHelper: Assert( c < 128, string.format("c is too big. It is %s.", tostring(c)))
|
|
local ret = tohex(math.floor(128 * c))
|
|
return ret
|
|
end
|
|
|
|
local function rep_comma(val)
|
|
return string.gsub(tostring(val), ",", ".")
|
|
end
|
|
|
|
local function BolusizeLocation(m, f, x, y)
|
|
-- m and f are positive integers.
|
|
-- x and y are floating-point values, generally between 0 and 1. We'll convert to string and then replace any "," decimal separator (because it'll be easier later to import on an enUS machine).
|
|
local str_x = rep_comma(x)
|
|
local str_y = rep_comma(y)
|
|
|
|
-- Next, we are going to calculate the distance this point is from either Azeroth 50,50 or Outland 50,50.
|
|
-- We will only keep the dx and dy values, since we can compute distance from those (dist = sqrt(dx*dx + dy*dy)). We can also compute a bearing from dx and dy, since we are going relative to (50,50)
|
|
-- Said bearing is the inverse tangent of dy/dx, trig people, trig. SOHCAHTOA. I have all three values, so I could use any pair, but dx and dy make the most sense.
|
|
-- Of course, the bearing DOES need adjusting, since WoW sets 0 to be north. Normally, angles increase counter-clockwise, WoW does the same... SO, all we'd have to do is add 90 degrees, or pi/2 radians to the result of the inverse tangent.
|
|
-- This discourse is of no real consequence, beyond explaining the WHY of collecting dx and dy, rather than just the distance.
|
|
local _, dxAz, dyAz = QuestHelper.Astrolabe:ComputeDistance( 0, 0, 0.5, 0.5, m, f, x, y)
|
|
local _, dxOl, dyOl = QuestHelper.Astrolabe:ComputeDistance(466, 0, 0.5, 0.5, m, f, x, y)
|
|
|
|
local dx_str, dy_str
|
|
local dist_rel
|
|
if dxAz then
|
|
dx_str = rep_comma(dxAz)
|
|
dy_str = rep_comma(dyAz)
|
|
dist_rel = "A"
|
|
elseif dxOl then
|
|
dx_str = rep_comma(dxOl)
|
|
dy_str = rep_comma(dyOl)
|
|
dist_rel = "A"
|
|
end
|
|
|
|
-- Finally, we are going to go back to doing a string for the location bolus, but it will be tab delimited in the form "m\tf\tx\t\y\tA\tdx\tdy" or "m\tf\tx\t\y\tO\tdx\tdy" where A means dx,dy are relative to Azeroth (50,50) (in yards) and O means they are relative to Outland (50,50)
|
|
-- Note: if only four values are present, then we couldn't compute a distance... Probably because we are in an instance of some kind.
|
|
|
|
local loc = string.format("%d\t%d\t%s\t%s", m, f, str_x, str_y)
|
|
if dxAz or dxOl then
|
|
loc = string.format("%s\t%s\t%s\t%s", loc, dist_rel, dx_str, dy_str)
|
|
end
|
|
|
|
return loc;
|
|
--return string.format("%s,%s,%s,%s,%s", signed(delayed and 1 or 0), signed(c), signed(z), float_x, float_y)
|
|
--return signed(delayed and 1 or 0) .. signed(c) .. signed(z) .. float_x .. float_y
|
|
end
|
|
|
|
-- This merely provides another API function
|
|
function QH_Collect_Location_Init(_, API)
|
|
API.Callback_LocationBolus = BolusizeLocation -- Yeah. *Bolusize*. You heard me.
|
|
API.Callback_LocationBolusCurrent = function () return BolusizeLocation(API.Callback_Location_Raw()) end -- This is just a convenience function, really
|
|
end
|