View Single Post
  #6  
Unread 09-18-2012, 02:42 PM
Galuhad's Avatar
Galuhad Galuhad is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: Dec 2010
Location: Norwich, UK
Posts: 24
Try this:

Code:

-- Set SocialGuy Window Positions
--local Settings = Turbine.PluginData.Load(Turbine.DataScope.Character, "SocialGuySettings");
local WindX,WindY=Turbine.UI.Display:GetWidth()/2-100,Turbine.UI.Display:GetHeight()/2-100;
--~ if Settings~=nil then
--~   if Settings["WindPosX"]~=nil then WindX=Settings["WindPosX"] end
--~   if Settings["WindPosY"]~=nil then WindY=Settings["WindPosY"] end
--~ end

-- Create Window
wSocialGuy = Turbine.UI.Lotro.Window();
wSocialGuy:SetSize(500,300);
wSocialGuy:SetPosition(WindX,WindY);
wSocialGuy:SetText("SocialGuy by Radicus");
wSocialGuy:SetVisible(true);
-- if Settings["WindState"] == true then wSocialGuy:SetVisible(true) end

-- Create Heading Label
xpos = 25;
ypos = 35;
yinc = 25;
label = "Emotes";
labelEmotes = Turbine.UI.Label();
labelEmotes:SetParent(wSocialGuy);
labelEmotes:SetText(label);
labelEmotes:SetPosition(wSocialGuy:GetWidth()/4,ypos)
labelEmotes:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
labelEmotes:SetForeColor(Turbine.UI.Color(1,1,0));
labelEmotes:SetSize(wSocialGuy:GetWidth()/2,20);
labelEmotes:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleCenter);

-- Create Checkboxes
-- Changed this to a table, if you wish to add more emotes in the future then you actually don't need to write any extra code
-- except to add the emotes to the _EMOTES table below - as the checkboxes are created based on these entries.
_EMOTES = {"/hug", "/hail", "/confused","/kiss"};
checkbox = {};

for k,v in pairs (_EMOTES) do

	ypos=ypos+yinc;


	checkbox[k] = Turbine.UI.Lotro.CheckBox();
	checkbox[k]:SetPosition(xpos,ypos);
	checkbox[k]:SetCheckAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
	checkbox[k]:SetTextAlignment(Turbine.UI.ContentAlignment.MiddleLeft);
	checkbox[k]:SetFont(Turbine.UI.Lotro.Font.TrajanPro14);
	checkbox[k]:SetForeColor(Turbine.UI.Color(1,1,0));
	checkbox[k]:SetText(" " .. v);
	checkbox[k]:SetParent(wSocialGuy);
	checkbox[k]:SetSize(180,20);
	checkbox[k]:SetChecked(true);

end


-- Create Send Emote Button
ypos=ypos+yinc;
wSocialGuy.GoButton=Turbine.UI.Label();
wSocialGuy.GoButton:SetParent(wSocialGuy);
wSocialGuy.GoButton:SetSize(50,15);
wSocialGuy.GoButton:SetPosition(wSocialGuy:GetWidth()/4,ypos)
wSocialGuy.GoButton:SetText("Be Sociable");
wSocialGuy.GoButton:SetBackColor(Turbine.UI.Color(.3,.3,.3)); -- needed to prevent the quickslot icon boundary from displaying
wSocialGuy.GoButton:SetMouseVisible(false);

currentEmote=_EMOTES[1]; -- sets the starting emote

wSocialGuy.EmoteQSBack=Turbine.UI.Control(); -- used to prevent the quickslot from drawing outside the mask bounds
wSocialGuy.EmoteQSBack:SetParent(wSocialGuy);
wSocialGuy.EmoteQSBack:SetSize(wSocialGuy.GoButton:GetWidth(),wSocialGuy.GoButton:GetHeight())
wSocialGuy.EmoteQSBack:SetPosition(wSocialGuy.GoButton:GetLeft(),wSocialGuy.GoButton:GetTop())
wSocialGuy.EmoteQSBack:SetZOrder(-1);

wSocialGuy.EmoteQS = Turbine.UI.Lotro.Quickslot();
wSocialGuy.EmoteQS:SetParent(wSocialGuy.EmoteQSBack);
 -- note, if there is any chance that the alias could contain a special (non-ASCII) character then you should use the SetData method to assign it to avoid a bug in the Shortcut constructor
