lotrointerface.com
Search Downloads


Go Back   LoTROInterface > LotRO > Developer Discussions > Lua Programming Help (L)

Reply
Thread Tools Display Modes
  #1  
Unread 06-13-2016, 07:22 PM
Hamkaas Hamkaas is offline
The Wary
 
Join Date: Jun 2016
Posts: 3
Question Lua Beginner has some questions

Hello,
I just started messing around with creating lua lotro plugins and i have quite a lot of questions. Please feel free to answer just a couple instead of all if you don't know all answers or you don't feel like it.

I've just started and i don't have a lot of experience with programming and have a lot of questions. I'll start with the questions most important to me.

1. Is there a way to disable the tooltip that pops up when you hover over a alias shortcut. the "alias: bla bla bla" popup?

2. When i make a quickslot and bind an alias shortcut to it, can i somehow make it do something extra when you click it? like do the alias shortcut and perform commands. If i try to catch the mouseclick event it does not seem to be willing to do both. At the moment i'm using a workaround by catching the message it sends in the chat and then run the commands from that but it is too slow for what i want to use it for and also not very elegant.

3. When i create a quickslot and drag an item to it ingame and then try to unload the plugin my client crashes 100% of the time. Is this because i do not handle the unloading properly? i've read the "writing plugins for noobs" post from garan on lotro forums (https://www.lotro.com/forums/showthr...gins-for-Noobs) but i didn't really understand the part about unloading right. How should i write the unload section for my plugin?

4. What is the max size image i can load? I was trying to make an animation by making 2 Turbine.UI.Control() things, then making control 1 parent of control 2 and setting a size for control 1 and then setting a image with the whole animation (like 10 frames) as background for control 2 and then moving control 2's relative position to control 1 so it gets cropped.
When trying this it worked for really small images but it didn't when my images were larger then around 50x50 pixels. Would you advice me to not use animations or load 10 different pictures?

5. Then finally i have a couple of questions about what i saw in this thread:
http://www.lotrointerface.com/forums...ead.php?t=1866
Here in the 2nd post Garan gives tips on hiding quickslots.

Garan says you should make your quickslot 34 pixels higher and wider and then crop it by making another control with a smaller size the parent to hide the alias text. But in the example code Garan also makes a black window in front of the quickslot to hide the icon boundry when you hover.
But why make the extra control and crop the quickslot? the black window hides the text as well right?
Or let me ask it like this: What extra functionality do you get making your quickslot part of a different control like this?

Also Garan says you should write code to prevent people from dragging your shortcut out of the quickslot, but somehow for me this behavior is default? i cannot drag the shortcut out of there even if i wanted to.

Did an update change these things or do i miss the point of these things altogether?

Thanks in advance.
Reply With Quote
  #2  
Unread 06-13-2016, 08:23 PM
Garan's Avatar
Garan Garan is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: Oct 2010
Posts: 340
Hello,

I'll try answering your questions in order:
Quote:
Originally Posted by Hamkaas
Hello,
I just started messing around with creating lua lotro plugins and i have quite a lot of questions. Please feel free to answer just a couple instead of all if you don't know all answers or you don't feel like it.

I've just started and i don't have a lot of experience with programming and have a lot of questions. I'll start with the questions most important to me.

1. Is there a way to disable the tooltip that pops up when you hover over a alias shortcut. the "alias: bla bla bla" popup?
There's a few UI options for changing how tooltips function but nothing via Lua.
Quote:
2. When i make a quickslot and bind an alias shortcut to it, can i somehow make it do something extra when you click it? like do the alias shortcut and perform commands. If i try to catch the mouseclick event it does not seem to be willing to do both. At the moment i'm using a workaround by catching the message it sends in the chat and then run the commands from that but it is too slow for what i want to use it for and also not very elegant.
Unfortunately you've already found the best solution for that one which is the chat listener. FWIW, very few of the solutions to the Turbine limitations on Lua are elegant
Quote:
3. When i create a quickslot and drag an item to it ingame and then try to unload the plugin my client crashes 100% of the time. Is this because i do not handle the unloading properly? i've read the "writing plugins for noobs" post from garan on lotro forums (https://www.lotro.com/forums/showthr...gins-for-Noobs) but i didn't really understand the part about unloading right. How should i write the unload section for my plugin?
I suspect the crashes are due to the way you are creating your quickslots. I'd have to see your code to be sure. The unload event handler is more for cleaning up event handlers and command objects (the client used to crash if you created a command and exited without removing it but I believe that bug was fixed many years ago).
Quote:
4. What is the max size image i can load? I was trying to make an animation by making 2 Turbine.UI.Control() things, then making control 1 parent of control 2 and setting a size for control 1 and then setting a image with the whole animation (like 10 frames) as background for control 2 and then moving control 2's relative position to control 1 so it gets cropped.
When trying this it worked for really small images but it didn't when my images were larger then around 50x50 pixels. Would you advice me to not use animations or load 10 different pictures?
I don't actually know what the max size for an image would be but it's several meg. However, Turbine's implementation of Lua probably does not handle animated images very well. I would recommend using separate images and controlling their loading via an Update event and a timer, that way you can also retain some control of the speed of the animation.
Quote:
5. Then finally i have a couple of questions about what i saw in this thread:
http://www.lotrointerface.com/forums...ead.php?t=1866
Here in the 2nd post Garan gives tips on hiding quickslots.

