changeset 34:6ce173840e68

Reworked the whole "wow object" system: - Only save what is strictly necessary. - Save appropriate persistent information for all objects (like spellIDs instead of spellBook+spellIndex). - Fixed Battle Pets objects (non-combat pets in pre-MoP). - Fixed item objects. - Cleaned and simplified most objects implementation. - Moved the settings and button profile to the root of the saved data, rather than in a per-character sub-table (that data is already tagged as saved per character). This should fix most issues with objects changing without user interaction on diverse occasions. Old profiles are not converted to the new system. This will come soon. Some issues persist due to the asynchronous loading of some informations: - Pet icons are never properly loaded from saved data. - Items are not properly loaded the first time the UI is started (a "/reload ui" or disconnect/connect cycle fixes this problem).
author madcatzinc@35b17cf1-18cd-47ff-9ca3-31d6b526ef09
date Thu, 25 Apr 2013 01:31:31 +0000
parents 1c0af1810e06
children 16b2ff47b6db
files CyborgMMO7.lua RatPageController.lua RatPageModel.lua RatPageView.lua WowObjects.lua
diffstat 5 files changed, 185 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/CyborgMMO7.lua	Thu Apr 25 01:31:26 2013 +0000
+++ b/CyborgMMO7.lua	Thu Apr 25 01:31:31 2013 +0000
@@ -84,14 +84,22 @@
 	assert(VarsLoaded)
 	if not CyborgMMO7SaveData then
 		CyborgMMO7SaveData = {}
-		CyborgMMO7SaveData[SaveName] = {}
 	end
-	return CyborgMMO7SaveData[SaveName]
+	return CyborgMMO7SaveData
 end
 
-function CyborgMMO_SetSaveData(data, index)
+function CyborgMMO_SetRatSaveData(data)
 	assert(VarsLoaded)
-	CyborgMMO_GetSaveData()[index] = data
+	local saveData = {}
+	for mode=1,#data do
+		saveData[mode] = {}
+		for button=1,#data[mode] do
+			if data[mode][button] then
+				saveData[mode][button] = data[mode][button]:SaveData()
+			end
+		end
+	end
+	CyborgMMO_GetSaveData().Rat = saveData
 end
 
 function CyborgMMO_Event(self, event, ...)
--- a/RatPageController.lua	Thu Apr 25 01:31:26 2013 +0000
+++ b/RatPageController.lua	Thu Apr 25 01:31:31 2013 +0000
@@ -46,12 +46,37 @@
 end
 
 function RatPageController_methods:GetCursorObject()
-	local cursorObject = nil
-	if GetCursorInfo() then
-		cursorObject = CyborgMMO_CreateWowObject(GetCursorInfo())
-		ClearCursor()
+	local type,a,b,c = GetCursorInfo()
+	ClearCursor()
+	if type=='item' then
+		local id,link = a,b
+		return CyborgMMO_CreateWowObject('item', id)
+	elseif type=='spell' then
+		local index,book,id = a,b,c
+		return CyborgMMO_CreateWowObject('spell', id)
+	elseif type=='macro' then
+		local index = a
+		local name = GetMacroInfo(index)
+		return CyborgMMO_CreateWowObject('macro', name)
+	elseif type=='companion' then
+		local index,subtype = a,b
+		local spellID = select(3, GetCompanionInfo(subtype, index))
+		return CyborgMMO_CreateWowObject('companion', spellID)
+	elseif type=='battlepet' then
+		local petID = a
+		return CyborgMMO_CreateWowObject('battlepet', petID)
+	elseif type=='petaction' then
+		return nil
+	elseif type=='money' then
+		return nil
+	elseif type=='merchant' then
+		return nil
+	elseif type==nil then
+		return nil
+	else
+		CyborgMMO_DPrint("unexpected cursor info:", type, a, b, c)
+		return nil
 	end
-	return cursorObject
 end
 
 function RatPageController_methods:CallbackDropped(callbackObject)
--- a/RatPageModel.lua	Thu Apr 25 01:31:26 2013 +0000
+++ b/RatPageModel.lua	Thu Apr 25 01:31:31 2013 +0000
@@ -77,10 +77,10 @@
 		for mode=1,RAT7.MODES do
 			for button=1,RAT7.BUTTONS do
 				if self.data[mode][button] then
