Willfa has written an extensive Lua module which lets you easily set up gauges and other information in MUSHclient, using the new Miniwindows. Sample screenshots are in the next posting in this thread.
[EDIT] The file InfoBox.lua is now part of the MUSHclient install (from version 4.47 onwards) so you don't need to download anything extra in order to use it.
This file includes:
InfoBox.lua (put into your MUSHclient "lua" subdirectory)
InfoBox_Demo.xml (demo plugin - put into your world/plugins directory)
The demo plugin is best run in a dummy world (just make a new world with IP address of 0.0.0.0 and then install the plugin). It runs you through the various things the module can do.
As described in the demo:
For a Quick start, you can be up and running with only the following lines of code:
require "InfoBox"
box = InfoBox:New("HP")
hp = box:AddBar("HP: ", 50)
and in your prompt/hpbar trigger:
hp.value = <new percentage number>
box:Update()
(Results in next posting).
This is a great contribution, as it takes all the technical stuff needed to make miniwindows appear, and leaves you with nice pleasing results. Applications could be for HP/Mana gauges, stats (str/int/dex etc.), combat progress, and other things.
The Demo plugin is written as a demo or tutorial and has samples, as you can see above.
The module itself has a Doc() function that's more of an object reference but still serves as on-line help.
Most values or functions should be intuitively named, and easily viewed by tprint'ing either the module, or the table returned from the New() function (referred to as MiniWindow or MW in my documentation).
Thanks again Nick, this module started out as your hpbar sample, and also borrows from your color coding and commas functions. Without your samples, this never would have evolved. Without your application, this wouldn't have come into existence either... ;)
I've just started using this InfoBox module, and it's pretty great so far! I have a couple of questions and/or feature requests, if I may.
1. I'm interested in creating more than one panel docked to the same part of the screen, such that I have one group of bars (just a pair of text labels, really) for something like date/time that sits above another group of bars for health, mana, and ego, both in the SE corner of my screen. Basically, I want to dynamically build a stack of miniwindows from the corner that goes up the side. Would it be possible to nest these and have info boxes inside other info boxes?
2. Any chance that this module will support hotspots? Or is that left as an exercise for the end user to explore? :)
3. Why is it that when I set the .backgroundColour for an info box that I have to reverse the hex for red with the hex for green? For example, I had to use 0xff901e instead of 0x1e90ff to get "dodgerblue" color.
4. I had troubles blending my gauges (in "glass" + "gradientFixed" mode) from certain colors to certain other colors. They looked normal at 100%, but they went part black and part some odd gradient when the percentage fell to less than 100. Just played around with it until I found "compatible" colors...
Thanks for making all this available, guys! Great work.
Why is it that when I set the .backgroundColour for an info box that I have to reverse the hex for red with the hex for green?
The order of RGB in a hex constant is confusing, probably because of the endian-ness issue of CPUs.
If you look up Red in the Colour Picker, you will see:
MXP: #FF0000
JScript: 0x0000FF
Note that when using HTML (or MXP) the byte order is:
#RRGGBB
However when expressing as a simple number (eg. in hex) it is:
0xBBGGRR
As you can also see from the colour picker red is in the lower-order byte. Now when using Little Endian (as Intel does), when expressed in memory, that number will be:
RR GG BB
So it actually makes sense when stored in memory itself (little endian puts the little byte first). For more information on endian, see:
3. Nick's answer was precise, and dead on; there's nothing I could add.
4. The glass effect works by blending a gray gradient image over the luminance channel of the bar, some colors that have their luminance at 100% won't really glass well, and all colors tend to end up lighter than what you specify. That's why the samples use colour_names.firebrick instead of colour_names.red.
As for the weird black/gray issue, there may be a bug in my math that I didn't find. If you can give me example colors I'll look into it.
2. Just put hotspots in two days ago myself. With 3 other small changes so far (backgroundColour value applying to individual bars as well as the whole window, so effects like Nick's Aardwolf inventory titlebars are possible; top and left (thinking of renaming them to cellTop and cellLeft) getting set during the draw routine so the absolute coordinates of where a bar is drawn are available if you did want to add/draw after the Infobox is updated) I'll probably beat on it over the weekend before harassing Nick with an update.
(see http://cid-73890baf188d56e7.skydrive.live.com/self.aspx/MCForum/Infobox1.2.jpg )
1. The module itself will draw as many bars as you throw at it. I suppose the only limitation would be a consistent number of columns. Different section groupings could be achieved by tinkering with a Bar's .padding value to add some extra separation between them.
i.e.
How would someone go about making a plugin for things with that? I would like to make bars for Hp, mana, moves, tnl, alignment and anything else I can think of :P
Would someone please be able to give me an example? I'm not sure where to start...
Copy Infobox.lua to the C:\Program Files\Mushclient\Lua directory.
Press CTRL+N to make a new world.
Type 0.0.0.0 in the world's IP address field.
Click OK.
Press CTRL+SHIFT+P to bring up the Add Plugins dialog.
Click Add
Browse to where you extracted the InfoBox_Demo.xml
Click OK
Click OK
The module doesn't teach you how to make a prompt/hpbar trigger, or how to code in lua in general, tho a lot of the sample code can show you where to start.
My current goal is to make two separate boxes that are nudged up against one another. The placement rules are a little confusing to me, so I'm asking for some clarification and/or advice.
If I setup two boxes with SE window positions, they are drawn directly over one another (same position) so that one occludes the other. I was hoping that the new box would be "anchored" to the top of the first box.
If I setup two boxes with E window positions, the second one gets its own position such that both are now visible, but there's a large gap in between the two boxes. The gap appears to be centered around the middle of the right edge of the window. I was hoping that the first box would be centered on the left edge until the second box was created. When both boxes are created, the first should have the top edge on the center and the second box has its bottom edge on that same center line. (Kind of a "push a box in and bump the others outward from the center" sort of thing?)
The middle ones (ie. N, S, E, W) are designed to space themselves evenly between any other middle ones and whatever is in the corners. However if you specify a corner that is what you get. It all gets too confusing having rules for "the corner but one down" or something like that, because then you ask "which one goes first" and so on.
If the auto positions don't work, you need to use manual positioning. For example the second one could detect where the first one is (the SE one) and then manually position itself directly on top.
That's just how the miniwindow positioning code works. It's Nick's code. not mine that determines it. :)
If you wanted to fake it, you could make a dummy infobox window, anchored in the corners, that are (GetInfo(263)-box1.windowHeight-box2.windowHeight)/2 in height. That tricks nick's code to squish em together.
The draw back of doing that is that adding a new plugin or another window would need those corner-shim windows to be recreated.
Not sure I understand the "shim window" concept, actually. I guess I could add some padding to the second window equal in height to the first window, eh?
I'm also still confused why the miniwindows on N, S, E, and W get pushed so far out toward the corners, but I suppose I get that more. I know it's not a simple thing to compute for the general case (or else I'd already be sizing and positioning them manually myself).
There's no perfect solution for the auto positioning. your example of the bottom edge/top edge being centered is one solution, but what if window1 is twice as tall as window 2? should it still be the bottom edge, or have the centerline be 2/3rds the way down window1?
For the shim windows...
The code for autopositioning makes sure there's n+1 (where n is the number of miniwindows) equally sized gaps above and below the miniwindows so that the windows are centered between the space left from what's occupied by the corner windows.
The shims sit in the corners, and are basically 1 pixel wide by how ever many pixels it takes so that those 3 equal gaps above, between, and below window1 and window2 are 0 pixels.
I wrote this before movewindow, and I haven't gone through it's code to know exactly how it works... I'll have to look into it later this weekend.
Adding text and hotspots are simple tho. "To simplify the process" </marketing spin> or perhaps as a limitation depending on your perspective, each cell can easily be a hotspot (but not divided up into smaller sections) by setting a table with the parameters the WindowHotSpot function.
require "InfoBox"
InfoBox:Doc("button")
for more information.
Also, go through the Demo plugin for a get ready quick run-through of what InfoBox does.
Digging into the module might be ... fun. :) It's 73k of code and documentation. ;) It's mostly well-written though, so looking at the source shouldn't be mind-boggling... just overwhelming at first.
Except for, obviously, mcicon.png; all these are screen shots of InfoBox Windows.
http://cid-73890baf188d56e7.skydrive.live.com/browse.aspx/MCForum
Doing text is fairly simple with them, as you can see with InfoBox1.2.jpg .
Ok I don't think I understood the demo properly I'll go back and read some more.
I don't suppose you have the documentation in another format. Just a text file would
be great so I can have it up while I'm working with the module.
Thanks WillFa, this module is great btw, I'm itching to make a slick looking health
bar etc plugin for Aardwolf.
Sorry, I wrote all the documentation right in the Lua module. What I normally do is have another world open, that has it's IP Adress set to 0.0.0.0, a scripting prefix set, and auto-say turned on that's set to prefix each line with the scripting char and checked to send to the interpreter. I have this world saved as Scratchpad.
When I want a quick Lua interactive session, the dummy world serves nicely.
I am completely new to LUA and to Writing my own Plugins/Scripts. I am trying to write a plugin for a miniwindow for my HP/EP (health and energy points)
Could you guys make a guide, like step by step as to what is requried to make this? I know that guys mention a prompt/hp trigger that is required, can anyone go into some detail, with the steps required, IE what variables need to be stored and then called up in the plugin?
I am familiar with C++ coding but have never done any LUA stuff. Any help would be appreciated.
Thorr686 said: I am familiar with C++ coding but have never done any LUA stuff. Any help would be appreciated.
I was in the same position as you about 2.5 months ago - familiar with C++, but no experience with Lua or MUSHclient scripts. I wanted to create a plugin with energy bars, but wasn't really sure where to start.
Then I spent some time playing with it and reading the documentation on this site. I googled Lua to find the syntax for certain things when necessary, but the language is pretty simple and you can pick most of it up as you go along.
After a couple of weeks I'd modified the plugin into what I wanted, and felt confident enough to start working on my own plugin. Two months later and I've now got energy bars, a background image, an avatar, timers, a couple of click-to-move maps, and information about your opponent.
A couple of days ago I posted a thread on MudBytes where I briefly discussed the different stages of my plugin, with a screenshot at each stage. Perhaps you'll find it of interest: http://www.mudbytes.net/index.php?a=topic&t=2899
So my suggestion would be to look through the existing plugins, read over the documentation, and have a play - try changing things, see what works and what doesn't, get a feel for it.
One other point worth mentioning though: I don't know which mud you play, but if it supports an out-of-band protocol such as ZMP, ATCP/2, MSDP or 102, you can have energy bars that don't rely on your prompt. Not only does this make the plugin easier to write, it's also nicer to use, as you don't have to keep hitting enter for the energy bars to update.
Ok, well I know that the mud i play on does not have the ability to update the health bars without the prompt appearing so unfortunately i will just have to have a bunch of spam on my screen.
I will look through those pages and get back to you with my progress.
A general process of what I will need, sorta like a toolbox with all my tools in it before i start building my plugin would still be helpful. Thanks for the quick response :)
You basically just need to modify the trigger to match what you receive. You don't have to have the screen fill up with prompts if you don't want, because you could omit them from output.
I'm very new to all of this and am trying to do something that may already be easy, or possibly could require changing the module...
Basically, I want a MW that has a dynamic set of Bars... one for the hp's of each current member of my group. Whenever I check group status, I'd like to update the respective hp bar of each member, assuming it's not a new member. In that case I'd need to add a hp bar for them ( and delete the bar of any group members that left the group).
The approach that I thought of was to have the bars indexed by group member name... so I could do a test like:
if ( MW ["Bars"] [member.name] ) then
-- update their bar
else
-- add their bar and set its initial values
end
Is there a way to do something like this cleanly? Am I being stupid again and overlooking something obvious? :) I'd hate to have to loop through all the bars checking the captions for the names...