Garan says you should make your quickslot 34 pixels higher and wider and then crop it by making another control with a smaller size the parent to hide the alias text. But in the example code Garan also makes a black window in front of the quickslot to hide the icon boundry when you hover.
But why make the extra control and crop the quickslot? the black window hides the text as well right?
Or let me ask it like this: What extra functionality do you get making your quickslot part of a different control like this?

Also Garan says you should write code to prevent people from dragging your shortcut out of the quickslot, but somehow for me this behavior is default? i cannot drag the shortcut out of there even if i wanted to.

Did an update change these things or do i miss the point of these things altogether?

Thanks in advance.
You don't gain any advantage other than masking by putting the quickslot inside another control. The point of the excess size is so that the quickslot will still be clickable but will be positioned far enough behind the border of its parent so as to be properly clipped. If you have more than one quickslot then the window would not be sufficient - with only one, yes, you could just use the window as the parent.

As to dragging the shortcut out of the quickslot, I believe it is still possible to accidentally drag a shortcut out of a quickslot if it is not prevented by the author. Are you possibly playing with a Mac or Linux install? That may make a difference to the shortcut drag behavior.
Reply With Quote
  #3  
Unread 06-14-2016, 06:50 AM
Hamkaas Hamkaas is offline
The Wary
 
Join Date: Jun 2016
Posts: 3
Thank you so much for the quick response and answers to my questions!

For the answers:
1.
Quote:
There's a few UI options for changing how tooltips function but nothing via Lua.
That is too bad as i think most people have tooltips turned on and it doesn't look nice if the tooltip pops up in front of a fancy button.

2.
Quote:
Unfortunately you've already found the best solution for that one which is the chat listener. FWIW, very few of the solutions to the Turbine limitations on Lua are elegant
Thats too bad as well

3.
Quote:
I suspect the crashes are due to the way you are creating your quickslots. I'd have to see your code to be sure. The unload event handler is more for cleaning up event handlers and command objects (the client used to crash if you created a command and exited without removing it but I believe that bug was fixed many years ago).
I've done some experimentation with it and this is my code:
Code:
DisplaySize = {Turbine.UI.Display:GetWidth(),Turbine.UI.Display:GetHeight()};
WindowSize = {200,100};


LotroWindow = Turbine.UI.Lotro.Window();
LotroWindow:SetSize(WindowSize[1]+12,WindowSize[2]+80);
LotroWindow:SetPosition((DisplaySize[1]*4/3-WindowSize[1])/2,(DisplaySize[2]*2/3-WindowSize[2])/2);
LotroWindow:SetText("Reversi");

MainWindow = Turbine.UI.Window();
MainWindow:SetParent(LotroWindow);
MainWindow:SetPosition(6,46);
MainWindow:SetSize(WindowSize[1],WindowSize[2]);
MainWindow:SetBackColor(Turbine.UI.Color(.1,.1,.1));
MainWindow:SetVisible(true);

MainWindow.Button = {};
MainWindow.Button[1] = Turbine.UI.Lotro.Quickslot();
MainWindow.Button[1]:SetParent(MainWindow);
MainWindow.Button[1]:SetSize(35,35);
Shortcut = Turbine.UI.Lotro.Shortcut( Turbine.UI.Lotro.ShortcutType.Alias, "/w Hamkaas hoifcdfgdsfgdsfgsdfgsdfgsdfgsdfgsdfgdfsgsdfgsdfgsdfgsdfgsdfgsdf");
MainWindow.Button[1]:SetShortcut(Shortcut);
MainWindow.Button[1]:SetZOrder(-1);
MainWindow.Button[1]:SetPosition(WindowSize[1]/2-17,WindowSize[2]/2-17);
-- MainWindow.Button[1]:SetAllowDrop(false);

