Achaea health (stats) bar

Posted by Nick Gammon on Tue 09 Mar 2010 01:57 AM — 11 posts, 40,867 views.

Australia Forum Administrator #0
The plugin below draws a health bar with health, mana, endurance and willpower from the information passed down from ATCP messages. You need the ATCP_NJG plugin described in this thread to generate the messages for this plugin to use:

http://www.gammon.com.au/forum/?id=10129


Template:saveplugin=Achaea_Health_Bar
To save and install the Achaea_Health_Bar plugin do this:
  1. Copy the code below (in the code box) to the Clipboard
  2. Open a text editor (such as Notepad) and paste the plugin code into it
  3. Save to disk on your PC, preferably in your plugins directory, as Achaea_Health_Bar.xml
    • The "plugins" directory is usually under the "worlds" directory inside where you installed MUSHclient.
  4. Go to the MUSHclient File menu -> Plugins
  5. Click "Add"
  6. Choose the file Achaea_Health_Bar.xml (which you just saved in step 3) as a plugin
  7. Click "Close"
  8. Save your world file, so that the plugin loads next time you open it.



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Achaea_Health_Bar"
   author="Nick Gammon"
   id="e149d30173eb8af91dae945f"
   language="Lua"
   purpose="Shows stats in a mini window"
   date_written="2010-03-09"
   requires="4.50"
   version="1.0"
   save_state="y"
   >
<description trim="y">
<![CDATA[
Install this plugin to show an info bar with HP, Mana, Endurance and Willpower.
]]>
</description>

</plugin>

<!--  Script  -->


