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