Fix EP award to Standby/Reserve List and add it to addon comms. Show the AFK check countdown to reserves with the addon, on the popup. Hook LootFrame and BagSlots pre-emptively to make the masterlooter clicks seamless. Check that ML has permissions to update points before showing GP Action popup. Change some of the prefab messages to make them clearer to members.
1874 lines
64 KiB
Lua
1874 lines
64 KiB
Lua
sepgp = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceHook-2.1", "AceDB-2.0", "AceDebug-2.0", "AceEvent-2.0", "AceModuleCore-2.0", "FuBarPlugin-2.0")
|
|
sepgp:SetModuleMixins("AceDebug-2.0")
|
|
local D = AceLibrary("Dewdrop-2.0")
|
|
local BZ = AceLibrary("Babble-Zone-2.2")
|
|
local C = AceLibrary("Crayon-2.0")
|
|
local BC = AceLibrary("Babble-Class-2.2")
|
|
local DF = AceLibrary("Deformat-2.0")
|
|
local G = AceLibrary("Gratuity-2.0")
|
|
sepgp.VARS = {
|
|
basegp = 135,
|
|
baseaward_ep = 100,
|
|
decay = 0.85,
|
|
max = 5000,
|
|
timeout = 60,
|
|
maxloglines = 500,
|
|
prefix = "SEPGP_PREFIX",
|
|
bop = C:Red("BoP"),
|
|
boe = C:Yellow("BoE"),
|
|
nobid = C:White("NoBind"),
|
|
msgp = "Mainspec GP",
|
|
osgp = "Offspec GP",
|
|
bankde = "Bank-D/E",
|
|
reminder = C:Red("Unassigned"),
|
|
}
|
|
local playerName = (UnitName("player"))
|
|
local shooty_reservechan = "Reserves"
|
|
local shooty_reservecall = string.format("{shootyepgp}Type \"+\" if on main, or \"+<YourMainName>\" (without quotes) if on alt within %dsec.",sepgp.VARS.timeout)
|
|
local shooty_reserveanswer = "^(%+)(%a*)$"
|
|
local out = "|cff9664c8shootyepgp:|r %s"
|
|
local lastUpdate = 0
|
|
local needInit = true
|
|
local admin,sanitizeNote
|
|
local shooty_debugchat
|
|
local running_check,running_bid
|
|
local partyUnit,raidUnit = {},{}
|
|
local hexColorQuality = {}
|
|
local reserves_blacklist,bids_blacklist = {},{}
|
|
local bidlink = {
|
|
["ms"]="|cffFF3333|Hshootybid:1:$ML|h[Mainspec/NEED]|h|r",
|
|
["os"]="|cff009900|Hshootybid:2:$ML|h[Offspec/GREED]|h|r"
|
|
}
|
|
do
|
|
for i=1,40 do
|
|
raidUnit[i] = "raid"..i
|
|
end
|
|
for i=1,4 do
|
|
partyUnit[i] = "party"..i
|
|
end
|
|
for i=-1,6 do
|
|
hexColorQuality[ITEM_QUALITY_COLORS[i].hex] = i
|
|
end
|
|
end
|
|
-- TODO:
|
|
-- 2. Implement an Import facility to mirror Export.
|
|
sepgp.reserves = {}
|
|
sepgp.bids_main,sepgp.bids_off,sepgp.bid_item = {},{},{}
|
|
sepgp.timer = CreateFrame("Frame")
|
|
sepgp.timer.cd_text = ""
|
|
sepgp.timer:Hide()
|
|
sepgp.timer:SetScript("OnUpdate",function() sepgp.OnUpdate(this,arg1) end)
|
|
sepgp.timer:SetScript("OnEvent",function()
|
|
end)
|
|
|
|
function sepgp:OnInitialize() -- ADDON_LOADED (1) unless LoD
|
|
if sepgp_saychannel == nil then sepgp_saychannel = "GUILD" end
|
|
if sepgp_decay == nil then sepgp_decay = sepgp.VARS.decay end
|
|
if sepgp_progress == nil then sepgp_progress = "T1" end
|
|
if sepgp_discount == nil then sepgp_discount = 0.25 end
|
|
if sepgp_log == nil then sepgp_log = {} end
|
|
if sepgp_looted == nil then sepgp_looted = {} end
|
|
sepgp.extratip = CreateFrame("GameTooltip","shootyepgp_tooltip",UIParent,"GameTooltipTemplate")
|
|
end
|
|
|
|
function sepgp:AceEvent_FullyInitialized() -- SYNTHETIC EVENT, later than PLAYER_LOGIN, PLAYER_ENTERING_WORLD (3)
|
|
for i=1,NUM_CHAT_WINDOWS do
|
|
local tab = getglobal("ChatFrame"..i.."Tab")
|
|
local cf = getglobal("ChatFrame"..i)
|
|
local tabName = tab:GetText()
|
|
if tab ~= nil and (string.lower(tabName) == "debug") then
|
|
shooty_debugchat = cf
|
|
ChatFrame_RemoveAllMessageGroups(shooty_debugchat)
|
|
shooty_debugchat:SetMaxLines(1024)
|
|
break
|
|
end
|
|
end
|
|
|
|
if (sepgp_main == nil) or (sepgp_main == "") then
|
|
if (IsInGuild()) then
|
|
StaticPopup_Show("SHOOTY_EPGP_SET_MAIN")
|
|
end
|
|
end
|
|
|
|
if not self:IsEventScheduled("shootyepgpChannelInit") then
|
|
self:ScheduleEvent("shootyepgpChannelInit",self.delayedInit,2,self)
|
|
end
|
|
|
|
-- if pfUI loaded, skin the extra tooltip
|
|
if (pfUI) and pfUI.api and pfUI.api.CreateBackdrop and pfUI_config and pfUI_config.tooltip and pfUI_config.tooltip.alpha then
|
|
pfUI.api.CreateBackdrop(sepgp.extratip,nil,nil,pfUI_config.tooltip.alpha)
|
|
end
|
|
-- hook SetItemRef to parse our client bid links
|
|
self:Hook("SetItemRef")
|
|
-- hook tooltip to add our GP values
|
|
self:TipHook()
|
|
-- hook LootFrameItem_OnClick to add our own click handlers for bid calls
|
|
self:SecureHook("LootFrameItem_OnClick")
|
|
-- hook ContainerFrameItemButton_OnClick to add our own click handlers for bid calls
|
|
self:Hook("ContainerFrameItemButton_OnClick")
|
|
-- hook pfUI loot module :(
|
|
if pfUI ~= nil and pfUI.loot ~= nil and type(pfUI.loot.UpdateLootFrame) == "function" then
|
|
self:SecureHook(pfUI.loot, "UpdateLootFrame", "pfUI_UpdateLootFrame")
|
|
end
|
|
-- make tablets closable with ESC
|
|
for i=1,5 do
|
|
table.insert(UISpecialFrames,string.format("Tablet20DetachedFrame%d",i))
|
|
end
|
|
self:RegisterChatCommand({"/shooty","/sepgp","/shootyepgp"},function() sepgp_standings:Toggle() end)
|
|
end
|
|
|
|
function sepgp:OnEnable() -- PLAYER_LOGIN (2)
|
|
self:RegisterEvent("GUILD_ROSTER_UPDATE",function()
|
|
if (arg1) then -- member join /leave
|
|
self:SetRefresh(true)
|
|
end
|
|
end)
|
|
self:RegisterEvent("RAID_ROSTER_UPDATE",function()
|
|
self:SetRefresh(true)
|
|
end)
|
|
self:RegisterEvent("PARTY_MEMBERS_CHANGED",function()
|
|
self:SetRefresh(true)
|
|
end)
|
|
self:RegisterEvent("CHAT_MSG_RAID","captureLootCall")
|
|
self:RegisterEvent("CHAT_MSG_RAID_LEADER","captureLootCall")
|
|
self:RegisterEvent("CHAT_MSG_RAID_WARNING","captureLootCall")
|
|
self:RegisterEvent("CHAT_MSG_WHISPER","captureBid")
|
|
self:RegisterEvent("CHAT_MSG_ADDON","addonComms")
|
|
self:RegisterEvent("CHAT_MSG_LOOT","captureLoot")
|
|
self:RegisterEvent("TRADE_PLAYER_ITEM_CHANGED","tradeLoot")
|
|
self:RegisterEvent("TRADE_ACCEPT_UPDATE","tradeLoot")
|
|
|
|
if (IsInGuild()) then
|
|
if (GetNumGuildMembers()==0) then
|
|
GuildRoster()
|
|
end
|
|
end
|
|
|
|
if AceLibrary("AceEvent-2.0"):IsFullyInitialized() then
|
|
self:AceEvent_FullyInitialized()
|
|
else
|
|
self:RegisterEvent("AceEvent_FullyInitialized")
|
|
end
|
|
|
|
end
|
|
|
|
sepgp._lastRosterRequest = false
|
|
function sepgp:OnMenuRequest()
|
|
local now = GetTime()
|
|
if not self._lastRosterRequest or (now - self._lastRosterRequest > 2) then
|
|
self._lastRosterRequest = now
|
|
GuildRoster()
|
|
end
|
|
D:FeedAceOptionsTable(self:buildMenu())
|
|
end
|
|
|
|
function sepgp:TipHook()
|
|
self:SecureHook(GameTooltip, "SetBagItem", function(this, bag, slot)
|
|
local itemLink = GetContainerItemLink(bag, slot)
|
|
local ml_tip
|
|
if (itemLink) then
|
|
local is_master = (sepgp:lootMaster()) and true or nil
|
|
local link_found, _, itemColor, itemString, itemName = string.find(itemLink, "^(|c%x+)|H(.+)|h(%[.+%])")
|
|
if (link_found) then
|
|
local bind = self:itemBinding(itemString) or ""
|
|
ml_tip = is_master and bind == sepgp.VARS.boe
|
|
if (ml_tip) then
|
|
local frame = GetMouseFocus()
|
|
if (frame) and (frame.IsFrameType ~= nil) and (frame:IsFrameType("Button")) then
|
|
if not (frame._hasExtraClicks) then
|
|
frame:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp")
|
|
frame._hasExtraClicks = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
sepgp:AddDataToTooltip(GameTooltip, itemLink, nil, ml_tip)
|
|
end
|
|
)
|
|
self:SecureHook(GameTooltip, "SetLootItem", function(this, slot)
|
|
local is_master = (sepgp:lootMaster()) and true or nil
|
|
if (is_master) then
|
|
local frame = GetMouseFocus()
|
|
if (frame) and (frame.IsFrameType ~= nil) and (frame:IsFrameType("Button")) then
|
|
if not (frame._hasExtraClicks) then
|
|
frame:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp")
|
|
frame._hasExtraClicks = true
|
|
end
|
|
end
|
|
end
|
|
sepgp:AddDataToTooltip(GameTooltip, GetLootSlotLink(slot), nil, is_master)
|
|
end
|
|
)
|
|
self:SecureHook(GameTooltip, "SetLootRollItem", function(this, id)
|
|
sepgp:AddDataToTooltip(GameTooltip, GetLootRollItemLink(id))
|
|
end
|
|
)
|
|
self:HookScript(GameTooltip, "OnHide", function()
|
|
if sepgp.extratip:IsVisible() then sepgp.extratip:Hide() end
|
|
self.hooks[GameTooltip]["OnHide"]()
|
|
end
|
|
)
|
|
self:HookScript(ItemRefTooltip, "OnHide", function()
|
|
if sepgp.extratip:IsVisible() then sepgp.extratip:Hide() end
|
|
self.hooks[ItemRefTooltip]["OnHide"]()
|
|
end
|
|
)
|
|
end
|
|
|
|
function sepgp:delayedInit()
|
|
if (IsInGuild()) then
|
|
local guildName = (GetGuildInfo("player"))
|
|
if (guildName) and guildName ~= "" then
|
|
sepgp_reservechannel = string.format("%sReserves",(string.gsub(guildName," ","")))
|
|
end
|
|
end
|
|
if sepgp_reservechannel == nil then sepgp_reservechannel = shooty_reservechan end
|
|
local reservesChannelID = tonumber((GetChannelName(sepgp_reservechannel)))
|
|
if (reservesChannelID) and (reservesChannelID ~= 0) then
|
|
self:reservesToggle(true)
|
|
end
|
|
-- migrate EPGP storage if needed
|
|
sepgp._versionString = GetAddOnMetadata("shootyepgp","Version")
|
|
sepgp._websiteString = GetAddOnMetadata("shootyepgp","X-Website")
|
|
self:parseVersion(sepgp._versionString)
|
|
local major_ver = self._version.major
|
|
if IsGuildLeader() and ( (sepgp_dbver == nil) or (major_ver > sepgp_dbver) ) then
|
|
sepgp[string.format("v%dtov%d",(sepgp_dbver or 2),major_ver)](sepgp)
|
|
end
|
|
-- broadcast our version
|
|
local addonMsg = string.format("VERSION;%s;%d",sepgp._versionString,major_ver)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
if (IsGuildLeader()) then
|
|
self:shareSettings()
|
|
end
|
|
-- safe officer note setting when we are admin
|
|
if (admin()) then
|
|
if not self:IsHooked("GuildRosterSetOfficerNote") then
|
|
self:Hook("GuildRosterSetOfficerNote")
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:AddDataToTooltip(tooltip,itemlink,itemstring,is_master)
|
|
local price
|
|
if (itemstring) then
|
|
price = sepgp_prices:GetPrice(itemstring,sepgp_progress)
|
|
elseif (itemlink) then
|
|
price = sepgp_prices:GetPrice(itemlink,sepgp_progress)
|
|
end
|
|
if not price then return end
|
|
local line_limit, left1,right1
|
|
if (is_master) then
|
|
line_limit = 28
|
|
left1,right1 = C:Yellow("Alt Click/RClick/MClick"), C:Orange("Call for: MS/OS/Both")
|
|
else
|
|
line_limit = 29
|
|
end
|
|
local ep,gp = (self:get_ep_v3(playerName) or 0), (self:get_gp_v3(playerName) or sepgp.VARS.basegp)
|
|
local off_price = math.floor(price*sepgp_discount)
|
|
local pr,new_pr,new_pr_off = ep/gp, ep/(gp+price), ep/(gp+off_price)
|
|
local pr_delta = new_pr - pr
|
|
local pr_delta_off = new_pr_off - pr
|
|
local textRight = string.format("gp:|cff32cd32%d|r(|cffff0000%.02f|r|cffff7f00pr|r) os:|cff20b2aa%d|r(|cffff0000%.02f|r|cffff7f00pr|r)",price,new_pr,off_price,new_pr_off)
|
|
if (tooltip:NumLines() < line_limit) then
|
|
tooltip:AddLine(" ")
|
|
tooltip:AddDoubleLine("|cff9664c8shootyepgp|r",textRight)
|
|
if (is_master) then
|
|
tooltip:AddDoubleLine(left1,right1)
|
|
end
|
|
tooltip:Show()
|
|
else
|
|
sepgp.extratip:ClearLines()
|
|
sepgp.extratip:SetOwner(tooltip,"ANCHOR_NONE")
|
|
sepgp.extratip:ClearAllPoints()
|
|
sepgp.extratip:SetPoint("TOPLEFT", tooltip, "BOTTOMLEFT", 0, -5)
|
|
--sepgp.extratip:SetPoint("TOPRIGHT", tooltip, "BOTTOMRIGHT", 0, -5)
|
|
sepgp.extratip:SetText("|cff9664c8shootyepgp|r")
|
|
sepgp.extratip:AddLine(textRight)
|
|
if (is_master) then
|
|
sepgp.extratip:AddDoubleLine(left1,right1)
|
|
end
|
|
sepgp.extratip:Show()
|
|
end
|
|
end
|
|
|
|
function sepgp:OnUpdate(elapsed)
|
|
sepgp.timer.count_down = sepgp.timer.count_down - elapsed
|
|
lastUpdate = lastUpdate + elapsed
|
|
if sepgp.timer.count_down <= 0 then
|
|
running_check = nil
|
|
sepgp.timer:Hide()
|
|
sepgp.timer.cd_text = "|cffff0000Finished|r"
|
|
sepgp_reserves:Refresh()
|
|
else
|
|
sepgp.timer.cd_text = string.format("|cff00ff00%02d|r|cffffffffsec|r",sepgp.timer.count_down)
|
|
end
|
|
if lastUpdate > 0.5 then
|
|
lastUpdate = 0
|
|
sepgp_reserves:Refresh()
|
|
end
|
|
end
|
|
|
|
function sepgp:GuildRosterSetOfficerNote(index,note,fromAddon)
|
|
if (fromAddon) then
|
|
self.hooks["GuildRosterSetOfficerNote"](index,note)
|
|
else
|
|
local name, _, _, _, _, _, _, prevnote, _, _ = GetGuildRosterInfo(index)
|
|
local _,_,_,oldepgp,_ = string.find(prevnote or "","(.*)({%d+:%d+})(.*)")
|
|
local _,_,_,epgp,_ = string.find(note or "","(.*)({%d+:%d+})(.*)")
|
|
if oldepgp ~= nil then
|
|
if epgp == nil or epgp ~= oldepgp then
|
|
self:adminSay(string.format("Manually modified %s\'s note. EPGP was %s",name,oldepgp))
|
|
self:defaultPrint(string.format("|cffff0000Manually modified %s\'s note. EPGP was %s|r",name,oldepgp))
|
|
end
|
|
end
|
|
local safenote = string.gsub(note,"(.*)({%d+:%d+})(.*)",sanitizeNote)
|
|
self.hooks["GuildRosterSetOfficerNote"](index,safenote)
|
|
end
|
|
end
|
|
|
|
function sepgp:SetItemRef(link, name, button)
|
|
if string.sub(link,1,9) == "shootybid" then
|
|
local _,_,bid,masterlooter = string.find(link,"shootybid:(%d+):(%w+)")
|
|
if bid == "1" then
|
|
bid = "+"
|
|
elseif bid == "2" then
|
|
bid = "-"
|
|
else
|
|
bid = nil
|
|
end
|
|
if not self:inRaid(masterlooter) then
|
|
masterlooter = nil
|
|
end
|
|
if (bid and masterlooter) then
|
|
SendChatMessage(bid,"WHISPER",nil,masterlooter)
|
|
end
|
|
return
|
|
end
|
|
self.hooks["SetItemRef"](link, name, button)
|
|
if (link and name and ItemRefTooltip) then
|
|
if (strsub(link, 1, 4) == "item") then
|
|
if (ItemRefTooltip:IsVisible()) then
|
|
if (not DressUpFrame:IsVisible()) then
|
|
self:AddDataToTooltip(ItemRefTooltip, link)
|
|
end
|
|
ItemRefTooltip.isDisplayDone = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:LootFrameItem_OnClick(button,data)
|
|
if not IsAltKeyDown() then return end
|
|
if not UnitInRaid("player") then return end
|
|
if not self:lootMaster() then return end
|
|
local slot, quality
|
|
if data ~= nil then
|
|
slot,quality = data:GetID(), data.quality
|
|
else
|
|
slot = LootFrame.selectedSlot or 0
|
|
quality = LootFrame.selectedQuality or -1
|
|
if not (this._hasExtraClicks) then
|
|
this:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp")
|
|
this._hasExtraClicks = true
|
|
end
|
|
end
|
|
if LootSlotIsItem(slot) and quality >= 3 then
|
|
local itemLink = GetLootSlotLink(slot)
|
|
if (itemLink) then
|
|
if button == "LeftButton" then
|
|
self:widestAudience(string.format("Whisper me + for %s (mainspec)",itemLink))
|
|
elseif button == "RightButton" then
|
|
self:widestAudience(string.format("Whisper me - for %s (offspec)",itemLink))
|
|
elseif button == "MiddleButton" then
|
|
self:widestAudience(string.format("Whisper me + or - for %s (mainspec or offspec)",itemLink))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:ContainerFrameItemButton_OnClick(button,ignoreModifiers)
|
|
if not IsAltKeyDown() then
|
|
return self.hooks["ContainerFrameItemButton_OnClick"](button,ignoreModifiers)
|
|
end
|
|
if not UnitInRaid("player") then
|
|
return self.hooks["ContainerFrameItemButton_OnClick"](button,ignoreModifiers)
|
|
end
|
|
if not self:lootMaster() then
|
|
return self.hooks["ContainerFrameItemButton_OnClick"](button,ignoreModifiers)
|
|
end
|
|
if not (this._hasExtraClicks) then
|
|
this:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp")
|
|
this._hasExtraClicks = true
|
|
end
|
|
local bag,slot = this:GetParent():GetID(), this:GetID()
|
|
local itemLink = GetContainerItemLink(bag, slot)
|
|
if (itemLink) then
|
|
local link_found, _, itemColor, itemString, itemName = string.find(itemLink, "^(|c%x+)|H(.+)|h(%[.+%])")
|
|
if (link_found) then
|
|
local bind = self:itemBinding(itemString) or ""
|
|
if (bind == self.VARS.boe) then
|
|
if button == "LeftButton" then
|
|
self:widestAudience(string.format("Whisper me + for %s (mainspec)",itemLink))
|
|
return
|
|
elseif button == "RightButton" then
|
|
self:widestAudience(string.format("Whisper me - for %s (offspec)",itemLink))
|
|
return
|
|
elseif button == "MiddleButton" then
|
|
self:widestAudience(string.format("Whisper me + or - for %s (mainspec or offspec)",itemLink))
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return self.hooks["ContainerFrameItemButton_OnClick"](button,ignoreModifiers)
|
|
end
|
|
|
|
function sepgp:pfUI_UpdateLootFrame()
|
|
for slotid, pflootitem in pairs(pfUI.loot.slots) do
|
|
if not self:IsHooked(pflootitem,"OnClick") then
|
|
pflootitem:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp")
|
|
self:HookScript(pflootitem,"OnClick",function()
|
|
self:LootFrameItem_OnClick(arg1,this)
|
|
self.hooks[this]["OnClick"](this,arg1)
|
|
end)
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------
|
|
-- Communication
|
|
-------------------
|
|
function sepgp:flashFrame(frame)
|
|
local tabFlash = getglobal(frame:GetName().."TabFlash")
|
|
if ( not frame.isDocked or (frame == SELECTED_DOCK_FRAME) or UIFrameIsFlashing(tabFlash) ) then
|
|
return
|
|
end
|
|
tabFlash:Show()
|
|
UIFrameFlash(tabFlash, 0.25, 0.25, 60, nil, 0.5, 0.5)
|
|
end
|
|
|
|
function sepgp:debugPrint(msg)
|
|
if (shooty_debugchat) then
|
|
shooty_debugchat:AddMessage(string.format(out,msg))
|
|
self:flashFrame(shooty_debugchat)
|
|
else
|
|
self:defaultPrint(msg)
|
|
end
|
|
end
|
|
|
|
function sepgp:defaultPrint(msg)
|
|
if not DEFAULT_CHAT_FRAME:IsVisible() then
|
|
FCF_SelectDockFrame(DEFAULT_CHAT_FRAME)
|
|
end
|
|
DEFAULT_CHAT_FRAME:AddMessage(string.format(out,msg))
|
|
end
|
|
|
|
function sepgp:bidPrint(link,masterlooter,need,greed,bid)
|
|
local mslink = string.gsub(bidlink["ms"],"$ML",masterlooter)
|
|
local oslink = string.gsub(bidlink["os"],"$ML",masterlooter)
|
|
local msg = string.format("Click $MS or $OS for %s",link)
|
|
if (need and greed) then
|
|
msg = string.gsub(msg,"$MS",mslink)
|
|
msg = string.gsub(msg,"$OS",oslink)
|
|
elseif (need) then
|
|
msg = string.gsub(msg,"$MS",mslink)
|
|
msg = string.gsub(msg,"or $OS ","")
|
|
elseif (greed) then
|
|
msg = string.gsub(msg,"$OS",oslink)
|
|
msg = string.gsub(msg,"$MS or ","")
|
|
elseif (bid) then
|
|
msg = string.gsub(msg,"$MS",mslink)
|
|
msg = string.gsub(msg,"$OS",oslink)
|
|
end
|
|
local _, count = string.gsub(msg,"%$","%$")
|
|
if (count > 0) then return end
|
|
local chatframe
|
|
if (SELECTED_CHAT_FRAME) then
|
|
chatframe = SELECTED_CHAT_FRAME
|
|
else
|
|
if not DEFAULT_CHAT_FRAME:IsVisible() then
|
|
FCF_SelectDockFrame(DEFAULT_CHAT_FRAME)
|
|
end
|
|
chatframe = DEFAULT_CHAT_FRAME
|
|
end
|
|
if (chatframe) then
|
|
chatframe:AddMessage(" ")
|
|
chatframe:AddMessage(string.format(out,msg),NORMAL_FONT_COLOR.r,NORMAL_FONT_COLOR.g,NORMAL_FONT_COLOR.b)
|
|
end
|
|
end
|
|
|
|
function sepgp:simpleSay(msg)
|
|
SendChatMessage(string.format("shootyepgp: %s",msg), sepgp_saychannel)
|
|
end
|
|
|
|
function sepgp:adminSay(msg)
|
|
-- API is broken on Elysium
|
|
-- local g_listen, g_speak, officer_listen, officer_speak, g_promote, g_demote, g_invite, g_remove, set_gmotd, set_publicnote, view_officernote, edit_officernote, set_guildinfo = GuildControlGetRankFlags()
|
|
-- if (officer_speak) then
|
|
SendChatMessage(string.format("shootyepgp: %s",msg),"OFFICER")
|
|
-- end
|
|
end
|
|
|
|
function sepgp:widestAudience(msg)
|
|
local channel = "SAY"
|
|
if UnitInRaid("player") then
|
|
if (IsRaidLeader() or IsRaidOfficer()) then
|
|
channel = "RAID_WARNING"
|
|
else
|
|
channel = "RAID"
|
|
end
|
|
elseif UnitExists("party1") then
|
|
channel = "PARTY"
|
|
end
|
|
SendChatMessage(msg, channel)
|
|
end
|
|
|
|
function sepgp:addonMessage(message,channel,sender)
|
|
SendAddonMessage(self.VARS.prefix,message,channel,sender)
|
|
end
|
|
|
|
function sepgp:addonComms(prefix,message,channel,sender)
|
|
if not prefix == self.VARS.prefix then return end -- we don't care for messages from other addons
|
|
if sender == playerName then return end -- we don't care for messages from ourselves
|
|
local name_g,class,rank = self:verifyGuildMember(sender,true)
|
|
if not (name_g) then return end -- only accept messages from guild members
|
|
local who,what,amount
|
|
for name,epgp,change in string.gfind(message,"([^;]+);([^;]+);([^;]+)") do
|
|
who=name
|
|
what=epgp
|
|
amount=tonumber(change)
|
|
end
|
|
if (who) and (what) and (amount) then
|
|
local msg
|
|
if who == playerName then
|
|
if what == "EP" then
|
|
if amount < 0 then
|
|
msg = string.format("You have received a %d EP penalty.",amount)
|
|
else
|
|
msg = string.format("You have been awarded %d EP.",amount)
|
|
end
|
|
elseif what == "GP" then
|
|
msg = string.format("You have gained %d GP.",amount)
|
|
end
|
|
elseif who == "ALL" and what == "DECAY" then
|
|
msg = string.format("%s%% decay to EP and GP.",amount)
|
|
elseif who == "RAID" and what == "AWARD" then
|
|
msg = string.format("%d EP awarded to Raid.",amount)
|
|
elseif who == "RESERVES" and what == "AWARD" then
|
|
msg = string.format("%d EP awarded to Reserves.",amount)
|
|
elseif who == "VERSION" then
|
|
local out_of_date, version_type = self:parseVersion(self._versionString,what)
|
|
if (out_of_date) and self._newVersionNotification == nil then
|
|
self._newVersionNotification = true -- only inform once per session
|
|
self:defaultPrint(string.format("New %s version available: |cff00ff00%s|r",version_type,what))
|
|
self:defaultPrint(string.format("Visit %s to update.",self._websiteString))
|
|
end
|
|
if (IsGuildLeader()) then
|
|
self:shareSettings()
|
|
end
|
|
elseif who == "SETTINGS" then
|
|
for progress,discount,decay in string.gfind(what,"([^:]+):([^:]+):([^:]+)") do
|
|
discount = tonumber(discount)
|
|
decay = tonumber(decay)
|
|
local settings_notice
|
|
if progress and progress ~= sepgp_progress then
|
|
sepgp_progress = progress
|
|
settings_notice = "New raid progress"
|
|
end
|
|
if discount and discount ~= sepgp_discount then
|
|
sepgp_discount = discount
|
|
if (settings_notice) then
|
|
settings_notice = settings_notice..", offspec price %"
|
|
else
|
|
settings_notice = "New offspec price %"
|
|
end
|
|
end
|
|
if decay and decay ~= sepgp_decay then
|
|
sepgp_decay = decay
|
|
if (admin()) then
|
|
if (settings_notice) then
|
|
settings_notice = settings_notice..", decay %"
|
|
else
|
|
settings_notice = "New decay %"
|
|
end
|
|
end
|
|
end
|
|
if (settings_notice) and settings_notice ~= "" then
|
|
local sender_rank = string.format("%s(%s)",C:Colorize(BC:GetHexColor(class),sender),rank)
|
|
settings_notice = settings_notice..string.format(" settings accepted from %s",sender_rank)
|
|
self:defaultPrint(settings_notice)
|
|
end
|
|
end
|
|
end
|
|
if msg and msg~="" then
|
|
self:defaultPrint(msg)
|
|
self:my_epgp()
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:shareSettings(force)
|
|
local now = GetTime()
|
|
if self._lastSettingsShare == nil or (now - self._lastSettingsShare > 30) or (force) then
|
|
self._lastSettingsShare = now
|
|
local addonMsg = string.format("SETTINGS;%s:%s:%s;1",sepgp_progress,sepgp_discount,sepgp_decay)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
end
|
|
end
|
|
|
|
---------------------
|
|
-- EPGP Operations
|
|
---------------------
|
|
function sepgp:init_notes_v2(guild_index,note,officernote)
|
|
if not tonumber(note) or (tonumber(note) < 0) then
|
|
GuildRosterSetPublicNote(guild_index,0)
|
|
end
|
|
if not tonumber(officernote) or (tonumber(officernote) < sepgp.VARS.basegp) then
|
|
GuildRosterSetOfficerNote(guild_index,sepgp.VARS.basegp,true)
|
|
end
|
|
end
|
|
|
|
function sepgp:init_notes_v3(guild_index,name,officernote)
|
|
local ep,gp = self:get_ep_v3(name,officernote), self:get_gp_v3(name,officernote)
|
|
if not (ep and gp) then
|
|
local initstring = string.format("{%d:%d}",0,sepgp.VARS.basegp)
|
|
local newnote = string.format("%s%s",officernote,initstring)
|
|
newnote = string.gsub(newnote,"(.*)({%d+:%d+})(.*)",sanitizeNote)
|
|
officernote = newnote
|
|
else
|
|
officernote = string.gsub(officernote,"(.*)({%d+:%d+})(.*)",sanitizeNote)
|
|
end
|
|
GuildRosterSetOfficerNote(guild_index,officernote,true)
|
|
return officernote
|
|
end
|
|
|
|
function sepgp:update_epgp_v3(ep,gp,guild_index,name,officernote,special_action)
|
|
officernote = self:init_notes_v3(guild_index,name,officernote)
|
|
local newnote
|
|
if (ep) then
|
|
ep = math.max(0,ep)
|
|
newnote = string.gsub(officernote,"(.*{)(%d+)(:)(%d+)(}.*)",function(head,oldep,divider,oldgp,tail)
|
|
return string.format("%s%s%s%s%s",head,ep,divider,oldgp,tail)
|
|
end)
|
|
end
|
|
if (gp) then
|
|
gp = math.max(sepgp.VARS.basegp,gp)
|
|
if (newnote) then
|
|
newnote = string.gsub(newnote,"(.*{)(%d+)(:)(%d+)(}.*)",function(head,oldep,divider,oldgp,tail)
|
|
return string.format("%s%s%s%s%s",head,oldep,divider,gp,tail)
|
|
end)
|
|
else
|
|
newnote = string.gsub(officernote,"(.*{)(%d+)(:)(%d+)(}.*)",function(head,oldep,divider,oldgp,tail)
|
|
return string.format("%s%s%s%s%s",head,oldep,divider,gp,tail)
|
|
end)
|
|
end
|
|
end
|
|
if (newnote) then
|
|
GuildRosterSetOfficerNote(guild_index,newnote,true)
|
|
end
|
|
end
|
|
|
|
function sepgp:update_ep_v2(getname,ep)
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if (name==getname) then
|
|
self:init_notes_v2(i,note,officernote)
|
|
GuildRosterSetPublicNote(i,ep)
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:update_ep_v3(getname,ep)
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if (name==getname) then
|
|
self:update_epgp_v3(ep,nil,i,name,officernote)
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:update_gp_v2(getname,gp)
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if (name==getname) then
|
|
self:init_notes_v2(i,note,officernote)
|
|
GuildRosterSetOfficerNote(i,gp,true)
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:update_gp_v3(getname,gp)
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if (name==getname) then
|
|
self:update_epgp_v3(nil,gp,i,name,officernote)
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:get_ep_v2(getname,note) -- gets ep by name or note
|
|
if (note) then
|
|
if tonumber(note)==nil then return 0 end
|
|
end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if tonumber(note)==nil then note=0 end
|
|
if (name==getname) then return tonumber(note) end
|
|
end
|
|
return(0)
|
|
end
|
|
|
|
function sepgp:get_ep_v3(getname,officernote) -- gets ep by name or note
|
|
if (officernote) then
|
|
local _,_,ep = string.find(officernote,".*{(%d+):%d+}.*")
|
|
return tonumber(ep)
|
|
end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
local _,_,ep = string.find(officernote,".*{(%d+):%d+}.*")
|
|
if (name==getname) then return tonumber(ep) end
|
|
end
|
|
return
|
|
end
|
|
|
|
function sepgp:get_gp_v2(getname,officernote) -- gets gp by name or officernote
|
|
if (officernote) then
|
|
if tonumber(officernote)==nil then return sepgp.VARS.basegp end
|
|
end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if tonumber(officernote)==nil then officernote=sepgp.VARS.basegp end
|
|
if (name==getname) then return tonumber(officernote) end
|
|
end
|
|
return(sepgp.VARS.basegp)
|
|
end
|
|
|
|
function sepgp:get_gp_v3(getname,officernote) -- gets gp by name or officernote
|
|
if (officernote) then
|
|
local _,_,gp = string.find(officernote,".*{%d+:(%d+)}.*")
|
|
return tonumber(gp)
|
|
end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
local _,_,gp = string.find(officernote,".*{%d+:(%d+)}.*")
|
|
if (name==getname) then return tonumber(gp) end
|
|
end
|
|
return
|
|
end
|
|
|
|
function sepgp:award_raid_ep(ep) -- awards ep to raid members in zone
|
|
if GetNumRaidMembers()>0 then
|
|
for i = 1, GetNumRaidMembers(true) do
|
|
local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i)
|
|
self:givename_ep(name,ep)
|
|
end
|
|
self:simpleSay(string.format("Giving %d ep to all raidmembers",ep))
|
|
self:addToLog(string.format("Giving %d ep to all raidmembers",ep))
|
|
local addonMsg = string.format("RAID;AWARD;%s",ep)
|
|
self:addonMessage(addonMsg,"RAID")
|
|
else UIErrorsFrame:AddMessage("You aren't in a raid dummy",1,0,0)end
|
|
end
|
|
|
|
function sepgp:award_reserve_ep(ep) -- awards ep to reserve list
|
|
if table.getn(sepgp.reserves) > 0 then
|
|
for i, reserve in ipairs(sepgp.reserves) do
|
|
local name, class, rank, alt = unpack(reserve)
|
|
self:givename_ep(name,ep)
|
|
end
|
|
self:simpleSay(string.format("Giving %d ep to active reserves",ep))
|
|
self:addToLog(string.format("Giving %d ep to active reserves",ep))
|
|
local addonMsg = string.format("RESERVES;AWARD;%s",ep)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
sepgp.reserves = {}
|
|
reserves_blacklist = {}
|
|
sepgp_reserves:Refresh()
|
|
end
|
|
end
|
|
|
|
function sepgp:givename_ep(getname,ep) -- awards ep to a single character
|
|
if not (admin()) then return end
|
|
local newep = ep + (self:get_ep_v3(getname) or 0) --DONE: update v3
|
|
self:update_ep_v3(getname,newep) --DONE: update v3
|
|
self:debugPrint(string.format("Giving %d ep to %s",ep,getname))
|
|
if ep < 0 then -- inform admins and victim of penalties
|
|
local msg = string.format("%s EP Penalty to %s.",ep,getname)
|
|
self:adminSay(msg)
|
|
self:addToLog(msg)
|
|
local addonMsg = string.format("%s;%s;%s",getname,"EP",ep)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
end
|
|
end
|
|
|
|
function sepgp:givename_gp(getname,gp) -- assigns gp to a single character
|
|
if not (admin()) then return end
|
|
local oldgp = (self:get_gp_v3(getname) or sepgp.VARS.basegp) --DONE: update v3
|
|
local newgp = gp + oldgp
|
|
self:update_gp_v3(getname,newgp) --DONE: update v3
|
|
self:debugPrint(string.format("Giving %d gp to %s",gp,getname))
|
|
local msg = string.format("Awarding %d GP to %s. (Previous: %d, New: %d)",gp,getname,oldgp,math.max(sepgp.VARS.basegp,newgp))
|
|
self:adminSay(msg)
|
|
self:addToLog(msg)
|
|
local addonMsg = string.format("%s;%s;%s",getname,"GP",gp)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
end
|
|
|
|
function sepgp:decay_epgp_v2() -- decays entire roster's ep and gp
|
|
if not (admin()) then return end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name,_,_,_,class,_,ep,gp,_,_ = GetGuildRosterInfo(i)
|
|
ep = tonumber(ep)
|
|
gp = tonumber(gp)
|
|
if ep == nil then
|
|
else
|
|
if gp == nil then
|
|
local msg = string.format("%s\'s officernote is broken:%q",name,tostring(gp))
|
|
self:debugPrint(msg)
|
|
self:adminSay(msg)
|
|
else
|
|
ep = math.max(0,self:num_round(ep*sepgp_decay))
|
|
GuildRosterSetPublicNote(i,ep)
|
|
gp = math.max(sepgp.VARS.basegp,self:num_round(gp*sepgp_decay))
|
|
GuildRosterSetOfficerNote(i,gp,true)
|
|
end
|
|
end
|
|
end
|
|
local msg = string.format("All EP and GP decayed by %d%%",(1-sepgp_decay)*100)
|
|
self:simpleSay(msg)
|
|
if not (sepgp_saychannel=="OFFICER") then self:adminSay(msg) end
|
|
self:addToLog(msg)
|
|
end
|
|
|
|
function sepgp:decay_epgp_v3()
|
|
if not (admin()) then return end
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name,_,_,_,class,_,note,officernote,_,_ = GetGuildRosterInfo(i)
|
|
local ep,gp = self:get_ep_v3(name,officernote), self:get_gp_v3(name,officernote)
|
|
if (ep and gp) then
|
|
ep = self:num_round(ep*sepgp_decay)
|
|
gp = self:num_round(gp*sepgp_decay)
|
|
self:update_epgp_v3(ep,gp,i,name,officernote)
|
|
end
|
|
end
|
|
local msg = string.format("All EP and GP decayed by %s%%",(1-sepgp_decay)*100)
|
|
self:simpleSay(msg)
|
|
if not (sepgp_saychannel=="OFFICER") then self:adminSay(msg) end
|
|
local addonMsg = string.format("ALL;DECAY;%s",(1-(sepgp_decay or sepgp.VARS.decay))*100)
|
|
self:addonMessage(addonMsg,"GUILD")
|
|
self:addToLog(msg)
|
|
end
|
|
|
|
function sepgp:gp_reset_v2()
|
|
if (IsGuildLeader()) then
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
GuildRosterSetOfficerNote(i, sepgp.VARS.basegp,true)
|
|
end
|
|
self:debugPrint(string.format("All GP has been reset to %d.",sepgp.VARS.basegp))
|
|
self:adminSay(string.format("All GP has been reset to %d.",sepgp.VARS.basegp))
|
|
self:addToLog(string.format("All GP has been reset to %d.",sepgp.VARS.basegp))
|
|
end
|
|
end
|
|
|
|
function sepgp:gp_reset_v3()
|
|
if (IsGuildLeader()) then
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name,_,_,_,class,_,note,officernote,_,_ = GetGuildRosterInfo(i)
|
|
local ep,gp = self:get_ep_v3(name,officernote), self:get_gp_v3(name,officernote)
|
|
if (ep and gp) then
|
|
self:update_epgp_v3(0,sepgp.VARS.basegp,i,name,officernote)
|
|
end
|
|
end
|
|
local msg = "All EP and GP has been reset to 0/%d."
|
|
self:debugPrint(string.format(msg,sepgp.VARS.basegp))
|
|
self:adminSay(string.format(msg,sepgp.VARS.basegp))
|
|
self:addToLog(string.format(msg,sepgp.VARS.basegp))
|
|
end
|
|
end
|
|
|
|
function sepgp:my_epgp_announce()
|
|
local ep,gp = (self:get_ep_v3(playerName) or 0), (self:get_gp_v3(playerName) or sepgp.VARS.basegp)
|
|
local pr = ep/gp
|
|
local msg = string.format("You now have: %d EP %d GP |cffffff00%.03f|r|cffff7f00PR|r.", ep,gp,pr)
|
|
self:defaultPrint(msg)
|
|
end
|
|
|
|
function sepgp:my_epgp()
|
|
GuildRoster()
|
|
self:ScheduleEvent("shootyepgpRosterRefresh",self.my_epgp_announce,2,self)
|
|
end
|
|
|
|
---------
|
|
-- Menu
|
|
---------
|
|
local T = AceLibrary("Tablet-2.0")
|
|
|
|
sepgp.defaultMinimapPosition = 180
|
|
sepgp.cannotDetachTooltip = true
|
|
sepgp.tooltipHiddenWhenEmpty = false
|
|
sepgp.hasIcon = "Interface\\Icons\\INV_Misc_Orb_04"
|
|
|
|
function sepgp:OnTooltipUpdate()
|
|
local hint = "|cffffff00Click|r to toggle Standings.%s \n|cffffff00Right-Click|r for Options."
|
|
if (admin()) then
|
|
hint = string.format(hint," \n|cffffff00Ctrl+Click|r to toggle Reserves. \n|cffffff00Alt+Click|r to toggle Bids. \n|cffffff00Shift+Click|r to toggle Loot. \n|cffffff00Ctrl+Shift+Click|r to toggle Logs.")
|
|
else
|
|
hint = string.format(hint,"")
|
|
end
|
|
T:SetHint(hint)
|
|
end
|
|
|
|
function sepgp:OnClick()
|
|
local is_admin = admin()
|
|
if (IsControlKeyDown() and IsShiftKeyDown() and is_admin) then
|
|
sepgp_logs:Toggle()
|
|
elseif (IsControlKeyDown() and is_admin) then
|
|
sepgp_reserves:Toggle()
|
|
elseif (IsShiftKeyDown() and is_admin) then
|
|
sepgp_loot:Toggle()
|
|
elseif (IsAltKeyDown() and is_admin) then
|
|
sepgp_bids:Toggle()
|
|
else
|
|
sepgp_standings:Toggle()
|
|
end
|
|
end
|
|
|
|
function sepgp:SetRefresh(flag)
|
|
needRefresh = flag
|
|
if (flag) then
|
|
sepgp_standings:Refresh()
|
|
end
|
|
end
|
|
|
|
function sepgp:buildRosterTable()
|
|
local g, r = { }, { }
|
|
local numGuildMembers = GetNumGuildMembers(1)
|
|
if (sepgp_raidonly) and GetNumRaidMembers() > 0 then
|
|
for i = 1, GetNumRaidMembers(true) do
|
|
local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i)
|
|
r[name] = true
|
|
end
|
|
end
|
|
for i = 1, numGuildMembers do
|
|
local member_name,_,_,_,class,_,ep,gp,_,_ = GetGuildRosterInfo(i)
|
|
if (sepgp_raidonly) and next(r) then
|
|
if r[member_name] then
|
|
table.insert(g,{["name"]=member_name,["class"]=class})
|
|
end
|
|
else
|
|
table.insert(g,{["name"]=member_name,["class"]=class})
|
|
end
|
|
end
|
|
return g
|
|
end
|
|
|
|
function sepgp:buildClassMemberTable(roster,epgp)
|
|
local desc,usage
|
|
if epgp == "ep" then
|
|
desc = "Account EPs to %s."
|
|
usage = "<EP>"
|
|
elseif epgp == "gp" then
|
|
desc = "Account GPs to %s."
|
|
usage = "<GP>"
|
|
end
|
|
local c = { }
|
|
for i,member in ipairs(roster) do
|
|
local class,name = member.class, member.name
|
|
if (class) and (c[class] == nil) then
|
|
c[class] = { }
|
|
c[class].type = "group"
|
|
c[class].name = class
|
|
c[class].desc = class .. " members"
|
|
c[class].hidden = function() return not (admin()) end
|
|
c[class].args = { }
|
|
end
|
|
if (name) and (c[class].args[name] == nil) then
|
|
c[class].args[name] = { }
|
|
c[class].args[name].type = "text"
|
|
c[class].args[name].name = name
|
|
c[class].args[name].desc = string.format(desc,name)
|
|
c[class].args[name].usage = usage
|
|
if epgp == "ep" then
|
|
c[class].args[name].get = "suggestedAwardEP"
|
|
c[class].args[name].set = function(v) sepgp:givename_ep(name, tonumber(v)) end
|
|
elseif epgp == "gp" then
|
|
c[class].args[name].get = false
|
|
c[class].args[name].set = function(v) sepgp:givename_gp(name, tonumber(v)) end
|
|
end
|
|
c[class].args[name].validate = function(v) return (type(v) == "number" or tonumber(v)) and tonumber(v) < sepgp.VARS.max end
|
|
end
|
|
end
|
|
return c
|
|
end
|
|
|
|
local options
|
|
function sepgp:buildMenu()
|
|
if not (options) then
|
|
options = {
|
|
type = "group",
|
|
desc = "shootyepgp options",
|
|
handler = self,
|
|
args = { }
|
|
}
|
|
options.args["ep"] = {
|
|
type = "group",
|
|
name = "+EPs to Member",
|
|
desc = "Account EPs for member.",
|
|
order = 10,
|
|
hidden = function() return not (admin()) end,
|
|
}
|
|
options.args["ep_raid"] = {
|
|
type = "text",
|
|
name = "+EPs to Raid",
|
|
desc = "Award EPs to all raid members.",
|
|
order = 20,
|
|
get = "suggestedAwardEP",
|
|
set = function(v) sepgp:award_raid_ep(tonumber(v)) end,
|
|
usage = "<EP>",
|
|
hidden = function() return not (admin()) end,
|
|
validate = function(v)
|
|
local n = tonumber(v)
|
|
return n and n >= 0 and n < sepgp.VARS.max
|
|
end
|
|
}
|
|
options.args["gp"] = {
|
|
type = "group",
|
|
name = "+GPs to Member",
|
|
desc = "Account GPs for member.",
|
|
order = 30,
|
|
hidden = function() return not (admin()) end,
|
|
}
|
|
options.args["ep_reserves"] = {
|
|
type = "text",
|
|
name = "+EPs to Reserves",
|
|
desc = "Award EPs to all active Reserves.",
|
|
order = 40,
|
|
get = "suggestedAwardEP",
|
|
set = function(v) sepgp:award_reserve_ep(tonumber(v)) end,
|
|
usage = "<EP>",
|
|
hidden = function() return not (admin()) end,
|
|
validate = function(v)
|
|
local n = tonumber(v)
|
|
return n and n >= 0 and n < sepgp.VARS.max
|
|
end
|
|
}
|
|
options.args["reserves"] = {
|
|
type = "toggle",
|
|
name = "Enable Reserves",
|
|
desc = "Participate in Standby Raiders List.\n|cffff0000Requires Main Character Name.|r",
|
|
order = 50,
|
|
get = function() return (sepgp.reservesChannelID ~= nil) and (sepgp.reservesChannelID ~= 0) end,
|
|
set = function(v) sepgp:reservesToggle(v) end,
|
|
disabled = function() return (sepgp_main == nil) end
|
|
}
|
|
options.args["afkcheck_reserves"] = {
|
|
type = "execute",
|
|
name = "AFK Check Reserves",
|
|
desc = "AFK Check Reserves List",
|
|
order = 60,
|
|
hidden = function() return not (admin()) end,
|
|
func = function() sepgp:afkcheck_reserves() end
|
|
}
|
|
options.args["set_main"] = {
|
|
type = "text",
|
|
name = "Set Main",
|
|
desc = "Set your Main Character for Reserve List.",
|
|
order = 70,
|
|
usage = "<MainChar>",
|
|
get = function() return sepgp_main end,
|
|
set = function(v) sepgp_main = (sepgp:verifyGuildMember(v)) end,
|
|
}
|
|
options.args["raid_only"] = {
|
|
type = "toggle",
|
|
name = "Raid Only",
|
|
desc = "Only show members in raid.",
|
|
order = 80,
|
|
get = function() return not not sepgp_raidonly end,
|
|
set = function(v)
|
|
sepgp_raidonly = not sepgp_raidonly
|
|
sepgp:SetRefresh(true)
|
|
end,
|
|
}
|
|
options.args["progress_tier"] = {
|
|
type = "text",
|
|
name = "Raid Progress",
|
|
desc = "Highest Tier the Guild is raiding.\nUsed to adjust GP Prices.\nUsed for suggested EP awards.",
|
|
order = 90,
|
|
get = function() return sepgp_progress end,
|
|
set = function(v)
|
|
sepgp_progress = v
|
|
sepgp_bids:Refresh()
|
|
if (IsGuildLeader()) then
|
|
sepgp:shareSettings(true)
|
|
end
|
|
end,
|
|
validate = { ["T3"]="4.Naxxramas", ["T2.5"]="3.Temple of Ahn\'Qiraj", ["T2"]="2.Blackwing Lair", ["T1"]="1.Molten Core"},
|
|
}
|
|
options.args["report_channel"] = {
|
|
type = "text",
|
|
name = "Reporting channel",
|
|
desc = "Channel used by reporting functions.",
|
|
order = 95,
|
|
hidden = function() return not (admin()) end,
|
|
get = function() return sepgp_saychannel end,
|
|
set = function(v) sepgp_saychannel = v end,
|
|
validate = { "PARTY", "RAID", "GUILD", "OFFICER" },
|
|
}
|
|
options.args["decay"] = {
|
|
type = "execute",
|
|
name = "Decay EPGP",
|
|
desc = string.format("Decays all EPGP by %s%%",(1-(sepgp_decay or sepgp.VARS.decay))*100),
|
|
order = 100,
|
|
hidden = function() return not (admin()) end,
|
|
func = function() sepgp:decay_epgp_v3() end --DONE: update v3
|
|
}
|
|
options.args["set_decay"] = {
|
|
type = "range",
|
|
name = "Set Decay %",
|
|
desc = "Set Decay percentage (Admin only).",
|
|
order = 110,
|
|
usage = "<Decay>",
|
|
get = function() return (1.0-sepgp_decay) end,
|
|
set = function(v)
|
|
sepgp_decay = (1 - v)
|
|
options.args["decay"].desc = string.format("Decays all EPGP by %s%%",(1-sepgp_decay)*100)
|
|
if (IsGuildLeader()) then
|
|
sepgp:shareSettings(true)
|
|
end
|
|
end,
|
|
min = 0.01,
|
|
max = 0.5,
|
|
step = 0.01,
|
|
bigStep = 0.05,
|
|
isPercent = true,
|
|
hidden = function() return not (admin()) end,
|
|
}
|
|
options.args["set_discount"] = {
|
|
type = "range",
|
|
name = "Offspec Price %",
|
|
desc = "Set Offspec Items GP Percent.",
|
|
order = 115,
|
|
get = function() return sepgp_discount end,
|
|
set = function(v)
|
|
sepgp_discount = v
|
|
if (IsGuildLeader()) then
|
|
sepgp:shareSettings(true)
|
|
end
|
|
end,
|
|
min = 0,
|
|
max = 1,
|
|
step = 0.05,
|
|
isPercent = true
|
|
}
|
|
options.args["reset"] = {
|
|
type = "execute",
|
|
name = "Reset GP",
|
|
desc = string.format("Resets everyone\'s EPGP to 0/%d (Admin only).",sepgp.VARS.basegp),
|
|
order = 120,
|
|
hidden = function() return not (IsGuildLeader()) end,
|
|
func = function() StaticPopup_Show("SHOOTY_EPGP_CONFIRM_RESET") end
|
|
}
|
|
end
|
|
if (needInit) or (needRefresh) then
|
|
local members = sepgp:buildRosterTable()
|
|
self:debugPrint(string.format("Scanning %d members for EP/GP data. (%s)",table.getn(members),(sepgp_raidonly and "Raid" or "Full")))
|
|
options.args["ep"].args = sepgp:buildClassMemberTable(members,"ep")
|
|
options.args["gp"].args = sepgp:buildClassMemberTable(members,"gp")
|
|
if (needInit) then needInit = false end
|
|
if (needRefresh) then needRefresh = false end
|
|
end
|
|
return options
|
|
end
|
|
|
|
---------------
|
|
-- Reserves
|
|
---------------
|
|
function sepgp:reservesToggle(flag)
|
|
local reservesChannelID = tonumber((GetChannelName(sepgp_reservechannel)))
|
|
if (flag) then -- we want in
|
|
if (reservesChannelID) and reservesChannelID ~= 0 then
|
|
sepgp.reservesChannelID = reservesChannelID
|
|
if not self:IsEventRegistered("CHAT_MSG_CHANNEL") then
|
|
self:RegisterEvent("CHAT_MSG_CHANNEL","captureReserveChatter")
|
|
end
|
|
return true
|
|
else
|
|
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE","reservesChannelChange")
|
|
JoinChannelByName(sepgp_reservechannel)
|
|
return
|
|
end
|
|
else -- we want out
|
|
if (reservesChannelID) and reservesChannelID ~= 0 then
|
|
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE","reservesChannelChange")
|
|
LeaveChannelByName(sepgp_reservechannel)
|
|
return
|
|
else
|
|
if self:IsEventRegistered("CHAT_MSG_CHANNEL") then
|
|
self:UnregisterEvent("CHAT_MSG_CHANNEL")
|
|
end
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:reservesChannelChange(msg,_,_,_,_,_,_,_,channel)
|
|
if (msg) and (channel) and (channel == sepgp_reservechannel) then
|
|
if msg == "YOU_JOINED" then
|
|
sepgp.reservesChannelID = tonumber((GetChannelName(sepgp_reservechannel)))
|
|
RemoveChatWindowChannel(DEFAULT_CHAT_FRAME:GetID(), sepgp_reservechannel)
|
|
self:RegisterEvent("CHAT_MSG_CHANNEL","captureReserveChatter")
|
|
elseif msg == "YOU_LEFT" then
|
|
sepgp.reservesChannelID = nil
|
|
if self:IsEventRegistered("CHAT_MSG_CHANNEL") then
|
|
self:UnregisterEvent("CHAT_MSG_CHANNEL")
|
|
end
|
|
end
|
|
self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
|
D:Close()
|
|
end
|
|
end
|
|
|
|
function sepgp:afkcheck_reserves()
|
|
if (running_check) then return end
|
|
if sepgp.reservesChannelID ~= nil and ((GetChannelName(sepgp.reservesChannelID)) == sepgp.reservesChannelID) then
|
|
reserves_blacklist = {}
|
|
sepgp.reserves = {}
|
|
running_check = true
|
|
sepgp.timer.count_down = sepgp.VARS.timeout
|
|
sepgp.timer:Show()
|
|
SendChatMessage(shooty_reservecall,"CHANNEL",nil,sepgp.reservesChannelID)
|
|
sepgp_reserves:Toggle(true)
|
|
end
|
|
end
|
|
|
|
function sepgp:sendReserverResponce()
|
|
if sepgp.reservesChannelID ~= nil then
|
|
if (sepgp_main) then
|
|
if sepgp_main == playerName then
|
|
SendChatMessage("+","CHANNEL",nil,sepgp.reservesChannelID)
|
|
else
|
|
SendChatMessage(string.format("+%s",sepgp_main),"CHANNEL",nil,sepgp.reservesChannelID)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:captureReserveChatter(text, sender, _, _, _, _, _, _, channel)
|
|
if not (channel) or not (channel == sepgp_reservechannel) then return end
|
|
local reserve, reserve_class, reserve_rank, reserve_alt = nil,nil,nil,nil
|
|
local r,_,rdy,name = string.find(text,shooty_reserveanswer)
|
|
if (r) and (running_check) then
|
|
if (rdy) then
|
|
if (name) and (name ~= "") then
|
|
if (not self:inRaid(name)) then
|
|
reserve, reserve_class, reserve_rank = self:verifyGuildMember(name)
|
|
if reserve ~= sender then
|
|
reserve_alt = sender
|
|
end
|
|
end
|
|
else
|
|
if (not self:inRaid(sender)) then
|
|
reserve, reserve_class, reserve_rank = self:verifyGuildMember(sender)
|
|
end
|
|
end
|
|
if reserve and reserve_class and reserve_rank then
|
|
if reserve_alt then
|
|
if not reserves_blacklist[reserve_alt] then
|
|
reserves_blacklist[reserve_alt] = true
|
|
table.insert(sepgp.reserves,{reserve,reserve_class,reserve_rank,reserve_alt})
|
|
else
|
|
self:defaultPrint(string.format("|cffff0000%s|r trying to add %s to Reserves, but has already added a member. Discarding!",reserve_alt,reserve))
|
|
end
|
|
else
|
|
if not reserves_blacklist[reserve] then
|
|
reserves_blacklist[reserve] = true
|
|
table.insert(sepgp.reserves,{reserve,reserve_class,reserve_rank})
|
|
else
|
|
self:defaultPrint(string.format("|cffff0000%s|r has already been added to Reserves. Discarding!",reserve))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return
|
|
end
|
|
local q = string.find(text,"^{shootyepgp}Type")
|
|
if (q) and not (running_check) then
|
|
if (not UnitInRaid("player")) or (not self:inRaid(sender)) then
|
|
StaticPopup_Show("SHOOTY_EPGP_RESERVE_AFKCHECK_RESPONCE")
|
|
end
|
|
end
|
|
end
|
|
|
|
---------
|
|
-- Bids
|
|
---------
|
|
local lootCall = {}
|
|
lootCall.whisp = {
|
|
"^(w)[%s%p%c]+.+",".+[%s%p%c]+(w)$",".+[%s%p%c]+(w)[%s%p%c]+.*",".*[%s%p%c]+(w)[%s%p%c]+.+",
|
|
"^(whisper)[%s%p%c]+.+",".+[%s%p%c]+(whisper)$",".+[%s%p%c]+(whisper)[%s%p%c]+.*",".*[%s%p%c]+(whisper)[%s%p%c]+.+",
|
|
".+[%s%p%c]+(bid)[%s%p%c]*.*",".*[%s%p%c]*(bid)[%s%p%c]+.+"
|
|
}
|
|
lootCall.ms = {
|
|
".+(%+).*",".*(%+).+",
|
|
"^(ms)[%s%p%c]+.+",".+[%s%p%c]+(ms)$",".+[%s%p%c]+(ms)[%s%p%c]+.*",".*[%s%p%c]+(ms)[%s%p%c]+.+",
|
|
".+(mainspec).*",".*(mainspec).+"
|
|
}
|
|
lootCall.os = {
|
|
".+(%-).*",".*(%-).+",
|
|
"^(os)[%s%p%c]+.+",".+[%s%p%c]+(os)$",".+[%s%p%c]+(os)[%s%p%c]+.*",".*[%s%p%c]+(os)[%s%p%c]+.+",
|
|
".+(offspec).*",".*(offspec).+"
|
|
}
|
|
lootCall.bs = { -- blacklist
|
|
"^(roll)[%s%p%c]+.+",".+[%s%p%c]+(roll)$",".*[%s%p%c]+(roll)[%s%p%c]+.*"
|
|
}
|
|
function sepgp:captureLootCall(text, sender)
|
|
if not (string.find(text, "|Hitem:", 1, true)) then return end
|
|
local linkstriptext, count = string.gsub(text,"|c%x+|H[eimt:%d]+|h%[[%w%s',%-]+%]|h|r"," ; ")
|
|
if count > 1 then return end
|
|
local lowtext = string.lower(linkstriptext)
|
|
local whisperkw_found, mskw_found, oskw_found, link_found, blacklist_found
|
|
for _,f in ipairs(lootCall.bs) do
|
|
blacklist_found = string.find(lowtext,f)
|
|
if (blacklist_found) then return end
|
|
end
|
|
local _, itemLink, itemColor, itemString, itemName
|
|
for _,f in ipairs(lootCall.whisp) do
|
|
whisperkw_found = string.find(lowtext,f)
|
|
if (whisperkw_found) then break end
|
|
end
|
|
for _,f in ipairs(lootCall.ms) do
|
|
mskw_found = string.find(lowtext,f)
|
|
if (mskw_found) then break end
|
|
end
|
|
for _,f in ipairs(lootCall.os) do
|
|
oskw_found = string.find(lowtext,f)
|
|
if (oskw_found) then break end
|
|
end
|
|
if (whisperkw_found) or (mskw_found) or (oskw_found) then
|
|
_,_,itemLink = string.find(text,"(|c%x+|H[eimt:%d]+|h%[[%w%s',%-]+%]|h|r)")
|
|
if (itemLink) and (itemLink ~= "") then
|
|
link_found, _, itemColor, itemString, itemName = string.find(itemLink, "^(|c%x+)|H(.+)|h(%[.+%])")
|
|
end
|
|
if (link_found) then
|
|
local quality = hexColorQuality[itemColor] or -1
|
|
if (quality >= 3) then
|
|
if (IsRaidLeader() or self:lootMaster()) and (sender == playerName) then
|
|
self:clearBids(true)
|
|
sepgp.bid_item.link = itemString
|
|
sepgp.bid_item.linkFull = itemLink
|
|
sepgp.bid_item.name = string.format("%s%s|r",itemColor,itemName)
|
|
self:ScheduleEvent("shootyepgpBidTimeout",self.clearBids,300,self)
|
|
running_bid = true
|
|
self:debugPrint("Capturing Bids for 5min.")
|
|
sepgp_bids:Toggle(true)
|
|
end
|
|
self:bidPrint(itemLink,sender,mskw_found,oskw_found,whisperkw_found)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local lootBid = {}
|
|
lootBid.ms = {"(%+)",".+(%+).*",".*(%+).+",".*(%+).*","(ms)"}
|
|
lootBid.os = {"(%-)",".+(%-).*",".*(%-).+",".*(%-).*","(os)"}
|
|
function sepgp:captureBid(text, sender)
|
|
if not (running_bid) then return end
|
|
if not (IsRaidLeader() or self:lootMaster()) then return end
|
|
if not sepgp.bid_item.link then return end
|
|
local mskw_found,oskw_found
|
|
local lowtext = string.lower(text)
|
|
for _,f in ipairs(lootBid.ms) do
|
|
mskw_found = string.find(text,f)
|
|
if (mskw_found) then break end
|
|
end
|
|
for _,f in ipairs(lootBid.os) do
|
|
oskw_found = string.find(text,f)
|
|
if (oskw_found) then break end
|
|
end
|
|
if (mskw_found) or (oskw_found) then
|
|
if self:inRaid(sender) then
|
|
if bids_blacklist[sender] == nil then
|
|
for i = 1, GetNumGuildMembers(1) do
|
|
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
|
|
if name == sender then
|
|
local ep = (self:get_ep_v3(name,officernote) or 0) --DONE: update v3
|
|
local gp = (self:get_gp_v3(name,officernote) or sepgp.VARS.basegp) --DONE: update v3
|
|
if (mskw_found) then
|
|
bids_blacklist[sender] = true
|
|
table.insert(sepgp.bids_main,{name,class,ep,gp,ep/gp})
|
|
elseif (oskw_found) then
|
|
bids_blacklist[sender] = true
|
|
table.insert(sepgp.bids_off,{name,class,ep,gp,ep/gp})
|
|
end
|
|
sepgp_bids:Toggle(true)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:clearBids(reset)
|
|
if reset~=nil then
|
|
self:debugPrint("Clearing old Bids")
|
|
end
|
|
sepgp.bid_item = {}
|
|
sepgp.bids_main = {}
|
|
sepgp.bids_off = {}
|
|
bids_blacklist = {}
|
|
if self:IsEventScheduled("shootyepgpBidTimeout") then
|
|
self:CancelScheduledEvent("shootyepgpBidTimeout")
|
|
end
|
|
running_bid = false
|
|
sepgp_bids._counterText = ""
|
|
sepgp_bids:Refresh()
|
|
end
|
|
|
|
----------------
|
|
-- Loot Tracker
|
|
----------------
|
|
-- /script DEFAULT_CHAT_FRAME:AddMessage("\124cffa335ee\124Hitem:16864:0:0:0:0:0:0:0:0\124h[Belt of Might]\124h\124r");
|
|
-- test: "You receive loot: \124cffa335ee\124Hitem:16866:0:0:0\124h[Helm of Might]\124h\124r."
|
|
-- test: /run sepgp:captureLoot("Raerlas receives loot: \124cffa335ee\124Hitem:16846:0:0:0\124h[Giantstalker's Helmet]\124h\124r.")
|
|
-- test: /run sepgp:captureLoot("You receive loot: \124cffa335ee\124Hitem:16864:0:0:0\124h[Belt of Might]\124h\124r.")
|
|
sepgp.loot_index = {
|
|
time=1,
|
|
player=2,
|
|
player_c=3,
|
|
item=4,
|
|
bind=5,
|
|
price=6,
|
|
off_price=7,
|
|
action=8,
|
|
update=9
|
|
}
|
|
function sepgp:captureLoot(message)
|
|
if not (UnitInRaid("player") and self:lootMaster() and admin()) then return end
|
|
local who,what,amount,player,itemLink
|
|
who,what,amount = DF:Deformat(message,LOOT_ITEM_MULTIPLE)
|
|
if (amount) then -- skip multiples / stacks
|
|
else
|
|
player, itemLink = DF:Deformat(message,LOOT_ITEM)
|
|
end
|
|
who,what,amount = YOU, DF:Deformat(message,LOOT_ITEM_SELF_MULTIPLE)
|
|
if (amount) then -- skip multiples / stacks
|
|
else
|
|
if not (player and itemLink) then
|
|
player, itemLink = YOU, DF:Deformat(message,LOOT_ITEM_SELF)
|
|
end
|
|
end
|
|
if not (player and itemLink) then return end
|
|
local link_found, _, itemColor, itemString, itemName = string.find(itemLink, "^(|c%x+)|H(.+)|h(%[.+%])")
|
|
if player and itemLink and link_found then
|
|
local bind = self:itemBinding(itemString)
|
|
if not (bind) then return end
|
|
local price = sepgp_prices:GetPrice(itemString,sepgp_progress)
|
|
if not (price) or price == 0 then
|
|
return
|
|
end
|
|
local class,_
|
|
if player == YOU then
|
|
class = UnitClass("player") -- localized
|
|
else
|
|
_, class = self:verifyGuildMember(player,true) -- localized
|
|
end
|
|
if not (class) then return end
|
|
local player_color = C:Colorize(BC:GetHexColor(class),player)
|
|
local off_price = math.floor(price*sepgp_discount)
|
|
local quality = hexColorQuality[itemColor] or -1
|
|
local timestamp = date("%b/%d %H:%M:%S")
|
|
local data = {[self.loot_index.time]=timestamp,[self.loot_index.player]=player,[self.loot_index.player_c]=player_color,[self.loot_index.item]=itemLink,[self.loot_index.bind]=bind,[self.loot_index.price]=price,[self.loot_index.off_price]=off_price}
|
|
local dialog = StaticPopup_Show("SHOOTY_EPGP_AUTO_GEARPOINTS",data[self.loot_index.player_c],data[self.loot_index.item],data)
|
|
if (dialog) then
|
|
dialog.data = data
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:findLootReminder(itemLink)
|
|
for i,data in ipairs(sepgp_looted) do
|
|
if data[self.loot_index.item] == itemLink and data[self.loot_index.action] == self.VARS.reminder then
|
|
return data
|
|
end
|
|
end
|
|
end
|
|
|
|
function sepgp:tradeLoot(playerState,targetState)
|
|
if not (UnitInRaid("player") and self:lootMaster() and admin()) then return end
|
|
if (playerState ~= nil and targetState ~= nil) and playerState == 1 and targetState == 1 then
|
|
local itemLink
|
|
for id=1,MAX_TRADABLE_ITEMS do
|
|
itemLink = GetTradePlayerItemLink(id)
|
|
if (itemLink) then
|
|
break
|
|
end
|
|
end
|
|
if (itemLink) then
|
|
local link_found, _, itemColor, itemString, itemName = string.find(itemLink, "^(|c%x+)|H(.+)|h(%[.+%])")
|
|
if (link_found) then
|
|
local price = sepgp_prices:GetPrice(itemString,sepgp_progress)
|
|
if not (price) or price == 0 then
|
|
return
|
|
end
|
|
local bind = self:itemBinding(itemString)
|
|
if (not bind) or (bind ~= self.VARS.boe) then return end
|
|
if UnitExists("target") and UnitIsPlayer("target") and UnitCanCooperate("player","target") and (not UnitIsUnit("player","target")) then
|
|
local tradeTarget = UnitName("target")
|
|
local _, class = self:verifyGuildMember(tradeTarget,true)
|
|
if not (class) then return end
|
|
local target_color = C:Colorize(BC:GetHexColor(class),tradeTarget)
|
|
local timestamp = date("%b/%d %H:%M:%S")
|
|
local data = self:findLootReminder(itemLink)
|
|
if (data) then
|
|
data[self.loot_index.time] = timestamp
|
|
data[self.loot_index.player] = tradeTarget
|
|
data[self.loot_index.player_c] = target_color
|
|
data[self.loot_index.update] = 1
|
|
local dialog = StaticPopup_Show("SHOOTY_EPGP_AUTO_GEARPOINTS",data[self.loot_index.player_c],data[self.loot_index.item],data)
|
|
if (dialog) then
|
|
dialog.data = data
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
sepgp.item_bind_patterns = {
|
|
CRAFT = "("..ITEM_SPELL_TRIGGER_ONUSE..")",
|
|
BOP = "("..ITEM_BIND_ON_PICKUP..")",
|
|
QUEST = "("..ITEM_BIND_QUEST..")",
|
|
BOU = "("..ITEM_BIND_ON_EQUIP..")",
|
|
BOE = "("..ITEM_BIND_ON_USE..")"
|
|
}
|
|
function sepgp:itemBinding(item)
|
|
G:SetHyperlink(item)
|
|
if G:Find(self.item_bind_patterns.CRAFT,2,4,nil,true) then
|
|
else
|
|
if G:Find(self.item_bind_patterns.BOP,2,4,nil,true) then
|
|
return sepgp.VARS.bop
|
|
elseif G:Find(self.item_bind_patterns.QUEST,2,4,nil,true) then
|
|
return sepgp.VARS.bop
|
|
elseif G:Find(self.item_bind_patterns.BOE,2,4,nil,true) then
|
|
return sepgp.VARS.boe
|
|
elseif G:Find(self.item_bind_patterns.BOU,2,4,nil,true) then
|
|
return sepgp.VARS.boe
|
|
else
|
|
return sepgp.VARS.nobind
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
function sepgp:addOrUpdateLoot(data,update)
|
|
if not (update) then
|
|
table.insert(sepgp_looted,data)
|
|
end
|
|
end
|
|
|
|
------------
|
|
-- Logging
|
|
------------
|
|
function sepgp:addToLog(line,skipTime)
|
|
local over = table.getn(sepgp_log)-sepgp.VARS.maxloglines+1
|
|
if over > 0 then
|
|
for i=1,over do
|
|
table.remove(sepgp_log,1)
|
|
end
|
|
end
|
|
local timestamp
|
|
if (skipTime) then
|
|
timestamp = ""
|
|
else
|
|
timestamp = date("%b/%d %H:%M:%S")
|
|
end
|
|
table.insert(sepgp_log,{timestamp,line})
|
|
end
|
|
|
|
------------
|
|
-- Utility
|
|
------------
|
|
function sepgp:num_round(i)
|
|
return math.floor(i+0.5)
|
|
end
|
|
|
|
function sepgp:verifyGuildMember(name,silent)
|
|
for i=1,GetNumGuildMembers(1) do
|
|
local g_name, g_rank, g_rankIndex, g_level, g_class, g_zone, g_note, g_officernote, g_online = GetGuildRosterInfo(i)
|
|
if (string.lower(name) == string.lower(g_name)) and (tonumber(g_level) == MAX_PLAYER_LEVEL) then
|
|
return g_name, g_class, g_rank
|
|
end
|
|
end
|
|
if (name) and name ~= "" and not (silent) then
|
|
self:defaultPrint(string.format("%s not found in the guild or not max level!",name))
|
|
end
|
|
return
|
|
end
|
|
|
|
function sepgp:inRaid(name)
|
|
for i=1,GetNumRaidMembers() do
|
|
if name == (UnitName(raidUnit[i])) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function sepgp:lootMaster()
|
|
local method, lootmasterID = GetLootMethod()
|
|
if method == "master" and lootmasterID == 0 then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
local raidZones = {["Molten Core"]="T1",["Onyxia\'s Lair"]="T1.5",["Blackwing Lair"]="T2",["Ahn'Qiraj"]="T2.5",["Naxxramas"]="T3"}
|
|
local zone_multipliers = {
|
|
["T3"] = {["T3"]=1,["T2.5"]=0.75,["T2"]=0.5,["T1.5"]=0.25,["T1"]=0.25},
|
|
["T2.5"] = {["T3"]=1,["T2.5"]=1,["T2"]=0.7,["T1.5"]=0.4,["T1"]=0.4},
|
|
["T2"] = {["T3"]=1,["T2.5"]=1,["T2"]=1,["T1.5"]=0.5,["T1"]=0.5},
|
|
["T1"] = {["T3"]=1,["T2.5"]=1,["T2"]=1,["T1.5"]=1,["T1"]=1}
|
|
}
|
|
function sepgp:suggestedAwardEP()
|
|
local currentTier, zoneEN, zoneLoc, checkTier, multiplier
|
|
local inInstance, instanceType = IsInInstance()
|
|
if (inInstance == nil) or (instanceType ~= nil and instanceType == "none") then
|
|
currentTier = "T1.5"
|
|
end
|
|
if (inInstance) and (instanceType == "raid") then
|
|
zoneLoc = GetRealZoneText()
|
|
if (BZ:HasReverseTranslation(zoneLoc)) then
|
|
zoneEN = BZ:GetReverseTranslation(zoneLoc)
|
|
checkTier = raidZones[zoneEN]
|
|
if (checkTier) then
|
|
currentTier = checkTier
|
|
end
|
|
end
|
|
end
|
|
if not currentTier then
|
|
return sepgp.VARS.baseaward_ep
|
|
else
|
|
multiplier = zone_multipliers[sepgp_progress][currentTier]
|
|
end
|
|
if (multiplier) then
|
|
return multiplier*sepgp.VARS.baseaward_ep
|
|
else
|
|
return sepgp.VARS.baseaward_ep
|
|
end
|
|
end
|
|
|
|
function sepgp:parseVersion(version,otherVersion)
|
|
if not sepgp._version then sepgp._version = {} end
|
|
for major,minor,patch in string.gfind(version,"(%d+)[^%d]?(%d*)[^%d]?(%d*)") do
|
|
sepgp._version.major = tonumber(major)
|
|
sepgp._version.minor = tonumber(minor)
|
|
sepgp._version.patch = tonumber(patch)
|
|
end
|
|
if (otherVersion) then
|
|
if not sepgp._otherversion then sepgp._otherversion = {} end
|
|
for major,minor,patch in string.gfind(otherVersion,"(%d+)[^%d]?(%d*)[^%d]?(%d*)") do
|
|
sepgp._otherversion.major = tonumber(major)
|
|
sepgp._otherversion.minor = tonumber(minor)
|
|
sepgp._otherversion.patch = tonumber(patch)
|
|
end
|
|
if (sepgp._otherversion.major ~= nil and sepgp._version.major ~= nil) then
|
|
if (sepgp._otherversion.major > sepgp._version.major) then
|
|
return true, "major"
|
|
elseif (sepgp._otherversion.major == sepgp._version.major) then
|
|
if (sepgp._otherversion.minor ~= nil and sepgp._version.minor ~= nil) then
|
|
if (sepgp._otherversion.minor > sepgp._version.minor) then
|
|
return true, "minor"
|
|
elseif (sepgp._otherversion.patch ~= nil and sepgp._version.patch ~= nil) then
|
|
if (sepgp._otherversion.patch > sepgp._version.patch) then
|
|
return true, "patch"
|
|
end
|
|
elseif (sepgp._otherversion.patch ~= nil and sepgp._version.patch == nil) then
|
|
return true, "patch"
|
|
end
|
|
elseif (sepgp._otherversion.minor ~= nil and sepgp._version.minor == nil) then
|
|
return true, "minor"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
admin = function()
|
|
return (CanEditOfficerNote() and CanEditPublicNote())
|
|
end
|
|
|
|
sanitizeNote = function(prefix,epgp,postfix)
|
|
-- reserve 12 chars for the epgp pattern {xxxxx:yyyy} max public/officernote = 31
|
|
local remainder = string.format("%s%s",prefix,postfix)
|
|
local clip = math.min(31-12,string.len(remainder))
|
|
local prepend = string.sub(remainder,1,clip)
|
|
return string.format("%s%s",prepend,epgp)
|
|
end
|
|
|
|
-------------
|
|
-- Dialogs
|
|
-------------
|
|
|
|
StaticPopupDialogs["SHOOTY_EPGP_SET_MAIN"] = {
|
|
text = "Set your main to be able to participate in Reserve List EPGP Checks.",
|
|
button1 = TEXT(ACCEPT),
|
|
button2 = TEXT(CANCEL),
|
|
hasEditBox = 1,
|
|
maxLetters = 12,
|
|
OnAccept = function()
|
|
local editBox = getglobal(this:GetParent():GetName().."EditBox")
|
|
sepgp_main = sepgp:verifyGuildMember(editBox:GetText())
|
|
end,
|
|
OnShow = function()
|
|
getglobal(this:GetName().."EditBox"):SetText(sepgp_main or "")
|
|
getglobal(this:GetName().."EditBox"):SetFocus()
|
|
end,
|
|
OnHide = function()
|
|
if ( ChatFrameEditBox:IsVisible() ) then
|
|
ChatFrameEditBox:SetFocus()
|
|
end
|
|
getglobal(this:GetName().."EditBox"):SetText("")
|
|
end,
|
|
EditBoxOnEnterPressed = function()
|
|
local editBox = getglobal(this:GetParent():GetName().."EditBox")
|
|
sepgp_main = sepgp:verifyGuildMember(editBox:GetText())
|
|
this:GetParent():Hide()
|
|
end,
|
|
EditBoxOnEscapePressed = function()
|
|
this:GetParent():Hide()
|
|
end,
|
|
timeout = 0,
|
|
exclusive = 1,
|
|
whileDead = 1,
|
|
hideOnEscape = 1
|
|
}
|
|
StaticPopupDialogs["SHOOTY_EPGP_RESERVE_AFKCHECK_RESPONCE"] = {
|
|
text = " ",
|
|
button1 = TEXT(YES),
|
|
button2 = TEXT(NO),
|
|
OnShow = function()
|
|
this._timeout = sepgp.VARS.timeout-1
|
|
end,
|
|
OnUpdate = function(elapsed,dialog)
|
|
this._timeout = this._timeout - elapsed
|
|
getglobal(dialog:GetName().."Text"):SetText(string.format("Reserves AFKCheck. Are you available? |cff00ff00%0d|rsec.",this._timeout))
|
|
if (this._timeout<=0) then
|
|
this._timeout = 0
|
|
dialog:Hide()
|
|
end
|
|
end,
|
|
OnAccept = function()
|
|
this._timeout = 0
|
|
sepgp:sendReserverResponce()
|
|
end,
|
|
timeout = 0,--sepgp.VARS.timeout,
|
|
exclusive = 1,
|
|
showAlert = 1,
|
|
whileDead = 1,
|
|
hideOnEscape = 1
|
|
}
|
|
StaticPopupDialogs["SHOOTY_EPGP_CONFIRM_RESET"] = {
|
|
text = "|cffff0000Are you sure you want to Reset ALL EPGP?|r",
|
|
button1 = TEXT(OKAY),
|
|
button2 = TEXT(CANCEL),
|
|
OnAccept = function()
|
|
sepgp:gp_reset_v3()
|
|
end,
|
|
timeout = 0,
|
|
whileDead = 1,
|
|
exclusive = 1,
|
|
showAlert = 1,
|
|
hideOnEscape = 1
|
|
}
|
|
|
|
local sepgp_auto_gp_menu = {
|
|
--{text = "Choose an Action", isTitle = true},
|
|
{text = "Add MainSpec GP", func = function()
|
|
local dialog = StaticPopup_FindVisible("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
if (dialog) then
|
|
local data = dialog.data
|
|
local player, price = data[sepgp.loot_index.player], data[sepgp.loot_index.price]
|
|
sepgp:givename_gp((player==YOU and playerName or player),price)
|
|
data[sepgp.loot_index.action] = sepgp.VARS.msgp
|
|
local update = data[sepgp.loot_index.update] ~= nil
|
|
sepgp:addOrUpdateLoot(data,update)
|
|
StaticPopup_Hide("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
sepgp_loot:Refresh()
|
|
end
|
|
end},
|
|
{text = "Add OffSpec GP", func = function()
|
|
local dialog = StaticPopup_FindVisible("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
if (dialog) then
|
|
local data = dialog.data
|
|
local player, off_price = data[sepgp.loot_index.player], data[sepgp.loot_index.off_price]
|
|
sepgp:givename_gp((player==YOU and playerName or player),off_price)
|
|
data[sepgp.loot_index.action] = sepgp.VARS.osgp
|
|
local update = data[sepgp.loot_index.update] ~= nil
|
|
sepgp:addOrUpdateLoot(data,update)
|
|
StaticPopup_Hide("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
sepgp_loot:Refresh()
|
|
end
|
|
end},
|
|
{text = "Bank or D/E", func = function()
|
|
local dialog = StaticPopup_FindVisible("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
if (dialog) then
|
|
local data = dialog.data
|
|
data[sepgp.loot_index.action] = sepgp.VARS.bankde
|
|
local update = data[sepgp.loot_index.update] ~= nil
|
|
sepgp:addOrUpdateLoot(data,update)
|
|
StaticPopup_Hide("SHOOTY_EPGP_AUTO_GEARPOINTS")
|
|
sepgp_loot:Refresh()
|
|
end
|
|
end}
|
|
}
|
|
StaticPopupDialogs["SHOOTY_EPGP_AUTO_GEARPOINTS"] = {
|
|
text = "%s looted %s. What do you want to do?",
|
|
button1 = "GP Actions",
|
|
button2 = "Remind me Later",
|
|
OnAccept = function()
|
|
sepgp:EasyMenu(sepgp_auto_gp_menu, sepgp._menuFrame, this, 0, 0, "MENU")
|
|
return true
|
|
end,
|
|
OnCancel = function(data,reason)
|
|
if reason == "override" or reason == "clicked" then
|
|
data[sepgp.loot_index.action] = sepgp.VARS.reminder
|
|
local update = data[sepgp.loot_index.update] ~= nil
|
|
sepgp:addOrUpdateLoot(data,update)
|
|
sepgp_loot:Refresh()
|
|
return
|
|
elseif reason == "timeout" then
|
|
return
|
|
end
|
|
end,
|
|
OnShow = function()
|
|
sepgp._menuFrame = sepgp._menuFrame or CreateFrame("Frame", "sepgp_auto_gp_menuframe", UIParent, "UIDropDownMenuTemplate")
|
|
end,
|
|
OnHide = function()
|
|
CloseDropDownMenus()
|
|
end,
|
|
timeout = 0,
|
|
exclusive = 1,
|
|
whileDead = 0,
|
|
hideOnEscape = 1
|
|
}
|
|
|
|
function sepgp:EasyMenu(menuList, menuFrame, anchor, x, y, displayMode)
|
|
if ( displayMode == "MENU" ) then
|
|
menuFrame.displayMode = displayMode
|
|
end
|
|
UIDropDownMenu_Initialize(menuFrame, function() sepgp:EasyMenu_Initialize(level, menuList) end, displayMode, nil, menuList)
|
|
ToggleDropDownMenu(1, nil, menuFrame, anchor, x, y, menuList)
|
|
end
|
|
function sepgp:EasyMenu_Initialize(level, menuList)
|
|
for index = 1, table.getn( menuList ) do
|
|
value = menuList[index]
|
|
if (value.text) then
|
|
value.index = index;
|
|
UIDropDownMenu_AddButton( value, level );
|
|
end
|
|
end
|
|
end
|