Quantcast

Working rewards management

Alar of Daggerspine [06-19-15 - 22:17]
Working rewards management
Improving mission match

Signed-off-by: Alar of Daggerspine <alar@aspide.it>
Filename
BuildingPage.lua
Debug.lua
FollowerCache.lua
FollowerRecruiting.lua
GarrisonCommander.lua
Init.lua
MatchMaker.lua
MissionCache.lua
MissionControl.lua
PartyCache.lua
diff --git a/BuildingPage.lua b/BuildingPage.lua
index 3b6049b..199c52e 100644
--- a/BuildingPage.lua
+++ b/BuildingPage.lua
@@ -25,7 +25,7 @@ local L=ns.L
 local D=ns.D
 local C=ns.C
 local new,del=ns.new,ns.del
-local module=addon:NewModule("BuildingPage",addon) --#module
+local module=addon:NewSubClass("BuildingPage") --#module
 function module:OnInitialize()
 	--module:SafeHookScript(GBFMap,"OnShow","AddFollowersToMap")
 	module:SafeSecureHook("GarrisonBuildingList_Show","AddCheckBox")
diff --git a/Debug.lua b/Debug.lua
index aefdeda..3b4688a 100644
--- a/Debug.lua
+++ b/Debug.lua
@@ -1,4 +1,3 @@
-if true then return end
 --@do-not-package@
 local me, ns = ...
 if (me=="doc") then
@@ -56,6 +55,7 @@ end
 	for k,v in my() do print(k,v) end
 	return
 end
+local me, ns = ...
 local addon=ns.addon --#addon
 local L=ns.L
 local D=ns.D
@@ -119,11 +119,45 @@ function addon:DumpSinks()
 	self:cutePrint(scroll,sorted)
 end
 end
+local m={}
+function m:AddRow(text,...)
+	local l=AceGUI:Create("Label")
+	l:SetText(text)
+	l:SetColor(...)
+	l:SetFullWidth(true)
+	self:AddChild(l)
+	return l
+end
+function m:AddIconText(icon,text,qt)
+	local l=AceGUI:Create("InteractiveLabel")
+	l:SetFontObject(GameFontNormalSmall)
+	if (qt) then
+		l:SetText(format("%s x %s",text,qt))
+	else
+		l:SetText(text)
+	end
+	l:SetImage(icon)
+	l:SetImageSize(24,24)
+	l:SetFullWidth(true)
+	l.frame:EnableMouse(true)
+	l.frame:SetFrameLevel(999)
+	self:AddChild(l)
+	return l
+end
+function m:AddItem(itemID,qt)
+	local _,itemlink,itemquality,_,_,_,_,_,_,itemtexture=GetItemInfo(itemID)
+	if not itemlink then
+		return self:AddIconText(itemtexture,itemID)
+	else
+		return self:AddIconText(itemtexture,itemlink)
+	end
+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.frame:SetAlpha(1)
 	scrollerWindow:SetTitle(title)
 	scrollerWindow:SetLayout("Fill")
 	--local scrollcontainer = AceGUI:Create("SimpleGroup") -- "InlineGroup" is also good
@@ -141,7 +175,8 @@ function addon:GetScroller(title,type,h,w)
 	scrollerWindow:SetWidth(w)
 	scrollerWindow:SetPoint("CENTER")
 	scrollerWindow:Show()
-	scroll.AddRow=function (self,...) return addon:AddRow(self,...) end
+	for k,v in pairs(m) do scroll[k]=v end
+	scroll.addRow=scroll.AddRow
 	return scroll
 end
 function addon:AddRow(obj,text,...)
@@ -156,14 +191,22 @@ function addon:AddRow(obj,text,...)
 		obj:AddChild(l)
 	end
 end
+local function safesort(a,b)
+	if (tonumber(a) and tonumber(b)) then
+		return a < b
+	else
+		return tostring(a) < tostring(b)
+	end
+end
 function addon:cutePrint(scroll,level,k,v)
 	if (type(level)=="table") then
-		for k,v in pairs(level) do
+		for k,v in kpairs(level,safesort) do
 			self:cutePrint(scroll,"",k,v)
 		end
 		return
 	end
 	if (type(v)=="table") then
+		if (level:len()>6) then return end
 		self:AddRow(scroll,level..C(k,"Azure")..":" ..C("Table","Orange"))
 		for kk,vv in pairs(v) do
 			self:cutePrint(scroll,level .. "  ",kk,vv)
@@ -206,11 +249,11 @@ function addon:DumpIgnored()
 end
 function addon:DumpMission(missionID)
 	local scroll=self:GetScroller("MissionCache " .. self:GetMissionData(missionID,'name'))
-	self:cutePrint(scroll,cache.missions[missionID])
+	self:cutePrint(scroll,self:GetMissionData(missionID))
 end
 function addon:DumpMissions()
 	local scroll=self:GetScroller("MissionCache")
-	for id,data in pairs(cache.missions) do
+	for id,data in pairs(self:GetMissionData(missionID)) do
 		self:cutePrint(scroll,id .. '.'..data.name)
 	end
 end