MainWindow.ButtonHider = {};
MainWindow.ButtonHider[1] = Turbine.UI.Window();
MainWindow.ButtonHider[1]:SetParent(MainWindow.Button[1]);
MainWindow.ButtonHider[1]:SetBackColor(Turbine.UI.Color(0,0,0));
MainWindow.ButtonHider[1]:SetSize(MainWindow.Button[1]:GetWidth(),MainWindow.Button[1]:GetHeight());
MainWindow.ButtonHider[1]:SetVisible(true);
MainWindow.ButtonHider[1]:SetMouseVisible(false);
MainWindow.ButtonHider[1]:SetZOrder(1);
The client only crashes it seems if i enable the final "MainWindow.ButtonHider" part and then drag an item into the slot and unload the plugin. Am i somehow dragging the item onto the window instead or something?
It's not much of a problem as i would uncomment "MainWindow.Button[1]:SetAllowDrop(false);" if i would use it as a button, and i wouldn't try to hide it if i used it as a quickslot i want to drag stuff to.


4.
Quote:
I don't actually know what the max size for an image would be but it's several meg. However, Turbine's implementation of Lua probably does not handle animated images very well. I would recommend using separate images and controlling their loading via an Update event and a timer, that way you can also retain some control of the speed of the animation.
Sorry i did not make myself quite clear with this i noticed. I found my problem though. I did not set the size of the to be cropped control and it defaulted to ~50x50 pixels. For if you are curious:

Code:
MainWindow.AniCrop = Turbine.UI.Control();
MainWindow.AniCrop:SetParent(MainWindow);
MainWindow.AniCrop:SetSize(110,100);
MainWindow.AniCrop:SetPosition(WindowSize[1]/2-55,WindowSize[2]/2-50);

MainWindow.Ani = Turbine.UI.Control();
MainWindow.Ani:SetParent(MainWindow.AniCrop);
MainWindow.Ani:SetSize(1100,100);
MainWindow.Ani:SetBackground("Hamkaas/Test/Coinflip.tga");

Frames = 10;
FPS = 10;

framecount = 0
Timer = Turbine.Engine.GetGameTime();

MainWindow:SetWantsUpdates(true);
Winup = function(sender,args)
	if Turbine.Engine.GetGameTime() >= Timer then
		MainWindow.Ani:SetPosition(framecount*-110,0);
		
		if framecount < Frames-1 then 
			framecount = framecount+1;
		else
			framecount = 0;
		end
		
		Timer = Turbine.Engine.GetGameTime() + 1/FPS;
	end
end
AddCallback(MainWindow, "Update", Winup);
Here "Hamkaas/Test/Coinflip.tga" is an image with 10 times a 110x100 frame of an animation next to eachother. What went wrong is that i forgot the "MainWindow.Ani:SetSize(1100,100);" command before. Now it works perfectly

But what i meant with my question before regarding unloading was how do i unload this properly? i think i need 2 things here: "RemoveCallback(MainWindow, "Update", Winup);" and "MainWindow:SetWantsUpdates(false);". But where do i put them?
Maybe like this?

Code:
unload = function(sender,args)
	RemoveCallback(MainWindow, "Update", Winup);
	MainWindow:SetWantsUpdates(false);
end
AddCallback(Plugin, "Unload", unload);
But here i did not know what to put in the first argument of the "AddCallBack" command so i just put "Plugin" in there. Also in which file should i put it? in Main.lua? or should i make one for every file? and do i need to run the RemoveCallBack command for the unload event i just created as well? so add "RemoveCallback(Plugin, "Unload", unload);" in the function above?
I'm very confused sorry


5.
Quote:
You don't gain any advantage other than masking by putting the quickslot inside another control. The point of the excess size is so that the quickslot will still be clickable but will be positioned far enough behind the border of its parent so as to be properly clipped. If you have more than one quickslot then the window would not be sufficient - with only one, yes, you could just use the window as the parent.
Cool thanks.

