Files
shootyepgp/shootyepgp.lua
T

1040 lines
34 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 playerName = (UnitName("player"))
local shooty_basegp = 135
local shooty_baseaward_ep = 100
local shooty_decay = 0.85
local shooty_max = 5000
local shooty_timeout = 45
local shooty_maxloglines = 300
local shooty_reservechan = "Reserves"
local shooty_reservecall = string.format("{shootyepgp}Type \"+\" in this channel if on main, or \"+<MainName>\" if on alt within %dsec.",shooty_timeout)
local shooty_reserveanswer = "^(%+)(%a*)$"
local out = "|cff9664c8shootyepgp:|r %s"
local lastUpdate = 0
local needInit = true
local admin
local shooty_debugchat
local running_check,running_bid
local partyUnit,raidUnit = {},{}
local reserves_blacklist,bids_blacklist = {},{}
do
for i=1,40 do
raidUnit[i] = "raid"..i
end
for i=1,4 do
partyUnit[i] = "party"..i
end
end
sepgp.reserves = {}
sepgp.timer = CreateFrame("Frame")
sepgp.timer.cd_text = ""
sepgp.timer:Hide()
sepgp.timer:SetScript("OnUpdate",function() sepgp.OnUpdate(this,arg1) end)
sepgp.bids_main,sepgp.bids_off,sepgp.bid_item = {},{},{}
function sepgp:OnInitialize() -- ADDON_LOADED (1) unless LoD
if sepgp_saychannel == nil then sepgp_saychannel = "GUILD" end
if sepgp_decay == nil then sepgp_decay = shooty_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
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 (not sepgp_main) or (sepgp_main == "") then
StaticPopup_Show("SHOOTY_EPGP_SET_MAIN")
end
if not self:IsEventScheduled("shootyepgpChannelInit") then
self:ScheduleEvent("shootyepgpChannelInit",self.getReserveStatus,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 tooltip to add our GP values
sepgp:TipHook()
-- make tablets closable with ESC
for i=1,4 do
table.insert(UISpecialFrames,string.format("Tablet20DetachedFrame%d",i))
end
end
function sepgp:OnEnable() -- PLAYER_LOGIN (2)
sepgp:RegisterEvent("GUILD_ROSTER_UPDATE",function()
if (arg1) then -- member join /leave
self:SetRefresh(true)
end
end)
sepgp:RegisterEvent("RAID_ROSTER_UPDATE",function()
self:SetRefresh(true)
end)
sepgp:RegisterEvent("PARTY_MEMBERS_CHANGED",function()
self:SetRefresh(true)
end)
sepgp:RegisterEvent("CHAT_MSG_RAID","captureLootCall")
sepgp:RegisterEvent("CHAT_MSG_RAID_LEADER","captureLootCall")
sepgp:RegisterEvent("CHAT_MSG_RAID_WARNING","captureLootCall")
sepgp:RegisterEvent("CHAT_MSG_WHISPER","captureBid")
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
function sepgp:OnMenuRequest()
D:FeedAceOptionsTable(self:buildMenu())
end
function sepgp:TipHook()
self:SecureHook(GameTooltip, "SetBagItem", function(this, bag, slot)
sepgp:AddDataToTooltip(GameTooltip, GetContainerItemLink(bag, slot))
end
) -- we leave it in for now so they can check if they were billed the correct GP
self:SecureHook(GameTooltip, "SetLootItem", function(this, slot)
sepgp:AddDataToTooltip(GameTooltip, GetLootSlotLink(slot))
end
)
self:SecureHook(GameTooltip, "SetLootRollItem", function(this, id)
sepgp:AddDataToTooltip(GameTooltip, GetLootRollItemLink(id))
end
)
self:SecureHook("SetItemRef", function(link, name, button)
if (link and name and ItemRefTooltip) then
if (strsub(link, 1, 6) ~= "Player") then
if (ItemRefTooltip:IsVisible()) then
if (not DressUpFrame:IsVisible()) then
sepgp:AddDataToTooltip(ItemRefTooltip, link)
end
ItemRefTooltip.isDisplayDone = nil
end
end
end
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:getReserveStatus()
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
sepgp:reservesToggle(true)
end
end
function sepgp:AddDataToTooltip(tooltip,itemlink,itemstring)
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 textRight = string.format("cost:|cff32cd32%d|r offspec:|cff20b2aa%d|r",price,math.floor(price*sepgp_discount))
if (tooltip:NumLines() < 29) then
tooltip:AddLine(" ")
tooltip:AddDoubleLine("|cff9664c8shootyepgp|r",textRight)
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:AddDoubleLine("|cff9664c8shootyepgp|r",textRight)
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
-------------------
-- 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))
sepgp:flashFrame(shooty_debugchat)
else
sepgp: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: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
---------------------
-- EPGP Operations
---------------------
function sepgp:init_notes(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) < shooty_basegp) then
GuildRosterSetOfficerNote(guild_index,shooty_basegp)
end
end
function sepgp:update_ep(getname,ep)
for i = 1, GetNumGuildMembers(1) do
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
if (name==getname) then
sepgp:init_notes(i,note,officernote)
GuildRosterSetPublicNote(i,ep)
end
end
end
function sepgp:update_gp(getname,gp)
for i = 1, GetNumGuildMembers(1) do
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
if (name==getname) then
sepgp:init_notes(i,note,officernote)
GuildRosterSetOfficerNote(i,gp)
end
end
end
function sepgp:get_ep(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_gp(getname,officernote) -- gets gp by name or officernote
if (officernote) then
if tonumber(officernote)==nil then return shooty_basegp end
end
for i = 1, GetNumGuildMembers(1) do
local name, _, _, _, class, _, note, officernote, _, _ = GetGuildRosterInfo(i)
if tonumber(officernote)==nil then officernote=shooty_basegp end
if (name==getname) then return tonumber(officernote) end
end
return(shooty_basegp)
end
function sepgp:award_raid_ep(ep) -- awards ep to raid members in zone
if GetNumRaidMembers()>0 then
sepgp:simpleSay(string.format("Giving %d ep to all raidmembers",ep))
self:addToLog(string.format("Giving %d ep to all raidmembers",ep))
for i = 1, GetNumRaidMembers(true) do
local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i)
sepgp:givename_ep(name,ep)
end
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.shooty_reserves) > 0 then
sepgp:simpleSay(string.format("Giving %d ep to active reserves",ep))
self:addToLog(string.format("Giving %d ep to active reserves",ep))
for i, name in ipairs(sepgp.shooty_reserves) do
sepgp:givename_ep(name,ep)
end
sepgp.reserves = {}
reserves_blacklist = {}
end
end
function sepgp:givename_ep(getname,ep) -- awards ep to a single character
if not (admin()) then return end
sepgp:debugPrint(string.format("Giving %d ep to %s",ep,getname))
ep = ep + sepgp:get_ep(getname)
sepgp:update_ep(getname,ep)
end
function sepgp:givename_gp(getname,gp) -- assigns gp to a single character
if not (admin()) then return end
sepgp:debugPrint(string.format("Giving %d gp to %s",gp,getname))
local oldgp = sepgp:get_gp(getname)
local newgp = gp + oldgp
sepgp:adminSay(string.format("Awarding %d GP to %s. (Previous: %d, New: %d)",gp,getname,oldgp,newgp))
self:addToLog(string.format("Awarding %d GP to %s. (Previous: %d, New: %d)",gp,getname,oldgp,newgp))
sepgp:update_gp(getname,newgp)
end
function sepgp:decay_epgp() -- 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
ep = math.max(0,sepgp:num_round(ep*sepgp_decay))
GuildRosterSetPublicNote(i,ep)
gp = math.max(shooty_basegp,sepgp:num_round(gp*sepgp_decay))
GuildRosterSetOfficerNote(i,gp)
end
end
local msg = string.format("All EP and GP decayed by %d%%",(1-sepgp_decay)*100)
sepgp:simpleSay(msg)
if not (sepgp_saychannel=="OFFICER") then sepgp:adminSay(msg) end
self:addToLog(msg)
end
function sepgp:gp_reset()
if (IsGuildLeader()) then
for i = 1, GetNumGuildMembers(1) do
GuildRosterSetOfficerNote(i, shooty_basegp)
end
sepgp:debugPrint(string.format("All GP has been reset to %d.",shooty_basegp))
self:adminSay(string.format("All GP has been reset to %d.",shooty_basegp))
self:addToLog(string.format("All GP has been reset to %d.",shooty_basegp))
end
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 Logs.")
else
hint = string.format(hint,"")
end
T:SetHint(hint)
end
function sepgp:OnClick()
local is_admin = admin()
if (IsControlKeyDown() and is_admin) then
sepgp_reserves:Toggle()
elseif (IsAltKeyDown() and is_admin) then
sepgp_bids:Toggle()
elseif (IsShiftKeyDown() and is_admin) then
sepgp_logs: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 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 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) < shooty_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 < shooty_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 < shooty_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.",
order = 90,
get = function() return sepgp_progress end,
set = function(v) sepgp_progress = v sepgp_bids:Refresh() 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 %d%%",(1-(sepgp_decay or shooty_decay))*100),
order = 100,
hidden = function() return not (admin()) end,
func = function() sepgp:decay_epgp() end
}
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) 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 / Resistance Items GP Percent.",
order = 115,
get = function() return sepgp_discount end,
set = function(v) sepgp_discount = v end,
min = 0,
max = 1,
step = 0.05,
isPercent = true
}
options.args["reset"] = {
type = "execute",
name = "Reset GP",
desc = string.format("gives everybody %d basic GP (Admin only).",shooty_basegp),
order = 120,
hidden = function() return not (IsGuildLeader()) end,
func = function() StaticPopup_Show("SHOOTY_EPGP_CONFIRM_RESET_GP") 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
sepgp:RegisterEvent("CHAT_MSG_CHANNEL","captureReserveChatter")
end
return true
else
sepgp:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE","reservesChannelChange")
JoinChannelByName(sepgp_reservechannel)
return
end
else -- we want out
if (reservesChannelID) and reservesChannelID ~= 0 then
sepgp:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE","reservesChannelChange")
LeaveChannelByName(sepgp_reservechannel)
return
else
if sepgp:IsEventRegistered("CHAT_MSG_CHANNEL") then
sepgp: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)
sepgp:RegisterEvent("CHAT_MSG_CHANNEL","captureReserveChatter")
elseif msg == "YOU_LEFT" then
sepgp.reservesChannelID = nil
if sepgp:IsEventRegistered("CHAT_MSG_CHANNEL") then
sepgp:UnregisterEvent("CHAT_MSG_CHANNEL")
end
end
sepgp: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 = shooty_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 sepgp:inRaid(name)) then
reserve, reserve_class, reserve_rank = sepgp:verifyGuildMember(name)
if reserve ~= sender then
reserve_alt = sender
end
end
else
if (not sepgp:inRaid(sender)) then
reserve, reserve_class, reserve_rank = sepgp: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
sepgp: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
sepgp: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 sepgp: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 (IsRaidLeader() or self:lootMaster()) then return end
if not sender == playerName then return end
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
self:clearBids()
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,360,self)
running_bid = true
self:debugPrint("Capturing Bids for 6min.")
sepgp_bids:Toggle(true)
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(name,note)
local gp = self:get_gp(name,officernote)
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)
sepgp_bids:Refresh()
return
end
end
end
end
end
end
function sepgp:clearBids()
sepgp:defaultPrint("clearBids")
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:Refresh()
end
------------
-- Logging
------------
function sepgp:addToLog(line,skipTime)
local over = table.getn(sepgp_log)-shooty_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)
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 ~= "" then
sepgp: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 shooty_baseaward_ep
else
multiplier = zone_multipliers[sepgp_progress][currentTier]
end
if (multiplier) then
return multiplier*shooty_baseaward_ep
else
return shooty_baseaward_ep
end
end
admin = function()
return (CanEditOfficerNote() and CanEditPublicNote())
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 = "Reserves: AFKCheck. Are you available?",
button1 = TEXT(YES),
button2 = TEXT(NO),
OnAccept = function()
sepgp:sendReserverResponce()
end,
timeout = shooty_timeout,
exclusive = 1,
showAlert = 1,
whileDead = 1,
hideOnEscape = 1
}
StaticPopupDialogs["SHOOTY_EPGP_CONFIRM_RESET_GP"] = {
text = "|cffff0000Are you sure you want to Reset ALL GP?|r",
button1 = TEXT(OKAY),
button2 = TEXT(CANCEL),
OnAccept = function()
sepgp:gp_reset()
end,
timeout = 0,
whileDead = 1,
exclusive = 1,
showAlert = 1,
hideOnEscape = 1
};