Posted by
| Nick Gammon
Australia (23,072 posts) Bio
Forum Administrator |
Message
| Modern graphical MMORPGs tend to show an "experience bar" near the bottom of the screen, to show visually how close you are to levelling. The plugin below does the same thing for a text MUD (see screenshot in next message).
For the plugin to work it needs to know how much XP you have, and how much to level, in order to work out how far through the level you are.
In the case of Smaug, you need to change your default prompt and fight prompt, as per "help prompt". I made mine the same as the default, plus the experience, like this:
prompt &w<&Y%hhp &C%mm &G%vmv &C%x/&c%X&Cxp&w>
fprompt &w<&Y%hhp &C%mm &G%vmv &C%x/&c%X&Cxp&w>
(Note: trailing space after the prompt, as in the trigger)
This makes my prompt look like this:
<28hp 100m 102mv 2875/6325xp>
The stuff like &w, &C etc. is just colour-coding the prompt.
Below is the plugin.
Save between the lines as Experience_Bar.xml and use File menu -> Plugins to load that file as a plugin.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE muclient>
<!-- Plugin "Health_Bar" generated by Plugin Wizard -->
<muclient>
<plugin
name="Experience_Bar"
author="Nick Gammon"
id="7e2bf8628a8f51bf2115d2f0"
language="Lua"
purpose="Shows XP to level"
date_written="2009-02-08"
requires="4.35"
version="1.1"
>
<description trim="y">
<![CDATA[
Install this plugin to show an how close you are to levelling.
]]>
</description>
</plugin>
<!-- Triggers -->
<triggers>
<trigger
enabled="y"
match="<*hp *m *mv */*xp> "
script="do_prompt"
sequence="100"
>
</trigger>
</triggers>
<!-- Script -->
<script>
<![CDATA[
win = GetPluginID () -- get a unique name
-- configuration
GAUGE_HEIGHT = 11
NUMBER_OF_TICKS = 20
BACKGROUND_COLOUR = ColourNameToRGB "gray"
BOX_COLOUR = ColourNameToRGB "dodgerblue"
-- draw the bar here, on getting the prompt, or window resize
function draw_bar ()
-- check numbers for validity
if not current_xp or
not max_xp or
current_xp < 0 or
max_xp <= 0 then
return
end -- if
-- cannot have more than max xp
if current_xp > max_xp then
current_xp = max_xp
end -- if
-- width is window width minus 2
local gauge_width = GetInfo (281) - 2
-- make room for the bar
local bottom_margin = GetInfo (275)
-- adjust text rectangle, keeping existing settings where possible
if bottom_margin == 0 or
(bottom_margin < 0 and math.abs (bottom_margin) < (GAUGE_HEIGHT + 2)) then
TextRectangle(GetInfo (272), GetInfo (273), -- left, top
GetInfo (274), -- right
- (GAUGE_HEIGHT + 2), -- bottom (gauge height plus 2 more)
GetInfo (276), GetInfo (282) or 0, GetInfo (277), -- BorderOffset, BorderColour, BorderWidth
GetInfo (278), GetInfo (279)) -- OutsideFillColour, OutsideFillStyle
end -- if
-- make the miniwindow
WindowCreate (win,
0, 0, -- left, top (auto-positions)
gauge_width, -- width
GAUGE_HEIGHT, -- height
10, -- auto-position: bottom left
0, -- flags
BACKGROUND_COLOUR)
WindowRectOp (win, 2, 0, 0, 0, 0, BACKGROUND_COLOUR) -- fill entire box
-- how far through the level we are
local done = current_xp / max_xp
local bar_width = gauge_width * done
-- box size must be > 0 or WindowGradient fills the whole thing
if math.floor (bar_width) > 0 then
-- top half
WindowGradient (win, 0, 0,
bar_width, GAUGE_HEIGHT / 2,
0x000000, -- black
BOX_COLOUR,
2) -- vertical gradient
-- bottom half
WindowGradient (win, 0, GAUGE_HEIGHT / 2,
bar_width, 0,
BOX_COLOUR,
0x000000, -- black
2) -- vertical gradient
end -- any experience to speak of
-- show ticks
local ticks_at = gauge_width / NUMBER_OF_TICKS
-- ticks
for i = 1, NUMBER_OF_TICKS do
WindowLine (win, i * ticks_at, 0, i * ticks_at, GAUGE_HEIGHT, ColourNameToRGB ("silver"), 0, 1)
end -- for
-- draw a box around it
check (WindowRectOp (win, 1, 0, 0, 0, 0, ColourNameToRGB ("lightgrey"))) -- frame entire box
-- ensure window visible
WindowShow (win, true)
end -- draw_bar
function do_prompt (name, line, wildcards, styles)
-- CHANGE HERE if your prompt is different (eg. different wildcard numbers)
-- (string.gsub removes commas from the experience figures, if necessary)
current_xp = tonumber ((string.gsub (wildcards [4], ",", "")))
max_xp = tonumber ((string.gsub (wildcards [5], ",", ""))) + (current_xp or 0)
draw_bar ()
end -- do_prompt
function OnPluginWorldOutputResized ()
draw_bar ()
end -- function
-- hide window on removal
function OnPluginClose ()
WindowShow (win, false) -- hide it
end -- OnPluginClose
-- hide window on disable
function OnPluginDisable ()
WindowShow (win, false) -- hide it
end -- OnPluginDisable
]]>
</script>
</muclient>
If you have a different prompt, or find your experience out in a different way, you would need to change the trigger.
The main work is done in draw_bar, based on two global variables current_xp and max_xp. If you need to establish your experience differently, just make sure your trigger, or triggers, set those two variables.
There is also a plugin callback OnPluginWorldOutputResized which redraws the bar if the world window is resized.
The plugin uses TextRectangle to make the output window slightly smaller at the bottom edge, this is to fit in the experience bar.
You can play with the gauge_height variable to make the bar shorter or taller. An odd number would be better to make the bar look more even, as it is drawn with a gradient from top to the middle, then middle to the bottom. A value of 7 looks more discrete, or you could make it larger than 11.
There is also a configurable number of "tick marks" you can show. The default is 20, which means each "bubble" of experience would represent 5% of the way to the next level. If they are too close together (or too far apart) just change the variable NUMBER_OF_TICKS).
[EDIT] Amended on 5th March 2009 to allow for commas in the experience wildcards. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|