@@ -226,7 +269,15 @@ function addon:DumpCounters(missionID)
 	self:cutePrint(scroll,counterThreatIndex[missionID])
 end
 function addon:Dump(title,data)
+	if type(data)=="string" then
+		data=_G[data]
+	end
+	if type(data) ~= "table" then
+		print(data,"is not a table")
+		return
+	end
 	local scroll=self:GetScroller(title)
+	print("Dumping",title)
 	self:cutePrint(scroll,data)
 	return scroll
 end
@@ -239,16 +290,14 @@ function addon:DumpParty(missionID)
 	self:cutePrint(scroll,parties[missionID])
 end
 function addon:DumpAgeDb()
-	local t=new()
+	local t=ns.new()
 	for i,v in pairs(dbcache.seen) do
 		tinsert(t,format("%80s %s %d",self:GetMissionData(i,'name'),date("%d/%m/%y %H:%M:%S",v),ns.wowhead[i]))
 	end
 	local scroll=self:GetScroller("Expire db")
 	self:cutePrint(scroll,t)
-	del(t)
+	ns.del(t)
 end
-_G.GCF=GCF
-_G.MW=173
 --[[
 PlaySound("UI_Garrison_CommandTable_Open");
 	PlaySound("UI_Garrison_CommandTable_Close");
@@ -280,4 +329,4 @@ PlaySound("UI_Garrison_CommandTable_Open");
 				PlaySound("UI_Garrison_CommandTable_Follower_LevelUp");

 --]]
---@end-do-not-package@
+--@end-do-not-package@
\ No newline at end of file
diff --git a/FollowerCache.lua b/FollowerCache.lua
index 8be3391..dcff76d 100644
--- a/FollowerCache.lua
+++ b/FollowerCache.lua
@@ -22,10 +22,18 @@ local names={}
 local sorted={}
 local threats={}
 local traits={}
+--@debug@
+if LibDebug then LibDebug() end
+--@end-debug@
+--[===[@non-debug@
+setfenv(1,setmetatable({print=function(...) print("x",...) end},{__index=_G}))
+--@end-non-debug@]===]
+local LE_FOLLOWER_TYPE_GARRISON_6_0=LE_FOLLOWER_TYPE_GARRISON_6_0
+local LE_FOLLOWER_TYPE_SHIPYARD_6_2=LE_FOLLOWER_TYPE_SHIPYARD_6_2
 local function keyToIndex(key)
 	if (not Mbase.followers or not next(Mbase.followers)) then
 		Mbase.dirtyList=false