Quote:
As to dragging the shortcut out of the quickslot, I believe it is still possible to accidentally drag a shortcut out of a quickslot if it is not prevented by the author. Are you possibly playing with a Mac or Linux install? That may make a difference to the shortcut drag behavior.
I'm playing on windows 10. When i drag the shortcut out of the quickslot it does visually show the shortcut while i drag it but it does not remove it when i drop it somewhere else. Also it does not copy/move it to another Quickslot when i release it on one.


Thanks again for helping me understand LUA and Turbines API a lot better!
Reply With Quote
  #4  
Unread 06-14-2016, 07:59 AM
Garan's Avatar
Garan Garan is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: Oct 2010
Posts: 340
Hi,

The first thing I noticed in your code is that you are using SetParent on Window controls. Windows are top level objects and should never be used as child controls for two reasons. First, you should always use the object class that provides the needed functionality with the minimum of overhead - since all you are looking for is a container, a simple Control object is the best choice, Windows have a ton of additional functionality and thus overhead and will cause your plugin to run less efficiently. Second, some classes may include function definitions that were never meant to actually be implemented and implementing those functions can sometimes cause unreliable functionality - the SetParent function of the Window class is such a function (since Windows are top level and inherently parentless).

Additionally, I noticed that your ButtonHider is a child of the Quickslot - this is backwards, the quickslot should be a child of the container that is used to clip it. I don't know if assigning a child control to a quickslot could cause a crash as I've never tried it (but I probably will now, just out of curiosity). Your crash is probably a combination of assigning a child to a control that was never intended as a container AND that child being a window object.

