View Single Post
  #23  
Unread 12-15-2011, 01:18 PM
Stever1388 Stever1388 is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: Nov 2010
Posts: 33
I think the biggest problem stems from the fact that you can't use Quickslot:SetShortcut() to set an invalid shortcut, whether the shortcut was once valid or not. I'm not really sure how much interest there is in this, since it could be overcome in tons of other ways, depending on author preference and all that, but here is an extension of the Quickslot class stores the Shortcut when you use Quickslot:SetShortcut() separately from the actual Turbine.UI.Lotro.Quickslot:SetShortcut() method, meaning it will save the Shortcut even if the Shortcut is invalid, and will then continue to return that Shortcut when you call GetShortcut(). This should work for everyone without changing any code other than changing quickslot = Turbine.UI.Lotro.Quickslot() code to quickslot = Quickslot() (or where ever they place Quickslot.lua)

This doesn't actually fix the problem, it's up the programmer to then set Backpack ItemAdded event handlers to watch for items being added to the inventory so that the Quickslots can be updated.

This also surrounds the other SetShortcut() method with pcall() to prevent those errors, but returns true/false if the SetShortcut() worked/didn't work so you can still act accordingly.

Code:
-- This class attempts to fix the problem with the Quickslot class that 
-- 	prevents it from storing invalid Shortcuts, even if the Shortcut was once valid.
--	For example, if you have a Health Potion in a Quickslot, and you run out of that potion,
-- 	the next time you load the plugin that Quickslot will be cleared (you can't set a Shortcut if
--	you don't have the item in your bag). At that point GetShortcut() will return an empty Shortcut.
-- 	Using this class, GetShortcut() would still return the Health Potion shortcut.

-- Please note that if you use this class you MUST use the AddCallback function by Pengoros
-- 	for ShortcutChanged, since this class uses that EventHandler to make sure 
-- 	the Shortcut returned by GetShortcut() is the correct one.

-- One other thing, it is up to the programmer to decide how they want to handle invalid shortcuts outside
--	of this class. This class will not update a Quickslot/Shortcut every time the Backpack:ItemAdded event
-- 	is fired, so Quickslots/Shortcuts will not be fixed even if you get the item back into your inventory.
-- 	You will have to reload the plugin to get it to appear again.

import "Turbine.UI.Lotro";

-- Extend normal Turbine Quickslot class
Quickslot = class ( Turbine.UI.Lotro.Quickslot );

-- Constructor
function Quickslot:Constructor()
	Turbine.UI.Lotro.Quickslot.Constructor( self );

	-- self.shortcut stores the Shortcut even if 
	-- 	Turbine.UI.Lotro.Quickslot:SetShortcut(shortcut)
	-- 	would throw an error
	self.shortcut = Turbine.UI.Lotro.Quickslot.GetShortcut( self );

	-- Create an EventHandler that watches for when the Shortcut has changed;
	-- when it has, set self.shortcut to the new Shortcut
	shortcutChangedHandler = function(sender, args)
		self.shortcut = Turbine.UI.Lotro.Quickslot.GetShortcut( self );
	end

	AddCallback( self, "ShortcutChanged", shortcutChangedHandler );
end

-- Sets the Shortcut of the Quickslot by setting self.shortcut to the new Shortcut.

-- To simplify things, this method uses pcall() to set the Shortcut, which
-- 	means you won't get errors when setting Shortcuts.

-- In order to know whether the Shortcut was successfully set though, this method 
-- 	returns true if the Shortcut was set, and false if an error would have been thrown.

-- If you DO NOT want your Shortcuts set to invalid Shortcuts (even though they will never reappear
-- 	on the Quickslot unless the user gets the item back into their inventory and then reloads the plugin), set Shortcuts
--	like this: if(Quickslot.SetShortcut(Shortcut) == false) then Quickslot.SetShortcut(Turbine.UI.Lotro.Shortcut()) end
function Quickslot:SetShortcut(value)
	self.shortcut = value;
	return pcall(function() Turbine.UI.Lotro.Quickslot.SetShortcut( self , value) end);
end

-- This function only returns self.shortcut; However, the only time this will be different than
-- using the old GetShortcut() will be when you use SetShortcut() and SetShortcut() returns false.
function Quickslot:GetShortcut()
	return self.shortcut;
end

-- The amazing Callback function by Pengoros
function AddCallback(object, event, callback)
    if (object[event] == nil) then
        object[event] = callback;
    else
        if (type(object[event]) == "table") then
            table.insert(object[event], callback);
        else
            object[event] = {object[event], callback};
        end
    end
    return callback;
end
If anyone sees anything inherently wrong with this code, let me know, because I'm using it to do some fixes of plugins I use and need to work correctly with the LOTRO Plugin Manager (as I am really lazy and hate having to load plugins each time I log in, even though I use a shortcut key and Bootstray so it takes all of 2 keystrokes to do so). I haven't had any problems with it the last day I've used it, but I can't say I've done a whole bunch of testing.

If there's interest I (or someone else, doesn't really matter) can post this as a file so people can download it and use it. But as I said, not sure there will be much interest, since I'm not the best LUA programmer and there's probably better ways to do this depending on how your plugins are already coded.
Reply With Quote