-		Mbase.followers = G.GetFollowers();
+		Mbase.followers = G.GetFollowers(LE_FOLLOWER_TYPE_GARRISON_6_0);
 	end
 	local idx=key and index[key] or nil
 	if (idx and idx <= #Mbase.followers) then
@@ -82,7 +90,7 @@ local function AddExtraData(follower,refreshrank)
 	follower.abilities=G.GetFollowerAbilities(follower.followerID)
 end
 function addon:FollowerCacheInit()
-	pcall(GarrisonFollowerList_UpdateFollowers,Mbase)
+	pcall(GarrisonFollowerList_UpdateFollowers,Mbase,1)
 end
 function addon:CanCounter(followerID,id)
 	local abilities=self:GetFollowerData(followerID,'abilities')
@@ -110,11 +118,6 @@ function addon:GetFollowerData(followerID,key,default)
 	local idx=keyToIndex(followerID)
 	local follower=Mbase.followers[idx]
 	if (not follower) then
---@debug@
-		print("Not found",followerID,key,"at",idx,"len",#Mbase.followers)
-		DevTools_Dump(G.GetFollowerInfo(followerID))
-		print(debugstack())
---@end-debug@
 		return default
 	end
 	if (key==nil) then
@@ -139,9 +142,9 @@ end
 -- Iterator function
 -- @param func type of sorting (can be mitted if we dont care)
 --
-function addon:GetFollowerIterator(func)
+function addon:GetFollowerIterator(func,followerTypeID)
 	keyToIndex()
-	if (func) then
+	if type(func)=="function" then
 		table.sort(sorted,sorters[func])
 	end
 	local f=Mbase.followers
diff --git a/FollowerRecruiting.lua b/FollowerRecruiting.lua
index 0c693f7..b980395 100644
--- a/FollowerRecruiting.lua
+++ b/FollowerRecruiting.lua
@@ -13,7 +13,7 @@ local D=ns.D
 local C=ns.C
 local new,del=ns.new,ns.del
 local GRF=GarrisonRecruiterFrame.Pick
-local module=addon:NewModule("RecruitingPage",addon) --#module
+local module=addon:NewSubClass("RecruitingPage") --#module
 function module:OnInitialize()
 end
 local origGarrisonRecruiterFrame_AddEntryToDropdown=GarrisonRecruiterFrame_AddEntryToDropdown
diff --git a/GarrisonCommander.lua b/GarrisonCommander.lua
index 3f80202..acdc349 100644
--- a/GarrisonCommander.lua
+++ b/GarrisonCommander.lua
@@ -175,7 +175,6 @@ local FLSIZE=400
 local BIGBUTTON=BIGSIZEW-GCSIZE
 local SMALLBUTTON=BIGSIZEW-GCSIZE
 local GCF
-local GMC
 local GCFMissions
 local GCFBusyStatus
 local GameTooltip=GameTooltip
@@ -408,11 +407,6 @@ function addon:OnInitialized()
 	self:Trigger("MSORT")
 	self:AddOpenCmd("show","showdata","Prints a mission score")
 	LoadAddOn("GarrisonCommander-Broker")
-	if false and self.db.global.traits[ns.toc] then
-		return true
-	else
-		self.db.global.traits[ns.toc]=traitTable
-	end
 	return true
 end
 function addon:showdata(fullargs,action,missionid)
@@ -473,24 +467,17 @@ function _G.GarrisonTraitCountersFrame_OnLoad(self, followerType, tooltipString)
 	fillCounters(self,1)
 	do
 		local frame=self.choice
-		local list=addon:GetSortedProxy({})
-		for v,k in pairs(G.GetRecruiterAbilityCategories()) do
-			if (ns.traitTable[v]) then
-				list[k]=v
-			end
-		end
-
+		local list=G.GetRecruiterAbilityCategories()
 		local function sel(this,category,index)
-			print(category,index)
 			UIDropDownMenu_SetSelectedID(frame,index)
 			fillCounters(frame:GetParent(),category)
 		end
 		UIDropDownMenu_Initialize(frame, function(...)
 			local i=0
-			for k,v in list() do
+			for v,k in pairs(list) do
 				i=i+1
 				local info=UIDropDownMenu_CreateInfo()
-				info.text=v
+				info.text=k
 				info.value=v
 				info.func=sel
 				info.arg1=v
@@ -677,7 +664,7 @@ function addon:SetThreatColor(obj,threat)
 end

 function addon:HookedGarrisonMissionButton_AddThreatsToTooltip(missionID)
-	if (GMC:IsShown()) then return end
+	if (ns.ns.GMC:IsShown()) then return end
 	return self:RenderTooltip(missionID)
 end
 function addon:AddIconsToFollower(missionID,useful,followers,members,followerTypeID)
@@ -836,17 +823,25 @@ function addon:CreatePrivateDb()
 						gold=true,
 						equip=true,
 						resources=true,
-						xp=true
+						xp=true,
+						scroll=true,
+						apexis=true,
+						oil=true,
+						other=true
 					},
 					rewardChance={
 						followerEquip=100,
 						gold=100,
 						equip=100,
 						resources=100,
-						xp=100
+						xp=100,
+						scroll=100,
+						apexis=100,
+						oil=100,
+						other=100
 					},
+					rewardOrder={1,2,3,4,5,6,7,8,9},
 					useOneChance=true,
-					itemPrio = {},
 					minimumChance = 100,
 					minDuration = 0,
 					maxDuration = 24,
@@ -874,6 +869,13 @@ end
 function addon:SetClean()
 	dirty=false
 end
+function addon:HasSalvageYard()
+	local buildings=G.GetBuildings()
+	for i =1,#buildings do
+		local building=buildings[i]
+		if building.texPrefix=="GarrBuilding_SalvageYard_1_A" then return true end
+	end
+end

 function addon:WipeMission(missionID)
 	cache.missions[missionID]=nil
@@ -1673,7 +1675,7 @@ function addon:SetUp(...)
 	self:CheckMP()
 	self:CheckGMM()
 	self:Options()
-	GMC=self:GMCBuildPanel(ns.bigscreen)
+	--GMC=self:GMCBuildPanel(ns.bigscreen)
 	local tabMC=CreateFrame("CheckButton",nil,GMF,"SpellBookSkillLineTabTemplate")
 	GMF.tabMC=tabMC
 	tabMC.tooltip="Open Garrison Commander Mission Control"
@@ -2345,8 +2347,8 @@ end
 function addon:OpenLastTab()
 	lastTab=lastTab or PanelTemplates_GetSelectedTab(GMF)
 	if lastTab then
-		if GMC:IsShown() then
-			GMC:Hide()
+		if ns.GMC:IsShown() then
+			ns.GMC:Hide()
 			GMF.tabMC:SetChecked(false)
 			if lastTab==2 then
 				GMF.FollowerTab:Show()
@@ -2374,14 +2376,14 @@ function addon:OpenMissionsTab()
 	return self:OpenLastTab()
 end
 function addon:OpenMissionControlTab()
-	if (not GMC:IsShown()) then
+	if (not ns.GMC:IsShown()) then
 		lastTab=PanelTemplates_GetSelectedTab(GMF)
 		GMF.FollowerTab:Hide()
 		GMF.FollowerList:Hide()
 		GMF.MissionTab:Hide()
 		GMF.TitleText:SetText(L["Garrison Commander Mission Control"])
-		GMC:Show()
-		GMC.startButton:Click()
+		ns.GMC:Show()
+		ns.GMC.startButton:Click()
 		GMF.tabMC:SetChecked(true)
 	else
 		GMF.tabMC:SetChecked(false)
@@ -3047,6 +3049,7 @@ function addon:AddFollowersToButton(button,mission,missionID,bigscreen)
 end
 -- Switchs between active and availabla missions depending on tab object
 function over.GarrisonMissionList_SetTab(...)
+	print("Click su",...)
 	-- I dont actually care wich page we are shoing, I know I must redraw missions
 	orig.GarrisonMissionList_SetTab(...)
 	addon:RefreshFollowerStatus()
@@ -3055,6 +3058,18 @@ function over.GarrisonMissionList_SetTab(...)
 	end
 	if (HD) then addon:ResetSinks() end
 end
+function over.GarrisonMissionController_OnClickTab(self,tab,...)
+	print("Click su",...)
+	-- I dont actually care wich page we are shoing, I know I must redraw missions
+	orig.GarrisonMissionController_OnClickTab(self,tab,...)
+	addon:RefreshFollowerStatus()
+	for i=1,#GMFMissionListButtons do
+		GMFMissionListButtons.lastMissionID=nil
+	end
+	lastTab=tab:GetID()
+	if (HD) then addon:ResetSinks() end
+	addon:OpenLastTab();
+end
 function over.GarrisonMissionButton_OnClick(f,b)
 	print(f,f:GetName())
 	return orig.GarrisonMissionButton_OnClick(f,b)
@@ -3068,6 +3083,7 @@ override("GarrisonMissionButton_OnEnter")
 override("GarrisonMissionPageFollowerFrame_OnEnter")
 override("GarrisonMissionList_SetTab")
 override("GarrisonMissionButton_OnClick")
+override("GarrisonMissionController_OnClickTab")

 GMF.MissionTab.MissionPage.CloseButton:SetScript("OnClick",over.GarrisonMissionPage_Close)
 for i=1,#GMFMissionListButtons do
diff --git a/Init.lua b/Init.lua
index 97db8f9..8eceb16 100644
--- a/Init.lua
+++ b/Init.lua
@@ -294,13 +294,66 @@ end
 ATEINFO['abilities']=map
 --]]

