diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index a05d856..d6c9494 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -6,7 +6,7 @@ Fix: Was spamming "released" on main window closing
Fix: Another step in hide and seek with Master Plan. Use GC Interface now works also with MP 0.22.1. This fix also reenables Garrison Mission Manager
Fix: A minor incompatibility wuth some addons was causing them to display very small menus in some options pages. Thanks to Goldshire for pointing it
* 2.1.2
-Fix: Mission should appear sorted as requested bith on startup and after a mission completion
+Fix: Mission should appear sorted as requested both on startup and after a mission completion
Fix: Removed a couple fo rare lua error
* 2.1.1
Feature: Countered mechanics are now shown in standard mission button both in big and small screen mode
@@ -14,9 +14,9 @@ Feature: New sort method: mission age
Fix: Changed key for "skip auto fill" from shift to ctrl. Now it works
Fix: In mission page, counter ability were not shown in follower icon
* 2.1.0
-Feature: new layout is now optional, you can revert to 1.1.8 leayout disabling "big screen"
+Feature: new layout is now optional, you can revert to 1.1.8 layout disabling "big screen"
Feature: Mission page autopopulation is now optional
-Feature: If Master Plan is detecte, you can choose which layout you want between GC's one and MP's one
+Feature: If Master Plan is detected, you can choose which layout you want between GC's one and MP's one
Fix: error "Message: ...rface\AddOns\GarrisonCommander\GarrisonCommander.lua:930: attempt to compare number with nil"
* 2.0.1
Fixed: RU,KR,CH (both traditional and simplified) locales where broken
diff --git a/GarrisonCommander.lua b/GarrisonCommander.lua
index 7a08015..c7e2218 100644
--- a/GarrisonCommander.lua
+++ b/GarrisonCommander.lua
@@ -1,14 +1,24 @@
local me, ns = ...
local _G=_G
-local addon=LibStub("LibInit"):NewAddon(me,'AceHook-3.0','AceTimer-3.0','AceEvent-3.0') --#Addon
+local pp=print
+--@debug@
+ LoadAddOn("Blizzard_DebugTools")
+--@end-debug@
+local addon=LibStub("LibInit"):NewAddon(me,'AceHook-3.0','AceTimer-3.0','AceEvent-3.0','AceBucket-3.0') --#Addon
local AceGUI=LibStub("AceGUI-3.0")
local D=LibStub("LibDeformat-3.0")
local C=addon:GetColorTable()
local L=addon:GetLocale()
local print=addon:Wrap("Print")
-local xprint=function(...) print("DBG",...) end
local trace=addon:Wrap("Trace")
local xprint=function() end
+local xdump=function() end
+local xtrace=function() end
+--@debug@
+--xprint=function(...) print("DBG",...) end
+--xdump=function(d,t) print(t) DevTools_Dump(d) end
+--xtrace=trace
+--@end-debug@
local pairs=pairs
local select=select
local next=next
@@ -27,12 +37,12 @@ local bigscreen=true
local GMM=false
local MP=false
local MPGoodGuy=false
-local ttcalled=false
-local rendercalled=false
local MPSwitch
local dbg=false
-
---@debug@
+local trc=false
+local pin=false
+local baseHeight
+local minHeight
if (LibDebug) then LibDebug() end
local function tcopy(obj, seen)
if type(obj) ~= 'table' then return obj end
@@ -87,71 +97,21 @@ local function capitalize(s)
s=tostring(s)
return strupper(s:sub(1,1))..strlower(s:sub(2))
end
--- Name is here just for doc, I will be using the localized one
-
-local _abilities={
- {
- ["name"] = "Wild Aggression",
- ["icon"] = "Interface\\ICONS\\Spell_Nature_Reincarnation.blp",
- }, -- [1]
- {
- ["name"] = "Massive Strike",
- ["icon"] = "Interface\\ICONS\\Ability_Warrior_SavageBlow.blp",
- }, -- [2]
- {
- ["name"] = "Group Damage",
- ["icon"] = "Interface\\ICONS\\Spell_Fire_SelfDestruct.blp",
- }, -- [3]
- {
- ["name"] = "Magic Debuff",
- ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp",
- }, -- [4]
- nil, -- [5]
- {
- ["name"] = "Danger Zones",
- ["icon"] = "Interface\\ICONS\\spell_Shaman_Earthquake.blp",
- }, -- [6]
- {
- ["name"] = "Minion Swarms",
- ["icon"] = "Interface\\ICONS\\Spell_DeathKnight_ArmyOfTheDead.blp",
- }, -- [7]
- {
- ["name"] = "Powerful Spell",
- ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp",
- }, -- [8]
- {
- ["name"] = "Deadly Minions",
- ["icon"] = "Interface\\ICONS\\Achievement_Boss_TwinOrcBrutes.blp",
- }, -- [9]
- {
- ["name"] = "Timed Battle",
- ["icon"] = "Interface\\ICONS\\SPELL_HOLY_BORROWEDTIME.BLP",
- }, -- [10]
-}
-local abilities={}
-
-local function getAbilityName(texture)
- for i=1,#abilities do
- if (abilities[i] and abilities[i].icon==texture) then
- return abilities[i].name
- end
- end
- return "unknown"
-end
--- upvalues
+--
local AVAILABLE=AVAILABLE -- "Available"
local BUTTON_INFO=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS.. " " .. GARRISON_MISSION_PERCENT_CHANCE
local ENVIRONMENT_SUBHEADER=ENVIRONMENT_SUBHEADER -- "Environment"
local G=C_Garrison
-local GARRISON_BUILDING_SELECT_FOLLOWER_TITLE=GARRISON_BUILDING_SELECT_FOLLOWER_TITLE -- "Select a Follower";
-local GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP=GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP -- "Click here to assign a Follower";
-local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
-local GARRISON_FOLLOWER_CAN_COUNTER=GARRISON_FOLLOWER_CAN_COUNTER -- "This follower can counter:"
-local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
-local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
-local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
-local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
-local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
+--local GARRISON_BUILDING_SELECT_FOLLOWER_TITLE=GARRISON_BUILDING_SELECT_FOLLOWER_TITLE -- "Select a Follower";
+--local GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP=GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP -- "Click here to assign a Follower";
+--local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
+--local GARRISON_FOLLOWER_CAN_COUNTER=GARRISON_FOLLOWER_CAN_COUNTER -- "This follower can counter:"
+--local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
+--local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
+--local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
+--local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
+--local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
local GARRISON_MISSION_PERCENT_CHANCE="%d%%"-- GARRISON_MISSION_PERCENT_CHANCE
local GARRISON_MISSION_SUCCESS=GARRISON_MISSION_SUCCESS -- "Success"
local GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS -- "%d Follower mission";
@@ -164,6 +124,7 @@ local GARRISON_FOLLOWER_MAX_UPGRADE_QUALITY=GARRISON_FOLLOWER_MAX_UPGRADE_QUALIT
local GARRISON_FOLLOWER_MAX_LEVEL=GARRISON_FOLLOWER_MAX_LEVEL -- 100
local LEVEL=LEVEL -- Level
+local MISSING=ADDON_MISSING
local NOT_COLLECTED=NOT_COLLECTED -- not collected
local GMF=GarrisonMissionFrame
local GMFFollowerPage=GMF.FollowerTab
@@ -171,9 +132,6 @@ local GMFFollowers=GarrisonMissionFrameFollowers
local GMFMissionPage=GMF.MissionTab.MissionPage
local GMFMissionPageFollowers = GMFMissionPage.Followers
local GMFMissions=GarrisonMissionFrameMissions
-local GMFMissionsTab1=GarrisonMissionFrameMissionsTab1
-local GMFMissionsTab2=GarrisonMissionFrameMissionsTab2
-local GMFMissionsTab3=GarrisonMissionFrameMissionsTab2
local GMFRewardPage=GMF.MissionComplete
local GMFRewardSplash=GMFMissions.CompleteDialog
local GMFMissionsListScrollFrameScrollChild=GarrisonMissionFrameMissionsListScrollFrameScrollChild
@@ -181,12 +139,9 @@ local GMFMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
local GMFFollowersListScrollFrameScrollChild=GarrisonMissionFrameFollowersListScrollFrameScrollChild
local GMFFollowersListScrollFrame=GarrisonMissionFrameFollowersListScrollFrame
local GMFMissionListButtons=GMF.MissionTab.MissionList.listScroll.buttons
-local GMFTab1=GarrisonMissionFrameTab1
-local GMFTab2=GarrisonMissionFrameTab2
-local GMFTab3=_G.GarrisonMissionFrameTab3
local GarrisonFollowerTooltip=GarrisonFollowerTooltip
local GarrisonMissionFrameMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
-local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE .. ' ' .. GARRISON_FOLLOWERS
+local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE
local IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=IGNORE.. ' ' .. GARRISON_FOLLOWER_INACTIVE .. ',' .. GARRISON_FOLLOWER_ON_MISSION ..',' .. GARRISON_FOLLOWER_WORKING.. ' ' .. GARRISON_FOLLOWERS
local PARTY=PARTY -- "Party"
local SPELL_TARGET_TYPE1_DESC=capitalize(SPELL_TARGET_TYPE1_DESC) -- any
@@ -214,6 +169,11 @@ local function splitFormat(base)
local G2=G:sub(1,i-1)..m1..G:sub(s+1)
return G1,G2
end
+local function ShowTT(this)
+ GameTooltip:SetOwner(this, "ANCHOR_TOPRIGHT")
+ GameTooltip:SetText(this.tooltip)
+ GameTooltip:Show()
+end
local GARRISON_DURATION_DAY,GARRISON_DURATION_DAYS=splitFormat(GARRISON_DURATION_DAYS) -- "%d |4day:days;";
local GARRISON_DURATION_DAY_HOURS,GARRISON_DURATION_DAYS_HOURS=splitFormat(GARRISON_DURATION_DAYS_HOURS) -- "%d |4day:days; %d hr";
@@ -221,8 +181,8 @@ local GARRISON_DURATION_HOURS=GARRISON_DURATION_HOURS -- "%d hr";
local GARRISON_DURATION_HOURS_MINUTES=GARRISON_DURATION_HOURS_MINUTES -- "%d hr %d min";
local GARRISON_DURATION_MINUTES=GARRISON_DURATION_MINUTES -- "%d min";
local GARRISON_DURATION_SECONDS=GARRISON_DURATION_SECONDS -- "%d sec";
-local AGE_HOURS="First seen " .. GARRISON_DURATION_HOURS_MINUTES .. " ago"
-local AGE_DAYS="First seen " .. GARRISON_DURATION_DAYS_HOURS .. " ago"
+local AGE_HOURS="Expires in " .. GARRISON_DURATION_HOURS_MINUTES
+local AGE_DAYS="Expires in " .. GARRISON_DURATION_DAYS_HOURS
-- Panel sizes
@@ -236,6 +196,8 @@ local FLSIZE=400
local BIGBUTTON=BIGSIZEW-GCSIZE
local SMALLBUTTON=BIGSIZEW-GCSIZE
local GCF
+local GMC
+local GMCUsedFollowers={}
local GCFMissions
local GCFBusyStatus
local GameTooltip=GameTooltip
@@ -250,6 +212,10 @@ local GarrisonMissionButton_SetRewards=GarrisonMissionButton_SetRewards
local GetItemInfo=GetItemInfo
local type=type
local ITEM_QUALITY_COLORS=ITEM_QUALITY_COLORS
+function addon:GetDifficultyColors(perc,usePurple)
+ local q=self:GetDifficultyColor(perc,usePurple)
+ return q.r,q.g,q.b
+end
function addon:GetDifficultyColor(perc,usePurple)
if(perc >90) then
return QuestDifficultyColors['standard']
@@ -260,7 +226,7 @@ function addon:GetDifficultyColor(perc,usePurple)
elseif(perc >20) then
return QuestDifficultyColors['impossible']
else
- return not usePurple and QuestDifficultyColors['trivial'] or C.Purple
+ return not usePurple and C.Silver or C.Fuchsia
end
end
if (LibDebug) then LibDebug() end
@@ -278,6 +244,7 @@ local followersCacheIndex={}
local dirty=false
local cache
local dbcache
+local db
local n=setmetatable({},{
__index = function(t,k)
local name=addon:GetFollowerData(k,'fullname')
@@ -317,6 +284,39 @@ local function genIteratorByThreat(missionID,threat,tbl)
end
end
+--- Quick backdrop
+--
+local function addBackdrop(f)
+ local backdrop = {
+ bgFile="Interface\\TutorialFrame\\TutorialFrameBackground",
+ edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
+ tile=true,
+ tileSize=16,
+ edgeSize=16,
+ insets={bottom=7,left=7,right=7,top=7}
+ }
+ f:SetBackdrop(backdrop)
+end
+
+--generic table scan
+
+local function inTable(table, value)
+ if (type(table)~='table') then return false end
+ if (#table > 0) then
+ for i=1,#table do
+ if (value==table[i]) then return true end
+ end
+ else
+ for k,v in pairs(table) do
+ if v == value then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+
--- Parties storage
--
--
@@ -324,12 +324,7 @@ local parties=setmetatable({},{
__index=function(t,k) rawset(t,k,{members={},perc=0,full=false}) return t[k] end
})
local function inParty(missionID,followerID)
- local members=parties[missionID].members
- if (dbg) then print("Party check",missionID) end
- for i=1,#members do
- if (dbg) then print("Checking",members[i],"against",followerID) end
- if (members[i]==followerID) then return true end
- end
+ return inTable(parties[missionID].members,followerID)
end
--- Follower Missions Info
--
@@ -339,11 +334,11 @@ local followerMissions=setmetatable({},{
--
-- Temporary party management
-local openParty,isInParty,pushFollower,removeFollower,closeParty,roomInParty,storeFollowers,dumpParty
+local openParty,partyIgnore,isPartyIgnored,isInParty,pushFollower,removeFollower,fillParty,closeParty,roomInParty,storeFollowers,dumpParty,isPartyEmpty
do
- local ID,frames,members,maxFollowers=0,{},{},1
- ---@function [parent=#local] openParty
+ local ID,frames,members,maxFollowers,ignored=0,{},{},1,{}
+ ---@function [parent=#party] openParty
function openParty(missionID,followers)
if (#frames > 0 or #members > 0) then
error(format("Unbalanced openParty/closeParty %d %d",#frames,#members))
@@ -355,28 +350,41 @@ do
end
ID=missionID
end
- ---@function [parent=#local] isInParty
+
+ ---@function [parent=#party] partyIgnore
+ function partyIgnore(followerID,soft)
+ ignored[followerID]=soft and 1 or 2
+ end
+ ---@function [parent=#party] isPartyIgnored
+ function isPartyIgnored(followerID)
+ return ignored[followerID]
+ end
+
+ ---@function [parent=#party] isInParty
function isInParty(followerID)
- for i=1,maxFollowers do
- if (followerID==members[i]) then return true end
- end
+ return inTable(members,followerID)
end
- ---@function [parent=#local] roomInParty
+ ---@function [parent=#party] roomInParty
function roomInParty()
return maxFollowers-#members
end
- ---@function [parent=#local] dumpParty
+ ---@function [parent=#party] isPartyEmpty
+ function isPartyEmpty()
+ return maxFollowers>0 and #members==0
+ end
+
+ ---@function [parent=#party] dumpParty
function dumpParty()
for i=1,3 do
if (members[i]) then
- print(i,addob:GetFollowerData(members[i],'fullname'))
+ xprint(i,addon:GetFollowerData(members[i],'fullname'))
end
end
end
- ---@function [parent=#local] pushFollower
+ ---@function [parent=#party] pushFollower
function pushFollower(followerID)
if (followerID:sub(1,2) ~= '0x') then trace(followerID .. "is not an id") end
if (roomInParty()>0) then
@@ -391,7 +399,7 @@ do
end
end
end
- ---@function [parent=#local] removeFollowers
+ ---@function [parent=#party] removeFollowers
function removeFollower(followerID)
for i=1,maxFollowers do
if (followerID==members[i]) then
@@ -404,7 +412,7 @@ do
end
end
- ---@function [parent=#local] storeFollowers
+ ---@function [parent=#party] storeFollowers
function storeFollowers(table)
wipe(table)
for i=1,#members do
@@ -412,8 +420,22 @@ do
end
return #table
end
+ ---@function [parent=#party] fillParty
+ function fillParty()
+ if roomInParty() < 1 then return end
+ for followerID,soft in pairs(ignored) do
+ if soft==1 then
+ if not isInParty(followerID) then
+ pushFollower(followerID)
+ end
+ if (roomInParty()<=0) then
+ break
+ end
+ end
+ end
+ end
- ---@function [parent=#local] closeParty
+ ---@function [parent=#party] closeParty
function closeParty()
local perc=select(4,G.GetPartyMissionInfo(ID))
for i=1,3 do
@@ -433,7 +455,8 @@ do
end
wipe(frames)
wipe(members)
- return perc
+ wipe(ignored)
+ return perc or 0
end
end
--
@@ -441,14 +464,12 @@ end
local origGarrisonMissionButton_OnEnter = _G.GarrisonMissionButton_OnEnter
function _G.GarrisonMissionButton_OnEnter(this,button)
origGarrisonMissionButton_OnEnter(this,button)
+ --@debug@
if (this.info.inProgress) then
GameTooltip:AddDoubleLine("ID:",this.info.missionID)
- for i=1,#this.info.followers do
- GameTooltip:AddDoubleLine("ID:",this.info.followers[i])
- GameTooltip:AddDoubleLine("Name:",addon:GetFollowerData(this.info.followers[i],'fullname'))
- end
GameTooltip:Show()
end
+ --@end-debug@
end
--@end-debug@
-- These local will became conf var
@@ -508,34 +529,70 @@ function addon.Garrison_SortMissions_Followers(missionsList)
end
table.sort(missionsList, comparison);
end
+function addon.Garrison_SortMissions_Xp(missionsList)
+ local comparison
+ do
+ function comparison(mission1, mission2)
+ local p1=addon:GetMissionData(mission1.missionID,'globalXp')
+ local p2=addon:GetMissionData(mission2.missionID,'globalXp')
+ if (p1==p2) then
+ return strcmputf8i(mission1.name, mission2.name) < 0
+ else
+ return p2 < p1
+ end
+ end
+ end
+ table.sort(missionsList, comparison);
+end
function addon:OnInitialized()
--@debug@
xprint("OnInitialized")
- LoadAddOn("Blizzard_DebugTools")
- self:DebugEvents()
--@end-debug@
+--@alpha@
+ self:Popup(L["You are using an Alpha version of Garrison Commander. Please post bugs on Curse if you find them"],10)
+--@end-alpha@
+ for _,b in ipairs(GMFMissionsListScrollFrame.buttons) do
+ local scale=0.8
+ local f,h,s=b.Title:GetFont()
+ b.Title:SetFont(f,h*scale,s)
+ local f,h,s=b.Summary:GetFont()
+ b.Summary:SetFont(f,h*scale,s)
+ end
self:CreatePrivateDb()
+ db=self.db.global
self:SafeRegisterEvent("GARRISON_MISSION_STARTED")
self:SafeRegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE")
self:SafeRegisterEvent("GARRISON_MISSION_NPC_CLOSED",function(...) GCF:Hide() end)
self:SafeHookScript("GarrisonMissionFrame","OnShow","SetUp",true)
+ self:AddLabel("Appearance")
self:AddToggle("MOVEPANEL",true,L["Unlock Panel"])
+ self:AddToggle("BIGSCREEN",true,L["Use big screen"],L["Disabling this will give you the interface from 1.1.8, given or taken. Need to reload interface"])
+ self:AddToggle("PIN",true,L["Show Garrison Commander menu"],L["Disable if you dont want the full Garrison Commander Header."])
+ self:AddLabel("Mission Panel")
self:AddToggle("IGM",true,IGNORE_UNAIVALABLE_FOLLOWERS,IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL)
- self:AddToggle("IGP",true,L['Ignore "maxed" followers'],L["Level 100 epic followers are not used for match making unless they are needed to fill up the roster."])
- self:AddToggle("NOFILL",false,L["Do not prefill mission page"],L["Disables automatic population of mission page screen. You can also press control while clicking to disable it for a single mission"])
+ self:AddToggle("IGP",true,L['Ignore "maxed"'],L["Level 100 epic followers are not used for xp only missions."])
+ self:AddToggle("NOFILL",false,L["No mission prefill"],L["Disables automatic population of mission page screen. You can also press control while clicking to disable it for a single mission"])
self:AddSelect("MSORT","Garrison_SortMissions_Original",
{
Garrison_SortMissions_Original=L["Original method"],
Garrison_SortMissions_Chance=L["Success Chance"],
Garrison_SortMissions_Followers=L["Number of followers"],
Garrison_SortMissions_Age=L["Days since first seen"],
+ Garrison_SortMissions_Xp=L["Global approx. xp reward"],
},
L["Sort missions by:"],L["Original sort restores original sorting method, whatever it was (If you have another addon sorting mission, it should kick in again)"])
- self:AddToggle("BIGSCREEN",true,L["Use big screen"],L["Disabling this will give you the interface from 1.1.8, given or taken. Need to reload interface"])
bigscreen=self:GetBoolean("BIGSCREEN")
+ self:AddLabel("Followers Panel")
self:AddSlider("MAXMISSIONS",5,1,8,L["Mission shown for follower"],nil,1)
self:AddSlider("MINPERC",50,0,100,L["Minimun chance success under which ignore missions"],nil,5)
+ self:AddPrivateAction("ShowMissionControl",L["Mission control"],L["You can choose some criteria and have GC autosumbit missions for you"])
+--@debug@
+ self:AddLabel("Developers options")
+ self:AddToggle("DBG",false, "Enable Debug")
+ self:AddToggle("TRC",false, "Enable Trace")
+--@end-debug@
+
self:Trigger("MSORT")
return true
end
@@ -547,6 +604,7 @@ function addon:CheckMP()
return
end
if GetAddOnMetadata("MasterPlan","Version")>="0.23" then
+ -- New compatible version
self:AddToggle("CKMP",true,L["Use GC Interface"],L["Switches between Garrison Commander and Master Plan mission interface. Tested with MP >0.23"])
MPGoodGuy=true
MPSwitch=true
@@ -567,14 +625,24 @@ function addon:ApplyIGM(value)
self:RefreshMission()
end
function addon:ApplyCKMP(value)
+ self:Clock()
if (MasterPlanMissionList) then
if (value) then
MasterPlanMissionList:Hide()
else
MasterPlanMissionList:Show()
end
- self:RefreshMission()
end
+ self:RefreshMission()
+end
+function addon:ApplyDBG(value)
+ dbg=value
+end
+function addon:ApplyPIN(value)
+ pin=value
+end
+function addon:ApplyTRC(value)
+ trc=value
end
function addon:ApplyBIGSCREEN(value)
if (value) then
@@ -623,8 +691,6 @@ function addon:RestoreTooltip()
end
end
-
-
--[[
[12]={
description="Iron Horde raiders have descended on nearby draenei villages. Find the raiders' camp and raid it. Turnabout, they say, is fair play.",
@@ -723,66 +789,47 @@ function addon:FillCounters(missionID,mission)
local slots=mission.slots
local missioncounters=counters[missionID]
wipe(missioncounters)
- for id,d in pairs(G.GetBuffedFollowersForMission(missionID)) do
- local rank=self:GetFollowerData(id,'rank')
- local quality=self:GetFollowerData(id,'quality')
- local bias= G.GetFollowerBiasForMission(missionID,id);
- for i,l in pairs(d) do
- -- i is meaningful
- -- l.counterIcon
- -- l.name
- -- l.counterName
- -- l.icon
- -- l.description
- tinsert(missioncounters,{k=cleanicon(l.icon),mechanic=true,name=l.name,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
- followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
- end
- end
- for id,d in pairs(G.GetFollowersTraitsForMission(missionID)) do
- local bias= G.GetFollowerBiasForMission(missionID,id);
- local rank=self:GetFollowerData(id,'rank')
- local quality=self:GetFollowerData(id,'quality')
- for i,l in pairs(d) do
- --l.traitID
- --l.icon
- followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
- tinsert(missioncounters,{k=cleanicon(l.icon),trait=true,name=l.traitID,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
- end
- end
- table.sort(missioncounters,cmp)
- local cf=wipe(counterFollowerIndex[missionID])
- local ct=wipe(counterThreatIndex[missionID])
- for i=1,#missioncounters do
- tinsert(cf[missioncounters[i].followerID],i)
- tinsert(ct[missioncounters[i].k],i)
- end
-end
-function addon:Check(missionID)
-
-end
-function addon:ThreatDisplayer()
- TF="0x00000000000C2C1B"
- if (not AXE) then
- local AXE=CreateFrame("Frame","AXE",UIParent,"GarrisonAbilityLargeCounterTemplate")
- AXI=CreateFrame("Frame","AXI",UIParent,"GarrisonAbilityCounterTemplate")
- end
- if (not BUBU) then
- CreateFrame("CheckButton","BUBU",AXE,"UICheckButtonTemplate")
- end
-
- BUBU:SetPoint("CENTER")
- BUBU:SetChecked(true)
- BUBU:GetCheckedTexture():SetVertexColor(1,0,0)
-
- AXE:SetPoint("CENTER",-100.0)
- AXI:SetPoint("CENTER",100,0)
- AXE:Show()
- AXI:Show()
- local id=154
- local env=select(5,C_Garrison.GetMissionInfo(id))
- AXI.Icon:SetTexture(env)
- AXI.Border:SetVertexColor(1,0,0)
+ local t=G.GetBuffedFollowersForMission(missionID)
+ if t then
+ for id,d in pairs(t) do
+ local rank=self:GetFollowerData(id,'rank')
+ local quality=self:GetFollowerData(id,'quality')
+ local bias= G.GetFollowerBiasForMission(missionID,id);
+ for i,l in pairs(d) do
+ -- i is meaningful
+ -- l.counterIcon
+ -- l.name
+ -- l.counterName
+ -- l.icon
+ -- l.description
+ tinsert(missioncounters,{k=cleanicon(l.icon),mechanic=true,name=l.name,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
+ followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
+ end
+ end
+ end
+ t= G.GetFollowersTraitsForMission(missionID)
+ if t then
+ for id,d in pairs(t) do
+ local bias= G.GetFollowerBiasForMission(missionID,id);
+ local rank=self:GetFollowerData(id,'rank')
+ local quality=self:GetFollowerData(id,'quality')
+ for i,l in pairs(d) do
+ --l.traitID
+ --l.icon
+ followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
+ tinsert(missioncounters,{k=cleanicon(l.icon),trait=true,name=l.traitID,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
+ end
+ end
+ table.sort(missioncounters,cmp)
+ local cf=wipe(counterFollowerIndex[missionID])
+ local ct=wipe(counterThreatIndex[missionID])
+ for i=1,#missioncounters do
+ tinsert(cf[missioncounters[i].followerID],i)
+ tinsert(ct[missioncounters[i].k],i)
+ end
+ end
end
+
--[[
Matchmaker debug for Spell Check
Slots
@@ -890,6 +937,28 @@ local function best(fid1,fid2,counters)
end
return fid1
end
+local epicMountTrait=221
+local extraTrainingTrait=80 --all followers +35
+local fastLearnerTrait=29 -- only this follower +50
+local hearthStoneProTrait=236 -- all followers +36
+local scavengerTrait=79 -- More resources
+function addon:AddTraitsToParty(missionID,mission,skipBusy,skipMaxed)
+ local t=counters[missionID]
+ if (t) then
+ for i=1,#t do
+ local follower=t[i]
+ if (follower.trait and not isPartyIgnored(follower.followerID) and not isInParty(follower.followerID)) then
+ if mission.resources > 0 and follower.name==scavengerTrait then
+ pushFollower(follower.followerID)
+ elseif mission.xpOnly and (follower.name==extraTrainingTrait or follower.name==hearthStoneProTrait) then
+ pushFollower(follower.followerID)
+ elseif mission.durationSeconds > GARRISON_LONG_MISSION_TIME and follower.name==epicMountTrait then
+ pushFollower(follower.followerID)
+ end
+ end
+ end
+ end
+end
function addon:CompleteParty(missionID,mission,skipBusy,skipMaxed)
local perc=select(4,G.GetPartyMissionInfo(missionID)) -- If percentage is already 100, I'll try and add the most useless character
local candidateMissions=10000
@@ -906,7 +975,7 @@ function addon:CompleteParty(missionID,mission,skipBusy,skipMaxed)
for i=1,totFollowers do
local data=followersCache[i]
local followerID=data.followerID
- if (not self:IsIgnored(followerID,missionID) and not(skipMaxed and data.maxed) and not isInParty(followerID) and self:GetFollowerStatusForMission(followerID,skipBusy)) then
+ if (not isPartyIgnored(followerID) and not isInParty(followerID) and not self:IsIgnored(followerID,missionID) and not(skipMaxed and data.maxed and mission.xpOnly) and not isInParty(followerID) and self:GetFollowerStatusForMission(followerID,skipBusy)) then
local missions=#followerMissions[followerID]
local rank=data.rank
local quality=data.quality
@@ -926,7 +995,7 @@ function addon:CompleteParty(missionID,mission,skipBusy,skipMaxed)
break --continue
end
end
- -- This candidate is not improving success chance, minimize
+ -- This candidate is not improving success chance or we are already at 100%, minimize
if (i < totFollowers and data.maxed) then
break -- Pointless using a maxed follower if we have more follower to try
end
@@ -968,60 +1037,64 @@ function addon:MatchMaker(missionID,mission,party)
if (GMFRewardSplash:IsShown()) then return end
if (not mission) then mission=self:GetMissionData(missionID) end
if (not party) then party=parties[missionID] end
- local skipBusy=addon:GetBoolean("IGM")
+ local skipBusy=self:GetBoolean("IGM")
local skipMaxed=self:GetBoolean("IGP")
- dbg=missionID==(tonumber(_G.MW) or 0)
+ dbg=dbg or missionID==(tonumber(_G.MW) or 0)
local slots=mission.slots
local missionCounters=counters[missionID]
local ct=counterThreatIndex[missionID]
local maxedSkipped=new()
local ignoredSkipped=new()
openParty(missionID,mission.numFollowers)
- for i=1,#slots do
- local threat=cleanicon(slots[i].icon)
- local candidates=ct[threat]
- local choosen
- for i=1,#candidates do
- local followerID=missionCounters[candidates[i]].followerID
- if(not addon:GetFollowerStatusForMission(followerID,skipBusy)) then
- if (dbg) then print("Skipped",n[followerID],"due to skipbusy" ) end
- elseif (self:IsIgnored(followerID,missionID)) then
- tinsert(ignoredSkipped,followerID)
- if (dbg) then print("Skipped",n[followerID],"due to ignored" ) end
- elseif (skipMaxed and self:GetFollowerData(followerID,'maxed')) then
- tinsert(maxedSkipped,followerID)
- if (dbg) then print("Skipped",n[followerID],"due to maxed" ) end
+ -- Preloading skipped ones in party table.
+ if (missionCounters) then
+ for i=1,#missionCounters do
+ local followerID=missionCounters[i].followerID
+ if (not followerID) then
+ xprint("Trying to use [",followerID,"]")
else
- choosen=best(choosen,candidates[i],missionCounters)
- if (dbg) then print("Taken",n[missionCounters[choosen].followerID]) end
- end
- end
- if (choosen) then
- if (type(missionCounters[choosen]) ~="table") then
- trace(format("%s %s %d %d",mission.name,threat,missionID,tonumber(choosen) or 0))
- end
- pushFollower(missionCounters[choosen].followerID)
- end
- if (roomInParty()==0) then
- break
- end
- end
- self:CompleteParty(missionID,mission,skipBusy,skipMaxed)
- if (roomInParty()>0) then
- --We try to use maxed, then ignored followers
- for i=1,#maxedSkipped do
- pushFollower(maxedSkipped[i])
- if (roomInParty()==0) then
- break
+ if (self:IsIgnored(followerID,missionID)) then
+ if (dbg) then print("Skipped",n[followerID],"due to ignored" ) end
+ partyIgnore(followerID,true)
+ elseif not addon:GetFollowerStatusForMission(followerID,skipBusy) then
+ if (dbg) then print("Skipped",n[followerID],"due to busy" ) end
+ partyIgnore(followerID)
+ elseif (skipMaxed and mission.xpOnly and self:GetFollowerData(followerID,'maxed')) then
+ if (dbg) then print("Skipped",n[followerID],"due to busy" ) end
+ partyIgnore(followerID,true)
+ end
end
end
- for i=1,#ignoredSkipped do
- pushFollower(ignoredSkipped[i])
- if (roomInParty()==0) then
- break
+ if (type(slots)=='table') then
+ for i=1,#slots do
+ local threat=cleanicon(slots[i].icon)
+ local candidates=ct[threat]
+ local choosen
+ for i=1,#candidates do
+ local followerID=missionCounters[candidates[i]].followerID
+ if followerID then
+ if(not isPartyIgnored(followerID)) then
+ choosen=best(choosen,candidates[i],missionCounters)
+ if (dbg) then print("Taken",n[missionCounters[choosen].followerID]) end
+ end
+ end
+ end
+ if (choosen) then
+ if (type(missionCounters[choosen]) ~="table") then
+ trace(format("%s %s %d %d",mission.name,threat,missionID,tonumber(choosen) or 0))
+ end
+ pushFollower(missionCounters[choosen].followerID)
+ end
+ if (roomInParty()==0) then
+ break
+ end
end
+ else
+ xprint("Mission",missionID,"has no slots????")
end
+ if roomInParty() > 0 then self:AddTraitsToParty(missionID,mission) end
end
+ --if roomInParty() > 0 then self:CompleteParty(missionID,mission,skipBusy,skipMaxed) end
storeFollowers(party.members)
party.full= roomInParty()==0
party.perc=closeParty()
@@ -1030,6 +1103,16 @@ function addon:IsIgnored(followerID,missionID)
if (dbcache.ignored[missionID][followerID]) then return true end
if (dbcache.totallyignored[followerID]) then return true end
end
+function addon:GetAllCounters(missionID,threat,table)
+ wipe(table)
+ local iter=genIteratorByThreat(missionID,cleanicon(tostring(threat)),new())
+ for i=1,iter() do
+ if (iter[i]) then
+ tinsert(table,iter[i].followerID)
+ end
+ end
+ del(iter)
+end
function addon:GetCounterBias(missionID,threat)
local bias=-1
local who=""
@@ -1059,7 +1142,6 @@ function addon:AddLine(name,status)
GameTooltip:AddDoubleLine(name, status,nil,nil,nil,r2,g2,b2)
end
function addon:SetThreatColor(obj,missionID)
- dbg=missionID==(tonumber(_G.MW) or 0)
if (dbg) then print("Evaluating ",missionID,obj.Icon:GetTexture()) end
local bias=self:GetCounterBias(missionID,obj.Icon:GetTexture())
local color=self:GetBiasColor(bias,nil,"Green")
@@ -1068,11 +1150,11 @@ function addon:SetThreatColor(obj,missionID)
end
function addon:HookedGarrisonMissionButton_AddThreatsToTooltip(missionID)
+ if (GMC:IsShown()) then return end
+ self:RenderTooltip(missionID)
+end
+function addon:RenderTooltip(missionID)
local mission=self:GetMissionData(missionID)
- local button=GetMouseFocus()
---@debug@
- GameTooltip:AddLine("ID:" .. tostring(missionID))
---@end-debug@
if (not mission) then
--@debug@
GameTooltip:AddLine("E dove minchia è finita??")
@@ -1118,17 +1200,6 @@ function addon:HookedGarrisonMissionButton_AddThreatsToTooltip(missionID)
biascolors[fullname]={self:GetBiasColor(followerID,missionID,"White"),self:GetFollowerStatus(followerID,true)}
end
table.sort(fullnames)
- if (not bigscreen) then
- GameTooltip:AddLine(PARTY)
- for i=1,#party do
- local fullname=party[i]
- local info=biascolors[fullname]
- self:AddLine(fullname,info[2],info[1])
- end
- if (#party < mission.numFollowers) then
- GameTooltip:AddLine(GARRISON_PARTY_NOT_FULL_TOOLTIP,C.Red())
- end
- end
GameTooltip:AddLine(L["Other useful followers"])
for i=1,#fullnames do
local fullname=fullnames[i]
@@ -1173,7 +1244,8 @@ function addon:RefreshMission(missionID)
end
end
-function addon:BuildMissionsCache(fc,mm)
+function addon:BuildMissionsCache(fc,mm,OnEvent)
+--cache.missions
--@debug@
local start=GetTime()
xprint("Start Full Cache Rebuild")
@@ -1182,11 +1254,24 @@ function addon:BuildMissionsCache(fc,mm)
G.GetAvailableMissions(t)
for index=1,#t do
local missionID=t[index].missionID
+ if (not dbcache.seen[missionID]) then
+ dbcache.seen[missionID]=OnEvent and time() or dbcache.lastseen
+ end
self:BuildMissionCache(missionID,t[index])
if fc then self:FillCounters(missionID) end
if mm then self:MatchMaker(missionID) end
end
+ for k,v in pairs(dbcache.seen) do
+ if (not cache.missions[k]) then
+ local span=time()-tonumber(v) or time()
+ if (span > db.lifespan[k]) then
+ db.lifespan[k]=span
+ end
+ dbcache.seen[k]=nil
+ end
+ end
del(t)
+ collectgarbage("step",10)
--@debug@
xprint("Done in",GetTime()-start)
--@end-debug@
@@ -1260,39 +1345,87 @@ end
rank=0,
locPrefix=false
}
+GetBasicInfo Table Format={
+ description="With infernals and felguard invading Talador, the rest of the Burning Legion can't be far behind. Defeat them, and try to find their source.",
+ cost=15,
+ duration="8 hr",
+ durationSeconds=28800,
+ level=100,
+ type="Combat",
+ locPrefix="GarrMissionLocation-Talador",
+ rewards={
+ [248]={
+ itemID=114057,
+ quantity=1
+ }
+ },
+ numRewards=1,
+ numFollowers=3,
+ state=-2,
+ iLevel=0,
+ name="Burning Legion Vanguard",
+ followers={
+ },
+ location="Talador",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=113
+}
+
--]]
function addon:BuildMissionCache(id,data)
- if (not dbcache.seen[id]) then
- dbcache.seen[id]=time()
- end
local mission=cache.missions[id]
- if (mission.name=="<newmission>") then
- if (not data) then
- mission.name=G.GetMissionName(id)
- mission.numFollowers=G.GetMissionMaxFollowers(id)
- mission.durationSeconds=select(5,G.GetMissionTimers(id))
- else
- mission.name=data.name
- mission.numFollowers=data.numFollowers
- mission.durationSeconds=data.durationSeconds
- end
+ if (not mission) then
+--@dedbug@
+ xprint("Generating new data for ",id)
+--@end-debug@
+ mission = data or G.GetBasicMissionInfo(id)
+ if (not mission) then return end
+ cache.missions[id]=mission
+ if dbg then print("Retrieved",id,mission.name) end
+ local _,xp,type,typeDesc,typeIcon,locPrefix,_,enemies=G.GetMissionInfo(id)
mission.rank=mission.level < 100 and mission.level or mission.iLevel
- mission.xp=true
- mission.resources=false
- for k,v in pairs(G.GetMissionRewardInfo(id)) do
- if (not v.followerXP) then mission.xp=false end
- if (v.currencyID and v.currencyID==GARRISON_CURRENCY) then mission.resource=false end
+ mission.xp=xp
+ mission.xpBonus=0
+ mission.resources=0
+ mission.gold=0
+ mission.followerUpgrade=0
+ mission.itemLevel=0
+ for k,v in pairs(mission.rewards) do
+ if (v.followerXP) then mission.xpBonus=mission.xpBonus+v.followerXP end
+ if (v.currencyID and v.currencyID==GARRISON_CURRENCY) then mission.resources=v.quantity end
+ if (v.currencyID and v.currencyID==0) then mission.gold =mission.gold+v.quantity/10000 end
+ if (v.itemID) then
+ if (v.itemID~=120205) then
+ local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount,itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(v.itemID)
+ if (itemName) then
+ if (itemLevel > 1 ) then
+ mission.itemLevel=itemLevel
+ else
+ mission.followerUpgrade=1
+ end
+ end
+ end
+ end
+ end
+ mission.totalXp=(tonumber(mission.xp) or 0) + (tonumber(mission.xpBonus) or 0)
+ mission.globalXp=mission.totalXp*mission.numFollowers
+ if (mission.resources==0 and mission.gold==0 and mission.itemLevel==0 and mission.followerUpgrade==0) then
+ mission.xpOnly=true
+ else
+ mission.xpOnly=false
end
- local _,xp,type,typeDesc,typeIcon,locPrefix,_,enemies=G.GetMissionInfo(id)
mission.locPrefix=locPrefix
if (not type) then
--@debug@
- print("No type",id,data.name)
+ xprint("No type",id,data.name)
--@end-debug@
else
- self.db.global.types[type]={name=type,description=typeDesc,icon=typeIcon}
+ if (not self.db.global.types[type]) then
+ self.db.global.types[type]={name=type,description=typeDesc,icon=typeIcon}
+ end
end
- wipe(mission.slots)
+ mission.slots={}
local slots=mission.slots
for i=1,#enemies do
@@ -1305,13 +1438,16 @@ function addon:BuildMissionCache(id,data)
if (type) then
tinsert(slots,{name=TYPE,key=type,icon=typeIcon})
end
+ --collectgarbace("step",100)
end
mission.basePerc=select(4,G.GetPartyMissionInfo(id))
+
end
function addon:SetDbDefaults(default)
default.global=default.global or {}
default.global["*"]={
}
+ default.global.lifespan={["*"]=0}
end
function addon:CreatePrivateDb()
self.privatedb=self:RegisterDatabase(
@@ -1338,6 +1474,17 @@ function addon:CreatePrivateDb()
},
runningIndex={
["*"]=0
+ },
+ missionControl={
+ allowedRewards = {["*"]=true},
+ rewardChance={["*"]=100},
+ useOneChance=true,
+ itemPrio = {},
+ minimumChance = 100,
+ minDuration = 0,
+ maxDuration = 24,
+ epicExp = false,
+ skipRare=true
}
}
},
@@ -1346,21 +1493,7 @@ function addon:CreatePrivateDb()
"GACPrivateVolatile",
{
profile={
- missions={
- ["*"]={
- counters={},
- slots={},
- missionID=0,
- numFollowers=0,
- name="<newmission>",
- basePerc=0,
- durationSeconds=0,
- level=0,
- iLevel=0,
- rank=0,
- locPrefix=false
- }
- }
+ missions={}
}
}
,
@@ -1371,18 +1504,13 @@ end
function addon:SetClean()
dirty=false
end
-function addon:wipe(i)
---@debug@
- DevTools_Dump(i)
- self.privatedb:ResetDB()
---@end-debug@
-end
+
function addon:WipeMission(missionID)
cache.missions[missionID]=nil
counters[missionID]=nil
dbcache.seen[missionID]=nil
parties[missionID]=nil
- collectgarbage("step")
+ --collectgarbage("step")
end
@@ -1395,13 +1523,33 @@ function addon:EventGARRISON_MISSION_NPC_OPENED(event,...)
--@debug@
xprint(event,...)
--@end-debug@
- GCF:Show()
+ if (GCF) then GCF:Show() end
end
function addon:EventGARRISON_MISSION_NPC_CLOSED(event,...)
--@debug@
xprint(event,...)
--@end-debug@
- GCF:Hide()
+ if (GCF) then
+ self:RemoveMenu()
+ GCF:Hide()
+ end
+end
+function addon:EventGARRISON_MISSION_LIST_UPDATE(event)
+ local n=0
+ for _,k in pairs(event) do n=n+1 end
+ xprint("GARRISON_MISSION_LIST_UPDATE",n,date("%d/%m/%y %H:%M:%S"))
+ local t=new()
+ G.GetAvailableMissions(t)
+ local justseen={}
+ local now=time()
+ for i=1,#t do
+ justseen[t[i].missionID]=true
+ end
+ for missionID,_ in pairs(justseen) do
+ if (not tonumber(db.seen[missionID])) then db.seen[missionID]=now end
+ end
+ self:BuildMissionsCache(false,false,true)
+ del(t)
end
---
--@param #string event GARRISON_MISSION_STARTED
@@ -1429,6 +1577,12 @@ function addon:EventGARRISON_MISSION_STARTED(event,missionID,...)
dbcache.runningIndex[m]=missionID
end
end
+ local v=dbcache.seen[missionID]
+ local span=time()-tonumber(v) or time()
+ if (span > db.lifespan[missionID]) then
+ db.lifespan[missionID]=span
+ -- IF we started it.. it was alive, so it's expire time is at least the time we waited before starting it
+ end
dbcache.seen[missionID]=nil
counters[missionID]=nil
parties[missionID]=nil
@@ -1446,9 +1600,20 @@ end
function addon:EventGARRISON_MISSION_FINISHED(event,missionID,...)
--@debug@
xprint(event,missionID,...)
- DevTools_Dump(G.GetPartyMissionInfo(missionID))
+ xdump(G.GetPartyMissionInfo(missionID))
--@end-debug@
end
+function addon:EventGARRISON_FOLLOWER_LIST_UPDATE(event)
+--We need to update all followers, maybe this could be done in an onupdate handler
+end
+function addon:EventGARRISON_FOLLOWER_ADDED(event)
+ wipe(followersCache)
+ wipe(followersCacheIndex)
+end
+function addon:EventGARRISON_FOLLOWER_REMOVED(event)
+ wipe(followersCache)
+ wipe(followersCacheIndex)
+end
function addon:EventGARRISON_MISSION_BONUS_ROLL_COMPLETE(event,missionID,completed,success)
--@debug@
@@ -1499,9 +1664,45 @@ local coroutines={
local lastmin=0
local MPShown=nil
+local dbgFrame
+local lastCPU=0
+local startTime=GetTime()
-- Keeping it as a nice example of coroutine management.. but not using it anymore
function addon:Clock()
- collectgarbage("step")
+ if (GMFMissions.showInProgress) then
+ collectgarbage("collect") --while I fix it....
+ else
+ collectgarbage("step",100)
+ end
+--@debug@
+ if (not dbgFrame) then
+ dbgFrame=AceGUI:Create("Window")
+ dbgFrame:SetTitle("GC Performance")
+ dbgFrame:SetPoint("LEFT")
+ dbgFrame:SetHeight(60)
+ dbgFrame:SetWidth(350)
+ dbgFrame:SetLayout("fill")
+ dbgFrame.Text=AceGUI:Create("Label")
+ dbgFrame.Text:SetColor(1,0,0)
+ dbgFrame:AddChild(dbgFrame.Text)
+ end
+ local h,m=GetGameTime()
+ if (m~=lastmin) then
+ lastmin=m
+ end
+ if (trc) then
+ UpdateAddOnCPUUsage()
+ UpdateAddOnMemoryUsage()
+ end
+ local cpu=GetAddOnCPUUsage("GarrisonCommander")
+ dbgFrame.Text:SetText(format("GC Cpu %3.2f/%2.2f/%2.2f Mem %4.3fMB ",
+ cpu,
+ cpu-lastCPU,cpu/(GetTime()-startTime),
+ GetAddOnMemoryUsage("GarrisonCommander")/1024)
+ )
+ lastCPU=cpu
+--@end-debug@
+ dbcache.lastseen=time()
if (not MP or MPGoodGuy) then return end
MPShown=not self:GetBoolean("CKMP")
local children={GMFMissions:GetChildren()}
@@ -1538,32 +1739,19 @@ function addon:Clock()
end
end
--@end-debug@
---@debug@
- local h,m=GetGameTime()
- if (m~=lastmin) then
- lastmin=m
- UpdateAddOnCPUUsage()
- UpdateAddOnMemoryUsage()
- xprint("GC Usage",GetAddOnCPUUsage("GarrisonCommander"),GetAddOnMemoryUsage("GarrisonCommander"))
- end
---@end-debug@
end
function addon:ActivateButton(button,OnClick,Tooltiptext,persistent)
button:SetScript("OnClick",function(...) self[OnClick](self,...) end )
if (Tooltiptext) then
button.tooltip=Tooltiptext
- button:SetScript("OnEnter",function(...) self:ShowTT(...) end )
+ button:SetScript("OnEnter",ShowTT)
button:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
else
button:SetScript("OnEnter",nil)
button:SetScript("OnLeave",nil)
end
end
-function addon:ShowTT(this)
- GameTooltip:SetOwner(this, "ANCHOR_CURSOR_RIGHT")
- GameTooltip:SetText(this.tooltip)
- GameTooltip:Show()
-end
+
function addon:Shrink(button)
local f=button.Toggle
local name=f:GetName() or "Unnamed"
@@ -1574,11 +1762,29 @@ function addon:Shrink(button)
f:SetHeight(f.savedHeight)
end
end
+
+function addon:ShowMissionControl()
+ if (not GMC:IsShown()) then
+ GarrisonMissionFrame_SelectTab(999)
+ GMF.FollowerTab:Hide()
+ GMF.FollowerList:Hide()
+ GMF.MissionTab:Hide()
+ GMF.TitleText:SetText("Garrison Commander Mission Control")
+ GMC:Show()
+ GMC.startButton:Click()
+ GMC.tabMC:SetChecked(true)
+ else
+ GMC:Hide()
+ GMC.tabMC:SetChecked(false)
+ GarrisonMissionFrame_SelectTab(1)
+ end
+end
local helpwindow -- pseudo static
function addon:ShowHelpWindow(button)
if (not helpwindow) then
local backdrop = {
- bgFile="Interface\\TutorialFrame\\TutorialFrameBackground",
+ --bgFile="Interface\\TutorialFrame\\TutorialFrameBackground",
+ bgFile="Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
tile=true,
tileSize=16,
@@ -1594,6 +1800,7 @@ function addon:ShowHelpWindow(button)
insets={bottom=5,left=5,right=5,top=5}
}
helpwindow=CreateFrame("Frame",nil,GCF)
+ helpwindow:EnableMouse(true)
helpwindow:SetBackdrop(backdrop)
helpwindow:SetBackdropColor(1,1,1,1)
helpwindow:SetFrameStrata("TOOLTIP")
@@ -1611,50 +1818,61 @@ function addon:ShowHelpWindow(button)
local text=[[<html><body>
<h1 align="center">Garrison Commander Help</h1>
<br/>
-<p> GC enhances standard Garrison UI by adding a Menu header and a secondary list of mission button to the right of the standard list.<br/>
+<p align="center">GC enhances standard Garrison UI by adding a Menu header and useful information in mission button and tooltip.
Since 2.0.2, the "big screen" mode became optional. If you choosed to disable it, some feature described here will not be available
</p>
<br/>
-<h2> Secondary button list:</h2>
+<h2> Button list:</h2>
<p>
- * Time since the first time we saw this mission in log<br/>
- * Success percent with the current followers selection guidelines<br/>
- * A "Good" party composition, on each member countered mechanics are shown.<br/>
- *** Green border means full counter, Orange border low level counter<br/>
+* Success percent with the current followers selection guidelines<br/>
+* Time since the first time we saw this mission in log<br/>
+* A "Good" party composition. on each member countered mechanics are shown.<br/>
+*** Green border means full counter, Orange border low level counter<br/>
</p>
<h2>Tooltip:</h2>
<p>
- * Overall mission status<br/>
- * All members which can possibly play a role in the mission<br/>
+* Overall mission status<br/>
+* All members which can possibly play a role in the mission<br/>
</p>
-<h2>Standard button enhancement:</h2>
+<h2>Button enhancement:</h2>
<p>
- * In rewards, actual quantity is shown (xp, money and resources) ot iLevel (item rewards)<br/>
- * Countered status<br/>
+* In rewards, actual quantity is shown (xp, money and resources) ot iLevel (item rewards)<br/>
+* Countered status<br/>
</p>
<h2>Menu Header:</h2>
<p>
- * Quick selection of which follower ignore for match making<br/>
- * Quick mission list order selection<br/>
+* Quick selection of which follower ignore for match making<br/>
+* Quick mission list order selection<br/>
+</p>
+<h2>Mission Control:</h2>
+<p>Thanks to Motig which donated the code, we have an auto lancher for mission<br/>
+You specify some criteria mission should satisfy (success chance, rewards type etc) and matching missions will be autosubmitted<br/>
+BE WARNED, FEATURE IS |cffff0000EXPERIMENTAL|r
</p>
]]
if (MP) then
text=text..[[
-<h3>Clashing Master Plan Detected</h3>
-<p>You cold experience issues. Please update MP to the last revision or downgrade it to 0.18 for a smoother experience
+<p><br/></p>
+<h3>Master Plan 0.20 or above detected</h3>
+<p>Master Plan hides Garrison Commander interface for available missions<br/>
+You can still use Garrison Commander Mission Control<br/>
+You can switch between MP and GC interface for missions checking and unchecking "Use GC Interface" checkbox. It usually works :)
</p>
]]
end
if (MPGoodGuy) then
text=text..[[
-<h3>Master Plan 0.18 or 0.23 or above Detected</h3>
-<p>This version of Master Plan plays not so bad with GC<br/>
-You can use the "Use GC interface" switch to regain GC interface with MP 0.23 or above.<br/>
+<p><br/></p>
+<h3>Master Plan 0.18 Detected</h3>
+<p>This the last known version of Master Plan which leaves Blizzard UI available to other addons<br/>
+You loose Garrison Commander Active Mission page, but the one provided by MP is good enough.<br/>
+In order to see enhanced tooltips you need to hover on extra button.
</p>
]]
end
if (GMM) then
text=text..[[
+<p><br/></p>
<h3>Garrison Mission Manager Detected</h3>
<p>Garrison Mission Manager and Garrison Commander plays reasonably well together.<br/>
The red button to the right of rewards is from GMM. It spills out of button, Yes, it's designed this way. Dunno why. Ask GMM author :)<br/>
@@ -1666,12 +1884,13 @@ text=text.."</body></html>"
--html:SetTextColor('h1',C.Red())
--html:SetTextColor('h2',C.Orange())
helpwindow:SetWidth(800)
- helpwindow:SetHeight(600+ (MP and 80 or 0) + (GMM and 70 or 0))
- helpwindow:SetPoint("TOPLEFT",button,"TOPRIGHT",0,0)
+ helpwindow:SetHeight(590 + ((MP or MPGoodGuy) and 160 or 0) + (GMM and 120 or 0))
+ helpwindow:SetPoint("TOPRIGHT",button,"TOPLEFT",0,0)
html:ClearAllPoints()
html:SetWidth(helpwindow:GetWidth()-20)
html:SetHeight(helpwindow:GetHeight()-20)
html:SetPoint("TOPLEFT",helpwindow,"TOPLEFT",10,-10)
+ html:SetPoint("BOTTOMRIGHT",helpwindow,"BOTTOMRIGHT",-10,10)
html:SetText(text)
helpwindow:Show()
return
@@ -1687,42 +1906,242 @@ function addon:Toggle(button)
end
end
-- Unused, experimenting with acegui
-local function GFC_Constructor()
- local widget=setmetatable({},{__index=AceGUI:Create("SimpleGroup")})
- function widget:DrawOn(frame,l,r)
- self.frame:ClearAllPoints()
- self.frame:SetPoint("TOPLEFT",frame,"TOPLEFT",l,0)
- self.frame:SetPoint("BOTTOMRIGHT",frame,"TOPRIGHT",r,0)
- end
- function widget:OnRelease()
- self.frame:ClearAllPoints()
- end
- if (false) then
- AceGUI:RegisterWidgetType("GarrisonCommanderHeader",GFC_Constructor,1)
- local layer=AceGUI:Create("GarrisonCommanderHeader")
- layer:DrawOn(GCF)
- layer:SetLayout("flow")
- LibStub("AceConfigDialog-3.0"):Open(me,layer)
+function addon:GenerateMissionsWidgets()
+ self:GenerateMissionContainer()
+ self:GenerateMissionButton()
+end
+function addon:GenerateMissionContainer()
+ do
+ local Type="GMCLayer"
+ local Version=1
+ local function OnRelease(self)
+ wipe(self.childs)
+ end
+ local function OnAcquire(self)
+ self.frame:SetParent(UIParent)
+ self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
+ self.frame:SetHeight(50)
+ self.frame:SetWidth(100)
+ self.frame:Show()
+ self.frame:SetPoint("LEFT")
+ end
+ local function Show(self)
+ self.frame:Show()
+ end
+ local function Hide(self)
+ self.frame:Hide()
+ self:Release()
+ end
+ local function SetScript(self,...)
+ self.frame:SetScript(...)
+ end
+ local function SetParent(self,...)
+ self.frame:SetParent(...)
+ end
+ local function PushChild(self,child,index)
+ self.childs[index]=child
+ self.scroll:AddChild(child)
+ end
+ local function RemoveChild(self,index)
+ local child=self.childs[index]
+ if (child) then
+ self.childs[index]=nil
+ child:Hide()
+ self:DoLayout()
+ end
+ end
+ local function ClearChildren(self)
+ wipe(self.childs)
+ self:AddScroll()
+ end
+ local function AddScroll(self)
+ if (self.scroll) then
+ self:ReleaseChildren()
+ self.scroll=nil
+ end
+ self.scroll=AceGUI:Create("ScrollFrame")
+ local scroll=self.scroll
+ self:AddChild(scroll)
+ scroll:SetLayout("List") -- probably?
+ scroll:SetFullWidth(true)
+ scroll:SetFullHeight(true)
+ scroll:SetPoint("TOPLEFT",self.title,"BOTTOMLEFT",0,0)
+ scroll:SetPoint("TOPRIGHT",self.title,"BOTTOMRIGHT",0,0)
+ scroll:SetPoint("BOTTOM",self.content,"BOTTOM",0,0)
+ end
+ local function Constructor()
+ local frame=CreateFrame("Frame")
+ local title=frame:CreateFontString(nil, "BACKGROUND", "GameFontNormalHugeBlack")
+ title:SetJustifyH("CENTER")
+ title:SetJustifyV("CENTER")
+ title:SetPoint("TOPLEFT")
+ title:SetPoint("TOPRIGHT")
+ title:SetHeight(0)
+ title:SetWidth(0)
+ addBackdrop(frame)
+ local widget={childs={}}
+ widget.title=title
+ widget.type=Type
+ widget.SetTitle=function(self,...) self.title:SetText(...) end
+ widget.SetTitleColor=function(self,...) self.title:SetTextColor(...) end
+ widget.SetFormattedTitle=function(self,...) self.title:SetFormattedText(...) end
+ widget.SetTitleWidth=function(self,...) self.title:SetWidth(...) end
+ widget.SetTitleHeight=function(self,...) self.title:SetHeight(...) end
+ widget.frame=frame
+ frame.obj=widget
+ widget.OnAcquire=OnAcquire
+ widget.OnRelease=OnRelease
+ widget.Show=Show
+ widget.Hide=Hide
+ widget.SetScript=SetScript
+ widget.SetParent=SetParent
+ frame:SetScript("OnHide",function(self) self.obj:Fire('OnClose') end)
+ --Container Support
+ local content = CreateFrame("Frame",nil,frame)
+ widget.content = content
+ content.obj = self
+ content:SetPoint("TOPLEFT",title,"BOTTOMLEFT")
+ content:SetPoint("BOTTOMRIGHT")
+ AceGUI:RegisterAsContainer(widget)
+ widget.PushChild=PushChild
+ widget.RemoveChild=RemoveChild
+ widget.ClearChildren=ClearChildren
+ widget.AddScroll=AddScroll
+ return widget
+ end
+ AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
- return widget
end
-function addon:CreateOptionsLayer(...)
- local o=AceGUI:Create("SimpleGroup") -- a transparent frame
- xprint("Created options ", o)
- o:SetLayout("Flow")
- o:SetCallback("OnRelease",function(widget) widget.frame:SetScale(1.0) end)
- o:SetCallback("OnClose",function(widget) widget.frame:SetScale(1.0) widget:Release() end)
- for i=1,select('#',...) do
- self:AddOptionToOptionsLayer(o,select(i,...))
+function addon:GenerateMissionButton()
+ do
+ local Type="GMCMissionButton"
+ local Version=1
+ local unique=0
+ local function OnAcquire(self)
+ local frame=self.frame
+ frame.info=nil
+ frame:SetHeight(80)
+ self.frame:SetAlpha(1)
+ self.frame:Enable()
+ end
+ local function Show(self)
+ self.frame:Show()
+ end
+ local function Hide(self)
+ self.frame:SetHeight(1)
+ self.frame:SetAlpha(0)
+ self.frame:Disable()
+ end
+ local function SetScript(self,...)
+ self.frame:SetScript(...)
+ end
+ local function SetMission(self,mission,missionID)
+ self.frame.info=mission
+ addon:BuildMissionButton(self.frame,true)
+ self.frame:EnableMouse(true)
+ --self.frame:SetScript("OnEnter",GarrisonMissionPageFollowerFrame_OnEnter)
+ --self.frame:SetScript("OnLeave",GarrisonMissionPageFollowerFrame_OnLeave)
+ self.frame:SetScript("OnEnter",GarrisonMissionButton_OnEnter)
+ self.frame:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
+ local party
+ for i=1,#GMC.ml.Parties do
+ party=GMC.ml.Parties[i]
+ if party.missionID==missionID then
+ break
+ end
+ end
+ self.frame.Percent:SetFormattedText("%d%%",party.perc)
+ self.frame.Percent:SetTextColor(addon:GetDifficultyColors(party.perc))
+ local x=1
+ for i=1,#party.members do
+ x=i+1
+ addon:RenderFollowerButton(self.frame.members[i],party.members[i],missionID)
+ self.frame.members[i]:SetScript("OnEnter",GarrisonMissionPageFollowerFrame_OnEnter)
+ self.frame.members[i]:SetScript("OnLeave",GarrisonMissionPageFollowerFrame_OnLeave)
+ self.frame.members[i]:Show()
+ end
+ for i=x,3 do
+ self.frame.members[i]:SetScript("OnEnter",nil)
+ self.frame.members[i]:Hide()
+ end
+ end
+
+ local function Constructor()
+ unique=unique+1
+ local frame=CreateFrame("Button","Pippo"..unique,nil,"GarrisonMissionListButtonTemplate") --"GarrisonCommanderMissionListButtonTemplate")
+ local indicators=CreateFrame("Frame",nil,frame,"GarrisonCommanderIndicators")
+ frame.Title:SetFontObject("QuestFont_Shadow_Small")
+ frame.Summary:SetFontObject("QuestFont_Shadow_Small")
+ indicators:SetPoint("LEFT",65,0)
+ indicators.Age:Hide()
+ frame.Percent=indicators.Percent
+ frame:SetScript("OnEnter",nil)
+ frame:SetScript("OnLeave",nil)
+ frame:SetScript("OnClick",function(self,button) self.obj:Fire("OnClick",self,button) end)
+ frame.LocBG:SetPoint("LEFT")
+ frame.MissionType:SetPoint("TOPLEFT",5,-2)
+ frame.members={}
+ for i=1,3 do
+ local f=CreateFrame("Button",nil,frame,"GarrisonCommanderMissionPageFollowerTemplateSmall" )
+ frame.members[i]=f
+ f:SetPoint("BOTTOMRIGHT",-65 -65 *i,5)
+ f:SetScale(0.8)
+ end
+ local widget={}
+ setmetatable(widget,{__index=frame})
+ widget.type=Type
+ widget.frame=frame
+ frame.obj=widget
+ widget.OnAcquire=OnAcquire
+ widget.Show=Show
+ widget.Hide=Hide
+ widget.SetScript=SetScript
+ widget.SetMission=SetMission
+ return AceGUI:RegisterAsWidget(widget)
+
+ end
+ AceGUI:RegisterWidgetType(Type,Constructor,Version)
end
- _G.TEST=o
- local frame=setmetatable({},{__index=o})
- function frame:Show() self.frame:Show() end
- return frame
end
-function addon:AddOptionToOptionsLayer(o,flag)
- if (not flag) then return end
+function addon:GMCBuildMiniMissionButton(frame,i,mission,scale,perc,offset)
+ offset=offset or 20
+ scale=scale or 0.6
+ local panel=frame.Missions[i]
+ if (not panel) then
+ panel=CreateFrame("Button",nil,frame,"GarrisonCommanderMissionListButtonTemplate")
+ panel:SetPoint("TOPLEFT",frame,1,-((i-1)*panel:GetHeight() +offset))
+ panel:SetPoint("TOPRIGHT",frame,-1,-((i-1)*panel:GetHeight()-offset))
+ panel.orderId=i
+ tinsert(frame.Missions,panel)
+ --Creo una riga nuova
+ panel:SetScale(scale)
+ panel.LocBG:SetPoint("LEFT")
+ end
+ panel.info=mission
+ --panel.id=index[missionID]
+ self:BuildMissionButton(panel)
+ local q=self:GetDifficultyColor(perc)
+ panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
+ panel.Percent:SetTextColor(q.r,q.g,q.b)
+ panel.NumMembers:SetFormattedText(GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS,mission.numFollowers)
+ panel:Show()
+ return panel
+end
+
+function addon:CreateOptionsLayer(...)
+ local o=AceGUI:Create("SimpleGroup") -- a transparent frame
+ o:SetLayout("Flow")
+ o:SetCallback("OnClose",function(widget) widget:Release() end)
+ local totsize=0
+ for i=1,select('#',...) do
+ totsize=totsize+self:AddOptionToOptionsLayer(o,select(i,...))
+ end
+ return o,totsize
+end
+function addon:AddOptionToOptionsLayer(o,flag,maxsize)
+ maxsize=tonumber(maxsize) or 140
+ if (not flag) then return 0 end
local info=self:GetVarInfo(flag)
if (info) then
local data={option=info}
@@ -1733,13 +2152,25 @@ function addon:AddOptionToOptionsLayer(o,flag)
widget:SetValue(value)
local color=value and "Green" or "Silver"
widget:SetLabel(C(info.name,color))
- widget:SetWidth(max(widget.text:GetStringWidth(),120))
+ widget:SetWidth(max(widget.text:GetStringWidth(),maxsize))
elseif(info.type=="select") then
widget=AceGUI:Create("Dropdown")
widget:SetValue(self:GetVar(flag))
widget:SetLabel(info.name)
widget:SetText(info.values[self:GetVar(flag)])
widget:SetList(info.values)
+ widget:SetWidth(maxsize)
+ elseif (info.type=="execute") then
+ widget=AceGUI:Create("Button")
+ widget:SetText(info.name)
+ widget:SetWidth(maxsize)
+ widget:SetCallback("OnClick",function(widget,event,value)
+ self[info.func](self,data,value)
+ end)
+ else
+ widget=AceGUI:Create("Label")
+ widget:SetText(info.name)
+ widget:SetWidth(maxsize)
end
widget:SetCallback("OnValueChanged",function(widget,event,value)
if (type(value=='boolean')) then
@@ -1758,22 +2189,92 @@ function addon:AddOptionToOptionsLayer(o,flag)
end)
o:AddChildren(widget)
end
+ return maxsize
end
+
function addon:Options()
-- Main Garrison Commander Header
- local base=CreateFrame("Frame","GCF",UIParent,"GarrisonCommanderTitle")
- GCF=base
+ GCF=CreateFrame("Frame","GCF",UIParent,"GarrisonCommanderTitle")
+--@alpha@
+ local fs=GCF:CreateFontString(nil, "BACKGROUND", "WorldMapTextFont")
+ fs:SetAllPoints()
+ fs:SetJustifyH("CENTER")
+ fs:SetJustifyV("CENTER")
+ fs:SetText("A l p h a V e r s i o n")
+ fs:SetTextColor(C.Silver())
+ fs:SetAlpha(0.6)
+--@end-alpha@
+ -- Removing wood corner. I do it here to not derive an xml frame. This shoud play better with ui extensions
+ GCF.CloseButton:Hide()
+ for _,f in pairs({GCF:GetRegions()}) do
+ if (f:GetObjectType()=="Texture" and f:GetAtlas()=="Garr_WoodFrameCorner") then f:Hide() end
+ end
+ GCF:SetFrameStrata(GMF:GetFrameStrata())
+ GCF:SetFrameLevel(GMF:GetFrameLevel()-2)
+ if (not bigscreen) then GCF:SetHeight(GCF:GetHeight()+35) end
+ baseHeight=GCF:GetHeight()
+ minHeight=47
+ GCF.CloseButton:SetScript("OnClick",nil)
+ GCF.Pin:SetAllPoints(GCF.CloseButton)
GCF:SetWidth(BIGSIZEW)
GCF:SetPoint("TOP",UIParent,0,-60)
- base:SetHeight(40)
- base:EnableMouse(true)
+ if (self:GetBoolean("PIN")) then
+ GCF.Pin:SetChecked(true)
+ else
+ GCF.Pin:SetChecked(false)
+ end
+
+ do
+ local baseHeight=baseHeight
+ local minHeight=minHeight
+ local baseStrata=GCF:GetFrameStrata()
+ local baseLevel=GCF:GetFrameStrata()
+ local speed=3
+ local function shrink(this)
+ addon:RemoveMenu()
+ this:SetScript("OnUpdate",function(me,ts)
+ local h=me:GetHeight()
+ if (h<=45) then
+ me:SetHeight(45)
+ me:SetScript("OnUpdate",nil)
+ GCF.tooltip=L["You can open the menu clicking on the icon in top right corner"]
+ else
+ me:SetHeight(h-2)
+ end
+ end)
+ end
+ local function grow(this)
+ this:SetScript("OnUpdate",function(me,ts)
+ local h=me:GetHeight()
+ if (h>=baseHeight) then
+ me:SetScript("OnUpdate",nil)
+ me:SetHeight(baseHeight)
+ if (not me.Menu) then addon:AddMenu() end
+ GCF.tooltip=nil
+ me.Menu:DoLayout()
+ else
+ me:SetHeight(h+2)
+ end
+ end)
+ end
+ GCF.Pin.tooltip=L["Toggles Garrison Commander Menu AutoHide on/off"]
+ GCF.Pin:SetScript("OnEnter",ShowTT)
+ GCF.Pin:SetScript("OnClick",function(this)
+ local value=this:GetChecked()
+ this:SetChecked(value)
+ addon:SetBoolean("PIN",value)
+ if (value) then grow(GCF) else shrink(GCF) end
+ end)
+ end
+ GCF:EnableMouse(true)
GCF:SetMovable(true)
GCF:RegisterForDrag("LeftButton")
GCF:SetScript("OnDragStart",function(frame)if (self:GetBoolean("MOVEPANEL")) then frame:StartMoving() end end)
GCF:SetScript("OnDragStop",function(frame) frame:StopMovingOrSizing() end)
- self:ActivateButton(GCF.help,"ShowHelpWindow",L["Click to toggle Help page"])
if (bigscreen) then
--MinimizeButton
+ -- It's not working well, now I dont have time to fix it
+ if (false) then
local h=CreateFrame("Button",nil,base,"UIPanelCloseButton")
h:SetFrameLevel(999)
h:SetNormalTexture("Interface\\BUTTONS\\UI-Panel-CollapseButton-Up")
@@ -1784,6 +2285,7 @@ function addon:Options()
h:SetPoint("TOPRIGHT")
self:ActivateButton(h,"Shrink",L["Click to toggle Garrison Mission Frame"])
GCF.gcHIDE=h
+ end
-- Mission list on follower panels
local ml=CreateFrame("Frame","GCFMissions",GMFFollowers,"GarrisonCommanderFollowerMissionList")
ml:SetPoint("TOPLEFT",GMFFollowers,"TOPRIGHT")
@@ -1808,10 +2310,10 @@ function addon:ScriptTrace(hook,frame,...)
--@end-debug@
end
function addon:IsProgressMissionPage()
- return GMF:IsShown() and GMFMissions:IsShown() and GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
+ return GMF:IsShown() and GMF.MissionTab and GMF.MissionTab.MissionList.showInProgress
end
function addon:IsAvailableMissionPage()
- return GMF:IsShown() and GMFMissions:IsShown() and not GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
+ return GMF:IsShown() and GMF.MissionTab:IsShown() and not GMF.MissionTab.MissionList.showInProgress
end
function addon:IsFollowerList()
return GMF:IsShown() and GMFFollowers:IsShown()
@@ -1824,6 +2326,25 @@ end
function addon:IsMissionPage()
return GMF:IsShown() and GMFMissionPage:IsShown() and GMFFollowers:IsShown()
end
+---
+-- Switches between missions (1) and followers (others) panels
+function addon:HookedGarrisonMissionFrame_SelectTab(id)
+ GMC:Hide()
+ GMC.tabMC:SetChecked(false)
+ wipe(GMCUsedFollowers)
+end
+---
+-- Switchs between active and availabla missions depending on tab object
+do
+ local original=GarrisonMissionList_SetTab
+ function GarrisonMissionList_SetTab(...)
+ -- I dont actually care wich page we are shoing, I know I must redraw missions
+ original(...)
+ for i=1,#GMFMissionListButtons do
+ GMFMissionListButtons.lastMissionID=nil
+ end
+ end
+end
function addon:HookedGarrisonMissionFrame_HideCompleteMissions()
self:BuildMissionsCache(true,true)
end
@@ -1861,19 +2382,63 @@ function addon:HookedGarrisonFollowerTooltipTemplate_SetGarrisonFollower(...)
ft:Show()
end
end
+function addon:HookedGarrisonFollowerButton_UpdateCounters(frame,follower,showCounters)
+ if MP then self:Unhook("GarrisonFollowerButton_UpdateCounters") return end
+ if not frame.GCTime then
+ frame.GCTime=frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
+ frame.GCTime:SetPoint("TOPLEFT",frame.Status,"TOPRIGHT",5,0)
+ frame.GCXp=frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
+ frame.GCXp:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,2)
+ frame.GCIt=frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall")
+ frame.GCIt:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,-2)
+ end
+ if not frame.isCollected then
+ frame.GCTime:Hide()
+ frame.GCXp:Hide()
+ frame.GCIt:Hide()
+ return
+ end
+ if (frame.Status:GetText() == GARRISON_FOLLOWER_ON_MISSION) then
+ frame.GCTime:SetText(self:GetFollowerStatus(follower.followerID,true,true))
+ frame.GCTime:Show()
+ else
+ frame.GCTime:Hide()
+ end
+ local follower=self:GetFollowerData(follower.followerID)
+ if (follower.level >= GARRISON_FOLLOWER_MAX_LEVEL ) then
+ local c1=ITEM_QUALITY_COLORS[follower.weaponQuality or 1]
+ local c2=ITEM_QUALITY_COLORS[follower.armorQuality or 1]
+ frame.GCIt:SetFormattedText("W:%s%3d|r A:%s%3d|r",c1.hex,follower.weaponItemLevel,c2.hex,follower.armorItemLevel)
+ frame.GCIt:Show()
+ else
+ frame.GCIt:Hide()
+ end
+ if (follower.level >= GARRISON_FOLLOWER_MAX_LEVEL and follower.quality >= GARRISON_FOLLOWER_MAX_UPGRADE_QUALITY) then
+ frame.GCXp:Hide()
+ else
+ frame.GCXp:SetFormattedText("Xp to next upgrade: %d",follower.levelXP-follower.xp)
+ frame.GCXp:Show()
+ end
+
+end
function addon:HookedGarrisonFollowerListButton_OnClick(frame,button)
--@debug@
- trace("Click",button,GarrisonMissionFrame.FollowerTab.Model:IsShown())
+ trace("Click",frame:GetName(),button,GMF.FollowerTab.Model:IsShown())
--@end-debug@
- if (button=="LeftButton" and GarrisonMissionFrame.FollowerTab.FollowerID ~= frame.info.followerID) then
+ if (button=="LeftButton" and GMF.FollowerTab.FollowerID ~= frame.info.followerID) then
if (frame.info.isCollected) then
self:HookedGarrisonFollowerPage_ShowFollower(frame.info,frame.info.followerID)
end
end
end
-- Shamelessly stolen from Blizzard Code
-function addon:FillMissionButton(button)
+function addon:BuildMissionButton(button,gmc,...)
local mission=button.info
+ if (not mission or not mission.name) then
+ if (button.missionID) then
+ mission=self:GetMissionData(button.missionID)
+ end
+ end
if (not mission) then return end
button.Title:SetWidth(0);
button.Title:SetText(mission.name);
@@ -1895,6 +2460,7 @@ function addon:FillMissionButton(button)
button.Summary:ClearAllPoints();
button.Summary:SetPoint("TOPLEFT", button.Title, "BOTTOMLEFT", 0, -4);
end
+ if gmc then button.Title:SetPoint("LEFT",70,25) end
if ( mission.locPrefix ) then
button.LocBG:Show();
button.LocBG:SetAtlas(mission.locPrefix.."-List");
@@ -1932,7 +2498,7 @@ function addon:FillMissionButton(button)
button.Overlay:Hide();
end
button.MissionType:SetAtlas(mission.typeAtlas);
- self.ClonedGarrisonMissionButton_SetRewards(button, mission.rewards, mission.numRewards);
+ GarrisonMissionButton_SetRewards(button,mission.rewards, mission.numRewards);
button:Show();
end
@@ -1981,7 +2547,22 @@ function addon:ClonedGarrisonMissionButton_SetRewards(rewards, numRewards)
self.Rewards[i]:Hide();
end
end
-
+function addon:ClonedGarrisonMissionMechanic_OnEnter(missionID,this,...)
+ local tip=GameTooltip
+ tip:SetOwner(this, "ANCHOR_CURSOR_RIGHT");
+ tip:AddLine(this.info.name,C.White())
+ --tip:AddTexture(this.Icon:GetTexture())
+ tip:AddLine(this.info.description,C.Orange())
+ local t=new()
+ self:GetAllCounters(missionID,this.Icon:GetTexture(),t)
+ if( #t > 0) then
+ tip:AddLine(GARRISON_MISSION_COUNTER_FROM)
+ for i=1,#t do
+ tip:AddLine(self:GetFollowerData(t[i],'fullname'),C[self:GetBiasColor(t[i],missionID,C.White())]())
+ end
+ end
+ tip:Show()
+end
local Busystatusmessage
function addon:HookedGarrisonFollowerPage_ShowFollower(frame,followerID)
local i=0
@@ -1989,7 +2570,7 @@ function addon:HookedGarrisonFollowerPage_ShowFollower(frame,followerID)
if (not GCFMissions.Missions) then GCFMissions.Missions={} end
if (not Busystatusmessage) then Busystatusmessage=C(BUSY_MESSAGE,"Red)") end
-- frame has every info you can need on a follower, but here I dont really need them, maybe just counters
- --DevTools_Dump(table.Counters)
+ --xdump(table.Counters)
local followerName=self:GetFollowerData(followerID,'name')
repeat -- a poor man goto
if (type(frame.followerID)=="number") then
@@ -2035,7 +2616,7 @@ function addon:HookedGarrisonFollowerPage_ShowFollower(frame,followerID)
end
table.sort(partyIndex,function(a,b) return parties[a].perc > parties[b].perc end)
end
- self:FillFollowerButton(GCFMissions.Header,followerID)
+ self:RenderFollowerButton(GCFMissions.Header,followerID)
-- Scanning mission list
for z = 1,#partyIndex do
local missionID=partyIndex[z]
@@ -2066,6 +2647,8 @@ function addon:HookedGarrisonFollowerPage_ShowFollower(frame,followerID)
local panel=GCFMissions.Missions[i]
if (not panel) then
panel=CreateFrame("Button",nil,GCFMissions,"GarrisonCommanderMissionListButtonTemplate")
+ self:SafeHookScript(panel,"OnClick","OnClick_GarrisonMissionButton",true)
+
if (i==1) then
panel:SetPoint("TOPLEFT",GCFMissions.Header,"BOTTOMLEFT")
else
@@ -2079,8 +2662,8 @@ function addon:HookedGarrisonFollowerPage_ShowFollower(frame,followerID)
panel.LocBG:SetPoint("LEFT")
end
panel.info=mission
- panel.id=index[missionID]
- self:FillMissionButton(panel)
+ --panel.id=index[missionID]
+ self:BuildMissionButton(panel)
local q=self:GetDifficultyColor(perc)
panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
panel.Percent:SetTextColor(q.r,q.g,q.b)
@@ -2110,7 +2693,64 @@ function addon:SetUp(...)
self:CheckMP()
self:CheckGMM()
self:Options()
+ self:GenerateMissionsWidgets()
+ self:GMCBuildPanel()
+ local tabMC=CreateFrame("CheckButton",nil,GMF,"SpellBookSkillLineTabTemplate")
+ tabMC.tooltip="Open Garrison Commander Mission Control"
+ --tab:SetNormalTexture("World\\Dungeon\\Challenge\\clockRunes.blp")
+ --tab:SetNormalTexture("Interface\\Timer\\Challenges-Logo.blp")
+ tabMC:SetNormalTexture("Interface\\ICONS\\ACHIEVEMENT_GUILDPERK_WORKINGOVERTIME.blp")
+ self:MarkAsNew(tabMC,'MissionControl','New in 2.2.0! Try automatic mission management!')
+ tabMC:Show()
+ GMC.tabMC=tabMC
+ local tabCF=CreateFrame("Button",nil,GMF,"SpellBookSkillLineTabTemplate")
+ tabCF.tooltip="Open Garrison Commander Configuration Screen"
+ tabCF:SetNormalTexture("Interface\\ICONS\\Trade_Engineering.blp")
+ tabCF:SetPushedTexture("Interface\\ICONS\\Trade_Engineering.blp")
+ tabCF:Show()
+ local tabHP=CreateFrame("Button",nil,GMF,"SpellBookSkillLineTabTemplate")
+ tabHP.tooltip="Open Garrison Commander Help"
+ tabHP:SetNormalTexture("Interface\\ICONS\\INV_Misc_QuestionMark.blp")
+ tabHP:SetPushedTexture("Interface\\ICONS\\INV_Misc_QuestionMark.blp")
+ tabHP:Show()
+ tabMC:SetScript("OnClick",function(this,...) addon:ShowMissionControl() end)
+ tabCF:SetScript("OnClick",function(this,...) addon:Gui() end)
+ tabHP:SetScript("OnClick",function(this,button) addon:ShowHelpWindow(this,button) end)
+ tabHP:SetPoint('TOPLEFT',GCF,'TOPRIGHT',0,-10)
+ tabCF:SetPoint('TOPLEFT',GCF,'TOPRIGHT',0,-60)
+ tabMC:SetPoint('TOPLEFT',GCF,'TOPRIGHT',0,-110)
self:StartUp()
+ --collectgarbage("step",10)
+--/Interface/FriendsFrame/UI-Toast-FriendOnlineIcon
+end
+function addon:AddMenu()
+ local menu,size=self:CreateOptionsLayer(MP and 'CKMP' or nil,'BIGSCREEN','MOVEPANEL','IGM','IGP','NOFILL','MSORT')
+ --self:AddOptionToOptionsLayer(GCF.Menu,'MSORT')
+ --self:AddOptionToOptionsLayer(GCF.Menu,'ShowMissionControl')
+--@debug@
+ self:AddOptionToOptionsLayer(menu,'DBG')
+ self:AddOptionToOptionsLayer(menu,'TRC')
+--@end-debug@
+ local frame=menu.frame
+ frame:Show()
+ menu:ClearAllPoints()
+ menu:SetPoint("TOPLEFT",GCF,"TOPLEFT",25,-18)
+ menu:SetWidth(GCF:GetWidth()-50)
+ menu:SetHeight(GCF:GetHeight()-50)
+ menu:DoLayout()
+ GCF.Menu=menu
+end
+function addon:RemoveMenu()
+ if (GCF.Menu) then
+ pcall(GCF.Menu.Release,GCF.Menu)
+ GCF.Menu=nil
+ end
+end
+function addon:AddMissionId(b)
+ if (b.info and b.info.missionID) then
+ GameTooltip:AddDoubleLine("MissionID",b.info.missionID)
+ GameTooltip:Show()
+ end
end
---
-- Additional setup
@@ -2120,23 +2760,15 @@ function addon:StartUp(...)
--@debug@
xprint("Startup")
--@end-debug@
+ self:GrowPanel()
self:Unhook(GMF,"OnShow")
- self:Trigger("CKMP")
- self:PermanentEvents()
- GCF.Menu=self:CreateOptionsLayer(MPSwitch and 'CKMP' or nil,'BIGSCREEN','MOVEPANEL','IGM','IGP','NOFILL','MSORT')
- GCF.Menu:SetParent(GCF)
- GCF.Menu.frame:SetScale(0.6)
- if (bigscreen) then
- GCF.Menu:SetPoint("TOPLEFT",GCF.Signature,"TOPRIGHT",10,10)
+ if (self:GetBoolean("PIN")) then
+ GCF:SetHeight(baseHeight)
+ self:AddMenu()
else
- GCF:SetHeight(60)
- GCF.Menu:SetPoint("TOPLEFT",GCF,"TOPLEFT",0,-24)
+ GCF:SetHeight(minHeight)
end
- GCF.Menu:SetPoint("BOTTOMRIGHT",GCF,"BOTTOMRIGHT",-16,0)
- GCF.Menu:Show()
- self:GrowPanel()
- self:SafeSecureHook("GarrisonMissionButton_OnClick","OnClick_GarrisonMissionButton")
- self:SafeSecureHook("GarrisonMissionFrame_CheckCompleteMissions")
+ self:PermanentEvents()
self:SafeSecureHook("GarrisonMissionButton_AddThreatsToTooltip")
self:SafeSecureHook("GarrisonMissionButton_SetRewards")
if (bigscreen) then
@@ -2146,22 +2778,39 @@ function addon:StartUp(...)
end
self:SafeSecureHook("GarrisonMissionFrame_HideCompleteMissions") -- Mission reward completed
self:SafeSecureHook("GarrisonMissionPage_ShowMission")
- self:SafeSecureHook("GarrisonMissionList_UpdateMissions")
+ self:SafeSecureHook("GarrisonMissionFrame_SelectTab")
+ -- GarrisonMissionList_SetTab is overrided
+
self:SafeHookScript(GMFMissions,"OnShow")--,"GrowPanel")
self:SafeHookScript(GMFFollowers,"OnShow")--,"GrowPanel")
self:SafeHookScript(GCF,"OnHide","CleanUp",true)
+ -- Follower button enhancement in follower list
+ self:SafeSecureHook("GarrisonFollowerButton_UpdateCounters")
+ -- Mission management
self:SafeHookScript(GMF.MissionComplete.NextMissionButton,"OnClick","OnClick_GarrisonMissionFrame_MissionComplete_NextMissionButton",true)
-- Hooking mission buttons on click
for i=1,#GMFMissionListButtons do
local b=GMFMissionListButtons[i]
self:SafeHookScript(b,"OnClick","OnClick_GarrisonMissionButton",true)
+--@debug@
+ self:SafeHookScript(b,"OnEnter","AddMissionId",true)
+--@end-debug@
end
self:ScheduleRepeatingTimer("Clock",1)
self:BuildMissionsCache(true,true)
self:BuildRunningMissionsCache()
self:Trigger("MSORT")
+ self:Trigger("CKMP")
+end
+function addon:MarkAsNew(obj,key,message)
+ if (not db.news[key]) then
+ local f=CreateFrame("Frame",nil,obj,"GarrisonCommanderWhatsNew")
+ f.tooltip=message
+ f:SetPoint("BOTTOMLEFT",obj,"TOPRIGHT")
+ f:Show()
+ end
end
--- probably not really needed, haven seen yet them firing out of garrison
+-- probably not really needed, havenr seen yet them firing out of garrison
function addon:PermanentEvents()
self:SafeRegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE")
self:SafeRegisterEvent("GARRISON_MISSION_STARTED")
@@ -2170,18 +2819,24 @@ function addon:PermanentEvents()
self:SafeRegisterEvent("GARRISON_FOLLOWER_XP_CHANGED")
self:SafeRegisterEvent("GARRISON_FOLLOWER_ADDED")
self:SafeRegisterEvent("GARRISON_FOLLOWER_REMOVED")
+ self:RegisterBucketEvent("GARRISON_MISSION_LIST_UPDATE",2,"EventGARRISON_MISSION_LIST_UPDATE")
+ self:SafeRegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
--@debug@
self:DebugEvents()
--@end-debug@
end
function addon:DebugEvents()
- self:SafeRegisterEvent("GARRISON_MISSION_LIST_UPDATE")
- self:SafeRegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE") -- Should be used only when has true as parameter
self:SafeRegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT")
self:SafeRegisterEvent("GARRISON_MISSION_FINISHED")
self:SafeRegisterEvent("GARRISON_UPDATE")
self:SafeRegisterEvent("GARRISON_USE_PARTY_GARRISON_CHANGED")
self:SafeRegisterEvent("GARRISON_MISSION_NPC_OPENED")
+ self:SafeSecureHook("GarrisonMissionList_UpdateMissions")
+ self:SafeSecureHook("GarrisonMissionFrame_ShowCompleteMissions")
+ self:SafeSecureHook("GarrisonMissionFrame_CheckCompleteMissions")
+ self:SafeSecureHook("MissionCompletePreload_LoadMission")
+
+
end
function addon:checkMethod(method,hook)
if (type(self[method])=="function") then
@@ -2213,7 +2868,7 @@ function addon:SafeSecureHook(tobehooked,method)
else
do
local hooked=tobehooked
- return self:SecureHook(tobehooked,function(...) xprint(hooked,...) end)
+ return self:SecureHook(tobehooked,function(...) print(hooked,...) end)
end
--@end-debug@
end
@@ -2248,13 +2903,13 @@ end
function addon:CleanUp()
self:UnhookAll()
self:CancelAllTimers()
- GCF.Menu:Release()
+ self:RemoveMenu()
self:HookScript(GMF,"OnSHow","StartUp",true)
self:PermanentEvents() -- Reattaching permanent events
if (GarrisonFollowerTooltip.fs) then
GarrisonFollowerTooltip.fs:Hide()
end
- collectgarbage("collect")
+ --collectgarbage("collect")
--@debug@
xprint("Cleaning up")
--@end-debug@
@@ -2287,10 +2942,17 @@ function addon:GetFollowerData(key,subkey)
if (not follower.isCollected) then
followersCache[i]=nil
else
- follower.rank=follower.level==100 and follower.iLevel or follower.level
- follower.coloredname=C(follower.name,tostring(follower.quality))
- follower.fullname=format("%3d %s",follower.rank,follower.coloredname)
- follower.maxed=follower.quality >= GARRISON_FOLLOWER_MAX_UPGRADE_QUALITY and follower.level >=GARRISON_FOLLOWER_MAX_LEVEL
+ follower.rank=follower.level==100 and follower.iLevel or follower.level
+ follower.coloredname=C(follower.name,tostring(follower.quality))
+ follower.fullname=format("%3d %s",follower.rank,follower.coloredname)
+ follower.maxed=follower.quality >= GARRISON_FOLLOWER_MAX_UPGRADE_QUALITY and follower.level >=GARRISON_FOLLOWER_MAX_LEVEL
+ local weaponItemID, weaponItemLevel, armorItemID, armorItemLevel = G.GetFollowerItems(follower.followerID);
+ follower.weaponItemID=weaponItemID
+ follower.weaponItemLevel=weaponItemLevel
+ follower.armorItemID=armorItemID
+ follower.armorItemLevel=armorItemLevel
+ follower.weaponQuality=select(3,GetItemInfo(weaponItemID))
+ follower.armorQuality=select(3,GetItemInfo(armorItemID))
end
end
end
@@ -2317,20 +2979,24 @@ function addon:GetFollowerData(key,subkey)
end
function addon:GetMissionData(missionID,subkey)
local missionCache=cache.missions[missionID]
- if (missionCache.name=="<newmission>") then
+ if (not missionCache) then
--@debug@
- xprint("Found a new mission",missionID,"Refreshing mission list")
+ xprint("Found a new mission",missionID,G.GetMissionName(missionID),"Refreshing it")
--@end-debug@
- self:BuildMissionsCache()
+ self:BuildMissionCache(missionID)
self:FillCounters(missionID,cache.missions[missionID])
self:MatchMaker(missionID,cache.missions[missionID])
end
+ if not missionCache then return end
if (subkey) then
return missionCache[subkey]
end
return missionCache
end
function addon:GetFollowerStatusForMission(followerID,skipbusy)
+ if (GMCUsedFollowers[followerID]) then
+ return false
+ end
if (not skipbusy) then
return true
else
@@ -2338,6 +3004,7 @@ function addon:GetFollowerStatusForMission(followerID,skipbusy)
end
end
function addon:GetFollowerStatus(followerID,withTime,colored)
+ if (not followerID) then return UNAVAILABLE end
local status=G.GetFollowerStatus(followerID)
if (status and status== GARRISON_FOLLOWER_ON_MISSION and withTime) then
local running=dbcache.running[dbcache.runningIndex[followerID]]
@@ -2357,7 +3024,7 @@ function addon:FillMissionPage(missionInfo)
--@debug@
xprint("UpdateMissionPage for",missionID,missionInfo.name,missionInfo.numFollowers)
--@end-debug@
- --DevTools_Dump(missionInfo)
+ --xdump(missionInfo)
--self:BuildMissionData(missionInfo.missionID.missionInfo)
GarrisonMissionPage_ClearParty()
local party=parties[missionID]
@@ -2388,9 +3055,9 @@ local firstcall=true
function addon:GrowPanel()
GCF:Show()
if (bigscreen) then
- GMF:ClearAllPoints()
- GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
- GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
+-- GMF:ClearAllPoints()
+-- GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
+-- GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
GMFRewardSplash:ClearAllPoints()
GMFRewardSplash:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
GMFRewardSplash:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
@@ -2407,11 +3074,13 @@ function addon:GrowPanel()
GMF.MissionCompleteBackground:SetWidth(BIGSIZEW)
else
GCF:SetWidth(GMF:GetWidth())
- GMF:ClearAllPoints()
- GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
- GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
+-- GMF:ClearAllPoints()
+-- GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT",0,-25)
+-- GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT",0,-25)
end
-
+ GMF:ClearAllPoints()
+ GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT",0,23)
+ GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT",0,23)
end
---@function
-- Return bias color for follower and mission
@@ -2437,34 +3106,49 @@ function addon:GetBiasColor(followerID,missionID,goodcolor)
end
return goodcolor
end
-function addon:FillFollowerButton(frame,followerID,missionID)
+function addon:RenderFollowerButton(frame,followerID,missionID)
if (not frame) then return end
- for i=1,#frame.Threats do
- if (frame.Threats[i]) then frame.Threats[i]:Hide() end
+ if (frame.Threats) then
+ for i=1,#frame.Threats do
+ if (frame.Threats[i]) then frame.Threats[i]:Hide() end
+ end
+ frame.NotFull:Hide()
end
- frame.NotFull:Hide()
if (not followerID) then
- frame.PortraitFrame.Empty:Show()
- frame.Name:Hide()
- frame.Class:Hide()
- frame.Status:Hide()
+ if (frame.Name) then
+ frame.PortraitFrame.Empty:Show()
+ frame.Name:Hide()
+ frame.Class:Hide()
+ frame.Status:Hide()
+ else
+ frame.PortraitFrame.Empty:Hide()
+ frame.PortraitFrame.Portrait:Show()
+ frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_iLvlBorder");
+ frame.PortraitFrame.LevelBorder:SetWidth(70);
+ frame.PortraitFrame.Level:SetText(MISSING)
+ frame.PortraitFrame.Level:SetTextColor(1,0,0,0.7)
+ end
frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_LevelBorder");
frame.PortraitFrame.LevelBorder:SetWidth(58);
- frame.PortraitFrame.Level:SetText("")
- --frame:SetScript("OnEnter",nil)
GarrisonFollowerPortrait_Set(frame.PortraitFrame.Portrait)
+ frame.PortraitFrame.PortraitRingQuality:SetVertexColor(C.Silver());
+ frame.PortraitFrame.LevelBorder:SetVertexColor(C.Silver());
return
end
- local info=G.GetFollowerInfo(followerID)
- --local info=followers[ID]
+ frame.PortraitFrame.Level:SetTextColor(1,1,1,1)
+ frame.PortraitFrame.Portrait:Show()
+ local info=self:GetFollowerData(followerID)
+ if (not info) then return end
frame.info=info
frame.missionID=missionID
- frame.Name:Show();
- frame.Name:SetText(info.name);
- local color=missionID and self:GetBiasColor(followerID,missionID,"White") or "Yellow"
- frame.Name:SetTextColor(C[color]())
- frame.Status:SetText(self:GetFollowerStatus(followerID,true,true))
- frame.Status:Show()
+ if (frame.Name) then
+ frame.Name:Show()
+ frame.Name:SetText(info.name);
+ local color=missionID and self:GetBiasColor(followerID,missionID,"White") or "Yellow"
+ frame.Name:SetTextColor(C[color]())
+ frame.Status:SetText(self:GetFollowerStatus(followerID,true,true))
+ frame.Status:Show()
+ end
if (frame.Class) then
frame.Class:Show();
frame.Class:SetAtlas(info.classAtlas);
@@ -2472,7 +3156,7 @@ function addon:FillFollowerButton(frame,followerID,missionID)
frame.PortraitFrame.Empty:Hide();
local showItemLevel;
- if (info.level == GarrisonMissionFrame.followerMaxLevel ) then
+ if (info.level == GMF.followerMaxLevel ) then
frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_iLvlBorder");
frame.PortraitFrame.LevelBorder:SetWidth(70);
showItemLevel = true;
@@ -2483,22 +3167,24 @@ function addon:FillFollowerButton(frame,followerID,missionID)
end
GarrisonMissionFrame_SetFollowerPortrait(frame.PortraitFrame, info, showItemLevel);
-- Counters icon
- if (missionID and not GMF.MissionTab.MissionList.showInProgress) then
- local tohide=1
- local missionCounters=counters[missionID]
- local index=counterFollowerIndex[missionID][followerID]
- for i=1,#index do
- local k=index[i]
- local t=frame.Threats[i]
- local tx=missionCounters[k].icon
- t.Icon:SetTexture(tx)
- local color=self:GetBiasColor(missionCounters[k].bias,nil,"Green")
- t.Border:SetVertexColor(C[color]())
- t:Show()
- tohide=i+1
+ if (frame.Name) then
+ if (missionID and not GMF.MissionTab.MissionList.showInProgress) then
+ local tohide=1
+ local missionCounters=counters[missionID]
+ local index=counterFollowerIndex[missionID][followerID]
+ for i=1,#index do
+ local k=index[i]
+ local t=frame.Threats[i]
+ local tx=missionCounters[k].icon
+ t.Icon:SetTexture(tx)
+ local color=self:GetBiasColor(missionCounters[k].bias,nil,"Green")
+ t.Border:SetVertexColor(C[color]())
+ t:Show()
+ tohide=i+1
+ end
+ else
+ frame.Status:Hide()
end
- else
- frame.Status:Hide()
end
end
-- pseudo static
@@ -2507,11 +3193,15 @@ function addon:BuildFollowersButtons(button,bg,limit)
if (bg.Party) then return end
bg.Party={}
for numMembers=1,3 do
- local f=CreateFrame("Button",nil,bg,"GarrisonCommanderMissionPageFollowerTemplate")
+ local f=CreateFrame("Button",nil,bg,bigscreen and "GarrisonCommanderMissionPageFollowerTemplate" or "GarrisonCommanderMissionPageFollowerTemplateSmall" )
if (numMembers==1) then
- f:SetPoint("BOTTOMLEFT",bg.Percent,"BOTTOMRIGHT",10,0)
+ f:SetPoint("BOTTOMLEFT",button.Rewards[1],"BOTTOMRIGHT",10,0)
else
- f:SetPoint("LEFT",bg.Party[numMembers-1],"RIGHT",10,0)
+ if (bigscreen) then
+ f:SetPoint("LEFT",bg.Party[numMembers-1],"RIGHT",10,0)
+ else
+ f:SetPoint("LEFT",bg.Party[numMembers-1],"LEFT",65,0)
+ end
end
tinsert(bg.Party,f)
f:EnableMouse(true)
@@ -2519,14 +3209,16 @@ function addon:BuildFollowersButtons(button,bg,limit)
f:SetScript("OnLeave",GarrisonMissionPageFollowerFrame_OnLeave)
f:RegisterForClicks("AnyUp")
f:SetScript("OnClick",function(...) self:OnClick_PartyMember(...) end)
- for numThreats=1,4 do
- local threatFrame =f.Threats[numThreats];
- if ( not threatFrame ) then
- threatFrame = CreateFrame("Frame", nil, f, "GarrisonAbilityCounterTemplate");
- threatFrame:SetPoint("LEFT", f.Threats[numThreats - 1], "RIGHT", 10, 0);
- tinsert(f.Threats, threatFrame);
+ if (bigscreen) then
+ for numThreats=1,4 do
+ local threatFrame =f.Threats[numThreats];
+ if ( not threatFrame ) then
+ threatFrame = CreateFrame("Frame", nil, f, "GarrisonAbilityCounterTemplate");
+ threatFrame:SetPoint("LEFT", f.Threats[numThreats - 1], "RIGHT", 10, 0);
+ tinsert(f.Threats, threatFrame);
+ end
+ threatFrame:Hide()
end
- threatFrame:Hide()
end
end
for i=1,3 do bg.Party[i]:SetScale(0.9) end
@@ -2539,123 +3231,109 @@ function addon:BuildFollowersButtons(button,bg,limit)
button.Threats[1]:ClearAllPoints()
button.Threats[1]:SetPoint("TOPLEFT",165,0)
end
-
-
-
end
function addon:RenderExtraButton(button,numRewards)
- local panel=button.gcPANEL
+ local panel=button.gcINDICATOR
local missionInfo=button.info
local missionID=missionInfo.missionID
panel.missionID=missionID
+ local mission=missionInfo
+ if not mission then print "not yet updated missions" return end -- something went wrong while refreshing
+ if (not bigscreen) then
+ local index=mission.numFollowers+numRewards-3
+ local position=(index * -65) - 130
+ button.gcPANEL.Party[1]:ClearAllPoints()
+ button.gcPANEL.Party[1]:SetPoint("BOTTOMLEFT",button.Rewards[1],"BOTTOMLEFT", position,0)
+ end
if (GMF.MissionTab.MissionList.showInProgress) then
local perc=select(4,G.GetPartyMissionInfo(missionID))
panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
panel.Age:Hide()
- local q=self:GetDifficultyColor(perc)
- panel.Percent:SetTextColor(q.r,q.g,q.b)
- if (bigscreen) then
- for i=1,3 do
- local frame=panel.Party[i]
- if (missionInfo.followers[i]) then
- self:FillFollowerButton(frame,missionInfo.followers[i],missionID)
- frame:Show()
- else
- frame:Hide()
- end
- end
- if ( missionInfo.locPrefix ) then
- panel.LocBG:Show();
- panel.LocBG:SetAtlas(missionInfo.locPrefix.."-List");
+ panel.Percent:SetTextColor(self:GetDifficultyColors(perc))
+ for i=1,3 do
+ local frame=button.gcPANEL.Party[i]
+ if (missionInfo.followers[i]) then
+ self:RenderFollowerButton(frame,missionInfo.followers[i],missionID)
+ frame:Show()
else
- panel.LocBG:Hide();
+ frame:Hide()
end
end
return
end
- local mission=self:GetMissionData(missionID)
local party=parties[missionID]
if (#party.members==0) then
+ local mission=self:GetMissionData(missionID) -- matchmaker and fillcounters need our enriched mission
self:FillCounters(missionID,mission)
self:MatchMaker(missionID,mission,party)
end
local perc=party.perc
local age=tonumber(dbcache.seen[missionID])
local notFull=false
- if (bigscreen) then
- for i=1,3 do
- local frame=button.gcPANEL.Party[i]
- if (i>mission.numFollowers) then
- frame:Hide()
+ for i=1,3 do
+ local frame=button.gcPANEL.Party[i]
+ if (i>mission.numFollowers) then
+ frame:Hide()
+ else
+ if (party.members[i]) then
+ self:RenderFollowerButton(frame,party.members[i],missionID)
+ if (bigscreen) then frame.NotFull:Hide() end
else
- if (party.members[i]) then
- self:FillFollowerButton(frame,party.members[i],missionID)
- frame.NotFull:Hide()
- else
- self:FillFollowerButton(frame,false)
- frame.NotFull:Show()
- end
- frame:Show()
+ self:RenderFollowerButton(frame,false)
+ if (bigscreen) then frame.NotFull:Show() end
end
- end
- if ( mission.locPrefix ) then
- panel.LocBG:Show();
- panel.LocBG:SetAtlas(mission.locPrefix.."-List");
- else
- panel.LocBG:Hide();
+ frame:Show()
end
end
+ panel=button.gcINDICATOR
panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
- local q=self:GetDifficultyColor(perc)
- panel.Percent:SetTextColor(q.r,q.g,q.b)
+ panel.Percent:SetTextColor(self:GetDifficultyColors(perc))
panel.Percent:SetWidth(80)
panel.Percent:SetJustifyH("RIGHT")
if (age) then
- local day=60*24
- age=floor((time()-age)/60)
- local days=floor(age/day)
- if (days==0) then
- local hours=floor(age/60)
- panel.Age:SetFormattedText(AGE_HOURS,hours, age -hours*60 )
- panel.Age:SetTextColor(C.Green())
+ local expire=ns.wowhead[missionID]
+ if (expire==9999999) then
+ panel.Age:SetText("Expires: Far far away")
+ panel.Age:SetTextColor(C.White())
+ elseif (expire==0) then
+ panel.Age:SetText("Expires: " .. UNKNOWN)
+ panel.Age:SetTextColor(C.White())
else
- local q=self:GetDifficultyColor(100-(days*10),true)
+ local age=(age+expire-time())/60
+ if age < 0 then age=0 end
+ local hours=(floor((age/60)/6)+1)*6
+ local q=self:GetDifficultyColor(hours+20,true)
+ panel.Age:SetFormattedText("Expires in less than %d hr",hours)
panel.Age:SetTextColor(q.r,q.g,q.b)
- panel.Age:SetFormattedText(AGE_DAYS,days,(age-days*day)/60)
end
else
panel.Age:SetText(UNKNOWN)
end
panel.Age:Show()
panel.Percent:Show()
- if (not bigscreen) then
- panel:SetPoint("TOPRIGHT",numRewards *-75 - (GMM and 65 or 0),0)
- panel.Followers:SetFormattedText(GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS,mission.numFollowers)
- end
+end
+function addon:CheckExpire(missionID)
+ local age=tonumber(dbcache.seen[missionID])
+ local expire=ns.wowhead[missionID]
+ print("Age",date("%m/%d/%y %H:%M:%S",age))
+ print("Now",date("%m/%d/%y %H:%M:%S"))
+ print("Expire",expire,ns.expire[missionID])
+ print("Age+expire",date("%m/%d/%y %H:%M:%S",age+expire))
+ print("Delta",age+expire-time())
end
function addon:BuildExtraButton(button)
- if (bigscreen) then
- local bg=CreateFrame("Button",nil,button,"GarrisonCommanderMissionButton")
- bg:SetPoint("TOPLEFT",button,"TOPRIGHT")
- bg:SetPoint("RIGHT",GarrisonMissionFrameMissionsListScrollFrame,"RIGHT",-25,0)
- bg.button=button
- bg:SetScript("OnEnter",function(this) GarrisonMissionButton_OnEnter(this.button) end)
- bg:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
- bg:RegisterForClicks("AnyUp")
- bg:SetScript("OnClick",function(...) self:OnClick_GCMissionButton(...) end)
- button.gcPANEL=bg
- if (not bg.Party) then self:BuildFollowersButtons(button,bg,3) end
- else
- local bg=button.GC
- if (not bg) then
- bg=CreateFrame("Button",nil,button,"GarrisonCommanderMissionInfo")
- bg:SetHeight(button:GetHeight())
- button.gcPANEL=bg
- bg.button=button
- bg:SetScript("OnEnter",function(this) GarrisonMissionButton_OnEnter(this.button,"LeftUp") end)
- bg:SetScript("OnLeave",function(this) GameTooltip:FadeOut() end)
- end
- end
+ local bg=CreateFrame("Button",nil,button,"GarrisonCommanderMissionButton")
+ local indicators=CreateFrame("Frame",nil,button,"GarrisonCommanderIndicators")
+ indicators:SetPoint("LEFT",70,0)
+ bg:SetPoint("RIGHT")
+ bg.button=button
+ bg:SetScript("OnEnter",function(this) GarrisonMissionButton_OnEnter(this.button) end)
+ bg:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
+ bg:RegisterForClicks("AnyUp")
+ bg:SetScript("OnClick",function(...) self:OnClick_GCMissionButton(...) end)
+ button.gcPANEL=bg
+ button.gcINDICATOR=indicators
+ if (not bg.Party) then self:BuildFollowersButtons(button,bg,3) end
end
--function addon:GarrisonMissionButton_SetRewards(button,rewards,numrewards)
--end
@@ -2741,24 +3419,25 @@ function addon:OnClick_GarrisonMissionFrame_MissionComplete_NextMissionButton(th
end
end
function addon:OnClick_GarrisonMissionButton(tab,button)
+ if (GMF.MissionTab.MissionList.showInProgress) then
+ return
+ end
--@debug@
- trace("Clicked")
+ xprint("Clicked GarrisonMissionButto")
--@end-debug@
if (tab.fromFollowerPage) then
GarrisonMissionFrame_SelectTab(1)
self:FillMissionPage(tab.info)
else
--@debug@
- DevTools_Dump(tab.info)
+ xdump(tab.info)
--@end-debug@
self:FillMissionPage(tab.info)
end
end
function addon:OnClick_GCMissionButton(frame,button)
if (button=="RightButton") then
-
self:HookedGarrisonMissionButton_SetRewards(frame:GetParent(),{},0)
- _G.DBG=frame.button.info.missionID
else
frame.button:Click()
end
@@ -2774,99 +3453,124 @@ function addon:RenderButton(button,rewards,numRewards)
return
--@end-debug@
end
- --if (self:IsRewardPage()) then return end
+ local missionID=button.info.missionID
+ if GMF.MissionTab.MissionList.showInProgress and missionID==button.lastMissionID then return end
+ button.lastMissionID=missionID
if (bigscreen) then
local width=GMF.MissionTab.MissionList.showInProgress and BIGBUTTON or SMALLBUTTON
- button:SetWidth(width)
- button.LocBG:SetPoint("LEFT")
+ button:SetWidth(width+600)
+ button.Rewards[1]:SetPoint("RIGHT",button,"RIGHT",-500 - (GMM and 40 or 0),0)
+ end
+ if (not button.xp) then
+ button.xp=button:CreateFontString(nil, "ARTWORK", "QuestMaprewardsFont")
+ button.xp:SetPoint("TOPRIGHT",button.Rewards[1],"TOPRIGHT")
+ button.xp:SetJustifyH("RIGHT")
+ button.xp:Show()
+
end
- local tw=button:GetWidth()-165 - (GMM and 65 or 0)
- if ( button.Title:GetWidth() + button.Summary:GetWidth() + 8 < tw - numRewards * 65 ) then
+ button.MissionType:SetPoint("TOPLEFT",5,-2)
+ button.xp:SetWidth(0)
+ if (not GMF.MissionTab.MissionList.showInProgress) then
+ button.xp:SetFormattedText("Xp: %d (approx)",self:GetMissionData(missionID,'globalXp'))
+ button.xp:SetTextColor(self:GetDifficultyColors(self:GetMissionData(missionID,'totalXp')/3000*100))
+ else
+ button.xp:Hide()
+ end
+ --button.Title:SetText("123456789012345678901234567890123456789012345678901234567890") -- Used for design
+ local offset= bigscreen and (numRewards *65) or (button.info.numFollowers+numRewards) *65
+ local tw=button:GetWidth() - 165
+ if (button.Title:GetWidth() + button.Summary:GetWidth() + button.xp:GetWidth() < (tw -offset) ) then
button.Title:SetPoint("LEFT", 165, 5);
button.Summary:ClearAllPoints();
button.Summary:SetPoint("BOTTOMLEFT", button.Title, "BOTTOMRIGHT", 8, 0);
else
button.Title:SetPoint("LEFT", 165, 25);
- button.Title:SetWidth(tw - numRewards * 65);
+ button.Title:SetWidth(tw - offset);
button.Summary:ClearAllPoints();
button.Summary:SetPoint("TOPLEFT", button.Title, "BOTTOMLEFT", 0, -4);
end
- local missionID=button.info.missionID
- if (not button.Threats) then -- I am a good guy. If MP present, I dont make my own threat indicator (Only MP <= 1.8)
- if (not button.Env) then
- button.Env=CreateFrame("Frame",nil,button,"GarrisonAbilityCounterTemplate")
- button.Env:SetWidth(20)
- button.Env:SetHeight(20)
- button.Env:SetPoint("BOTTOMLEFT",button,165,8)
- button.GcThreats={}
- end
- local slots=self:GetMissionData(missionID,'slots')
- local threatIndex=1
- if (not GMF.MissionTab.MissionList.showInProgress) then
- button.Env:Show()
- dbg=missionID==(tonumber(_G.MW) or 0)
- if (dbg) then self:DumpParty(missionID) end
- for i=1,#slots do
- local slot=slots[i]
- if (slot.name==TYPE) then
- button.Env.Icon:SetTexture(slot.icon)
- self:SetThreatColor(button.Env,missionID)
- button.Env.info=self.db.global.types[slot.key]
- button.Env:SetScript("OnEnter",GarrisonMissionMechanic_OnEnter)
- button.Env:SetScript("OnLeave",function() GarrisonMissionMechanicTooltip:Hide() end)
- else
- local th=button.GcThreats[threatIndex]
- if (not th) then
- th=CreateFrame("Frame",nil,button,"GarrisonAbilityCounterTemplate")
- th:SetWidth(20)
- th:SetHeight(20)
- button.GcThreats[threatIndex]=th
- th:SetPoint("BOTTOMLEFT",button,165 + 35 * threatIndex,8)
+ local threatIndex=1
+ if (not GMF.MissionTab.MissionList.showInProgress) then
+ if (not button.Threats) then -- I am a good guy. If MP present, I dont make my own threat indicator (Only MP <= 1.8)
+ if (not button.Env) then
+ button.Env=CreateFrame("Frame",nil,button,"GarrisonAbilityCounterTemplate")
+ button.Env:SetWidth(20)
+ button.Env:SetHeight(20)
+ button.Env:SetPoint("BOTTOMLEFT",button,165,8)
+ button.GcThreats={}
+ end
+ local slots=self:GetMissionData(missionID,'slots')
+ if (not GMF.MissionTab.MissionList.showInProgress) then
+ button.Env:Show()
+ if (dbg) then self:DumpParty(missionID) end
+ for i=1,#slots do
+ local slot=slots[i]
+ if (slot.name==TYPE) then
+ button.Env.Icon:SetTexture(slot.icon)
+ self:SetThreatColor(button.Env,missionID)
+ button.Env.info=self.db.global.types[slot.key]
+ button.Env:SetScript("OnEnter",function(...) addon:ClonedGarrisonMissionMechanic_OnEnter(missionID,...) end)
+ button.Env:SetScript("OnLeave",function() GameTooltip:Hide() end)
+ else
+ local th=button.GcThreats[threatIndex]
+ if (not th) then
+ th=CreateFrame("Frame",nil,button,"GarrisonAbilityCounterTemplate")
+ th:SetWidth(20)
+ th:SetHeight(20)
+ th:SetPoint("BOTTOMLEFT",button,165 + 35 * threatIndex,8)
+ button.GcThreats[threatIndex]=th
+ end
th.info=slot
- th:SetScript("OnEnter",GarrisonMissionMechanic_OnEnter)
- th:SetScript("OnLeave",function() GarrisonMissionMechanicTooltip:Hide() end)
+ threatIndex=threatIndex+1
+ th.Icon:SetTexture(slot.icon)
+ self:SetThreatColor(th,missionID)
+ th:Show()
+ th:SetScript("OnEnter",function(...) addon:ClonedGarrisonMissionMechanic_OnEnter(missionID,...) end)
+ th:SetScript("OnLeave",function() GameTooltip:Hide() end)
end
- threatIndex=threatIndex+1
- th.Icon:SetTexture(slot.icon)
- self:SetThreatColor(th,missionID)
- th:Show()
end
+ else
+ button.Env:Hide()
end
- else
- button.Env:Hide()
end
- for i=threatIndex,#button.GcThreats do
- button.GcThreats[i]:Hide()
+ if (numRewards > 0) then
+ local index=1
+ for id,reward in pairs(rewards) do
+ local Reward = button.Rewards[index];
+ Reward.Quantity:SetTextColor(C.Yellow())
+ if (reward.followerXP) then
+ Reward.Quantity:SetText(reward.followerXP)
+ Reward.Quantity:Show()
+ elseif (reward.currencyID==0) then
+ Reward.Quantity:SetFormattedText("%d",reward.quantity/10000)
+ Reward.Quantity:Show()
+ elseif (reward.itemID and reward.itemID==120205) then
+ Reward.Quantity:SetFormattedText("%d",self:GetMissionData(missionID,'xp') or 1)
+ Reward.Quantity:Show()
+ elseif (reward.itemID and reward.quantity==1) then
+ local _,_,q,i=GetItemInfo(reward.itemID)
+ Reward.Quantity:SetText(i)
+ local c=ITEM_QUALITY_COLORS[q]
+ if (not c) then
+ Reward.Quantity:SetTextColor(1,1,1)
+ else
+ Reward.Quantity:SetTextColor(c.r,c.g,c.b)
+ end
+ Reward.Quantity:Show()
+ end
+ index=index+1
+ end
end
+ else
+ if (button.Env) then button.Env:Hide() end
end
- if (numRewards > 0) then
- local index=1
- for id,reward in pairs(rewards) do
- local Reward = button.Rewards[index];
- Reward.Quantity:SetTextColor(C.Yellow())
- if (reward.followerXP) then
- Reward.Quantity:SetText(reward.followerXP)
- Reward.Quantity:Show()
- elseif (reward.currencyID==0) then
- Reward.Quantity:SetFormattedText("%d",reward.quantity/10000)
- Reward.Quantity:Show()
- elseif (reward.itemID and reward.quantity==1) then
- local _,_,q,i=GetItemInfo(reward.itemID)
- local c=ITEM_QUALITY_COLORS[q]
- if (not c) then c={r=1,g=1,b=1} end
- Reward.Quantity:SetText(i)
- Reward.Quantity:SetTextColor(c.r,c.g,c.b)
- Reward.Quantity:Show()
- end
- index=index+1
+ if (button.GcThreats) then
+ for i=threatIndex,#button.GcThreats do
+ button.GcThreats[i]:Hide()
end
end
if (button.fromFollowerPage) then
- --button.Title:ClearAllPoints()
- --button.Title:SetPoint("TOPLEFT",165,-5)
- --button.Summary:ClearAllPoints()
- --button.Summary:SetPoint("BOTTOMLEFT",165,5)
- --button:SetHeight(70)
+ print("From follower page")
return
end
if (not button.gcPANEL) then
@@ -2874,213 +3578,703 @@ function addon:RenderButton(button,rewards,numRewards)
end
self:RenderExtraButton(button,numRewards)
end
---@do-not-package@
-_G.GAC=addon
---[[
-GMFMissions.CompleteDialog.BorderFrame.CompleteAll
-Garrison page structure
-Tab selection:
-Managed by
-GarrisonMissionFrameTab(1|2) onclick:
-->GarrisonMissionFrameTab_OnClick(self)
---->GarrisonMissionFrame_SelectTab(self:GetID()) - 1 for Missions, 2 for followers
+-- Courtesy of Motig
+-- Concept and interface reused with permission
+-- Mission building rewritten from scratch
+local GMC_G = {}
+--GMC_G.frame = CreateFrame('FRAME')
+local aMissions={}
-Main Container is GarrisonMissionFrame
-Followers tab selected:
-->GarrisonMissionFrameFollowers -> anchored GarrisonMissionFrame TOPLEFT 33,-64
--->GarrisonMissionFrameFollowersListScrollFrame
---->GarrisonMissionFrameFollowersListScrooFrameScrollChild
----->GarrisonMissionFrameFollowersListScrooFrameButton(1..9)
-->GarrisonMissionFrame.FollowerTab -> abcuored GarrisonMissionFrame TOPRIGHT -35 -64
-Missions tab selected
-->GarrisonMissionFrameMissions -> anchored (parent)e TOPLEFT 35,-65
+function addon:GMCCreateMissionList(workList)
+ --First get rid of unwanted rewards and missions that are too long
+ local settings=self.privatedb.profile.missionControl
+ local ar=settings.allowedRewards
+ wipe(workList)
+ for missionID,mission in pairs(cache.missions) do
+ local discarded=false
+ repeat
+ if (mission.durationSeconds > settings.maxDuration * 3600 or mission.durationSeconds < settings.minDuration * 3600) then
+ xprint(missionID,"discarded due to len",mission.durationSeconds /3600)
+ break
+ end -- Mission too long, out of here
+ if (mission.isRare and settings.skipRare) then
+ xprint(missionID,"discarded due to rarity")
+ break
+ end
+ for k,v in pairs(ar) do
+ if (not v) then
+ if (mission[k] and mission[k]~=0) then -- we have a forbidden reward
+ discarded=true
+ break
+ end
+ end
+ end
+ if (not discarded) then
+ tinsert(workList,missionID)
+ end
+ until true
+ end
+ local function msort(i1,i2)
+ local m1=addon:GetMissionData(i1)
+ local m2=addon:GetMissionData(i2)
+ for i=1,#GMC.settings.itemPrio do
+ local criterium=GMC.settings.itemPrio[i]
+ xprint("Checking",criterium)
+ if (criterium) then
+ xprint(i1,i2,"Sorting on ",criterium,m1[criterium] , m2[criterium])
+ if (m1[criterium] ~= m2[criterium]) then
+ xprint(i1,i2,"Sorted on ",criterium,m1[criterium] , m2[criterium])
+ return m1[criterium] > m2[criterium]
+ end
+ end
+ end
+ xprint(i1,i2,"Sorted on level",m1.level , m2.level)
+ return m1.level > m2.level
+ end
+ table.sort(workList,msort)
+end
+local factory={} --#factory
+do
+ local nonce=0
+ local GetTime=GetTime
+ function factory:Slider(father,min,max,current,message)
+ local name=tostring(self)..GetTime()*1000 ..nonce
+ nonce=nonce+1
+ local sl = CreateFrame('Slider',name, father, 'OptionsSliderTemplate')
+ sl:SetWidth(128)
+ sl:SetHeight(20)
+ sl:SetOrientation('HORIZONTAL')
+ sl:SetMinMaxValues(min, max)
+ sl:SetValue(current)
+ sl:SetValueStep(1)
+ sl.Low=_G[name ..'Low']
+ sl.Low:SetText(min)
+ sl.High=_G[name .. 'High']
+ sl.High:SetText(max)
+ sl.Text=_G[name.. 'Text']
+ sl.Text:SetText(message)
+ sl.OnValueChanged=function(this,value)
+ if (not this.unrounded) then
+ value = math.floor(value)
+ end
+ if (this.isPercent) then
+ this.Text:SetFormattedText('%d%%',value)
+ else
+ this.Text:SetText(value)
+ end
+ return value
+ end
+ sl:SetScript("OnValueChanged",sl.OnValueChanged)
+ return sl
+ end
+ function factory:Checkbox(father,current,message)
+ local name=tostring(self)..GetTime()*1000 ..nonce
+ nonce=nonce+1
+ local ck=CreateFrame("CheckButton",name,father,"ChatConfigCheckButtonTemplate")
+ ck.Text=_G[name..'Text']
+ ck.Text:SetText(message)
+ ck:SetChecked(current)
+ return ck
+ end
+end
+--- This routine can be called both as coroutin and as a standard one
+-- In standard version, delay between group building and submitting is done via a self schedule
+--@param #integer missionID Optional, to run a single mission
+--@param #bool start Optional, tells that follower already are on mission and that we need just to start it
+function addon:GMCRunMission(missionID,start)
+ xprint("Asked to start mission",missionID)
+ if (start) then
+ G.StartMission(missionID)
+ PlaySound("UI_Garrison_CommandTable_MissionStart")
+ return
+ end
+ for i=1,#GMC.ml.Parties do
+ local party=GMC.ml.Parties[i]
+ xprint("Checking",party.missionID)
+ if (missionID and party.missionID==missionID or not missionID) then
+ GMC.ml.widget:RemoveChild(party.missionID)
+ GMC.ml.widget:DoLayout()
+ if (party.full) then
+ for j=1,#party.members do
+ G.AddFollowerToMission(party.missionID, party.members[j])
+ end
+ if (not missionID) then
+ coroutine.yield(true)
+ G.StartMission(party.missionID)
+ PlaySound("UI_Garrison_CommandTable_MissionStart")
+ coroutine.yield(true)
+ else
+ self:ScheduleTimer("GMCRunMission",0.25,party.missionID,true)
+ end
+ end
+ end
+ end
+end
+do
+ local timeElapsed=0
+ local currentMission=0
+ local x=0
+ function addon:GMCCalculateMissions(this,elapsed)
+ db.news.MissionControl=true
+ timeElapsed = timeElapsed + elapsed
+ if (#aMissions == 0 ) then
+ if timeElapsed >= 1 then
+ currentMission=0
+ x=0
+ self:Unhook(this,"OnUpdate")
+ GMC.ml.widget:SetTitle(READY)
+ GMC.ml.widget:SetTitleColor(C.Green())
+ this:Enable()
+ if (#GMC.ml.Parties>0) then
+ GMC.runButton:Enable()
+ end
+ end
+ return
+ end
+ if (timeElapsed >=0.) then
+ currentMission=currentMission+1
+ if (currentMission > #aMissions) then
+ wipe(aMissions)
+ currentMission=0
+ x=0
+ timeElapsed=0.2
+ else
+ GMC.ml.widget:SetFormattedTitle("Processing mission %d of %d",currentMission,#aMissions)
+ local missionID=aMissions[currentMission]
+ if (dbg) then print(C("Processing ","Red"),missionID) end
+ local party={members={},perc=0}
+ local mission=self:GetMissionData(missionID)
+ if (not mission ) then
+ if dbg then print ("NO data for",missionID) end
+ return
+ end
+ self:MatchMaker(missionID,mission,party) -- I need my mission data
+ local minimumChance=0
+ if (GMC.settings.useOneChance) then
+ minimumChance=GMC.settings.minimumChance
+ end
+ for prio,enabled in pairs(GMC.settings.allowedRewards) do
+ if (dbg) then print("Chance from ",prio,"=",GMC.settings.rewardChance[prio],enabled) end
+ if (enabled and (tonumber(self:GetMissionData(missionID,prio)) or 0) >0) then
+ minimumChance=math.max(GMC.settings.rewardChance[prio],minimumChance)
+ end
+ end
+ if (dbg) then print ("Missionid",missionID,"Chance",minimumChance,"chance",party.perc) end
+ if ( party.full and party.perc >= minimumChance) then
+ if (dbg) then print("Preparing button for",missionID) end
+ local mb=AceGUI:Create("GMCMissionButton")
+ for i=1,#party.members do
+ GMCUsedFollowers[party.members[i]]=true
+ end
+ party.missionID=missionID
+ tinsert(GMC.ml.Parties,party)
+ GMC.ml.widget:PushChild(mb,missionID)
+ mb:SetFullWidth(true)
+ mb:SetMission(mission)
+ mb:SetCallback("OnClick",function(...)
+ addon:GMCRunMission(missionID)
+ GMC.ml.widget:RemoveChild(missionID)
+ end
+ )
+ end
+ timeElapsed=0
+ end
+ end
+ end
+end
+function addon:GMC_OnClick_Run(this,button)
+ this:Disable()
+ do
+ local elapsed=0
+ local co=coroutine.wrap(self.GMCRunMission)
+ self:RawHookScript(GMC.runButton,'OnUpdate',function(this,ts)
+ elapsed=elapsed+ts
+ if (elapsed>0.25) then
+ elapsed=0
+ local rc=co(self)
+ if (not rc) then
+ self:Unhook(GMC.runButton,'OnUpdate')
+ end
+ end
+ end
+ )
+ end
+end
+function addon:GMC_OnClick_Start(this,button)
+ xprint(C("-------------------------------------------------","Yellow"))
+ this:Disable()
+ GMC.ml.widget:ClearChildren()
+ addon:GMCCreateMissionList(aMissions)
+ wipe(GMCUsedFollowers)
+ wipe(GMC.ml.Parties)
+ if (#aMissions>0) then
+ GMC.ml.widget:SetFormattedTitle(L["Processing mission %d of %d"],1,#aMissions)
+ else
+ GMC.ml.widget:SetTitle("No mission matches your criteria")
+ GMC.ml.widget:SetTitleColor(C.Red())
+ end
+ self:RawHookScript(GMC.startButton,'OnUpdate',"GMCCalculateMissions")
+end
+local chestTexture
+function addon:GMCBuildPanel()
+ --PanelTemplates_SetNumTabs(GarrisonMissionFrame, 4)
+ --PanelTemplates_UpdateTabs(GarrisonMissionFrame)
+ chestTexture='GarrMission-'..UnitFactionGroup('player').. 'Chest'
+ GMC = CreateFrame('FRAME', 'GMCOptions', GarrisonMissionFrame)
+ GMC.settings=dbcache.missionControl
+ GMC:SetPoint('CENTER')
+ GMC:SetSize(GarrisonMissionFrame:GetWidth(), GarrisonMissionFrame:GetHeight())
+ GMC:Hide()
+ local chance=self:GMCBuildChance()
+ local duration=self:GMCBuildDuration()
+ local rewards=self:GMCBuildRewards()
+ local priorities=self:GMCBuildPriorities()
+ local list=self:GMCBuildMissionList()
+ duration:SetPoint("TOPLEFT",0,-50)
+ chance:SetPoint("TOPLEFT",duration,"TOPRIGHT",bigscreen and 50 or 10,0)
+ priorities:SetPoint("TOPLEFT",duration,"BOTTOMLEFT",25,-40)
+ rewards:SetPoint("TOPLEFT",priorities,"TOPRIGHT",bigscreen and 50 or 15,0)
+ list:SetPoint("TOPLEFT",chance,"TOPRIGHT",10,0)
+ list:SetPoint("BOTTOMRIGHT",GMF,"BOTTOMRIGHT",-25,25)
+ GMC.skipRare=factory:Checkbox(GMC,GMC.settings.skipRare,L["Ignore rare missions"])
+ GMC.skipRare:SetPoint("TOPLEFT",priorities,"BOTTOMLEFT",0,-10)
+ GMC.startButton = CreateFrame('BUTTON',nil, list.frame, 'GameMenuButtonTemplate')
+ GMC.startButton:SetText('Calculate')
+ GMC.startButton:SetWidth(148)
+ GMC.startButton:SetPoint('TOPLEFT',15,25)
+ GMC.startButton:SetScript('OnClick', function(this,button) self:GMC_OnClick_Start(this,button) end)
+ GMC.startButton:SetScript('OnEnter', function() GameTooltip:SetOwner(GMC.startButton, 'ANCHOR_TOPRIGHT') GameTooltip:AddLine('Assign your followers to missions.') GameTooltip:Show() end)
+ GMC.startButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
+ GMC.runButton = CreateFrame('BUTTON', nil,list.frame, 'GameMenuButtonTemplate')
+ GMC.runButton:SetText('Send all mission at once')
+ GMC.runButton:SetScript('OnEnter', function()
+ GameTooltip:SetOwner(GMC.runButton, 'ANCHOR_TOPRIGHT')
+ GameTooltip:AddLine('Submit all yopur mission at once. No question asked.')
+ GameTooltip:AddLine('You can also send mission one by one clicking on each button.')
+ GameTooltip:Show()
+ end)
+ GMC.runButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
+ GMC.runButton:SetWidth(148)
+ GMC.runButton:SetPoint('TOPRIGHT',-15,25)
+ GMC.runButton:SetScript('OnClick',function(this,button) self:GMC_OnClick_Run(this,button) end)
+ GMC.runButton:Disable()
+ GMC.Credits=GMC:CreateFontString(nil,"ARTWORK","ReputationDetailFont")
+ GMC.Credits:SetWidth(0)
+ GMC.Credits:SetFormattedText("Original concept and interface by %s",C("Motig","Red") )
+ GMC.Credits:SetPoint("BOTTOMLEFT",25,25)
+end
+function addon:GMCRewardRefresh()
+ local single=GMC.settings.useOneChance
+ local ref
+ for i=1,#GMC.ignoreFrames do
+ local frame=GMC.ignoreFrames[i]
+ local allowed=GMC.settings.allowedRewards[frame.key]
+ frame.icon:SetDesaturated(not allowed)
+ local a1,o,a2,x,y=frame:GetPoint(1)
+ if (not single) then
+ frame.chest:Show()
+ frame.slider:Show()
+ frame:SetPoint(a1,o,a2,0,y)
+ else
+ frame.chest:Hide()
+ frame.slider:Hide()
+ frame:SetPoint(a1,o,a2,100,y)
+ end
+ ref=frame
+ end
+ if (single) then
+ GMC.itf2:SetPoint('TOPLEFT',ref,'BOTTOMLEFT', -110, -15)
+ GMC.cp:SetDesaturated(false)
+ GMC.ct:SetTextColor(C.Green())
+ else
+ GMC.itf2:SetPoint('TOPLEFT',ref,'BOTTOMLEFT', 10, -15)
+ GMC.cp:SetDesaturated(true)
+ GMC.ct:SetTextColor(C.Silver())
+ end
+end
+function addon:GMCBuildChance()
+ _G['GMC']=GMC
+ --Chance
+ GMC.cf = CreateFrame('FRAME', nil, GMC)
+ GMC.cf:SetSize(256, 150)
+ GMC.cp = GMC.cf:CreateTexture(nil, 'BACKGROUND')
+ GMC.cp:SetTexture('Interface\\Garrison\\GarrisonMissionUI2.blp')
+ GMC.cp:SetAtlas(chestTexture)
+ GMC.cp:SetSize((209-(209*0.25))*0.60, (155-(155*0.25))*0.60)
+ GMC.cp:SetPoint('CENTER', 0, 20)
-GarrisonMissionFrameMissionsListScrollFrameButtonx.info:
-Dump: value=GarrisonMissionFrameMissionsListScrollFrameButton1.info
-[1]={
- description="In a remote corner of Talador, a small faction of draenei has embraced the worship of Sargeras. Stop their cult before it spreads.",
- cost=10,
- duration="4 hr",
- durationSeconds=14400,
- level=100,
- type="Combat",
- locPrefix="GarrMissionLocation-Talador",
- rewards={
- [290]={
- title="Money Reward",
- quantity=600000,
- icon="Interface\\Icons\\inv_misc_coin_01",
- currencyID=0
- }
- },
- numRewards=1,
- numFollowers=2,
- state=-2,
- iLevel=0,
- name="Cult of Sargeras",
- followers={
- },
- location="Talador",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=126
-}
-Dump: value=G.GetFollowerInfo("0x000000000002F5E1")
-[1]={
- displayHeight=0.5,
- iLevel=600,
- scale=0.60000002384186,
- classAtlas="GarrMission_ClassIcon-Druid",
- garrFollowerID="0x0000000000000022",
- displayScale=1,
- status="On Mission",
- level=100,
- quality=4,
- portraitIconID=1066112,
- isFavorite=false,
- xp=0,
- className="Guardian Druid",
- classSpec=8,
- name="Qiana Moonshadow",
- followerID="0x000000000002F5E1",
- height=1.3999999761581,
- displayID=55047,
- levelXP=0,
- isCollected=true
-}
-value=GarrisonMissionFrame.MissionTab.MissionList.availableMissions[13]
-[1]={
- description="Scouts report a many-headed beast named Festerbloom waylaying travelers crossing the Murkbog. Clear the path for everyone's sake.",
- cost=20,
- duration="10 hr",
- durationSeconds=36000,
- level=96,
- type="Combat",
- locPrefix="GarrMissionLocation-SpiresofArak",
- rewards={
- [778]={
- title="Bonus Follower XP",
- followerXP=1400,
- tooltip="+1,400 XP",
- icon="Interface\\Icons\\XPBonus_Icon",
- name="+1,400 XP"
- }
- },
- numRewards=1,
- numFollowers=3,
- state=-2,
- iLevel=0,
- name="Murkbog Terror",
- followers={
- },
- location="Spires of Arak",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=374
-}
-Dump: value=GarrisonMissionFrame.MissionTab.MissionList.inProgressMissions
-[1]={
- description="The voidlords and voidcallers plaguing Shadowmoon Valley are being summoned by someone. Find and kill whoever is responsible.",
- cost=15,
- duration="6 hr",
- durationSeconds=21600,
- level=100,
- timeLeft="1 hr 12 min",
- type="Combat",
- inProgress=true,
- locPrefix="GarrMissionLocation-ShadowmoonValley",
- rewards={
- [251]={
- title="Bonus Follower XP",
- followerXP=8000,
- tooltip="+8,000 XP",
- icon="Interface\\Icons\\XPBonus_Icon",
- name="+8,000 XP"
- }
- },
- numRewards=1,
- numFollowers=3,
- state=-1,
- iLevel=0,
- name="Twisting the Nether",
- followers={
- [1]="0x000000000002F5E1",
- [2]="0x0000000000079D62",
- [3]="0x00000000001307EF"
- },
- location="Shadowmoon Valley",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=114
-}
-Dump: value=G.GetMissionInfo(119)
-local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = C_Garrison.GetMissionInfo(missionID);
-[1]="Nagrand",
-[2]=1500,
-[3]="Orc",
-[4]="Lok'tar ogar!",
-[5]="Interface\\ICONS\\Achievement_Boss_General_Nazgrim.blp",
-[6]="GarrMissionLocation-Nagrand",
-[7]=false,
-[8]={
- [1]={
- portraitFileDataID=1067358,
- displayID=56189,
- name="Warsong Earthcaller",
- mechanics={
- [4]={
- description="A dangerous harmful effect that should be dispelled.",
- name="Magic Debuff",
- icon="Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp"
- },
- [8]={
- description="A dangerous spell that should be interrupted.",
- name="Powerful Spell",
- icon="Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp"
- }
- }
+ GMC.cc = GMC.cf:CreateFontString()
+ GMC.cc:SetFontObject('GameFontNormalHuge')
+ GMC.cc:SetText('Success Chance')
+ GMC.cc:SetPoint('TOP', 0, 0)
+ GMC.cc:SetTextColor(1, 1, 1)
+
+ GMC.ct = GMC.cf:CreateFontString()
+ GMC.ct:SetFontObject('ZoneTextFont')
+ GMC.ct:SetFormattedText('%d%%',GMC.settings.minimumChance)
+ GMC.ct:SetPoint('TOP', 0, -40)
+ GMC.ct:SetTextColor(0, 1, 0)
+
+ GMC.cs = factory:Slider(GMC.cf,0,100,GMC.settings.minimumChance,'Minumum chance to start a mission')
+ GMC.cs:SetPoint('BOTTOM', 10, 0)
+ GMC.cs:SetScript('OnValueChanged', function(self, value)
+ local value = math.floor(value)
+ GMC.ct:SetText(value..'%')
+ GMC.settings.minimumChance = value
+ end)
+ GMC.cs:SetValue(GMC.settings.minimumChance)
+ GMC.ck=factory:Checkbox(GMC.cs,GMC.settings.useOneChance,"Use this percentage for all missions")
+ GMC.ck.tooltip="Unchecking this will allow you to set specific success chance for each reward type"
+ GMC.ck:SetPoint("TOPLEFT",GMC.cs,"BOTTOMLEFT",-60,-10)
+ GMC.ck:SetScript("OnClick",function(this)
+ GMC.settings.useOneChance=this:GetChecked()
+ addon:GMCRewardRefresh()
+ end)
+ return GMC.cf
+end
+local function timeslidechange(this,value)
+ local value = math.floor(value)
+ if (this.max) then
+ GMC.settings.maxDuration = max(value,GMC.settings.minDuration)
+ if (value~=GMC.settings.maxDuration) then this:SetValue(GMC.settings.maxDuration) end
+ else
+ GMC.settings.minDuration = min(value,GMC.settings.maxDuration)
+ if (value~=GMC.settings.minDuration) then this:SetValue(GMC.settings.minDuration) end
+ end
+ local c = 1-(value*(1/24))
+ if c < 0.3 then c = 0.3 end
+ GMC.mt:SetTextColor(1, c, c)
+ GMC.mt:SetFormattedText("%d-%dh",GMC.settings.minDuration,GMC.settings.maxDuration)
+end
+function addon:GMCBuildDuration()
+ -- Duration
+ GMC.tf = CreateFrame('FRAME', nil, GMC)
+ GMC.tf:SetSize(256, 180)
+ GMC.tf:SetPoint('LEFT', 80, 120)
+
+ GMC.bg = GMC.tf:CreateTexture(nil, 'BACKGROUND')
+ GMC.bg:SetTexture('Interface\\Timer\\Challenges-Logo.blp')
+ GMC.bg:SetSize(100, 100)
+ GMC.bg:SetPoint('CENTER', 0, 0)
+ GMC.bg:SetBlendMode('ADD')
+
+ GMC.tcf = GMC.tf:CreateTexture(nil, 'BACKGROUND')
+ --bb:SetTexture('Interface\\Timer\\Challenges-Logo.blp')
+ --bb:SetTexture('dungeons\\textures\\devices\\mm_clockface_01.blp')
+ GMC.tcf:SetTexture('World\\Dungeon\\Challenge\\clockRunes.blp')
+ GMC.tcf:SetSize(110, 110)
+ GMC.tcf:SetPoint('CENTER', 0, 0)
+ GMC.tcf:SetBlendMode('ADD')
+
+ GMC.mdt = GMC.tf:CreateFontString()
+ GMC.mdt:SetFontObject('GameFontNormalHuge')
+ GMC.mdt:SetText('Mission Duration')
+ GMC.mdt:SetPoint('TOP', 0, 0)
+ GMC.mdt:SetTextColor(1, 1, 1)
+
+ GMC.mt = GMC.tf:CreateFontString()
+ GMC.mt:SetFontObject('ZoneTextFont')
+ GMC.mt:SetFormattedText('%d-%dh',GMC.settings.minDuration,GMC.settings.maxDuration)
+ GMC.mt:SetPoint('CENTER', 0, 0)
+ GMC.mt:SetTextColor(1, 1, 1)
+
+ GMC.ms1 = factory:Slider(GMC.tf,0,24,GMC.settings.minDuration,'Minimum mission duration.')
+ GMC.ms2 = factory:Slider(GMC.tf,0,24,GMC.settings.maxDuration,'Maximum mission duration.')
+ GMC.ms1:SetPoint('BOTTOM', 0, 0)
+ GMC.ms2:SetPoint('TOP', GMC.ms1,"BOTTOM",0, -25)
+ GMC.ms2.max=true
+ GMC.ms1:SetScript('OnValueChanged', timeslidechange)
+ GMC.ms2:SetScript('OnValueChanged', timeslidechange)
+ timeslidechange(GMC.ms1,GMC.settings.minDuration)
+ timeslidechange(GMC.ms2,GMC.settings.maxDuration)
+ return GMC.tf
+end
+function addon:GMCBuildRewards()
+ --Allowed rewards
+ GMC.aif = CreateFrame('FRAME', nil, GMC)
+ GMC.aif:SetPoint('CENTER', 0, 120)
+
+ GMC.itf = GMC.aif:CreateFontString()
+ GMC.itf:SetFontObject('GameFontNormalHuge')
+ GMC.itf:SetText('Allowed Rewards')
+ GMC.itf:SetPoint('TOP', 0, -10)
+ GMC.itf:SetTextColor(1, 1, 1)
+
+ GMC.itf2 = GMC.aif:CreateFontString()
+ GMC.itf2:SetFontObject('GameFontHighlight')
+ GMC.itf2:SetText('Click to enable/disable a reward.')
+ GMC.itf2:SetTextColor(1, 1, 1)
+
+
+ local t = {
+ {t = 'Enable/Disable money rewards.', i = 'Interface\\Icons\\inv_misc_coin_01', key = 'gold'},
+ {t = 'Enable/Disable other currency awards. (Resources/Seals)', i= 'Interface\\Icons\\inv_garrison_resource', key = 'resources'},
+ {t = 'Enable/Disable Follower XP Bonus rewards.', i = 'Interface\\Icons\\XPBonus_Icon', key = 'xpBonus'},
+ {t = 'Enable/Disable follower equip enhancement.', i = 'Interface\\ICONS\\Garrison_ArmorUpgrade', key = 'followerUpgrade'},
+ {t = 'Enable/Disable item tokens.', i = "Interface\\ICONS\\INV_Bracer_Cloth_Reputation_C_01", key = 'itemLevel'}
}
-}
-local totalTimeString, totalTimeSeconds, isMissionTimeImproved, successChance, partyBuffs, isEnvMechanicCountered, xpBonus, materialMultiplier = C_Garrison.GetPartyMissionInfo(MISSION_PAGE_FRAME.missionInfo.missionID);
-Dump: value=C_Garrison.GetPartyMissionInfo(118)
-[1]="8 hr",
-[2]=28800,
-[3]=false,
-[4]=0,
-[5]={
-},
-[6]=false,
-[7]=0,
-[8]=1
-Dump: value=table returned by GetFollowerInfo for a collected follower
-[1]={
- displayHeight=0.5,
- iLevel=600,
- isCollected=true,
- classAtlas="GarrMission_ClassIcon-Druid",
- garrFollowerID="0x0000000000000022",
- displayScale=1,
- level=100,
- quality=4,
- portraitIconID=1066112,
- isFavorite=false,
- xp=0,
- className="Guardian Druid",
- classSpec=8,
- name="Qiana Moonshadow",
- followerID="0x000000000002F5E1",
- height=1.3999999761581,
- displayID=55047,
- scale=0.60000002384186,
- levelXP=0
-}
- local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = G.GetMissionInfo(missionID)
---]]
-function addon:GetScroller(title)
+ local scale=1.1
+ GMC.ignoreFrames = {}
+ local ref
+ local h=37 -- itemButtonTemplate standard size
+ local gap=5
+ for i = 1, #t do
+ local frame = CreateFrame('BUTTON', nil, GMC.aif, 'ItemButtonTemplate')
+ frame:SetScale(scale)
+ frame:SetPoint('TOPLEFT', 0,(i) * (-h -gap) * scale)
+ frame.icon:SetTexture(t[i].i)
+ frame.key=t[i].key
+ frame.tooltip=t[i].t
+ local allowed=GMC.settings.allowedRewards[frame.key]
+ local chance=GMC.settings.rewardChance[frame.key]
+ -- Need to resave them asap in order to populate the array for future scans
+ GMC.settings.allowedRewards[frame.key]=allowed
+ GMC.settings.rewardChance[frame.key]=chance
+ frame.slider=factory:Slider(frame,0,100,chance or 100,chance or 100)
+ frame.slider:SetWidth(128)
+ frame.slider:SetPoint('BOTTOMLEFT',60,0)
+ frame.slider.Text:SetFontObject('NumberFont_Outline_Med')
+ frame.slider.Text:SetTextColor(C.Green())
+ frame.slider.isPercent=true
+ frame.slider:SetScript("OnValueChanged",function(this,value)
+ GMC.settings.rewardChance[this:GetParent().key]=this:OnValueChanged(value)
+ end
+ )
+ frame.chest = frame:CreateTexture(nil, 'BACKGROUND')
+ frame.chest:SetTexture('Interface\\Garrison\\GarrisonMissionUI2.blp')
+ frame.chest:SetAtlas(chestTexture)
+ frame.chest:SetSize((209-(209*0.25))*0.30, (155-(155*0.25)) * 0.30)
+ frame.chest:SetPoint('CENTER',frame.slider, 0, 25)
+ frame:SetScript('OnClick', function(this)
+ local allowed= this.icon:IsDesaturated() -- ID it was desaturated, I want it allowed, now
+ GMC.settings.allowedRewards[this.key] = allowed
+ addon:GMCRewardRefresh()
+ end)
+ frame:SetScript('OnEnter', function(this)
+ GameTooltip:SetOwner(this, 'ANCHOR_BOTTOMRIGHT')
+ GameTooltip:AddLine(this.tooltip);
+ GameTooltip:Show()
+ end)
+
+ frame:SetScript('OnLeave', function() GameTooltip:Hide() end)
+ GMC.ignoreFrames[i] = frame
+ ref=frame
+ end
+ self:GMCRewardRefresh()
+ GMC.aif:SetSize(256, (scale*h+gap) * #t)
+ GMC.itf2:SetPoint('TOPLEFT',ref,'BOTTOMLEFT', 5, -15)
+ return GMC.aif
+end
+
+local addPriorityRule,prioRefresh,removePriorityRule,prioMenu,prioTitles,prioCheck,prioVoices
+do
+-- 1 = item, 2 = folitem, 3 = exp, 4 = money, 5 = resource
+ prioTitles={
+ itemLevel="Gear Items",
+ followerUpgrade="Upgrade Items",
+ xpBonus="Follower XP Bonus",
+ gold="Gold Reward",
+ resources="Resource Rewards"
+ }
+ prioVoices=0
+ for _ in pairs(prioTitles) do prioVoices=prioVoices+1 end
+ prioMenu={}
+
+ ---@function [parent=#GMC] prioRefresh
+ function prioRefresh()
+ for i=1,prioVoices do
+ local group=GMC.prioFrames[i]
+ local code=GMC.settings.itemPrio[i]
+ if (not code) then
+ group.text:Hide()
+ group.xbutton:Hide()
+ group.nr:Hide()
+ else
+ group.text:Show()
+ group.text:SetText(prioTitles[code])
+ group.xbutton:Show()
+ group.nr:Show()
+ end
+ end
+ GMC.abutton:Hide()
+ for i=1,prioVoices do
+ local group=GMC.prioFrames[i]
+ if (not group.text:IsShown()) then
+ group.nr:Show()
+ GMC.abutton:SetPoint("TOPLEFT",group.text)
+ GMC.abutton:Show()
+ break
+ end
+ end
+ end
+ ---@function [parent=#GMC] addPriorityRule
+ function addPriorityRule(this,key)
+ tinsert(GMC.settings.itemPrio,key)
+ prioRefresh()
+ end
+ ---@function [parent=#GMC] removePriorityRule
+ function removePriorityRule(index)
+ tremove(GMC.settings.itemPrio,index)
+ prioRefresh()
+ end
+
+end
+_G.XPRIO=prioRefresh
+function addon:GMCBuildPriorities()
+ --Prio
+ GMC.pf = CreateFrame('FRAME', nil, GMC)
+ GMC.pf:SetSize(256, 240)
+
+ GMC.pft = GMC.pf:CreateFontString()
+ GMC.pft:SetFontObject('GameFontNormalHuge')
+ GMC.pft:SetText('Item Priority')
+ GMC.pft:SetPoint('TOP', 0, -10)
+ GMC.pft:SetTextColor(1, 1, 1)
+
+ GMC.pft2 = GMC.pf:CreateFontString()
+ GMC.pft2:SetFontObject('GameFontNormal')
+ GMC.pft2:SetText('Prioritize missions with certain a reward.')
+ GMC.pft2:SetPoint('BOTTOM', 0, 16)
+ GMC.pft2:SetTextColor(1, 1, 1)
+ GMC.pmf = CreateFrame("FRAME", "GMC_PRIO_MENU", GMC.pf, "UIDropDownMenuTemplate")
+
+
+ GMC.prioFrames = {}
+ GMC.prioFrames.selected = 0
+ for i = 1, prioVoices do
+ GMC.prioFrames[i] = {}
+ local this = GMC.prioFrames[i]
+ this.f = CreateFrame('FRAME', nil, GMC.pf)
+ this.f:SetSize(255, 32)
+ this.f:SetPoint('TOP', 0, -38-((i-1)*32))
+
+ this.nr = this.f:CreateFontString()
+ this.nr:SetFontObject('GameFontNormalHuge')
+ this.nr:SetText(i..'.')
+ this.nr:SetPoint('LEFT', 8, 0)
+ this.nr:SetTextColor(1, 1, 1)
+
+ this.text = this.f:CreateFontString()
+ this.text:SetFontObject('GameFontNormalLarge')
+ this.text:SetText('Def')
+ this.text:SetPoint('LEFT', 32, 0)
+ --this.text:SetTextColor(1, 1, 0)
+ this.text:SetJustifyH('LEFT')
+ this.text:Hide()
+
+ this.xbutton = CreateFrame('BUTTON', nil, this.f, 'GameMenuButtonTemplate')
+ this.xbutton:SetPoint('RIGHT', 0, 0)
+ this.xbutton:SetText('X')
+ this.xbutton:SetWidth(28)
+ this.xbutton:SetScript('OnClick', function() removePriorityRule(i) end)
+ this.xbutton:Hide()
+ end
+
+ GMC.abutton = CreateFrame('BUTTON', nil, GMC.pmf, 'GameMenuButtonTemplate')
+ GMC.abutton:SetText(L['Add priority rule'])
+ GMC.abutton:SetWidth(128)
+ GMC.abutton:Hide()
+ GMC.abutton:SetScript('OnClick', function()
+ wipe(prioMenu)
+ tinsert(prioMenu,{text = L["Select an item to add as priority."], isTitle = true, isNotRadio=true,disabled=true, notCheckable=true,notClickable=true})
+ for k,v in pairs(prioTitles) do
+ tinsert(prioMenu,{text = v, func = addPriorityRule, notCheckable=true, isNotRadio=true, arg1 = k , disabled=inTable(GMC.settings.itemPrio,k)})
+ end
+ EasyMenu(prioMenu, GMC.pmf, "cursor", 0 , 0, "MENU")
+ end
+ )
+ prioRefresh()
+ return GMC.pf
+end
+function addon:GMCBuildMissionList()
+ -- Mission list on follower panels
+-- local ml=CreateFrame("Frame",nil,GMC)
+-- addBackdrop(ml)
+-- ml:Show()
+-- ml.Missions={}
+-- ml.Parties={}
+-- GMC.ml=ml
+-- local fs=ml:CreateFontString(nil, "BACKGROUND", "GameFontNormalHugeBlack")
+-- fs:SetPoint("TOPLEFT",0,-5)
+-- fs:SetPoint("TOPRIGHT",0,-5)
+-- fs:SetText(READY)
+-- fs:SetTextColor(C.Green())
+-- fs:SetHeight(30)
+-- fs:SetJustifyV("CENTER")
+-- fs:Show()
+-- GMC.progressText=fs
+-- GMC.ml.Header=fs
+-- return GMC.ml
+ local ml={widget=AceGUI:Create("GMCLayer"),Parties={}}
+ ml.widget:SetTitle(READY)
+ ml.widget:SetTitleColor(C.Green())
+ ml.widget:SetTitleHeight(40)
+ ml.widget:SetParent(GMC)
+ ml.widget:Show()
+ GMC.ml=ml
+ return ml.widget
+
+end
+--@do-not-package@
+_G.GAC=addon
+--- Enable a trace for every function call. It's a VERY heavy debug
+--
+local memorysinks={}
+local lib=LibStub("LibInit")
+for k,v in pairs(addon) do
+ if (type(v))=="function" and not lib[k] then
+ local wrapped
+ do
+ local original=addon[k]
+ wrapped=function(...)
+ if trc then
+ UpdateAddOnMemoryUsage()
+ end
+ local membefore=floor(GetAddOnMemoryUsage("GarrisonCommander"))
+ local s=GetTime()
+ local a1,a2,a3,a4,a5,a6,a7,a8,a9=original(...)
+ local e=GetTime()
+ local memafter=floor(GetAddOnMemoryUsage("GarrisonCommander"))
+ memorysinks[k].mem=memorysinks[k].mem+memafter-membefore
+ memorysinks[k].calls=memorysinks[k].calls+1
+ memorysinks[k].elapsed=memorysinks[k].elapsed+e-s
+ if (memafter-membefore > 100) then
+ pp(C(k,'Red'),'used ',memafter-membefore)
+ end
+ return a1,a2,a3,a4,a5,a6,a7,a8,a9
+ end
+ end
+ addon[k]=wrapped
+ memorysinks[k]={mem=0,elapsed=0,calls=0}
+ end
+end
+function addon:ResetSinks()
+ for k,v in pairs(memorysinks) do
+ memorysinks[k].mem=0
+ memorysinks[k].calls=0
+ memorysinks[k].elapsed=0
+ end
+end
+local sorted={}
+function addon:DumpSinks()
+ local scroll=self:GetScroller("Sinks",400,1000)
+ wipe(sorted)
+ for k,v in pairs(memorysinks) do
+ if v.mem > 0 then
+ tinsert(sorted,format("Mem %06d %-80s (calls: %3d) Mem per call:%3.2f Elapsed %3.3f (per call %3.3f)",v.mem,k,v.calls,v.mem/v.calls,v.elapsed,v.elapsed/v.calls))
+ end
+ end
+ table.sort(sorted,function(a,b) return a>b end)
+ self:cutePrint(scroll,sorted)
+end
+function addon:GetScroller(title,type,h,w)
+ h=h or 800
+ w=w or 400
+ type=type or "Frame"
local scrollerWindow=AceGUI:Create("Frame")
scrollerWindow:SetTitle(title)
scrollerWindow:SetLayout("Fill")
@@ -3095,126 +4289,88 @@ function addon:GetScroller(title)
scroll:SetFullHeight(true)
scrollerWindow:AddChild(scroll)
scrollerWindow:SetCallback("OnClose","Release")
- scrollerWindow:SetHeight(800)
- scrollerWindow:SetWidth(400)
+ scrollerWindow:SetHeight(h)
+ scrollerWindow:SetWidth(w)
scrollerWindow:SetPoint("CENTER")
scrollerWindow:Show()
return scroll
end
-function addon:AddLabel(obj,text,...)
+function addon:AddRow(obj,text,...)
local l=AceGUI:Create("Label")
l:SetText(text)
l:SetColor(...)
l:SetFullWidth(true)
obj:AddChild(l)
end
-function addon:cuttyPrint(scroll,level,k,v)
+function addon:cutePrint(scroll,level,k,v)
if (type(level)=="table") then
for k,v in pairs(level) do
- self:cuttyPrint(scroll,"",k,v)
+ self:cutePrint(scroll,"",k,v)
end
return
end
if (type(v)=="table") then
- self:AddLabel(scroll,level..C(k,"Azure")..":" ..C("Table","Orange"))
+ self:AddRow(scroll,level..C(k,"Azure")..":" ..C("Table","Orange"))
for kk,vv in pairs(v) do
- self:cuttyPrint(scroll,level .. " ",kk,vv)
+ self:cutePrint(scroll,level .. " ",kk,vv)
end
else
if (type(v)=="string" and v:sub(1,2)=='0x') then
v=v.. " " ..tostring(self:GetFollowerData(v,'name'))
end
- self:AddLabel(scroll,level..C(k,"White")..":" ..C(v,"Yellow"))
+ self:AddRow(scroll,level..C(k,"White")..":" ..C(v,"Yellow"))
end
end
+function addon:DumpFollower(name)
+ local follower=self:GetFollowerData(name)
+ if (follower) then
+ local scroll=self:GetScroller(follower.name)
+ self:cutePrint(scroll,follower)
+ end
+
+end
function addon:DumpFollowerMissions(missionID)
local scroll=self:GetScroller("FollowerMissions " .. self:GetMissionData(missionID,'name'))
- self:cuttyPrint(scroll,followerMissions.missions[missionID])
+ self:cutePrint(scroll,followerMissions.missions[missionID])
end
-function addon:DumpIfnored()
+function addon:DumpIgnored()
local scroll=self:GetScroller("Ignored")
- self:cuttyPrint(scroll,self.privatedb.profile.ignored)
+ self:cutePrint(scroll,self.privatedb.profile.ignored)
end
function addon:DumpMission(missionID)
local scroll=self:GetScroller("MissionCache " .. self:GetMissionData(missionID,'name'))
- self:cuttyPrint(scroll,cache.missions[missionID])
+ self:cutePrint(scroll,cache.missions[missionID])
+end
+function addon:DumpMissions()
+ local scroll=self:GetScroller("MissionCache")
+ for id,data in pairs(cache.missions) do
+ self:cutePrint(scroll,id .. '.'..data.name)
+ end
end
---
-- Debug function
--@param missionID Identificativo missione
function addon:DumpCounters(missionID)
local scroll=self:GetScroller("Counters " .. self:GetMissionData(missionID,'name'))
- self:cuttyPrint(scroll,counters[missionID])
- self:cuttyPrint(scroll,"Lista per follower","","")
- self:cuttyPrint(scroll,counterFollowerIndex[missionID])
- self:cuttyPrint(scroll,"Lista per threat","","")
- self:cuttyPrint(scroll,counterThreatIndex[missionID])
+ self:cutePrint(scroll,counters[missionID])
+ self:cutePrint(scroll,"Lista per follower","","")
+ self:cutePrint(scroll,counterFollowerIndex[missionID])
+ self:cutePrint(scroll,"Lista per threat","","")
+ self:cutePrint(scroll,counterThreatIndex[missionID])
end
function addon:Dump(title,data)
local scroll=self:GetScroller(title)
- self:cuttyPrint(scroll,data)
+ self:cutePrint(scroll,data)
end
function addon:DumpCounterers(missionID)
local scroll=self:GetScroller("Counterers " .. self:GetMissionData(missionID,'name'))
- self:cuttyPrint(scroll,cache.missions[missionID].counterers)
+ self:cutePrint(scroll,cache.missions[missionID].counterers)
end
function addon:DumpParty(missionID)
local scroll=self:GetScroller("Party " .. self:GetMissionData(missionID,'name'))
- self:cuttyPrint(scroll,parties[missionID])
-end
-function addon:GenerateTimersPeriodic()
- return coroutine.wrap(
- function(self)
- repeat
- local t=new()
- G.GetInProgressMissions(t)
- for index=1,#t do
- local mission=t[index]
- for i=1,mission.numFollowers do
- end
- end
- coroutine.yield()
- until false
- end
- )
-end
-function addon:GMF_OnDragStart(frame)
- if (not self:GetBoolean('MOVEPANEL')) then return end
- frame.IsSizingOrMoving=true
- if (IsShiftKeyDown()) then
- frame.IsSizing=true
- frame:StartSizing("BOTTOMRIGHT")
- frame:SetScript("OnUpdate",function(frame,elapsed)
- if (frame.timepassed and frame.timepassed >1) then
- GarrisonMissionList_UpdateMissions()
- else
- frame.timepassed=frame.timepassed or 0
- frame.timepassed=frame.timepassed +elapsed
- end
- end)
- else
- frame.IsSizing=nil
- frame:StartMoving()
- end
-end
-function addon:GMF_OnDragStop(frame)
- frame:StopMovingOrSizing()
- frame:SetScript("OnUpdate",nil)
- if (frame.IsSizing) then
- BIGSIZEW=frame:GetWidth()
- SIZEV=frame:GetHeight()
- BIGBUTTON=min(BIGSIZEW*0.55,BIGSIZEW-GCSIZE)
- SMALLBUTTON=BIGBUTTON
- if (not self:IsFollowerList()) then
- HybridScrollFrame_CreateButtons(frame.MissionTab.MissionList.listScroll, "GarrisonMissionListButtonTemplate", 13, -8, nil, nil, nil, -4);
- GarrisonMissionList_Update();
- else
- HybridScrollFrame_CreateButtons(frame.FollowerList.listScroll, "GarrisonMissionFollowerButtonTemplate", 7, -7, nil, nil, nil, -6);
- end
- end
- frame.IsSizing=nil
- frame.IsSizingOrMoving=nil
+ self:cutePrint(scroll,parties[missionID])
end
+_G.GCF=GCF
--@end-do-not-package@
diff --git a/GarrisonCommander.toc b/GarrisonCommander.toc
index 980e124..6c7ff5c 100644
--- a/GarrisonCommander.toc
+++ b/GarrisonCommander.toc
@@ -24,5 +24,6 @@
## X-Embeds:
embeds.xml
localization.lua
+wowhead.lua
GarrisonCommander.xml
RelNotes.lua
diff --git a/GarrisonCommander.xml b/GarrisonCommander.xml
index 032901c..b02e3bd 100644
--- a/GarrisonCommander.xml
+++ b/GarrisonCommander.xml
@@ -1,133 +1,82 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="GarrisonCommander.lua"/>
- <Frame name="GarrisonCommanderBackground" virtual ="true">
- <Layers>
- <Layer level="BACKGROUND">
- <Texture atlas="GarrMission_MissionParchment" useAtlasSize="true" vertTile="true" horizTile="true">
- <Anchors>
- <Anchor point="TOPLEFT" x="3"/>
- <Anchor point="BOTTOMRIGHT" x="-3"/>
- </Anchors>
- </Texture>
- </Layer>
- <Layer level="BORDER">
- <Texture atlas="_GarrMission_TopBorder" useAtlasSize="true" horizTile="true">
- <Anchors>
- <Anchor point="TOPLEFT" x="20" y="4"/>
- <Anchor point="TOPRIGHT" x="-20" y="4"/>
- </Anchors>
- </Texture>
- <Texture atlas="_GarrMission_TopBorder" useAtlasSize="true" horizTile="true">
- <Anchors>
- <Anchor point="BOTTOMLEFT" x="20" y="-4"/>
- <Anchor point="BOTTOMRIGHT" x="-20" y="-4"/>
- </Anchors>
- <TexCoords left="0.0" right="1.0" top="1.0" bottom="0.0"/>
- </Texture>
- </Layer>
- <Layer level="BORDER" textureSubLevel="1">
- <Texture atlas="GarrMission_TopBorderCorner" useAtlasSize="true">
- <Anchors>
- <Anchor point="TOPLEFT" x="-5" y="4"/>
- </Anchors>
- </Texture>
- <Texture atlas="GarrMission_TopBorderCorner" useAtlasSize="true">
- <Anchors>
- <Anchor point="TOPRIGHT" x="4" y="4"/>
- </Anchors>
- <TexCoords left="1.0" right="0.0" top="0.0" bottom="1.0"/>
- </Texture>
- <Texture atlas="GarrMission_TopBorderCorner" useAtlasSize="true">
- <Anchors>
- <Anchor point="BOTTOMLEFT" x="-5" y="-4"/>
- </Anchors>
- <TexCoords left="0.0" right="1.0" top="1.0" bottom="0.0"/>
- </Texture>
- <Texture atlas="GarrMission_TopBorderCorner" useAtlasSize="true">
- <Anchors>
- <Anchor point="BOTTOMRIGHT" x="4" y="-4"/>
- </Anchors>
- <TexCoords left="1.0" right="0.0" top="1.0" bottom="0.0"/>
- </Texture>
- </Layer>
- <Layer level="BACKGROUND" textureSubLevel="3">
- <Texture parentKey="IconBG" atlas="Garr_MissionList-IconBG">
- <Size x="90" y="80"/>
- <Anchors>
- <Anchor point="TOPLEFT" y="-1"/>
- </Anchors>
- <Color r="0" g="0" b="0" a="0.4"/>
- </Texture>
- </Layer>
- <Layer level="ARTWORK" textureSubLevel="2">
- <Texture parentKey="LocBG">
- <Size x="792" y="78"/>
- <Anchors>
- <Anchor point="RIGHT"/>
- </Anchors>
- </Texture>
- </Layer>
- <Layer level="HIGHLIGHT" textureSubLevel="1">
- <Texture parentKey="HighlightTL" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
- <Anchors>
- <Anchor point="TOPLEFT" x="-5" y="4"/>
- </Anchors>
- </Texture>
- <Texture parentKey="HighlightTR" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
- <Anchors>
- <Anchor point="TOPRIGHT" x="4" y="4"/>
- </Anchors>
- <TexCoords left="1.0" right="0.0" top="0.0" bottom="1.0"/>
- </Texture>
- <Texture parentKey="HighlightBL" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
- <Anchors>
- <Anchor point="BOTTOMLEFT" x="-5" y="-4"/>
- </Anchors>
- <TexCoords left="0.0" right="1.0" top="1.0" bottom="0.0"/>
- </Texture>
- <Texture parentKey="HighlightBR" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
- <Anchors>
- <Anchor point="BOTTOMRIGHT" x="4" y="-4"/>
- </Anchors>
- <TexCoords left="1.0" right="0.0" top="1.0" bottom="0.0"/>
- </Texture>
- <Texture parentKey="Highlight" atlas="GarrMission_ListGlow-Highlight" useAtlasSize="true">
- <Anchors>
- <Anchor point="TOPLEFT" y="0"/>
- <Anchor point="TOPRIGHT" y="0"/>
- </Anchors>
- </Texture>
- </Layer>
- </Layers>
- </Frame>
- <Frame name="GarrisonCommanderTitle" inherits="GarrisonCommanderBackground" virtual="true">
- <Size x="150" y="32"/>
+ <Button name="GarrisonCommanderWhatsNew" inherits="UIPanelInfoButton" hidden="true" virtual="true">
+ <Scripts>
+ <OnLeave>GameTooltip:FadeOut()</OnLeave>
+ <OnEnter>
+ if self.tooltip then
+ GameTooltip:SetOwner(self,"ANCHOR_TOPLEFT")
+ GameTooltip:AddLine(self.tooltip)
+ GameTooltip:Show()
+ end
+ </OnEnter>
+ </Scripts>
+ </Button>
+ <Frame name="GarrisonCommanderTitle" inherits="GarrisonUITemplate" enableMouse="true" topevel="true" hidden="true" virtual="true">
+ <Size x="150" y="85"/>
<Frames>
- <Button parentKey="help" inherits="UIPanelInfoButton">
+ <CheckButton parentKey="Pin">
+ <Size x="32" y="32" />
<Anchors>
- <Anchor point="TOPLEFT" x="0" y="0"/>
+ <Anchor point="TOPRIGHT" x="4" y="5"/>
</Anchors>
- </Button>
+ <NormalTexture file="Interface\CHATFRAME\UI-ChatIcon-ScrollUp-Up">
+ <Size x="32" y="32" />
+ </NormalTexture>
+ <!--
+ <HighlightTexture file="Interface\CHATFRAME/UI-ChatIcon-BlinkHilight" alphaMode="ADD">
+ <Size x="32" y="32" />
+ </HighlightTexture>
+ -->
+ <CheckedTexture file="Interface\CHATFRAME\UI-ChatIcon-ScrollDown-Up">
+ <Size x="32" y="32" />
+ </CheckedTexture>
+ <Scripts>
+ <OnLeave>
+ GameTooltip:FadeOut()
+ </OnLeave>
+ </Scripts>
+ </CheckButton>
</Frames>
<Layers>
- <Layer level="ARTWORK">
+ <Layer level="OVERLAY">
<Texture parentKey="Shield" file="Interface\ACHIEVEMENTFRAME\UI-ACHIEVEMENT-SHIELDS-NOPOINTS">
<Size x="32" y="32"/>
<Anchors>
- <Anchor point="TOPLEFT" x="24" y="-5"/>
+ <Anchor point="TOPLEFT" x="-2" y="0"/>
</Anchors>
<TexCoords left="0" right="0.5" top="0.5" bottom="1"/>
</Texture>
- <FontString parentKey="Signature" inherits="QuestTitleFontBlackShadow" justifyH="LEFT" justifyV="TOP" text="Garrison Commander" >
- <Size x="200" y="32"/>
+ <FontString parentKey="Signature" inherits="QuestTitleFontBlackShadow" justifyH="RIGHT" justifyV="TOP" text="Garrison Commander" >
+ <Size x="220" y="80"/>
<Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent.Shield" relativePoint="TOPRIGHT" x="5" y="0"/>
+ <Anchor point="TOPRIGHT" x="-30" y="-2"/>
</Anchors>
</FontString>
</Layer>
</Layers>
+ <Scripts>
+ <OnLeave>GameTooltip:FadeOut()</OnLeave>
+ <OnEnter>
+ if self.tooltip then
+ GameTooltip:SetOwner(self,"ANCHOR_TOPLEFT")
+ GameTooltip:AddLine(self.tooltip)
+ GameTooltip:Show()
+ end
+ </OnEnter>
+ </Scripts>
</Frame>
+ <Button name="GarrisonCommanderMissionPageFollowerTemplateSmall" virtual="true">
+ <Size x="70" y="58"/>
+ <Frames>
+ <Frame parentKey="PortraitFrame" inherits="GarrisonFollowerMissionPortraitTemplate">
+ <Anchors>
+ <Anchor point="LEFT"/>
+ </Anchors>
+ </Frame>
+ </Frames>
+ </Button>
<Button name="GarrisonCommanderMissionPageFollowerTemplate" inherits="GarrisonMissionPageFollowerTemplate" virtual="true">
<Size x="170" y="58"/>
<Layers>
@@ -195,25 +144,40 @@
</Layer>
</Layers>
</Frame>
- <Button name="GarrisonCommanderMissionButton" inherits="GarrisonCommanderBackground" virtual="true">
- <Size x="600" y="80"/>
+ <Frame name="GarrisonCommanderIndicators" toplevel="true" virtual="true">
+ <Size x="90" y="80"/>
<Layers>
<Layer level="ARTWORK">
<FontString parentKey="Age" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="TOP" >
- <Size x="60" y="70"/>
+ <Size x="90" y="70"/>
<Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent" relativePoint="TOPLEFT" x="10" y="-5"/>
+ <Anchor point="TOPLEFT" relativeKey="$parent" relativePoint="TOPLEFT" x="0" y="-5"/>
</Anchors>
<Color r="0.698" g="0.941" b="1" a="1"/>
</FontString>
<FontString parentKey="Percent" inherits="NumberFontNormalHuge" justifyH="RIGHT" justifyV="BOTTOM" >
- <Size x="60" y="70"/>
+ <Size x="90" y="70"/>
<Anchors>
<Anchor point="BOTTOMLEFT" relativeKey="$parent" relativePoint="BOTTOMLEFT" x="0" y="10"/>
</Anchors>
</FontString>
</Layer>
</Layers>
+ </Frame>
+ <Button name="GarrisonCommanderMissionButton" virtual="true">
+ <Size x="1" y="80"/>
+ <Layers>
+ <Layer level="OVERLAY" >
+ <FontString parentKey="NotFull" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="CENTER" text="GARRISON_PARTY_NOT_FULL_TOOLTIP" >
+ <Size x="100" y="58"/>
+ <Anchors>
+ <Anchor point="TOPLEFT" relativeKey="$parent.PortraitFrame" relativePoint="TOPRIGHT" x="0" y="0"/>
+ <Anchor point="TOPRIGHT" relativeKey="$parent" relativePoint="TOPRIGHT" x="-10" y="0"/>
+ </Anchors>
+ <Color r="1.0" g="0.0" b="0.0" a="0.5" />
+ </FontString>
+ </Layer>
+ </Layers>
</Button>
<Button name="GarrisonCommanderMissionListButtonTemplate" inherits="GarrisonMissionListButtonTemplate" virtual="true">
<Size x="450" y="80" />
@@ -380,5 +344,20 @@
</OnHide>
</Scripts>
</Frame>
-
+ <Frame name="GarrisonCommanderLoadingFrame" inherits="LoadingSpinnerTemplate" hidden="true" virtual="true">
+ <Layers>
+ <Layer level="ARTWORK">
+ <FontString parentKey="Label" inherits="GameFontHighlight" text="LFG_LIST_LOADING">
+ <Anchors>
+ <Anchor point="LEFT" relativePoint="RIGHT"/>
+ </Anchors>
+ </FontString>
+ </Layer>
+ </Layers>
+ <Scripts>
+ <OnLoad>
+ self.Anim:Play();
+ </OnLoad>
+ </Scripts>
+ </Frame>
</Ui>
\ No newline at end of file
diff --git a/doc.txt b/doc.txt
new file mode 100644
index 0000000..fb27416
--- /dev/null
+++ b/doc.txt
@@ -0,0 +1,254 @@
+GarrisonMissionFrame_CheckCompleteMissions(OnShow) Controlla se sono presenti missione complete. Se è già mostrato GMF.MissionComplete ritorna
+ Viene chiamato
+ 1) su onshow del pannello missioni con OnShow=true
+ 2) sull'evento GARRISON_MISSION_FINISHED con OnSHow=false
+ - Inizializza GMF.MissionComplete.completeMissions
+ - Se ci sono missioni complete e GMF è mostrato
+ - le conta (#GMF.MissionComplete.completeMissions
+ - mostra GMF.MissionTab.MissionList.CompleteDialog
+ - MissionCompletePreload_LoadMission(id) id=missionID prima missione completata
+ - Usa una globale per la missione corrente, in modo da uscire se è sempre farlo sulla stessa
+ - Rimuove eventuali modelli già prensenti via MissionCompletePreload_Cancel
+ - Carica tutti i modelli necessari
+ - abilita il viewbutton GarrisonMissionFrameMissions.CompleteDialog.BorderFrame.ViewButton
+ - Onclick :
+ - GarrisonMissionFrame_ShowCompleteMissions
+ - continua a farsi rilanciare finché non ha finito di caricare i modelli, poi:
+ - Nasconde GMF.MissionTab.MissionList.CompleteDialog
+ - mostra GMF.MissionComplete GMF.MissionCompleteBackground
+ - GarrisonMissionComplete_Initialize(GMF.MissionComplete.completeMissions,GMF.MissionComplete.currentIndex)
+
+
+
+Altre utilities
+
+GarrisonMissionFrame_SelectTab(id): switcha fra missioni e followers
+ id è numerico, 1 mostra le missioni, altro mostra i followers
+
+GarrisonMissionList_SetTab(tab): switcha fra active e available
+ tab è l'oggetto tab "available" o "in progress" (GarrisonMissionFrameMissionsTab[12])
+
+Pannelli utili:
+
+GMF.MissionTab.MissionList.CompleteDialog.BorderFrame.LoadingFrame Loading col tondino
+
+
+Dump: value=C_Garrison.GetMissionRewardInfo(91)
+[1]={
+ [163]={
+ itemID=112848,
+ quantity=1
+ }
+}
+
+--[[
+
+GMFMissions.CompleteDialog.BorderFrame.CompleteAll
+Garrison page structure
+Tab selection:
+Managed by
+GarrisonMissionFrameTab(1|2) onclick:
+->GarrisonMissionFrameTab_OnClick(self)
+--->GarrisonMissionFrame_SelectTab(self:GetID()) - 1 for Missions, 2 for followers
+
+Main Container is GarrisonMissionFrame
+Followers tab selected:
+->GarrisonMissionFrameFollowers -> anchored GarrisonMissionFrame TOPLEFT 33,-64
+-->GarrisonMissionFrameFollowersListScrollFrame
+--->GarrisonMissionFrameFollowersListScrooFrameScrollChild
+---->GarrisonMissionFrameFollowersListScrooFrameButton(1..9)
+->GarrisonMissionFrame.FollowerTab -> abcuored GarrisonMissionFrame TOPRIGHT -35 -64
+Missions tab selected
+->GarrisonMissionFrameMissions -> anchored (parent)e TOPLEFT 35,-65
+
+
+
+
+GarrisonMissionFrameMissionsListScrollFrameButtonx.info:
+Dump: value=GarrisonMissionFrameMissionsListScrollFrameButton1.info
+[1]={
+ description="In a remote corner of Talador, a small faction of draenei has embraced the worship of Sargeras. Stop their cult before it spreads.",
+ cost=10,
+ duration="4 hr",
+ durationSeconds=14400,
+ level=100,
+ type="Combat",
+ locPrefix="GarrMissionLocation-Talador",
+ rewards={
+ [290]={
+ title="Money Reward",
+ quantity=600000,
+ icon="Interface\\Icons\\inv_misc_coin_01",
+ currencyID=0
+ }
+ },
+ numRewards=1,
+ numFollowers=2,
+ state=-2,
+ iLevel=0,
+ name="Cult of Sargeras",
+ followers={
+ },
+ location="Talador",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=126
+}
+Dump: value=G.GetFollowerInfo("0x000000000002F5E1")
+[1]={
+ displayHeight=0.5,
+ iLevel=600,
+ scale=0.60000002384186,
+ classAtlas="GarrMission_ClassIcon-Druid",
+ garrFollowerID="0x0000000000000022",
+ displayScale=1,
+ status="On Mission",
+ level=100,
+ quality=4,
+ portraitIconID=1066112,
+ isFavorite=false,
+ xp=0,
+ className="Guardian Druid",
+ classSpec=8,
+ name="Qiana Moonshadow",
+ followerID="0x000000000002F5E1",
+ height=1.3999999761581,
+ displayID=55047,
+ levelXP=0,
+ isCollected=true
+}
+value=GarrisonMissionFrame.MissionTab.MissionList.availableMissions[13]
+[1]={
+ description="Scouts report a many-headed beast named Festerbloom waylaying travelers crossing the Murkbog. Clear the path for everyone's sake.",
+ cost=20,
+ duration="10 hr",
+ durationSeconds=36000,
+ level=96,
+ type="Combat",
+ locPrefix="GarrMissionLocation-SpiresofArak",
+ rewards={
+ [778]={
+ title="Bonus Follower XP",
+ followerXP=1400,
+ tooltip="+1,400 XP",
+ icon="Interface\\Icons\\XPBonus_Icon",
+ name="+1,400 XP"
+ }
+ },
+ numRewards=1,
+ numFollowers=3,
+ state=-2,
+ iLevel=0,
+ name="Murkbog Terror",
+ followers={
+ },
+ location="Spires of Arak",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=374
+}
+Dump: value=GarrisonMissionFrame.MissionTab.MissionList.inProgressMissions
+[1]={
+ description="The voidlords and voidcallers plaguing Shadowmoon Valley are being summoned by someone. Find and kill whoever is responsible.",
+ cost=15,
+ duration="6 hr",
+ durationSeconds=21600,
+ level=100,
+ timeLeft="1 hr 12 min",
+ type="Combat",
+ inProgress=true,
+ locPrefix="GarrMissionLocation-ShadowmoonValley",
+ rewards={
+ [251]={
+ title="Bonus Follower XP",
+ followerXP=8000,
+ tooltip="+8,000 XP",
+ icon="Interface\\Icons\\XPBonus_Icon",
+ name="+8,000 XP"
+ }
+ },
+ numRewards=1,
+ numFollowers=3,
+ state=-1,
+ iLevel=0,
+ name="Twisting the Nether",
+ followers={
+ [1]="0x000000000002F5E1",
+ [2]="0x0000000000079D62",
+ [3]="0x00000000001307EF"
+ },
+ location="Shadowmoon Valley",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=114
+}
+Dump: value=G.GetMissionInfo(119)
+local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = C_Garrison.GetMissionInfo(missionID);
+[1]="Nagrand",
+[2]=1500,
+[3]="Orc",
+[4]="Lok'tar ogar!",
+[5]="Interface\\ICONS\\Achievement_Boss_General_Nazgrim.blp",
+[6]="GarrMissionLocation-Nagrand",
+[7]=false,
+[8]={
+ [1]={
+ portraitFileDataID=1067358,
+ displayID=56189,
+ name="Warsong Earthcaller",
+ mechanics={
+ [4]={
+ description="A dangerous harmful effect that should be dispelled.",
+ name="Magic Debuff",
+ icon="Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp"
+ },
+ [8]={
+ description="A dangerous spell that should be interrupted.",
+ name="Powerful Spell",
+ icon="Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp"
+ }
+ }
+ }
+}
+local totalTimeString, totalTimeSeconds, isMissionTimeImproved, successChance, partyBuffs, isEnvMechanicCountered, xpBonus, materialMultiplier = C_Garrison.GetPartyMissionInfo(MISSION_PAGE_FRAME.missionInfo.missionID);
+Dump: value=C_Garrison.GetPartyMissionInfo(118)
+[1]="8 hr",
+[2]=28800,
+[3]=false,
+[4]=0,
+[5]={
+},
+[6]=false,
+[7]=0,
+[8]=1
+Dump: value=table returned by GetFollowerInfo for a collected follower
+[1]={
+ displayHeight=0.5,
+ iLevel=600,
+ isCollected=true,
+ classAtlas="GarrMission_ClassIcon-Druid",
+ garrFollowerID="0x0000000000000022",
+ displayScale=1,
+ level=100,
+ quality=4,
+ portraitIconID=1066112,
+ isFavorite=false,
+ xp=0,
+ className="Guardian Druid",
+ classSpec=8,
+ name="Qiana Moonshadow",
+ followerID="0x000000000002F5E1",
+ height=1.3999999761581,
+ displayID=55047,
+ scale=0.60000002384186,
+ levelXP=0
+}
+ local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = G.GetMissionInfo(missionID)
+--]]
+-- In case we need to change rown number in GMF
+ if (not self:IsFollowerList()) then
+ HybridScrollFrame_CreateButtons(frame.MissionTab.MissionList.listScroll, "GarrisonMissionListButtonTemplate", 13, -8, nil, nil, nil, -4);
+ GarrisonMissionList_Update();
+ else
+ HybridScrollFrame_CreateButtons(frame.FollowerList.listScroll, "GarrisonMissionFollowerButtonTemplate", 7, -7, nil, nil, nil, -6);
+ end
diff --git a/example.js b/example.js
new file mode 100644
index 0000000..f2f1df2
--- /dev/null
+++ b/example.js
@@ -0,0 +1,3 @@
+/**
+ *
+ */
\ No newline at end of file
diff --git a/wowhead.lua b/wowhead.lua
new file mode 100644
index 0000000..a8aa0ad
--- /dev/null
+++ b/wowhead.lua
@@ -0,0 +1,408 @@
+-- DataMined from WowHead on 11/01/2015
+-- Contains 304 missions
+--[[
+Array
+(
+ [id] => 2
+ [level] => 90
+ [itemlevel] => 0
+ [traveltime] => 0
+ [missiontime] => 1800
+ [cooldown] => 9999999
+ [cost] => 0
+ [followers] => 1
+ [experience] => 100
+ [basebonuschance] => 65
+ [name] => Gronnlings Abound
+ [description] => Gronnlings are a menace to the region. We should partner with the Frostwolf clan to thin the population. One may even join our cause...
+ [location] => Frostwall Approach
+ [mechanictype] => 23
+ [missiontype] => 3
+ [flags] => 0
+ [rewards] => Array
+ (
+ [experience] => Array
+ (
+ )
+
+ [prestige] => Array
+ (
+ )
+
+ [item] => Array
+ (
+ [0] => Array
+ (
+ [item] => 112737
+ [amount] => 1
+ )
+
+ )
+
+ [currency] => Array
+ (
+ )
+
+ [chest] => Array
+ (
+ )
+
+ )
+
+ [encounters] => Array
+ (
+ [1] => Array
+ (
+ [setkey] => 2
+ [id] => 1
+ [npc] => 80693
+ [name] => Frostfire Gronnling
+ [portraitfile] => 1067373
+ [portraitfilename] => enemyportrait_56633
+ [mechanics] => Array
+ (
+ [10] => Array
+ (
+ [setkey] => 2
+ [id] => 10
+ [amount] => 300
+ [type] => 1
+ [category] => 2
+ [name] => Wild Aggression
+ [description] => An unpredictable enemy whose aggression should be controlled.
+ [icon] => spell_nature_reincarnation
+ )
+
+ )
+
+ )
+
+ )
+
+ [mechanics] => Array
+ (
+ [0] => Array
+ (
+ [setkey] => 2
+ [id] => 0
+ [amount] => 0
+ [type] => 23
+ [category] => 0
+ [name] => Snow
+ [description] => An arctic region.
+ [icon] => achievement_zone_stormpeaks_02
+ )
+
+ )
+
+)
+--]]
+local me,ns=...
+ ns.wowhead={
+[2]=9999999,
+[3]=9999999,
+[6]=9999999,
+[7]=9999999,
+[43]=9999999,
+[44]=9999999,
+[55]=9999999,
+[65]=9999999,
+[66]=9999999,
+[67]=0,
+[73]=86400,
+[86]=9999999,
+[87]=9999999,
+[88]=9999999,
+[89]=0,
+[90]=9999999,
+[91]=9999999,
+[107]=129600,
+[108]=129600,
+[109]=129600,
+[110]=129600,
+[111]=129600,
+[112]=129600,
+[113]=129600,
+[114]=129600,
+[115]=129600,
+[116]=129600,
+[117]=129600,
+[118]=129600,
+[119]=129600,
+[120]=129600,
+[125]=129600,
+[126]=129600,
+[127]=129600,
+[128]=129600,
+[129]=129600,
+[130]=129600,
+[131]=129600,
+[132]=129600,
+[133]=129600,
+[135]=86400,
+[136]=86400,
+[137]=86400,
+[138]=86400,
+[139]=86400,
+[140]=86400,
+[141]=86400,
+[142]=86400,
+[143]=86400,
+[144]=86400,
+[145]=86400,
+[146]=86400,
+[147]=86400,
+[148]=86400,
+[149]=86400,
+[150]=86400,
+[151]=86400,
+[152]=86400,
+[153]=86400,
+[154]=86400,
+[155]=86400,
+[156]=86400,
+[157]=86400,
+[158]=86400,
+[159]=86400,
+[160]=86400,
+[161]=86400,
+[162]=86400,
+[163]=86400,
+[164]=86400,
+[165]=86400,
+[166]=86400,
+[167]=86400,
+[168]=86400,
+[169]=86400,
+[170]=86400,
+[171]=86400,
+[172]=86400,
+[173]=86400,
+[174]=86400,
+[175]=86400,
+[176]=86400,
+[177]=86400,
+[178]=86400,
+[179]=86400,
+[180]=86400,
+[181]=86400,
+[182]=86400,
+[183]=86400,
+[184]=86400,
+[185]=86400,
+[186]=86400,
+[187]=86400,
+[188]=86400,
+[189]=86400,
+[190]=86400,
+[191]=86400,
+[192]=86400,
+[193]=86400,
+[194]=86400,
+[195]=86400,
+[196]=86400,
+[197]=86400,
+[198]=86400,
+[199]=86400,
+[200]=86400,
+[201]=86400,
+[202]=86400,
+[203]=86400,
+[204]=86400,
+[205]=86400,
+[206]=86400,
+[207]=86400,
+[208]=86400,
+[209]=86400,
+[210]=86400,
+[211]=86400,
+[212]=86400,
+[213]=86400,
+[214]=86400,
+[215]=86400,
+[217]=86400,
+[218]=86400,
+[219]=86400,
+[220]=86400,
+[221]=9999999,
+[222]=9999999,
+[223]=86400,
+[224]=86400,
+[228]=9999999,
+[229]=9999999,
+[230]=86400,
+[231]=86400,
+[232]=86400,
+[242]=86400,
+[243]=86400,
+[244]=86400,
+[245]=86400,
+[247]=129600,
+[248]=129600,
+[249]=129600,
+[250]=129600,
+[251]=129600,
+[252]=129600,
+[253]=129600,
+[254]=129600,
+[255]=129600,
+[256]=129600,
+[257]=129600,
+[258]=129600,
+[259]=129600,
+[260]=129600,
+[261]=129600,
+[262]=129600,
+[263]=129600,
+[264]=129600,
+[265]=129600,
+[266]=129600,
+[267]=129600,
+[268]=129600,
+[269]=129600,
+[271]=86400,
+[272]=86400,
+[273]=86400,
+[274]=86400,
+[275]=86400,
+[276]=86400,
+[277]=86400,
+[278]=86400,
+[279]=86400,
+[280]=86400,
+[281]=86400,
+[282]=86400,
+[283]=86400,
+[284]=86400,
+[285]=86400,
+[286]=86400,
+[287]=86400,
+[288]=86400,
+[289]=86400,
+[290]=129600,
+[291]=129600,
+[292]=129600,
+[293]=129600,
+[294]=129600,
+[295]=129600,
+[296]=129600,
+[297]=129600,
+[298]=129600,
+[299]=129600,
+[300]=129600,
+[301]=129600,
+[302]=129600,
+[303]=129600,
+[304]=129600,
+[305]=129600,
+[306]=129600,
+[307]=129600,
+[308]=129600,
+[309]=129600,
+[310]=129600,
+[311]=129600,
+[312]=129600,
+[313]=1209000,
+[314]=1209000,
+[315]=1209000,
+[316]=1209000,
+[317]=1209000,
+[318]=1209000,
+[319]=1209000,
+[320]=1209000,
+[321]=1209000,
+[322]=1209000,
+[323]=1209000,
+[324]=1209000,
+[325]=1209000,
+[326]=1209000,
+[327]=1209000,
+[328]=1209000,
+[329]=86400,
+[330]=86400,
+[331]=86400,
+[332]=86400,
+[333]=86400,
+[334]=252000,
+[335]=252000,
+[336]=252000,
+[337]=252000,
+[338]=86400,
+[339]=86400,
+[340]=86400,
+[341]=86400,
+[342]=86400,
+[343]=86400,
+[344]=86400,
+[345]=86400,
+[346]=86400,
+[347]=86400,
+[348]=86400,
+[349]=86400,
+[350]=86400,
+[351]=86400,
+[352]=86400,
+[353]=86400,
+[354]=86400,
+[355]=86400,
+[356]=86400,
+[357]=86400,
+[358]=252000,
+[359]=252000,
+[360]=252000,
+[361]=252000,
+[362]=86400,
+[363]=86400,
+[364]=86400,
+[365]=86400,
+[366]=57600,
+[367]=57600,
+[368]=57600,
+[369]=57600,
+[370]=57600,
+[371]=57600,
+[372]=57600,
+[373]=57600,
+[374]=57600,
+[375]=57600,
+[376]=57600,
+[377]=57600,
+[378]=86400,
+[379]=86400,
+[380]=129600,
+[381]=86400,
+[382]=86400,
+[383]=86400,
+[384]=86400,
+[385]=129600,
+[386]=86400,
+[387]=86400,
+[388]=86400,
+[389]=86400,
+[390]=86400,
+[391]=86400,
+[392]=86400,
+[393]=86400,
+[394]=86400,
+[395]=86400,
+[396]=86400,
+[397]=86400,
+[398]=86400,
+[399]=86400,
+[400]=86400,
+[401]=86400,
+[402]=86400,
+[403]=1209000,
+[404]=1209000,
+[405]=1209000,
+[406]=1209000,
+[407]=1209000,
+[408]=1209000,
+[409]=1209000,
+[410]=1209000,
+[411]=1209000,
+[412]=1209000,
+[413]=1209000,
+_lastupdate_=1421009516
+}
+setmetatable(ns.wowhead,{__index=function(t,k) return 0 end})