You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
7.5 KiB
225 lines
7.5 KiB
local Guide = {Waypoints = {}, Focus = nil, UserWaypoint = nil}
|
|
BtWQuests.Guide = Guide;
|
|
|
|
function Guide:AddWayPoint(mapId, x, y, name)
|
|
if not self.DataProvider then
|
|
self.DataProvider = CreateFromMixins(BtWQuestsGuideDataProviderMixin)
|
|
LibMapPinHandler[WorldMapFrame]:AddDataProvider(self.DataProvider);
|
|
end
|
|
|
|
local continentMapId = mapId
|
|
local mapInfo = C_Map.GetMapInfo(continentMapId)
|
|
while mapInfo and mapInfo.mapType > Enum.UIMapType.Continent do
|
|
continentMapId = mapInfo.parentMapID
|
|
mapInfo = C_Map.GetMapInfo(continentMapId)
|
|
end
|
|
|
|
if not continentMapId or not mapInfo then
|
|
return
|
|
end
|
|
|
|
local continentId, position = C_Map.GetWorldPosFromMapPos(mapId, {
|
|
x = x,
|
|
y = y,
|
|
})
|
|
if not continentId or not position then
|
|
return
|
|
end
|
|
position.mapId = continentId
|
|
local _, mapPosition = C_Map.GetMapPosFromWorldPos(continentId, position, continentMapId)
|
|
if not mapPosition then
|
|
continentMapId = mapId
|
|
mapPosition = select(2, C_Map.GetMapPosFromWorldPos(continentId, position, continentMapId))
|
|
end
|
|
if not mapPosition then
|
|
return
|
|
end
|
|
|
|
local waypoints = self.Waypoints[continentMapId]
|
|
if not waypoints then
|
|
waypoints = {}
|
|
self.Waypoints[continentMapId] = waypoints
|
|
end
|
|
|
|
mapPosition.mapId = continentMapId
|
|
mapPosition.itemName = name
|
|
mapPosition.world = position
|
|
waypoints[mapPosition] = true
|
|
self:SetFocus(mapPosition)
|
|
end
|
|
function Guide:SetFocus(item)
|
|
assert(item and item.mapId and self.Waypoints[item.mapId])
|
|
self.Focus = item
|
|
|
|
if C_Map and C_Map.SetUserWaypoint then
|
|
local waypoint = UiMapPoint.CreateFromVector2D(item.mapId, item)
|
|
self.UserWaypoint = waypoint
|
|
C_Map.SetUserWaypoint(waypoint)
|
|
C_SuperTrack.SetSuperTrackedUserWaypoint(true)
|
|
end
|
|
|
|
if WorldMapFrame:IsShown() then
|
|
self.DataProvider:RefreshAllData()
|
|
end
|
|
end
|
|
|
|
-- /run BtWQuests_QuestDataProvider = CreateFromMixins(BtWQuests_QuestDataProviderMixin);WorldMapFrame:AddDataProvider(BtWQuests_QuestDataProvider);
|
|
BtWQuestsGuideDataProviderMixin = CreateFromMixins(MapCanvasDataProviderMixin);
|
|
function BtWQuestsGuideDataProviderMixin:OnAdded(mapCanvas)
|
|
MapCanvasDataProviderMixin.OnAdded(self, mapCanvas);
|
|
mapCanvas:SetPinTemplateType("BtWQuestsGuidePinTemplate", "BUTTON");
|
|
end
|
|
function BtWQuestsGuideDataProviderMixin:RemoveAllData()
|
|
self:GetMap():RemoveAllPinsByTemplate("BtWQuestsGuidePinTemplate");
|
|
end
|
|
function BtWQuestsGuideDataProviderMixin:RefreshAllData(fromOnShow)
|
|
self:RemoveAllData();
|
|
|
|
local mapId = self:GetMap():GetMapID();
|
|
if not mapId then
|
|
return
|
|
end
|
|
|
|
local continentMapId = mapId
|
|
local mapInfo = C_Map.GetMapInfo(continentMapId)
|
|
while mapInfo and mapInfo.mapType > Enum.UIMapType.Continent do
|
|
continentMapId = mapInfo.parentMapID
|
|
mapInfo = C_Map.GetMapInfo(continentMapId)
|
|
end
|
|
|
|
local waypoints = Guide.Waypoints[continentMapId]
|
|
if not waypoints then
|
|
continentMapId = mapId
|
|
waypoints = Guide.Waypoints[continentMapId]
|
|
end
|
|
if not waypoints then
|
|
return
|
|
end
|
|
for item in pairs(waypoints) do
|
|
local position = item
|
|
if continentMapId ~= mapId then
|
|
local continentId, continentPosition = C_Map.GetWorldPosFromMapPos(continentMapId, item)
|
|
position = select(2, C_Map.GetMapPosFromWorldPos(continentId, continentPosition, mapId))
|
|
end
|
|
|
|
if position and position.x > 0 and position.x < 1 and position.y > 0 and position.y < 1 then
|
|
local pin = self:GetMap():AcquirePin("BtWQuestsGuidePinTemplate", item.itemName);
|
|
pin.waypoints = waypoints
|
|
pin.item = item
|
|
|
|
pin:SetPosition(position.x, position.y);
|
|
pin.Focus:SetShown(false);--item == Guide.Focus)
|
|
pin:Show();
|
|
end
|
|
end
|
|
end
|
|
|
|
BtWQuestsGuidePinMixin = CreateFromMixins(MapCanvasPinMixin);
|
|
function BtWQuestsGuidePinMixin:OnLoad()
|
|
self:SetScalingLimits(1, 1.0, 1.2);
|
|
self:UseFrameLevelType("PIN_FRAME_LEVEL_TRACKED_CONTENT");
|
|
end
|
|
function BtWQuestsGuidePinMixin:OnAcquired(itemName)
|
|
self.itemName = itemName;
|
|
self.mapID = self:GetMap():GetMapID();
|
|
end
|
|
function BtWQuestsGuidePinMixin:SetName(value)
|
|
self.name = value
|
|
end
|
|
function BtWQuestsGuidePinMixin:OnMouseEnter()
|
|
local tooltip = WorldMapTooltip or GameTooltip
|
|
if self.itemName then
|
|
tooltip:SetOwner(self, "ANCHOR_LEFT");
|
|
tooltip:SetText(self.itemName);
|
|
tooltip:Show();
|
|
end
|
|
end
|
|
function BtWQuestsGuidePinMixin:OnMouseLeave()
|
|
local tooltip = WorldMapTooltip or GameTooltip
|
|
tooltip:Hide();
|
|
end
|
|
function BtWQuestsGuidePinMixin:OnClick(button)
|
|
if button == "RightButton" or (button == "LeftButton" and IsControlKeyDown()) then
|
|
self.waypoints[self.item] = nil
|
|
self:GetMap():RemovePin(self);
|
|
elseif button == "LeftButton" then
|
|
Guide:SetFocus(self.item)
|
|
end
|
|
end
|
|
|
|
if C_Map and C_Map.SetUserWaypoint then
|
|
hooksecurefunc(C_Map, "SetUserWaypoint", function (waypoint)
|
|
if Guide.UserWaypoint ~= waypoint then
|
|
Guide.UserWaypoint = nil
|
|
end
|
|
end)
|
|
hooksecurefunc(C_Map, "ClearUserWaypoint", function ()
|
|
if Guide.UserWaypoint then
|
|
Guide.UserWaypoint = nil
|
|
Guide.Waypoints[Guide.Focus.mapId][Guide.Focus] = nil
|
|
Guide.DataProvider:RefreshAllData()
|
|
end
|
|
end);
|
|
end
|
|
|
|
local function GetClosestWaypoint(playerX, playerY, playerMapId)
|
|
local closestWaypoint, closestDistanceSq = nil, 0xffffffff;
|
|
for _,waypoints in pairs(Guide.Waypoints) do
|
|
for waypoint in pairs(waypoints) do
|
|
local targetX, targetY, targetMapId = waypoint.world.x, waypoint.world.y, waypoint.world.mapId;
|
|
if playerMapId == targetMapId then
|
|
local x = playerX - targetX;
|
|
local y = playerY - targetY;
|
|
local distanceSq = x * x + y * y;
|
|
|
|
if closestDistanceSq > distanceSq then
|
|
closestDistanceSq = distanceSq
|
|
closestWaypoint = waypoint
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return closestWaypoint;
|
|
end
|
|
|
|
local maxDistanceSq = 100
|
|
local function CheckGuideDistance()
|
|
while true do
|
|
if not Guide.Focus then
|
|
return;
|
|
end
|
|
|
|
local playerX, playerY, _, playerMapId = UnitPosition("player");
|
|
local targetX, targetY, targetMapId = Guide.Focus.world.x, Guide.Focus.world.y, Guide.Focus.world.mapId;
|
|
if playerMapId ~= targetMapId then
|
|
return;
|
|
end
|
|
|
|
local x = playerX - targetX;
|
|
local y = playerY - targetY;
|
|
local distanceSq = x * x + y * y;
|
|
|
|
if distanceSq > maxDistanceSq then
|
|
return
|
|
end
|
|
|
|
C_Map.ClearUserWaypoint(); -- We dont need to remove the Guide data because it hooks C_Map.ClearUserWaypoint
|
|
|
|
local waypoint = GetClosestWaypoint(playerX, playerY, playerMapId);
|
|
if not waypoint then
|
|
return;
|
|
end
|
|
Guide:SetFocus(waypoint);
|
|
end
|
|
end
|
|
|
|
local timer;
|
|
EventRegistry:RegisterFrameEventAndCallback("PLAYER_STARTED_MOVING", function ()
|
|
timer = C_Timer.NewTicker(0.5, CheckGuideDistance)
|
|
end);
|
|
EventRegistry:RegisterFrameEventAndCallback("PLAYER_STOPPED_MOVING", function ()
|
|
if timer then
|
|
CheckGuideDistance()
|
|
timer:Cancel()
|
|
end
|
|
end);
|
|
|