---

---[===[@non-debug@
-if true then return end
---@end-non-debug@]===]
+--Debug.lua (da aggiungere al toc)
+
 --@do-not-package@
+local me, ns = ...
+if (me=="doc") then
+	local mt={
+		keys=setmetatable({},{__index=function(t,k) rawset(t,k,{}) return t[k] end }),
+		__metatable=true
+
+	}
+	function mt:__index(k)

+		if k=="n" then
+			return #mt.keys[self]
+		end
+		return rawget(self,k)
+	end
+	function mt:__len()
+		return #mt.keys[self]
+	end
+	function mt:__newindex(k,v)
+		local keys=mt.keys[self]
+		local pos=#keys+1
+		print("Inserting",k)
+		for i,x in ipairs(keys) do
+			if x>k then
+				pos=i
+				break;
+			end
+		end
+		table.insert(keys,pos,k)
+		print("Inserted",k,"at",pos)
+		rawset(self,k,v)
+	end
+	function a()
+				return function(unsorted,i)
+				i=i+1
+				local k=mt.keys[unsorted][i]
+				if k then return i,k end
+			end,self,0
+	end
+	function mt:__call()
+		do
+			local current=0
+			return function(unsorted,i)
+				current=current+1
+				local k=mt.keys[unsorted][current]
+				if k then return k,self[k] end
+			end,self,0
+		end
+end
+	local my=setmetatable({},mt)
+	my.pippo=3
+	my.pluto=4
+	my.andrea=2
+	my.zanzi=1
+	for k,v in my() do print(k,v) end
+	return
+end
 local me, ns = ...
 local addon=ns.addon --#addon
 local L=ns.L
@@ -576,4 +629,3 @@ PlaySound("UI_Garrison_CommandTable_Open");

 --]]
 --@end-do-not-package@
-
diff --git a/MatchMaker.lua b/MatchMaker.lua
index 60d439c..1368b78 100644
--- a/MatchMaker.lua
+++ b/MatchMaker.lua
@@ -87,11 +87,11 @@ end
 function filters.ignored(followerID,missionID)
 	return addon:IsIgnored(followerID,missionID)
 end
-function filters.generic(followerID,missionID)
+function filters.other(followerID,missionID)
 	return filters.busy(followerID,missionID) or filters.ignored(followerID,missionID)
 end
 function filters.xp(followerID,missionID)
-	return filters.maxed(followerID,missionID) or filters.generic(followerID,missionID)
+	return filters.maxed(followerID,missionID) or filters.other(followerID,missionID)
 end
 --alias
 --filters.resources=filters.generic
@@ -129,7 +129,7 @@ local filterTypes = setmetatable({}, {__index=function(self, missionClass)
 end})
 local function AddMoreFollowers(self,mission,scores,justdo)
 	local missionID=mission.missionID
-	local filterOut=filters[mission.class] or filters.generic
+	local filterOut=filters[mission.class] or filters.other
 	local missionScore=self:MissionScore(mission)

 	for p=1,P:FreeSlots() do
