WoW:USERAPI GetPlayerBearing: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
(fixed error in model path (probably due to API change))
m (Move page script moved page USERAPI GetPlayerBearing to USERAPI GetPlayerBearing without leaving a redirect)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{localuserfunc}}
{{userfunc}}
Returns the player's current facing bearing based on the rotation of the minimap arrow.
Returns the player's current facing bearing based on the rotation of the minimap arrow.
  bearing = GetPlayerBearing();
  bearing = GetPlayerBearing();


==Return values==
==Return values==
; bearing : number [0, 360] - the player's current bearing, 000 being North, 090 East, 180 South and 270 West; nil if the function is unable to determine the bearing.
; bearing
: number - The player's current bearing (in Radians).


==Example Implementation==
==Example Implementation==
  local function GetPlayerBearing()
  local GetPlayerBearing;-- Local definition, remove to make global
  local obj; -- Remains an upvalue
do
  do
local math=math;-- Local pointer to the Math library
local t = {Minimap:GetChildren()}; -- Becomes garbage
  local mmring=MinimapCompassTexture;-- Pointer to the Compass Ring
for k, v in pairs(t) do
  local mmarrow;-- Upvalue to hold the pointer to the Player Arrow
if v:IsObjectType("Model") and not v:GetName() and v:GetModel() == "interface\\minimap\\minimaparrow.m2" then
obj = v; break;
-- Scan for Player Arrow Texture
end
local list={Minimap:GetRegions()};
for i,j in pairs(list) do
-- Scan for a no-name texture with a specific file loaded.
if j:IsObjectType("Texture") and not j:GetName() and j:GetTexture():lower()=="interface\\minimap\\minimaparrow" then
mmarrow=j;-- Found it, save and stop scanning
break;
  end
  end
  end
  end
if not obj then return; end
   
   
-- If we've found what we were looking for, rewrite function to skip the search next time.
-- Function definition
  GetPlayerBearing = function() return (1-obj:GetFacing()/math.pi/2)*360; end
  GetPlayerBearing=function()
return GetPlayerBearing();
local obj=GetCVar("rotateMinimap")=="1" and mmring or mmarrow;-- Use the correct texture
if not obj then return 0; end-- Hopefully this doesn't happen
local fx,fy,bx,by=obj:GetTexCoord();-- Only need front and back of one side (left is returned first)
local a,dx,dy=0,fx-bx,by-fy;-- Y-Axis flipped for textures so Y values are swapped
if obj==mmring then dx=-dx; end-- Compass Ring spins the opposite direction
if dy==0 then-- Can't divide by zero
a=dx<0 and math.pi or 0;-- Could either be one or the other in this condition
else
a=math.atan(dx/dy)+(dy<0 and math.pi or 0);-- atan() only returns half of the values we need, add PI when needed
end
return a;
end
  end
  end
== Notes ==
The old code posted here broke due to a change in the Minimap object. The player arrow shown is no longer a Model frame, it's a Texture now.
Also note '''atan()''' is not the same function as '''math.atan''', the first returns in Degrees while the later returns in Radians.
Due to the returns on '''math.atan()''', the range this function returns with is between -0.5*PI and 1.5*PI

Latest revision as of 04:49, 15 August 2023

This page documents a <i>user-defined function</i> that you can copy and paste into your addon. Replace PREFIX with your addon or lib prefix to avoid conflicts between different versions of these functions.

User defined functions

Returns the player's current facing bearing based on the rotation of the minimap arrow.

bearing = GetPlayerBearing();

Return values

bearing
number - The player's current bearing (in Radians).

Example Implementation

local GetPlayerBearing;--	Local definition, remove to make global
do
	local math=math;--			Local pointer to the Math library
	local mmring=MinimapCompassTexture;--	Pointer to the Compass Ring
	local mmarrow;--			Upvalue to hold the pointer to the Player Arrow

--	Scan for Player Arrow Texture
	local list={Minimap:GetRegions()};
	for i,j in pairs(list) do
--		Scan for a no-name texture with a specific file loaded.
		if j:IsObjectType("Texture") and not j:GetName() and j:GetTexture():lower()=="interface\\minimap\\minimaparrow" then
			mmarrow=j;--	Found it, save and stop scanning
			break;
		end
	end

--	Function definition
	GetPlayerBearing=function()
		local obj=GetCVar("rotateMinimap")=="1" and mmring or mmarrow;--	Use the correct texture
		if not obj then return 0; end--						Hopefully this doesn't happen

		local fx,fy,bx,by=obj:GetTexCoord();--	Only need front and back of one side (left is returned first)
		local a,dx,dy=0,fx-bx,by-fy;--		Y-Axis flipped for textures so Y values are swapped
		if obj==mmring then dx=-dx; end--	Compass Ring spins the opposite direction
		if dy==0 then--				Can't divide by zero
			a=dx<0 and math.pi or 0;--	Could either be one or the other in this condition
		else
			a=math.atan(dx/dy)+(dy<0 and math.pi or 0);--	atan() only returns half of the values we need, add PI when needed
		end

		return a;
	end
end

Notes

The old code posted here broke due to a change in the Minimap object. The player arrow shown is no longer a Model frame, it's a Texture now. Also note atan() is not the same function as math.atan, the first returns in Degrees while the later returns in Radians.

Due to the returns on math.atan(), the range this function returns with is between -0.5*PI and 1.5*PI