wSocialGuy.EmoteQS:SetSize(wSocialGuy.GoButton:GetWidth()+34,wSocialGuy.GoButton:GetHeight()+34)
wSocialGuy.EmoteQS:SetPosition(-34,-34);
wSocialGuy.EmoteQS:SetAllowDrop(false);

wSocialGuy.EmoteQS.DragDrop=function(sender)
	local sc=Turbine.UI.Lotro.Shortcut(Turbine.UI.Lotro.ShortcutType.Alias,"");
	sc:SetData(currentEmote);
	sender:SetShortcut(sc);
	Turbine.Shell.WriteLine(sc);
end

function SetEmote(e)
	wSocialGuy.EmoteQS:SetShortcut(Turbine.UI.Lotro.Shortcut(Turbine.UI.Lotro.ShortcutType.Alias, e));
	wSocialGuy.EmoteQS.AliasText=e;
end


-- Emote doesn't send until after the mouse events have completed, meaning if you change the alias mid-event it won't work.
-- Instead we can get around this by using the Update() function of the control.

wSocialGuy.EmoteQS.MouseClick=function(sender,args)

	wSocialGuy.EmoteQS:SetWantsUpdates(true);

end

wSocialGuy.EmoteQS.Update=function(sender,args)

	sender:SetWantsUpdates(false); -- Reset to false otherwise it will loop forever.
	SetEmote(currentEmote);
	currentEmote = FindNextChecked(currentEmote);

end


-- This function will loop through the emotes and checklist tables to get the next emote command
-- which can then be set using SetEmote()
function FindNextChecked(CURRENTEMOTE)

	if CURRENTEMOTE == nil then return _EMOTES[1] end;

	local NEXTEMOTE = CURRENTEMOTE; -- default incase of some error (perhaps the user unticked all boxes).

	-- Check to see if the checkboxes are all unchecked (in which case we can't get the next emote);
	if AllUnchecked() == true then

		Turbine.Shell.WriteLine("You must select at least one emote");

	else

		local CURRENTEMOTEID = 1;
		local MAXEMOTES = 0;

		-- This gets the ID for the current emote in the table
		for k,v in pairs (_EMOTES) do

			if v == CURRENTEMOTE then CURRENTEMOTEID = k + 1 end;
			MAXEMOTES = MAXEMOTES + 1;

		end

		-- If the emote is the last in the list then go back to the beginning to start checking from there.
		if CURRENTEMOTEID > MAXEMOTES then CURRENTEMOTEID = 1 end;

		-- Loop through the checkbox table to find the next checked box.
		local loopThreshhold = 50; -- This is more a safety net incase some error in the code causes an infinity loop.
		local curLoop = 1;
		local blFOUNDCHECKBOX = false;

		while blFOUNDCHECKBOX == false and curLoop < loopThreshhold do

			if checkbox[CURRENTEMOTEID]:IsChecked() == true then

				NEXTEMOTE = _EMOTES[CURRENTEMOTEID];
				blFOUNDCHECKBOX = true;
				break;

			else

				if CURRENTEMOTEID >= MAXEMOTES then -- Either add 1 to CURRENTEMOTEID or reset to 1.
					CURRENTEMOTEID = 1;
				else
					CURRENTEMOTEID = CURRENTEMOTEID + 1;
				end

			end

			curLoop = curLoop + 1; -- Safety net counter.

		end

	end

	return NEXTEMOTE;

end



function AllUnchecked()

	-- This checks each checkbox to see if they are all unchecked, if it finds one that is checked then it returns false.
	-- If it doesn't find any checked, then it returns the default value of true.

	local blALLUNCHECKED = true;

	for k,v in pairs (checkbox) do

		if checkbox[k]:IsChecked() == true then
			blALLUNCHECKED = false;
			break;
		end

	end

	return blALLUNCHECKED;

end
If you unchecked a box which was set to nextemote, the plugin would never have found it. A better option is to construct the checkboxes as a table which means you can easily loop through them to see which are checked and which aren't.

In the code above this is how I've done it. I also put your emotes into a table which will make it easier for you if you want to expand the plugin in future with more emotes as you will not need to change any of the code except the table entries.

Also another bug I found was that the emotes wouldn't fire because the alias is changed mid-event during the mouseclick. If you unticked all but one emote it would then work as the alias would not be changing. To get around this I put the setEmote call in the quickslot control's Update() function and used the mouseclick event to SetWantsUpdates() to true.

I've tested this ingame and found it to work efficiently.
__________________
Galuhad, Guardians of the Light, Evernight (formally of Eldar RIP)
---
Reply With Quote