@@ -171,7 +171,7 @@ local function MatchMaker(self,missionID,party,includeBusy,onlyBest)
 	local mission=self:GetMissionData(missionID)
 	local class=self:GetMissionData(missionID,'class')
 	print(C(format("MATCHMAKER %s (%d) class: %s",mission.name,missionID,class),'Orange'),includeBusy and "Busy" or "Ready")
-	local filterOut=filters[class] or filters.generic
+	local filterOut=filters[class] or filters.other
 	filters.skipMaxed=self:GetBoolean("IGP")
 	if (includeBusy==nil) then
 		filters.skipBusy=self:GetBoolean("IGM")
@@ -239,6 +239,7 @@ local function MatchMaker(self,missionID,party,includeBusy,onlyBest)
 			end
 			if mission.numFollowers > 1 then
 				AddMoreFollowers(self,mission,scores)
+				AddMoreFollowers(self,mission,fillers)
 			end
 		end
 	end
@@ -271,6 +272,10 @@ local function MatchMaker(self,missionID,party,includeBusy,onlyBest)
 		party.xpBonus=mission.xpBonus
 		party.gold=mission.gold
 		party.resources=mission.resources
+		party.oil=mission.oil
+		party.apexis=mission.apexis
+		party.epic=mission.epic
+		party.other=mission.other
 	end
 	P:StoreFollowers(party.members)
 	P:Close(party)
diff --git a/MissionCache.lua b/MissionCache.lua
index c0cec7f..42b3586 100644
--- a/MissionCache.lua
+++ b/MissionCache.lua
@@ -22,7 +22,6 @@ local Mbase = GMFMissions
 --	C_Garrison.GetAvailableMissions(self.availableMissions);
 local Index={}
 local sorted={}
-local AddExtraData
 local ItemRewards={122484,118529,128391}
 local rushOrders="interface\\icons\\inv_scroll_12.blp"
 local function keyToIndex(key)
@@ -68,15 +67,17 @@ function addon:GetMissionData(missionID,key,default)
 	if not mission then
 		mission=G.GetMissionInfo(missionID)
 	end
---@debug@
 	if not mission then
+--@debug@
 		self:Print("Could not find info for mission",missionID,G.GetMissionName(missionID))
-	end
 --@end-debug@
-	if (mission.class=="retry" or not mission.globalXp) then
-		AddExtraData(mission)
+		return default
 	end
 	if (key==nil) then
+		if (mission.class=="retry" or not mission.globalXp or key=="globalXp") then
+			print(key)
+			self:AddExtraData(mission)
+		end
 		return mission
 	end
 	if not mission then
@@ -103,12 +104,13 @@ function addon:GetMissionData(missionID,key,default)
 		return mission[key] or default
 	end
 end
-function AddExtraData(mission)
+function addon:AddExtraData(mission)
 	local _
 	_,mission.xp,mission.type,mission.typeDesc,mission.typeIcon,mission.locPrefix,_,mission.enemies=G.GetMissionInfo(mission.missionID)
 	mission.rank=mission.level < GARRISON_FOLLOWER_MAX_LEVEL and mission.level or mission.iLevel
 	mission.resources=0
 	mission.oil=0
+	mission.apexis=0
 	mission.gold=0
 	mission.followerUpgrade=0
 	mission.itemLevel=0
@@ -123,6 +125,7 @@ function AddExtraData(mission)
 		if k==615 and 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==GARRISON_SHIP_OIL_CURRENCY then mission.oil=v.quantity end
+		if v.currencyID and v.currencyID==823 then mission.apexis =mission.apexis+v.quantity end
 		if v.currencyID and v.currencyID==0 then mission.gold =mission.gold+v.quantity/10000 end
 		if v.icon=="Interface\\Icons\\XPBonus_Icon" and v.followerXP then
 			mission.xpBonus=mission.xpBonus+v.followerXP
@@ -158,14 +161,18 @@ function AddExtraData(mission)
 		mission.class='oil'
 		mission.maxable=true
 		mission.mat=true
+	elseif mission.apexis > 0 then
+		mission.class='apexis'
+		mission.maxable=true
+		mission.mat=true
 	elseif mission.gold >0 then
 		mission.class='gold'
 		mission.maxable=true
 		mission.mat=true
 	elseif mission.itemLevel >0 then
-		mission.class='equip'
+		mission.class='itemLevel'
 	elseif mission.followerUpgrade>0 then
-		mission.class='followerEquip'
+		mission.class='followerUpgrade'
 	elseif mission.itemLevel>=645 then
 		mission.class='epic'
 	elseif mission.rush>=0 then
diff --git a/MissionControl.lua b/MissionControl.lua
index d6adb07..e9a9cbd 100644
--- a/MissionControl.lua
+++ b/MissionControl.lua
@@ -28,18 +28,36 @@ _G.GAC=addon
 if LibDebug then LibDebug() end
 --@end-debug@
 local dbg