<script>
<![CDATA[

require "movewindow"
require "gauge"
require "serialize"
require "checkplugin"

GAUGE_HEIGHT = 15

WINDOW_WIDTH = 300
GAUGE_COUNT = 4
GAP_BETWEEN_BARS = 4
NUMBER_OF_TICKS = 5

BACKGROUND_COLOUR = ColourNameToRGB "rosybrown"
FONT_COLOUR = ColourNameToRGB "darkred"
BORDER_COLOUR = ColourNameToRGB "#553333"

FONT_NAME = get_preferred_font {"Sylfaen", "Dina", "Lucida Console", "Fixedsys", "Courier" } 
FONT_SIZE = 10

function DoGauge (sPrompt, win, current, max, Colour)
  local width = WindowTextWidth (win, FONT_ID, sPrompt, true)  -- to right-justify it
  WindowText (win, FONT_ID, sPrompt, gauge_left - width + 5, vertical, 0, 0, ColourNameToRGB "#444444", true)
  
  gauge (win, sPrompt, 
          current, max, 
          gauge_left + 10, vertical, WINDOW_WIDTH - gauge_left - 20, font_height,
          ColourNameToRGB (Colour or "darkgreen"), ColourNameToRGB "gray",
          5, ColourNameToRGB "silver", -- ticks
          ColourNameToRGB "lightgrey",  -- frame
          0x444444)   -- shadow

  vertical = vertical + font_height + GAP_BETWEEN_BARS
end --  DoGauge


function OnPluginInstall ()
  
  win = GetPluginID ()
  FONT_ID = "fn"

  -- make initial window
  WindowCreate (win, 0, 0, 0, 0, 0, 0, 0)
  -- add the fonts
  WindowFont (win, FONT_ID, FONT_NAME, FONT_SIZE)
  font_height = WindowFontInfo (win, FONT_ID, 1)  -- height
  
  -- install the window movement handler, get back the window position
  windowinfo = movewindow.install (win, 7)  -- default to 7 (on right, center top/bottom)
    
  window_height = (font_height * GAUGE_COUNT) + (GAUGE_COUNT * 2) * GAP_BETWEEN_BARS 
  
  -- make miniwindow so I can grab the font info
  WindowCreate (win, 
                windowinfo.window_left,
                windowinfo.window_top,
                WINDOW_WIDTH, 
                window_height,  
                windowinfo.window_mode,   
                windowinfo.window_flags,    
                BACKGROUND_COLOUR)

  -- add the drag handler so they can move the window around
  movewindow.add_drag_handler (win, 0, 0, 0, 0)
  
  -- work out how far in to start the gauge
  
  gauge_left =  max_text_width (win, FONT_ID, {"Health", "Mana", "Endurance", "Willpower" }) + 5
  
  if GetVariable ("enabled") == "false" then
    ColourNote ("yellow", "", "Warning: Plugin " .. GetPluginName ().. " is currently disabled.")
    check (EnablePlugin(GetPluginID (), false))
  end -- they didn't enable us last time
 
end -- OnPluginInstall

function OnPluginDisable ()
  WindowShow (win, false)
end -- OnPluginDisable

function OnPluginEnable ()
  WindowShow (win, true)
end -- OnPluginEnable

function OnPluginSaveState ()
   -- save window current location for next time  
  movewindow.save_state (win)
  SetVariable ("enabled", tostring (GetPluginInfo (GetPluginID (), 17)))
end -- OnPluginSaveState

stats = {}

function got_vitals (s)
  stats.health, stats.maxhealth, 
  stats.mana, stats.maxmana, 
  stats.endurance, stats.maxendurance, 
  stats.willpower, stats.maxwillpower, 
  stats.exp, stats.maxexp = string.match (s, "^H:(%d+)/(%d+) M:(%d+)/(%d+) E:(%d+)/(%d+) W:(%d+)/(%d+) NL:(%d+)/(%d+)")
  
  if stats.health then
   
    hp, max_hp = tonumber (stats.health), tonumber (stats.maxhealth)
    mana, max_mana = tonumber (stats.mana), tonumber (stats.maxmana)
    endurance, max_endurance = tonumber (stats.endurance), tonumber (stats.maxendurance)
    willpower, max_willpower = tonumber (stats.willpower), tonumber (stats.maxwillpower)
  
    -- fill entire box to clear it
    check (WindowRectOp (win, 2, 0, 0, 0, 0, BACKGROUND_COLOUR))  -- fill entire box
    
    -- Edge around box rectangle
    check (WindowCircleOp (win, 3, 0, 0, 0, 0, BORDER_COLOUR, 0, 2, 0, 1))
  
    vertical = 6  -- pixel to start at
  
    DoGauge ("Heath: ",     win, hp ,       max_hp,         "darkgreen")
    DoGauge ("Mana: ",      win, mana,      max_mana,       "mediumblue")
    DoGauge ("Endurance: ", win, endurance, max_endurance,  "gold")
    DoGauge ("Willpower: ", win, willpower, max_willpower,  "brown")
  
    WindowShow (win, true)
  end -- if
end -- function got_vitals

function OnPluginBroadcast (msg, id, name, text)
  if id == "85f72d0e263d75df7bde6f00" then
  
    if msg == 1 then
      got_vitals (text)      -- eg. "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100 "
    end -- if   
 
  end -- if ATCP message
end

function OnPluginListChanged ()
  do_plugin_check_now ("85f72d0e263d75df7bde6f00", "ATCP_NJG")    -- check we have ATCP plugin
end -- OnPluginListChanged


]]>
</script>

</muclient>
Amended on Tue 09 Mar 2010 08:29 PM by Nick Gammon
#1
How could I change that so that It only shows my health without me having to change my prompt. Thanks
Australia Forum Administrator #2
See these four lines?


    DoGauge ("Heath: ",     win, hp ,       max_hp,         "darkgreen")
    DoGauge ("Mana: ",      win, mana,      max_mana,       "mediumblue")
    DoGauge ("Endurance: ", win, endurance, max_endurance,  "gold")
    DoGauge ("Willpower: ", win, willpower, max_willpower,  "brown")


Just remove the ones you don't want.

Then change:


GAUGE_COUNT = 4


... to be how many you want. That controls the height of the box.
Amended on Wed 10 Mar 2010 04:56 AM by Nick Gammon
#3
I see a problem with the scripting of this plugin the set up of where you grab the info from is

stats.exp, stats.maxexp = string.match (s, "^H:(%d+)/(%d+) M:(%d+)/(%d+) E:(%d+)/(%d+) W:(%d+)/(%d+) NL:(%d+)/(%d+)")

