ESOUI SVN EsoHeadMarkers

[/] [trunk/] [EsoheadMarkers/] [CustomCompassPins/] [CustomCompassPins.lua] - Rev 5

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" } )
        
]]--

Compare with Previous | Blame