-					local object = CyborgMMO_CreateWowObject(self.data[mode][button].Type, self.data[mode][button].Detail, self.data[mode][button].Subdetail)
+					local object = CyborgMMO_CreateWowObject(self.data[mode][button].type, self.data[mode][button].detail, self.data[mode][button].subdetail)
 					self:SetObjectOnButtonNoUpdate(button, mode, object)
 				else
-					local object = CyborgMMO_CreateWowObject("", "", "")
+					local object = CyborgMMO_CreateWowObject()
 					self:SetObjectOnButtonNoUpdate(button, mode, object)
 					self.data[mode][button] = object
 				end
@@ -92,7 +92,7 @@
 
 function RatPageModel_methods:SaveData()
 	CyborgMMO_DPrint("Saving...")
-	CyborgMMO_SetSaveData(self.data, "Rat")
+	CyborgMMO_SetRatSaveData(self.data)
 end
 
 function RatPageModel_methods:SetMode(mode)
@@ -122,10 +122,10 @@
 
 	if object then
 		object:SetBinding(CyborgMMO_ProfileKeyBindings[((mode-1)*RAT7.BUTTONS)+button])
-		if("callback" == object.Type) then
+		if "callback" == object.type then
 			CyborgMMO_DPrint("trying to set texture")
 			local slot = getglobal("CyborgMMO_MainPageSlotListSlot"..button)
-			slot:SetNormalTexture(object.Texture)
+			slot:SetNormalTexture(object.texture)
 		end
 	else
 		CyborgMMO_DPrint("clearing "..button)
--- a/RatPageView.lua	Thu Apr 25 01:31:26 2013 +0000
+++ b/RatPageView.lua	Thu Apr 25 01:31:31 2013 +0000
@@ -82,7 +82,7 @@
 			local icon = _G[self:GetName().."Icon"]
 			if data[activeMode][self.Id] then
 				self:SetChecked(true)
-				icon:SetTexture(data[activeMode][self.Id].Texture)
+				icon:SetTexture(data[activeMode][self.Id].texture)
 			else
 				icon:SetTexture(nil)
 				self:SetChecked(false)
@@ -107,7 +107,7 @@
 			if data[activeMode][self.Id] then
 				self:SetChecked(true)
 
-				icon:SetTexture(data[activeMode][self.Id].Texture)
+				icon:SetTexture(data[activeMode][self.Id].texture)
 				icon:SetAlpha(.5)
 			else
 				icon:SetTexture(nil)
--- a/WowObjects.lua	Thu Apr 25 01:31:26 2013 +0000
+++ b/WowObjects.lua	Thu Apr 25 01:31:31 2013 +0000
@@ -26,17 +26,23 @@
 local function WowObject(type, detail, subdetail)
 	local self = {}
 
-	self.Texture = nil
-	self.Name = "NoName"
-	self.Type = type
-	self.Detail = detail
-	self.Subdetail = subdetail
+	self.type = type
+	self.detail = detail
+	self.subdetail = subdetail
 
 	setmetatable(self, WowObject_mt)
 
 	return self
 end
 
+function WowObject_methods:SaveData()
+	return {
+		type = self.type,
+		detail = self.detail,
+		subdetail = self.subdetail,
+	}
+end
+
 function WowObject_methods:DoAction()
 	CyborgMMO_DPrint("Nothing To Do")
 end
@@ -48,10 +54,6 @@
 function WowObject_methods:SetBinding(key)
 end
 
-function WowObject_methods:PlaySound()
-	PlaySound("igAbilityIconDrop")
-end
-
 ------------------------------------------------------------------------------
 
 local WowCallback_methods = setmetatable({}, {__index=WowObject_methods})
@@ -60,8 +62,8 @@
 local function WowCallback(callbackName)
 	local self = WowObject("callback", callbackName, "")
 
-	self.CallbackName = callbackName
-	self.Texture = "Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.CallbackName.."Unselected.tga"
+	self.callbackName = callbackName
+	self.texture = "Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.callbackName.."Unselected.tga"
 
 	setmetatable(self, WowCallback_mt)
 
@@ -69,15 +71,13 @@
 end
 
 function WowCallback_methods:SetTextures(buttonFrame)