Where as in Achaea the prompt is like this

Numeric: 1073h, 3073m, 15688e, 15688w ex-

Text: H:Full, M:Low, E:High, W:High ex-

So could stats.exp, stats.maxexp = string.match (s, "^H:(%d+)/(%d+) M:(%d+)/(%d+) E:(%d+)/(%d+) W:(%d+)/(%d+) NL:(%d+)/(%d+)") be substitued with stats.exp, stats.maxexp = string.match (s, "^(\d+)h, (\d+)m, (\d+)e, (\d+)w (.+)-$")and still work. Of course you'd have to create a capture to grab the max and that could be done off of a qsc


qsc
Archdragon Deladan Seir-Lichlord, Ashuran Knight (male Troll)
You are level 97 (First Among the Hosts) and 15.0% of the way to the next level.
Health: 6838 / 6838 Mana: 3511 / 3648
Endurance: 29985 /29985 Willpower: 13980 /13980
Strength: 16 Dexterity: 10 Constitution: 19 Intelligence: 8

Health\:\s+(?pval.health:\d+) \/\s*(?pval.maxhealth:\d+)\s+Mana\:\s+(?pval.mana:\d+) \/\s*(?pval.maxmana:\d+)\nEndurance\:\s+(?pval.endurance:\d+) \/\s*(?pval.maxendurance:\d+)\s+Willpower\:\s+(?pval.willpower:\d+) \/\s*(?pval.maxwillpower:\d+

Where I guess pval would be a table on mush and you'd have to call the table. I'm really new to coding in mush. But I know in zmud it's a table filled with variables.
USA #4
Deladan said:
I see a problem with the scripting of this plugin the set up of where you grab the info from is

stats.exp, stats.maxexp = string.match (s, "^H:(%d+)/(%d+) M:(%d+)/(%d+) E:(%d+)/(%d+) W:(%d+)/(%d+) NL:(%d+)/(%d+)")

It's matching against hidden ATCP data, the same stuff that powers the Nexus graphical widgets like the compass, gauges, latency meter, etc. It's not a problem unless you don't have the right ATCP plugin.

In fact, whereas normally you -would- have to parse the prompt and QSC just to get the current and max values, ATCP gives them both to you in one easy-to-grab package, along with your experience values.
Australia Forum Administrator #5
Deladan said:

I see a problem with the scripting of this plugin the set up of where you grab the info from is

...

Where as in Achaea the prompt is like this

Numeric: 1073h, 3073m, 15688e, 15688w ex-

Text: H:Full, M:Low, E:High, W:High ex-


It's not a problem, it's a feature. As Twisol says, if you install the plugin (and the ATCP_NJG plugin mentioned) then: It. Just. Works.

Regardless of your prompt or anything else. It uses the hidden data sent down by the server (which is sent every time the visual prompt updates).
#6
*Edit for clarity

What if you're using Mush client to connect you to a program that connects you to achaea, because I have both of those installed and I still don't have a health bar :( I'll look at the other program's coding in a sec see if I see anything there
Amended on Sat 13 Mar 2010 02:51 AM by Deladan
#7
Found it. Going to try something see if it works
USA #8
Deladan said:

*Edit for clarity

What if you're using Mush client to connect you to a program that connects you to achaea, because I have both of those installed and I still don't have a health bar :( I'll look at the other program's coding in a sec see if I see anything there


If you mean Vadi's system, you need to enable the "atcp_info" option in its configuration file. Just add this line to it (or if the atcp_info line is already there, make it match):

atcp_info "yes"
Australia Forum Administrator #9
The Char.Vitals needs to be enabled by negotiation with the server, and I'm not sure they have double-negotiation implemented just yet.
USA #10
Nick Gammon said:

The Char.Vitals needs to be enabled by negotiation with the server, and I'm not sure they have double-negotiation implemented just yet.


Vadi's system enables a whole bunch of modules - maybe all of them - so it's not really an issue of enabling it. It's just that the system, by default, doesn't pass the ATCP data on to the client.