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