-	CyborgMMO_DPrint("TextureName = "..self.CallbackName)
-	buttonFrame:SetNormalTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.CallbackName.."Unselected.tga")
-	buttonFrame:SetPushedTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.CallbackName.."Down.tga")
-	buttonFrame:SetHighlightTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.CallbackName.."Over.tga")
+	buttonFrame:SetNormalTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.callbackName.."Unselected.tga")
+	buttonFrame:SetPushedTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.callbackName.."Down.tga")
+	buttonFrame:SetHighlightTexture("Interface\\AddOns\\CyborgMMO7\\Graphics\\"..self.callbackName.."Over.tga")
 end
 
 function WowCallback_methods:DoAction()
-	local action = CyborgMMO_CallbackFactory:GetCallback(self.CallbackName)
-	CyborgMMO_DPrint("calling callback:- "..self.CallbackName)
+	local action = CyborgMMO_CallbackFactory:GetCallback(self.callbackName)
 	action()
 end
 
@@ -94,7 +94,7 @@
 end
 
 function WowCallback_methods:Pickup()
-	self:PlaySound()
+	PlaySound("igAbilityIconDrop")
 	ClearCursor()
 	self:PickupCallback()
 end
@@ -109,39 +109,27 @@
 local WowItem_methods = setmetatable({}, {__index=WowObject_methods})
 local WowItem_mt = {__index=WowItem_methods}
 
-local function WowItem(number, itemID)
-	local self = WowObject("item", number, itemID)
+local function WowItem(itemID)
+	local self = WowObject("item", itemID)
 
-	self.Name,
-	self.Link,
-	self.Rarity,
-	self.Level,
-	self.MinLevel,
-	self.Type,
-	self.SubType,
-	self.StackCount,
-	self.EquipLoc,
-	self.Texture,
-	self.SellPrice = GetItemInfo(itemID)
+	self.itemID = itemID
+	self.texture = select(10, GetItemInfo(itemID)) -- :FIXME: this may fail too early in the session (like when loading saved data)
 
 	setmetatable(self, WowItem_mt)
 
 	return self
 end
 
-function WowItem_methods:DoAction()
-	CyborgMMO_DPrint("Use Item")
-end
-
 function WowItem_methods:Pickup()
-	self:PlaySound()
+--	PlaySound("igAbilityIconDrop")
 	ClearCursor()
---	SetCursor(self.Texture)
-	return PickupItem(self.Link)
+--	SetCursor(self.texture)
+	return PickupItem(self.itemID)
 end
 
 function WowItem_methods:SetBinding(key)
-	SetOverrideBinding(CyborgMMO_CallbackFactory.Frame, true, key, "ITEM "..self.Name)
+	local name = GetItemInfo(self.itemID)
+	SetOverrideBindingItem(CyborgMMO_CallbackFactory.Frame, true, key, name)
 end
 
 ------------------------------------------------------------------------------
@@ -149,13 +137,11 @@
 local WowSpell_methods = setmetatable({}, {__index=WowObject_methods})
 local WowSpell_mt = {__index=WowSpell_methods}
 
-local function WowSpell(spellbookID, spellbook)
-	local self = WowObject("spell", spellbookID, spellbook)
+local function WowSpell(spellID)
+	local self = WowObject("spell", spellID)
 
-	self.SpellbookID = spellbookID
-	self.Spellbook = spellbook
-	self.Name,self.Rank = GetSpellBookItemName(spellbookID, spellbook)
-	self.Texture = GetSpellBookItemTexture(spellbookID, spellbook)
+	self.spellID = spellID
+	self.texture = GetSpellTexture(spellID)
 
 	setmetatable(self, WowSpell_mt)
 
@@ -167,16 +153,18 @@
 end
 
 function WowSpell_methods:Pickup()
-	self:PlaySound()
+--	PlaySound("igAbilityIconDrop")
 	ClearCursor()
---	SetCursor(self.Texture)
-	return PickupSpellBookItem(self.SpellbookID, self.Spellbook)
+--	SetCursor(self.texture)
+--	return PickupSpellBookItem(self.SpellbookID, self.Spellbook)
+	return PickupSpell(self.spellID)
 end
 
 function WowSpell_methods:SetBinding(key)
