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.

412 lines
11 KiB

local _, addon = ...
local API = addon.API;
local L = addon.L;
local time = time;
local SearchChatHistory = API.SearchChatHistory;
local SecondsToTime = API.SecondsToTime;
local COOLDOWN_ANNOUNCE = 20;
local CAN_SEND_MESSAGE = false;
local DELENSION = "";
local HornButton = CreateFrame("Button");
HornButton:Hide();
HornButton:SetSize(20, 20);
HornButton:SetMotionScriptsWhileDisabled(true);
HornButton:RegisterForClicks("LeftButtonUp");
local PrivateFrame = CreateFrame("Frame");
PrivateFrame:Hide();
local function AlwaysFalse()
return false
end
PrivateFrame.validateFunc = AlwaysFalse;
function PrivateFrame:GetGlobalUnlockTime()
--This time is stored in our SavedVariable
local db = PlumberDB;
if db and db.announceButtonLockUntil and type(db.announceButtonLockUntil) == "number" then
local currentTime = time();
if db.announceButtonLockUntil - currentTime > 60 then
db.announceButtonLockUntil = currentTime + COOLDOWN_ANNOUNCE;
end
return db.announceButtonLockUntil
else
return 0
end
end
function PrivateFrame:SetGlobalUnlockTime(endTime)
local db = PlumberDB;
if db then
if endTime then
db.announceButtonLockUntil = endTime;
else
local currentTime = time();
db.announceButtonLockUntil = currentTime + COOLDOWN_ANNOUNCE;
end
end
end
function PrivateFrame:OnUpdate(elapsed)
self.t = self.t + elapsed;
if self.t >= 0 then
self:SetScript("OnUpdate", nil);
self.t = nil;
self.endTime = nil;
if HornButton:IsVisible() then
self:UpdateValidity();
end
end
end
function PrivateFrame:StartLockTimer(forceRestart)
if (not self.endTime) or forceRestart then
self.t = -COOLDOWN_ANNOUNCE;
self.endTime = time() + COOLDOWN_ANNOUNCE;
PrivateFrame:SetGlobalUnlockTime(self.endTime);
self:SetScript("OnUpdate", self.OnUpdate);
end
end
function PrivateFrame:GetLockEndTime()
return self.endTime or self:GetGlobalUnlockTime();
end
function PrivateFrame:GetLockRemainingSeconds()
local seconds = self:GetLockEndTime() - time();
if seconds < 0 then
seconds = 0;
end
return seconds
end
function PrivateFrame:IsButtonInCooldown()
return self:GetLockRemainingSeconds() > 0
end
function PrivateFrame:CalibrateTimer()
local remainingSeconds = self:GetLockRemainingSeconds()
if remainingSeconds <= 0 then
self:UnlockButton();
self:SetScript("OnUpdate", nil);
else
self:LockButton(1, true);
self.t = -remainingSeconds;
self.endTime = time() + remainingSeconds;
self:SetScript("OnUpdate", self.OnUpdate);
end
end
function PrivateFrame:UpdateValidity()
local messageFound = SearchChatHistory(self.validateFunc);
if messageFound then
self:LockButton(2, true);
else
if not self:IsButtonInCooldown() then
self:UnlockButton();
end
end
end
function PrivateFrame:LockButton(reason, overridePreviousReason)
if (not self.disableReason) or overridePreviousReason then
self.disableReason = reason;
end
CAN_SEND_MESSAGE = false;
HornButton:Disable();
--Disable Reason
--#1 In cooldown (start OnClick)
--#2 Shared by another player (search chat)
--#3 Target soon despawn
end
function PrivateFrame:GetLockReason()
local reason, hasTimer;
if self.disableReason == 1 then
reason = L["Announce Forbidden Reason In Cooldown"];
hasTimer = true;
elseif self.disableReason == 2 then
reason = L["Announce Forbidden Reason Duplicate Message"];
elseif self.disableReason == 3 then
reason = L["Announce Forbidden Reason Soon Despawn"];
else
reason = TOKEN_MARKET_PRICE_NOT_AVAILABLE or "Not Available";
end
return reason, hasTimer
end
function PrivateFrame:UnlockButton()
CAN_SEND_MESSAGE = true;
HornButton:Enable();
self.disableReason = nil;
end
function PrivateFrame:ListenEvents(state)
if state then
self:RegisterEvent("CHAT_MSG_CHANNEL");
else
self:UnregisterEvent("CHAT_MSG_CHANNEL");
end
end
function PrivateFrame:OnShow()
self:CalibrateTimer();
self:ListenEvents(true);
self:UpdateValidity();
end
function PrivateFrame:OnHide()
self:ListenEvents(false);
end
PrivateFrame:SetScript("OnShow", PrivateFrame.OnShow);
PrivateFrame:SetScript("OnHide", PrivateFrame.OnHide);
PrivateFrame:SetScript("OnEvent", function(self, event, ...)
local text = ...
if text and self.validateFunc(text) then
self:LockButton(2, true);
end
end);
function HornButton:OnMouseDown(button)
if self:IsEnabled() and button == "LeftButton" then
self.Icon:SetPoint("CENTER", self, "CENTER", 0, -1);
end
end
function HornButton:OnMouseUp()
self.Icon:SetPoint("CENTER", self, "CENTER", 0, 0);
end
function HornButton:GetAnnounceText()
if self.sourceFunction then
return self.sourceFunction()
end
end
function HornButton:SetAnnouceTextSource(sourceFunction)
self.sourceFunction = sourceFunction;
end
function HornButton:OnClick()
local success, msg = self:GetAnnounceText();
if not success then
local reasonCode = msg;
PrivateFrame:LockButton(reasonCode, true);
return
end
if CAN_SEND_MESSAGE and msg then
--print(msg);
local channelID = C_ChatInfo.GetGeneralChannelID();
if channelID then
SendChatMessage(msg, "CHANNEL", nil, channelID);
else
UIErrorsFrame:AddExternalErrorMessage("Could not find General Chat channel.");
end
PrivateFrame:LockButton(1, true);
PrivateFrame:StartLockTimer(true);
end
end
function HornButton:OnEnable()
self.Icon:SetDesaturated(false);
self.Icon:SetVertexColor(1, 1, 1);
self.Icon:SetPoint("CENTER", self, "CENTER", 0, 0);
self:RefreshOnEnter();
end
function HornButton:OnDisable()
self.Icon:SetDesaturated(true);
self.Icon:SetVertexColor(0.8, 0.8, 0.8);
self.Icon:SetPoint("CENTER", self, "CENTER", 0, 0);
self.Highlight:Hide();
self:RefreshOnEnter();
end
function HornButton:RefreshOnEnter()
if self:IsVisible() and self:IsMouseOver() then
self:OnEnter();
end
end
function HornButton:OnShow()
--PrivateFrame:Show();
end
function HornButton:OnHide()
self:SetScript("OnUpdate", nil);
PrivateFrame:Hide();
end
function HornButton:UpdateTooltipTimer()
self:OnEnter();
end
function HornButton:OnEnter()
local tooltip = GameTooltip;
tooltip:Hide();
tooltip:SetOwner(self, "ANCHOR_RIGHT");
tooltip:SetText(BATTLENET_BROADCAST or "Broadcast", 1, 1, 1);
if self:IsEnabled() and CAN_SEND_MESSAGE then
self.Highlight:Show();
tooltip:AddLine(L["Announce Location Tooltip"], 1, 0.82, 0, true);
self.UpdateTooltip = nil;
else
self.Highlight:Hide();
local lockReason, hasTimer = PrivateFrame:GetLockReason();
tooltip:AddLine(lockReason, 1.000, 0.282, 0.000, true); --WARNING_FONT_COLOR
if hasTimer then
local seconds = PrivateFrame:GetLockRemainingSeconds();
if seconds and seconds > 0 then
local remainingTime = string.format(L["Available In Format"], SecondsToTime(seconds, true));
tooltip:AddLine(remainingTime, 1, 0.82, 0, true);
self.UpdateTooltip = self.UpdateTooltipTimer;
else
self.UpdateTooltip = nil;
end
else
self.UpdateTooltip = nil;
end
end
tooltip:Show();
end
function HornButton:OnLeave()
GameTooltip:Hide();
self.Highlight:Hide();
end
function HornButton:EnableCursorBlocker(state)
self.CursorBlocker:SetShown(state);
end
function HornButton:Init()
local tex = "Interface/AddOns/Plumber/Art/Button/HornButton";
self.Highlight = self:CreateTexture(nil, "OVERLAY"); --HIGHLIGHT layers doesn't work well when SetMotionScriptsWhileDisabled = true
self.Highlight:Hide();
self.Highlight:SetSize(32, 32);
self.Highlight:SetPoint("CENTER", self, "CENTER", 0, 0);
self.Highlight:SetTexture(tex);
self.Highlight:SetTexCoord(0.5, 1, 0, 1);
self.Icon = self:CreateTexture(nil, "ARTWORK");
self.Icon:SetSize(32, 32);
self.Icon:SetPoint("CENTER", self, "CENTER", 0, 0);
self.Icon:SetTexture(tex);
self.Icon:SetTexCoord(0, 0.5, 0, 1);
self:SetScript("OnMouseDown", self.OnMouseDown);
self:SetScript("OnMouseUp", self.OnMouseUp);
self:SetScript("OnClick", self.OnClick);
self:SetScript("OnEnable", self.OnEnable);
self:SetScript("OnDisable", self.OnDisable);
self:SetScript("OnShow", self.OnShow);
self:SetScript("OnHide", self.OnHide);
self:SetScript("OnEnter", self.OnEnter);
self:SetScript("OnLeave", self.OnLeave);
local CursorBlocker = CreateFrame("Frame", nil, self);
self.CursorBlocker = CursorBlocker;
CursorBlocker:SetSize(40, 40);
CursorBlocker:Hide();
CursorBlocker:SetPoint("CENTER", self, "CENTER", 0, 0);
CursorBlocker:SetFrameStrata("BACKGROUND");
CursorBlocker:SetFixedFrameStrata(true);
CursorBlocker:EnableMouse(true);
self.Init = nil;
end
function HornButton:SetValidityCheck(validateFunc)
PrivateFrame.validateFunc = validateFunc or AlwaysFalse;
end
function HornButton:OnUpdate(elapsed)
self.t = self.t + elapsed;
if self.t >= 0.5 then
self:SetScript("OnUpdate", nil);
if self.callback then
self.callback();
self.callback = nil;
end
PrivateFrame:Show();
PrivateFrame:UpdateValidity();
end
end
function HornButton:ShowAndRequestUpdate(optionalCallback)
self:Disable();
self.t = 0;
self.callback = optionalCallback;
self:SetScript("OnUpdate", self.OnUpdate);
self:Show();
end
local function GetAnnounceButton()
if HornButton.Init then
HornButton:Init();
end
HornButton:Hide();
return HornButton
end
addon.GetAnnounceButton = GetAnnounceButton;
do
local locale = GetLocale();
if locale == "ruRU" then
DELENSION = ": ";
end
end
--Debug
--[[
local function ProcessChatMessage(msg)
local uiMapID, x, y = GetWaypointFromText(msg);
if uiMapID then
print(uiMapID, x, y)
end
end
function PrintChatWaypoints()
SearchChatHistory(ProcessChatMessage);
end
function Debug_WaypointsMatch()
local uiMapID = C_Map.GetBestMapForUnit("player");
local posVector = C_Map.GetUserWaypointPositionForMap(uiMapID);
if posVector then
local x, y = posVector:GetXY();
local LocationDataProvider = API.DreamseedUtil;
local isClose;
for creatureID, position in LocationDataProvider:EnumerateSpawnLocations() do
isClose = AreWaypointsClose(x, y, position[1], position[2]);
if isClose then
local name = LocationDataProvider:GetPlantNameByCreatureID(creatureID);
print(name)
break
end
end
end
end
--]]