-function addon:GMCBusy(followerID)
+local tItems = {
+	{t = 'Enable/Disable money rewards.', i = 'Interface\\Icons\\inv_misc_coin_01', key = 'gold'},
+	{t = 'Enable/Disable resource awards. (Resources/Seals)', i= 'Interface\\Icons\\inv_garrison_resource', key = 'resources'},
+	{t = 'Enable/Disable rush scroll.', i= 'Interface\\ICONS\\INV_Scroll_12', key = 'rush'},
+	{t = 'Enable/Disable Follower XP Bonus rewards.', i = 'Interface\\Icons\\XPBonus_Icon', key = 'xp'},
+	{t = 'Enable/Disable follower equip enhancement.', i = 'Interface\\ICONS\\Garrison_ArmorUpgrade', key = 'followerEquip'},
+	{t = 'Enable/Disable item tokens.', i = "Interface\\ICONS\\INV_Bracer_Cloth_Reputation_C_01", key = 'equip'},
+	{t = 'Enable/Disable apexis.', i = "Interface\\Icons\\inv_apexis_draenor", key = 'apexis'},
+	{t = 'Enable/Disable other rewards.', i = "Interface\\ICONS\\INV_Box_02", key = 'other'}
+}
+local tOrder
+local settings
+if (ns.toc >=60200) then
+	tinsert(tItems,3,{t = 'Enable/Disable oil awards.', i= 'Interface\\Icons\\garrison_oil', key = 'oil'})
+end
+local module=addon:NewSubClass("MissionControl") --#module
+function module:GMCBusy(followerID)
 	return GMCUsedFollowers[followerID]
 end
-function addon:GMCCreateMissionList(workList)
+addon.GMCBusy=module.GMCBusy
+function module: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 in self:GetMissionIterator() do
 		local discarded=false
+		local class=self:GetMissionData(missionID,"class")
 		repeat
-			print("|cffff0000",'Examing',self:GetMissionData(missionID,"name"),self:GetMissionData(missionID,"class"),"|r")
+			print("|cffff0000",'Examing',missionID,self:GetMissionData(missionID,"name"),class,"|r")
 			local durationSeconds=self:GetMissionData(missionID,'durationSeconds')
 			if (durationSeconds > settings.maxDuration * 3600 or durationSeconds <  settings.minDuration * 3600) then
 				print(missionID,"discarded due to len",durationSeconds /3600)
@@ -49,14 +67,10 @@ function addon:GMCCreateMissionList(workList)
 				print(missionID,"discarded due to rarity")
 				break
 			end
-			for k,v in pairs(ar) do
-				if (not v) then
-					if (self:GetMissionData(missionID,"class")==k) then -- we have a forbidden reward
-						print(missionID,"discarded due to class == ", k)
-						discarded=true
-						break
-					end
-				end
+			if (not ar[class]) then
+				print(missionID,"discarded due to class == ", class)
+				discarded=true
+				break
 			end
 			if (not discarded) then
 				tinsert(workList,missionID)
@@ -65,18 +79,9 @@ function addon:GMCCreateMissionList(workList)
 	end
 	local parties=self:GetParty()
 	local function msort(i1,i2)
-		for i=1,#GMC.settings.itemPrio do
-			local criterium=GMC.settings.itemPrio[i]
-			if (criterium) then
-				if addon:GetMissionData(i1,criterium) ~= addon:GetMissionData(i2,criterium) then
-					return addon:GetMissionData(i1,criterium) > addon:GetMissionData(i2,criterium)
-				end
-			end
-		end
-		if (parties[i1].perc and parties[i2].perc) then
-			return parties[i1].perc > parties[i2].perc
-		end
-		return addon:GetMissionData(i1,'level') > addon:GetMissionData(i2,'level')
+		local c1=addon:GetMissionData(i1,'class','other')
+		local c2=addon:GetMissionData(i2,'class','other')
+		return addon:GetMissionData(i1,c1,0) > addon:GetMissionData(i2,c2,0)
 	end
 	table.sort(workList,msort)
 end
@@ -84,7 +89,7 @@ end
 -- 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)
+function module:GMCRunMission(missionID,start)
 	print("Asked to start mission",missionID)
 	if (start) then
 		G.StartMission(missionID)
@@ -117,7 +122,7 @@ do
 	local timeElapsed=0
 	local currentMission=0
 	local x=0
-	function addon:GMCCalculateMissions(this,elapsed)
+	function module:GMCCalculateMissions(this,elapsed)
 		db.news.MissionControl=true
 		timeElapsed = timeElapsed + elapsed
 		if (#aMissions == 0 ) then
@@ -172,7 +177,7 @@ do
 					mb:SetFullWidth(true)
 					mb:SetMission(self:GetMissionData(missionID),party)
 					mb:SetCallback("OnClick",function(...)
-						addon:GMCRunMission(missionID)
+						module:GMCRunMission(missionID)
 						GMC.ml.widget:RemoveChild(missionID)
 					end
 					)
@@ -183,7 +188,7 @@ do
 	end
 end

-function addon:GMC_OnClick_Run(this,button)
+function module:GMC_OnClick_Run(this,button)
 	this:Disable()
 	GMC.logoutButton:Disable()
 	do
@@ -203,7 +208,7 @@ function addon:GMC_OnClick_Run(this,button)
 	)
 	end
 end
