Compare with Previous | Blame | View Log
-- CustomCompassPins by Shinni
local PARENT = COMPASS.container
local FOV = math.pi * 1.1
--
-- Base class, can be accessed via COMPASS_PINS
--
local CustomCompassPins = ZO_Object:Subclass()
local CompassPinManager = ZO_ControlPool:Subclass()
function CustomCompassPins:New( ... )
local result = ZO_Object.New( self )
result:Initialize( ... )
return result
end
function CustomCompassPins:Initialize( ... )
self.pinCallbacks = {}
self.pinManager = CompassPinManager:New()
end
-- pinType should be a string eg "skyshard"
-- addCallback should be a function, it receives the pinManager as argument
-- layout should be table, currently only the key texture is used (which should return a string)
function CustomCompassPins:AddCustomPin( pinType, addCallback, layout )
self.pinCallbacks[ pinType ] = addCallback
self.pinManager:CreatePinType( pinType, layout )
end
-- refreshes/calls the addCallback of the given pinType
-- refreshes all custom pins if no pinType is given
function CustomCompassPins:RefreshPins( pinType )
self.pinManager:RemovePins( pinType )
if pinType then
self.addCallbacks[ pinType ]( self.pinManager )
else
for tag, callback in pairs( self.pinCallbacks ) do
callback( self.pinManager )
end
end
end
-- updates the pins (recalculates the position of the pins)
function CustomCompassPins:Update()
-- maybe add some delay, because pin update could be to expensive to be calculated every frame
local heading = GetPlayerCameraHeading()
if not heading then
return
end
if heading > math.pi then
heading = heading - 2 * math.pi
end
local x, y = GetMapPlayerPosition("player")
self.pinManager:Update( x, y, heading )
end
--
-- pin manager class, updates position etc
--
function CompassPinManager:New( ... )
local result = ZO_ControlPool.New(self, "CustomCompassPin", PARENT, "Pin")
result:Initialize( ... )
return result
end
function CompassPinManager:Initialize( ... )
self.pins = {}
self.pinLayouts = {}
end
function CompassPinManager:CreatePinType( pinType, layout )
self.pinLayouts[ pinType ] = layout
self.pins[ pinType ] = {}
end
-- creates a pin of the given pinType at the given location
-- (radius is not implemented yet)
function CompassPinManager:CreatePin( pinType, xLoc, yLoc, radius )
local pin, pinKey = self:AcquireObject()
table.insert( self.pins[ pinType ], pinKey )
pin.xLoc = xLoc
pin.yLoc = yLoc
pin.type = pinType
local layout = self.pinLayouts[ pinType ]
local texture = pin:GetNamedChild( "Background" )
texture:SetTexture( layout.texture )
end
function CompassPinManager:RemovePins( pinType )
if not pinType then
self:ReleaseAllObjects()
for pinType, _ in pairs( self.pins ) do
self.pins[ pinType ] = {}
end
else
for _, pinKey in pairs( self.pins[ pinType ] ) do
self:ReleaseObject( pinKey )
end
self.pins[ pinType ] = {}
end
end
function CompassPinManager:Update( x, y, heading )
local value
local tex
local pin
local angle
local normalizedAngle
local xDif, yDif
for _, pinKeys in pairs( self.pins ) do
for _, pinKey in pairs( pinKeys ) do
pin = self:GetExistingObject( pinKey )
if pin then
xDif = x - pin.xLoc
yDif = y - pin.yLoc
if xDif * xDif + yDif * yDif < 0.001 then
angle = -math.atan2( xDif, yDif )
angle = (angle + heading)
if angle > math.pi then
angle = angle - 2 * math.pi
elseif angle < -math.pi then
angle = angle + 2 * math.pi
end
--if angle > Math.
normalizedAngle = 2 * angle / FOV
pin:ClearAnchors()
pin:SetAnchor( CENTER, PARENT, CENTER, PARENT:GetWidth() * normalizedAngle, 0)
pin:SetHidden( zo_abs(normalizedAngle) > 0.5 )
value = ZO_WorldMap_GetFilterValue((pin.type).."color")
tex = pin:GetNamedChild( "Background" )
if value == "r" then
tex:SetColor(1,0.1,0.1,1)
elseif value == "g" then
tex:SetColor(0.1,1,0.1,1)
elseif value == "b" then
tex:SetColor(0.2,0.2,1,1)
else
tex:SetColor(1,1,1,1)
end
-- maybe i could add some neat animation as well eg:
if zo_abs(normalizedAngle) > 0.25 then
pin:SetDimensions( 72 - 32 * zo_abs(normalizedAngle), 72 - 32 * zo_abs(normalizedAngle) )
pin:SetAlpha( -4 * (zo_abs(normalizedAngle) - 0.5) )
else
pin:SetDimensions( 64 , 64 )
pin:SetAlpha( 1 )
end
else
pin:SetHidden(true)
end
end
end
end
end
--
-- API to create compass pins
--
COMPASS_PINS = CustomCompassPins:New()
--[[
example:
COMPASS_PINS:CreatePinType( "skyshard", function (pinManager)
for _, skyshard in pairs( mySkyshards ) do
pinManager:CreatePin( "skyshard", skyshard.x, skyshard.y )
end
end,
{ texture = "esoui/art/compass/quest_assistedareapin.dds" } )
]]--