The Unload handler does not have to be treated like an event handler in that it is not a shared function (no need for AddCallback). Theoretically you could use AddCallback if you wanted a table of Unload handlers (I can think of at least one use for this) but it is not necessary. There are two ways to assign the Unload handler due to a quirk in the way Lua works. When plugins were first implemented, there was no way for a plugin to reference itself while its code was being parsed and loaded so authors took to using an Update event to assign the Unload handler using the Plugins collection in the first Update event after the plugin started actually running. Turbine has since created the "plugin" object (notice the all lowercase name) which is a temporary reference to the instance of the plugin that is only valid while the plugin is loading so you can now assign your Unload handler by referencing your plugin as "plugin". Ex:
Code:
plugin.Unload=function()
--dosomething
end
Typically the Unload event would be defined in your main lua file. You do not need to call RemoveCallback for the Unload event.
Most of my plugins use the Plugins collection and Update handler method just because most of my plugins were created prior to Turbine developing the "plugin" reference (and I'm just too lazy to go back and change all of them).

Another minor point, I noticed you created and use your shortcut as:
Code:
Shortcut = Turbine.UI.Lotro.Shortcut( Turbine.UI.Lotro.ShortcutType.Alias, "/w Hamkaas hoifcdfgdsfgdsfgsdfgsdfgsdfgsdfgsdfgdfsgsdfgsdfgsdfgsdfgsdfgsdf");
MainWindow.Button[1]:SetShortcut(Shortcut);
Unless you intend to reference Shortcut later (such as reassigning it) it is better to use a local variable or create it in-line without a variable otherwise the environment will keep a copy of "Shortcut" the whole time your plugin is loaded.
Code:
MainWindow.Button[1]:SetShortcut(Turbine.UI.Lotro.Shortcut( Turbine.UI.Lotro.ShortcutType.Alias, "/w Hamkaas hoifcdfgdsfgdsfgsdfgsdfgsdfgsdfgsdfgdfsgsdfgsdfgsdfgsdfgsdfgsdf"));
lets the garbage collection clean up the temporary object and is more efficient - plugins can get bloated and contribute to excessive memory usage and lag pretty quickly so writing efficient code can be important.

Last edited by Garan : 06-14-2016 at 01:07 PM. Reason: typo
Reply With Quote
  #5  
Unread 06-14-2016, 07:35 PM
Thurallor's Avatar
Thurallor Thurallor is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: May 2013
Posts: 202
Quote:
Originally Posted by Hamkaas
2. When i make a quickslot and bind an alias shortcut to it, can i somehow make it do something extra when you click it? like do the alias shortcut and perform commands. If i try to catch the mouseclick event it does not seem to be willing to do both. At the moment i'm using a workaround by catching the message it sends in the chat and then run the commands from that but it is too slow for what i want to use it for and also not very elegant.
If I understand the question correctly, there is nothing preventing you from doing this, and I depend on this functionality in some of my plugins.

But I just do it the obvious way, which makes me think I am misunderstanding the question. Example:
Code:
import "Turbine.UI.Lotro";

win = Turbine.UI.Window();
win:SetVisible(true);

shortcut = Turbine.UI.Lotro.Shortcut(Turbine.UI.Lotro.ShortcutType.Alias, "/laugh");
quickslot = Turbine.UI.Lotro.Quickslot();
quickslot:SetShortcut(shortcut);
quickslot:SetParent(win);
quickslot:SetUseOnRightClick(false); -- don't execute the shortcut when the user right-clicks

quickslot.MouseClick = function(sender, args)
    if (args.Button == Turbine.UI.MouseButton.Left) then
        Turbine.Shell.WriteLine("left-click");
    elseif (args.Button == Turbine.UI.MouseButton.Right) then
        Turbine.Shell.WriteLine("right-click");
    end
end
Reply With Quote
  #6  
Unread 06-15-2016, 09:14 AM
Hamkaas Hamkaas is offline
The Wary
 
Join Date: Jun 2016
Posts: 3
Quote:
The first thing I noticed in your code is that you are using SetParent on Window controls.
I see that makes a lot more sense now, i've updated all my code to make sure Window controls stay top level.



Quote:
The Unload handler does not have to be treated like an event handler in that it is not a shared function (no need for AddCallback).
Quote:
so you can now assign your Unload handler by referencing your plugin as "plugin".
Thanks this makes a lot more sense to me now and i'm using your example to execute the RemoveCallback functions.

Quote:
it is better to use a local variable or create it in-line without a variable
Good advice and i'm certainly gonna follow it and think about that more now. I wasn't aware it would take more memory like this and for me it seemed a bit more neat for me this way.

P.S. did you edit this in since when i had less time when i first read your post i did not read this

But now i'm trying to use more Local variables and such i was wondering what is the proper way of using them within a function or something?
for example:
Code:
function DirFlip(DirX,DirY,number,player)
	local x = GetCol(number)+DirX;
	local y = GetRow(number)+DirY;	
	while State[GetNum(x,y)] ~= player do
		Flip(GetNum(x,y));
		x = x + DirX;
		y = y + DirY;
	end
end
In this code i define local variables x and y, but when i update x and y in the while loop does it update the local variables or does it create global x and y variables? I did not put "local" in front of the x and y variables inside the while loop since i would think it would create new local variables only accesable within the while loop.

Quote:
Originally Posted by Thurallor
But I just do it the obvious way, which makes me think I am misunderstanding the question.
Holy shit, no you didn't misunderstand the question. I guess when i tried this before i must have made a different mistake, maybe some typo or something. I tried it copying your code and it totally works! thanks!


Thank you guys so much! I'm really learning a lot from this.
Next time i ask questions i really should try to make myself more clear and also add more of my own code to show what i tried. It was late at night when i wrote this so i guess looking back my post does seem a bit unclear.
Reply With Quote
  #7  
Unread 06-15-2016, 03:43 PM
Garan's Avatar
Garan Garan is offline
The Undying
Interface Author - Click to view interfaces
 
Join Date: Oct 2010
Posts: 340
I would recommend reading up on variable scoping. A simple tutorial specific to Lua can be found at:
http://lua-users.org/wiki/ScopeTutorial

iirc that tutorial does leave out one important thing, iterators are always local, for instance, in the line
"for k,v in pairs(test) do"
the variables k and v are automatically local to their iterative loop (you don't need to explicitly create them as local variables first).

Last edited by Garan : 06-15-2016 at 03:53 PM.
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
A Couple of Questions Heta Lua Programming Help (L) 2 09-15-2010 04:07 AM
A few basic questions Dain93 General Authoring Discussion (L) 2 01-21-2009 01:19 AM
Book 10 UI Issues and Questions AncientWolf General Authoring Discussion (L) 6 08-23-2007 03:09 PM
Noob Questions - Layouts CJezorek Interface Help (L) 5 06-30-2007 02:58 PM
beginner question for letterboxbottom. Pro Graphics modification help (L) 2 05-02-2007 07:49 PM


All times are GMT -5. The time now is 09:56 AM.


Our Network
EQInterface | EQ2Interface | Minion | WoWInterface | ESOUI | LoTROInterface | MMOUI | Swtorui