-	CyborgMMO_DPrint("Binding to key "..key)
-	self.Key = key
-	SetOverrideBinding(CyborgMMO_CallbackFactory.Frame, true, self.Key, self.Type.." "..self.Name)
+--	CyborgMMO_DPrint("Binding to key "..key)
+	local name = GetSpellInfo(self.spellID)
+	CyborgMMO_DPrint("binding spell:", self.spellID, name)
+	SetOverrideBindingSpell(CyborgMMO_CallbackFactory.Frame, true, key, name)
 end
 
 ------------------------------------------------------------------------------
@@ -184,14 +172,11 @@
 local WowMacro_methods = setmetatable({}, {__index=WowObject_methods})
 local WowMacro_mt = {__index=WowMacro_methods}
 
-local function WowMacro(index)
-	local self = WowObject("macro", index, nil)
+local function WowMacro(name)
+	local self = WowObject("macro", name)
 
-	self.Name,
-	self.Texture,
-	self.Body,
-	self.isLocal = GetMacroInfo(index)
-	self.Index = index
+	self.name = name
+	self.texture = select(2, GetMacroInfo(name))
 
 	setmetatable(self, WowMacro_mt)
 
@@ -203,15 +188,14 @@
 end
 
 function WowMacro_methods:Pickup()
-	self:PlaySound()
+--	PlaySound("igAbilityIconDrop")
 	ClearCursor()
---	SetCursor(self.Texture)
-	return PickupMacro(self.Index)
+--	SetCursor(self.texture)
+	return PickupMacro(self.name)
 end
 
 function WowMacro_methods:SetBinding(key)
-	self.Key = key
-	SetOverrideBinding(CyborgMMO_CallbackFactory.Frame, true, key, "MACRO "..self.Index)
+	SetOverrideBindingMacro(CyborgMMO_CallbackFactory.Frame, true, key, self.name)
 end
 
 ------------------------------------------------------------------------------
@@ -219,40 +203,50 @@
 local WowCompanion_methods = setmetatable({}, {__index=WowObject_methods})
 local WowCompanion_mt = {__index=WowCompanion_methods}
 
-local function WowCompanion(index, SubType)
-	local self = WowObject("companion", index, SubType)
+local function WowCompanion(spellID)
+	local self = WowObject("companion", spellID)
+	CyborgMMO_DPrint("creating companion binding:", type, spellID)
 
-	self.Id,
-	self.Name,
-	self.SpellId,
-	self.Texture,
-	self.isSummoned = GetCompanionInfo(SubType, index)
-	self.SubType = SubType
-	self.index = index
+	self.spellID = spellID
+	self.texture = select(3, GetSpellInfo(spellID))
 
 	setmetatable(self, WowCompanion_mt)
 
 	return self
 end
 
+local function IdentifyCompanion(spellID)
+	for _,subtype in ipairs{'MOUNT', 'CRITTER'} do
+		for index=1,GetNumCompanions(subtype) do
+			local spellID2,_,active = select(3, GetCompanionInfo(subtype, index))
+			if spellID2 == spellID then
+				return subtype,index,active
+			end
+		end
+	end
+end
+
 function WowCompanion_methods:DoAction()
-	if self.SubType == "MOUNT" and IsMounted() then
+	local subtype,index,active = IdentifyCompanion(self.spellID)
+--	if subtype == "MOUNT" and IsMounted() then
+	if subtype == "MOUNT" and active then
 		Dismount()
-	else
-		CallCompanion(self.SubType, self.index)
+	elseif subtype and index then
+		CallCompanion(subtype, index)
 	end
 end
 
 function WowCompanion_methods:Pickup()
-	self:PlaySound()
-	return PickupCompanion(self.SubType, self.index)
+--	PlaySound("igAbilityIconDrop")
+	local subtype,index = IdentifyCompanion(self.spellID)
+	if subtype and index then
+		return PickupCompanion(subtype, index)
+	end
 end
 
 function WowCompanion_methods:SetBinding(key)
-	self.Key = key
 	local buttonFrame,parentFrame,name = CyborgMMO_CallbackFactory:AddCallback(function() self:DoAction() end)
 	SetOverrideBindingClick(parentFrame, true, key, name, "LeftButton")
---	SetOverrideBinding(hiddenModeChanger, true, key, "MACRO "..self.Index)
 end
 
 ------------------------------------------------------------------------------