-function addon:GMC_OnClick_Start(this,button)
+function module:GMC_OnClick_Start(this,button)
 	print(C("-------------------------------------------------","Yellow"))
 	GMC.ml.widget:ClearChildren()
 	if (self:GetTotFollowers(AVAILABLE) == 0) then
@@ -218,7 +223,7 @@ function addon:GMC_OnClick_Start(this,button)
 	end
 	this:Disable()
 	GMC.ml.widget:SetTitleColor(C.Green())
-	addon:GMCCreateMissionList(aMissions)
+	module:GMCCreateMissionList(aMissions)
 	wipe(GMCUsedFollowers)
 	wipe(GMC.ml.Parties)
 	self:RefreshFollowerStatus()
@@ -231,26 +236,6 @@ function addon:GMC_OnClick_Start(this,button)
 	self:RawHookScript(GMC.startButton,'OnUpdate',"GMCCalculateMissions")

 end
-function addon:HasSalvageYard()
-	local buildings=G.GetBuildings()
-	for i =1,#buildings do
-		local building=buildings[i]
-		if building.texPrefix=="GarrBuilding_SalvageYard_1_A" then return true end
-	end
-end
-local tItems = {
-	{t = 'Enable/Disable money rewards.', i = 'Interface\\Icons\\inv_misc_coin_01', key = 'gold'},
-	{t = 'Enable/Disable resource awards. (Resources/Seals)', i= 'Interface\\Icons\\inv_garrison_resource', key = 'resources'},
-	{t = 'Enable/Disable rush scroll.', i= 'Interface\\ICONS\\INV_Scroll_12', key = 'scroll'},
-	{t = 'Enable/Disable Follower XP Bonus rewards.', i = 'Interface\\Icons\\XPBonus_Icon', key = 'xp'},
-	{t = 'Enable/Disable follower equip enhancement.', i = 'Interface\\ICONS\\Garrison_ArmorUpgrade', key = 'followerEquip'},
-	{t = 'Enable/Disable item tokens.', i = "Interface\\ICONS\\INV_Bracer_Cloth_Reputation_C_01", key = 'equip'},
-	{t = 'Enable/Disable other rewards.', i = "Interface\\ICONS\\INV_Box_02", key = 'generic'}
-}
-if (ns.toc >=60200) then
-	tinsert(tItems,3,{t = 'Enable/Disable oil awards.', i='Interface\\Icons\\garrison_oil', key = 'oil'})
-end
-local tOrder={1,2,3,4,5,6,7,8}
 local chestTexture
 local function drawItemButtons()
 	local scale=1.1
@@ -259,7 +244,6 @@ local function drawItemButtons()
 	local single=GMC.settings.useOneChance
 	for j = 1, #tItems do
 		local i=tOrder[j]
-		print(j,i)
 		local frame = GMC.ignoreFrames[j] or CreateFrame('BUTTON', "Priority" .. j, GMC.aif, 'ItemButtonTemplate')
 		GMC.ignoreFrames[j] = frame
 		frame:SetID(i)
@@ -305,6 +289,7 @@ local function drawItemButtons()
 		frame:SetScript('OnClick', function(this)
 			GMC.settings.allowedRewards[this.key] = not GMC.settings.allowedRewards[this.key]
 			drawItemButtons()
+			GMC.startButton:Click()
 		end)
 		frame:SetScript('OnEnter', function(this)
 			GameTooltip:SetOwner(this, 'ANCHOR_BOTTOMRIGHT')
@@ -316,8 +301,15 @@ local function drawItemButtons()
 		frame:SetScript("OnDragStart",function(this,button)
 			print("Start",this:GetID())
 			this:StartMoving()
+			this.oldframestrata=this:GetFrameStrata()
+			this:SetFrameStrata("FULLSCREEN_DIALOG")
+		end)
+		frame:SetScript("OnDragStop",function(this,button)
+			this:StopMovingOrSizing()
+			print("Stopped",this:GetID())
+			this:SetFrameStrata(this.oldframestrata)
+
 		end)
-		frame:SetScript("OnDragStop",function(this,button) this:StopMovingOrSizing() print("Stopped",this:GetID()) end)
 		frame:SetScript("OnReceiveDrag",function(this)
 				local x,y=this:GetCenter()
 				local id=this:GetID()
@@ -336,6 +328,7 @@ local function drawItemButtons()
 					end
 				end
 				drawItemButtons()
+				GMC.startButton:Click()
 		end)
 		frame:SetScript('OnLeave', function() GameTooltip:Hide() end)
 		frame:Show()
@@ -346,7 +339,7 @@ local function drawItemButtons()
 		GMC.rewardinfo = GMC.aif:CreateFontString()
 		local info=GMC.rewardinfo
 		info:SetFontObject('GameFontHighlight')
-		info:SetText('Click to enable/disable a reward.')
+		info:SetText("Click to enable/disable a reward.\nDrag to reorder")
 		info:SetTextColor(1, 1, 1)
 		info:SetPoint("TOP",GMC.ignoreFrames[#tItems],"BOTTOM",256/2,-15)
 	end
@@ -355,13 +348,28 @@ local function drawItemButtons()

 end

-function addon:GMCBuildPanel(bigscreen)
-	db=self.db.global
-	dbcache=self.privatedb.profile
-	cache=self.private.profile
+function module:OnInitialized()
+	local bigscreen=ns.bigscreen
+	db=addon.db.global
+	dbcache=addon.privatedb.profile
+	cache=addon.private.profile
 	chestTexture='GarrMission-'..UnitFactionGroup('player').. 'Chest'
 	GMC = CreateFrame('FRAME', 'GMCOptions', GMF)
+	ns.GMC=GMC
 	GMC.settings=dbcache.missionControl
+	settings=dbcache.missionControl
+	if type(settings.allowedRewards['equip'])~='nil' then
+		settings.allowedRewards['itemLevel']=settings.allowedRewards['equip']
+		settings.allowedRewards['equip']=nil
+	end
+	if type(settings.allowedRewards['followerEquip'])~='nil' then
+		settings.allowedRewards['followerUpgrade']=settings.allowedRewards['followerUpgrade']
+		settings.allowedRewards['followerEquip']=nil
+	end
+	tOrder=GMC.settings.rewardOrder
+	if GMC.settings.itemPrio then
+		GMC.settings.itemPrio=nil
+	end
 	GMC:SetAllPoints()
 	--GMC:SetPoint('LEFT')
 	--GMC:SetSize(GMF:GetWidth(), GMF:GetHeight())
@@ -404,7 +412,7 @@ function addon:GMCBuildPanel(bigscreen)
 	GMC.skipRare:SetPoint("TOPLEFT",chance,"BOTTOMLEFT",40,-50)
 	GMC.skipRare:SetScript("OnClick",function(this)
 		GMC.settings.skipRare=this:GetChecked()
-		addon:GMC_OnClick_Start(GMC.startButton,"LeftUp")
+		module:GMC_OnClick_Start(GMC.startButton,"LeftUp")
 	end)
 	local warning=GMC:CreateFontString(nil,"ARTWORK","CombatTextFont")
 	warning:SetText(L["Epic followers are NOT sent alone on xp only missions"])
@@ -418,7 +426,7 @@ function addon:GMCBuildPanel(bigscreen)
 	GMC.skipEpic:SetScript("OnClick",function(this)
 		GMC.settings.skipEpic=this:GetChecked()
 		if (GMC.settings.skipEpic) then warning:Show() else warning:Hide() end
-		addon:GMC_OnClick_Start(GMC.startButton,"LeftUp")
+		module:GMC_OnClick_Start(GMC.startButton,"LeftUp")
 	end)
 	GMC.Credits=GMC:CreateFontString(nil,"ARTWORK","QuestFont_Shadow_Small")
 	GMC.Credits:SetWidth(0)
@@ -427,7 +435,7 @@ function addon:GMCBuildPanel(bigscreen)
 	GMC.Credits:SetPoint("BOTTOMLEFT",25,25)
 	return GMC
 end
-function addon:GMCBuildChance()
+function module:GMCBuildChance()
 	_G['GMC']=GMC
 	--Chance
 	GMC.cf = CreateFrame('FRAME', nil, GMC)
@@ -489,7 +497,7 @@ local function timeslidechange(this,value)
 	GMC.mt:SetTextColor(1, c, c)
 	GMC.mt:SetFormattedText("%d-%dh",GMC.settings.minDuration,GMC.settings.maxDuration)
 end
-function addon:GMCBuildDuration()
+function module:GMCBuildDuration()
 	-- Duration
 	GMC.tf = CreateFrame('FRAME', nil, GMC)
 	GMC.tf:SetSize(256, 180)
@@ -532,7 +540,7 @@ function addon:GMCBuildDuration()
 	timeslidechange(GMC.ms2,GMC.settings.maxDuration)
 	return GMC.tf
 end
-function addon:GMCBuildRewards()
+function module:GMCBuildRewards()
 	--Allowed rewards
 	GMC.aif = CreateFrame('FRAME', nil, GMC)
 	GMC.itf = GMC.aif:CreateFontString()
@@ -560,7 +568,7 @@ function addon:GMCBuildRewards()
 	return GMC.aif
 end

-function addon:GMCBuildMissionList()
+function module:GMCBuildMissionList()
 		-- Mission list on follower panels
 --		local ml=CreateFrame("Frame",nil,GMC)
 --		addBackdrop(ml)
diff --git a/PartyCache.lua b/PartyCache.lua
index 4000db7..2c70da5 100644
--- a/PartyCache.lua
+++ b/PartyCache.lua
@@ -13,7 +13,12 @@ local pcall=pcall
 local type=type
 local pairs=pairs
 local format=format
-
+--@debug@
+if LibDebug then LibDebug() end
+--@end-debug@
+--[===[@non-debug@
+setfenv(1,setmetatable({print=function(...) print("x",...) end},{__index=_G}))
+--@end-non-debug@]===]
 --
 -- Temporary party management
 local parties=setmetatable({},{