@@ -260,13 +254,12 @@
 local WowEquipmentSet_methods = setmetatable({}, {__index=WowObject_methods})
 local WowEquipmentSet_mt = {__index=WowEquipmentSet_methods}
 
-local function WowEquipmentSet(objectType, name, index)
-	local self = WowObject(objectType, name, index)
+local function WowEquipmentSet(name)
+	local self = WowObject("equipmentset", name)
 
-	local texture,lessIndex = GetEquipmentSetInfoByName(name)
-	self.Texture = "Interface\\Icons\\"..texture
-	self.Name = name
-	self.Index = lessIndex + 1
+	self.name = name
+	local texture = GetEquipmentSetInfoByName(name)
+	self.texture = "Interface\\Icons\\"..texture
 
 	setmetatable(self, WowEquipmentSet_mt)
 
@@ -274,19 +267,62 @@
 end
 
 function WowEquipmentSet_methods:DoAction()
-	UseEquipmentSet(self.Name)
+	UseEquipmentSet(self.name)
 end
 
 function WowEquipmentSet_methods:Pickup()
-	self:PlaySound()
+--	PlaySound("igAbilityIconDrop")
 	ClearCursor()
---	SetCursor(self.Texture)
+--	SetCursor(self.texture)
 	return PickupEquipmentSetByName(self.Name)
 end
 
 function WowEquipmentSet_methods:SetBinding(key)
-	self.Key = key
-	local buttonFrame,parentFrame,name = CyborgMMO_CallbackFactory:AddCallback(function() self:DoAction() end);
+	local buttonFrame,parentFrame,name = CyborgMMO_CallbackFactory:AddCallback(function() self:DoAction() end)
+	SetOverrideBindingClick(parentFrame, true, key, name, "LeftButton")
+end
+
+------------------------------------------------------------------------------
+
+local WowBattlePet_methods = setmetatable({}, {__index=WowObject_methods})
+local WowBattlePet_mt = {__index=WowBattlePet_methods}
+
+local function WowBattlePet(petID)
+	local self = WowObject("battlepet", petID)
+	CyborgMMO_DPrint("creating battle pet binding:", petID)
+
+	self.petID = petID
+	self.texture = select(9, C_PetJournal.GetPetInfoByPetID(petID)) -- :FIXME: this may fail too early in the session (like when loading saved data)
+
+	setmetatable(self, WowBattlePet_mt)
+
+	return self
+end
+
+--[[
+local function IdentifyPet(petID)
+	local creatureID = select(11, C_PetJournal.GetPetInfoByPetID(petID))
+	for index=1,GetNumCompanions('CRITTER') do
+		local creatureID2,_,spellID = GetCompanionInfo('CRITTER', index)
+		if creatureID2 == creatureID then
+			return spellID
+		end
+	end
+end
+--]]
+
+function WowBattlePet_methods:DoAction()
+--	PlaySound("igMainMenuOptionCheckBoxOn")
+	C_PetJournal.SummonPetByGUID(self.petID)
+end
+
+function WowBattlePet_methods:Pickup()
+--	PlaySound("igAbilityIconDrop")
+	return C_PetJournal.PickupPet(self.petID)
+end
+
+function WowBattlePet_methods:SetBinding(key)
+	local buttonFrame,parentFrame,name = CyborgMMO_CallbackFactory:AddCallback(function() self:DoAction() end)
 	SetOverrideBindingClick(parentFrame, true, key, name, "LeftButton")
 end
 
@@ -340,7 +376,13 @@
 	local object
 
 	if type == "item" then
-		object = WowItem(...)
+		-- :KLUDGE: if the item is not in the cache, return an empty WowObject
+		local id = ...
+		if not GetItemInfo(id) then
+			object = WowObject()
+		else
+			object = WowItem(...)
+		end
 	elseif type == "macro" then
 		object = WowMacro(...)
 	elseif type == "spell" then
@@ -348,7 +390,9 @@
 	elseif type == "companion" then
 		object = WowCompanion(...)
 	elseif type == "equipmentset" then
-		object = WowEquipmentSet(type, ...)
+		object = WowEquipmentSet(...)
+	elseif type == "battlepet" then
+		object = WowBattlePet(...)
 	elseif type == "callback" then
 		object = WowCallback(...)
 	else