Mushclient Questions

by Esano

Back to Mechanic's Corner.

Unknown2009-04-08 11:07:56
In your world properties, there's a Scripting page that tells you what language you're using. Lua is the default these days, so if you haven't changed it, I'd assume that's what you've got for now.

To create different settings for different characters, you simply create a new world and change your options to suit each new character.

There are many tutorials on the web on how to do regular expressions, or you could just ask for tips here on how to match various things until you get the hang of how to do it yourself.
Unknown2009-04-09 02:16:21
Moving my prompt decoration questions here since it doesn't really involve Treant.

Alright, I finally managed to make my prompt decorator:

The trigger (which I stole from the Treant prompt capture)
CODE

     enabled="y"
   keep_evaluating="y"
   match="^(\\d+)h\\, (\\d+)\\m\\, (\\d+)e\\, (\\d+)p\\, (\\d+)en\\, (\\d+)w(?:\\, \\d+mo)? (.*?\\-)(?:\\((?:\\d+ \\- \\w+|Done\\.)\\)\\s*)?$"
   name="prompt_dec__"
   omit_from_log="y"
   omit_from_output="y"
   regexp="y"
   script="decorate_prompt"
   send_to="12"
   sequence="1000"
  >
  decorateprompt:capture(%1, %2, %3, %4, %5, %6)
  


And the script:
CODE
--]

if not decorateprompt then  
  decorateprompt = {
    health = 0,
    mana = 0,
    ego = 0,
    power = 0,
    endurance = 0,
    willpower = 0,
    time_justnow = 0
  }
end

function decorateprompt:capture(health, mana, ego, power, endurance, willpower)
last_health = GetVariable("health")
last_mana = GetVariable("mana")
last_ego = GetVariable("ego")
last_power = GetVariable("power")
last_endurance = GetVariable("endurance")
last_willpower = GetVariable("willpower")

health = health
mana = mana
ego = ego
power = power
endurance = endurance
willpower = willpower

SetVariable("health", health)
SetVariable("mana", mana)
SetVariable("ego", ego)
SetVariable("power", power)
SetVariable("endurance", endurance)
SetVariable("willpower", willpower)

end


function decorate_prompt(name, line, wildcards, styles)

   for _, v in ipairs(styles) do
     ColourTell(RGBColourToName(v.textcolour), RGBColourToName (v.backcolour), v.text)
   end

   time_justnow = GetVariable("time")
   time_now = GetInfo(232)
   SetVariable("time", time_now)


   ColourTell("dimgray", "", string.format(" ", time_now - time_justnow))

     if last_health > GetVariable("health") then
        ColourTell("lightcoral", "", string.format(" ", last_health - GetVariable("health")))
     elseif last_health < GetVariable("health") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("health") - last_health))
     end

     if last_mana > GetVariable("mana") then
        ColourTell("lightcoral", "", string.format(" ", last_mana - GetVariable("mana")))
     elseif last_mana < GetVariable("mana") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("mana") - last_mana))
     end

     if last_ego > GetVariable("ego") then
        ColourTell("lightcoral", "", string.format(" ", last_ego - GetVariable("ego")))
     elseif last_ego < GetVariable("ego") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("ego") - last_ego))
     end

     if last_power > GetVariable("power") then
        ColourTell("lightcoral", "", string.format(" ", last_power - GetVariable("power")))
     elseif last_power < GetVariable("power") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("power") - last_power))
     end

     if last_endurance > GetVariable("endurance") then
        ColourTell("lightcoral", "", string.format(" ", last_endurance - GetVariable("endurance")))
     elseif last_endurance < GetVariable("endurance") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("endurance") - last_endurance))
     end

     if last_willpower > GetVariable("willpower") then
        ColourTell("lightcoral", "", string.format(" ", last_willpower - GetVariable("willpower")))
     elseif last_willpower < GetVariable("willpower") then
        ColourTell("lightgreen", "", string.format(" ", GetVariable("willpower") - last_willpower))
     end


   Note("")

end

return decorateprompt


Now the questions:
Why did I get a nil result when I tried to just use health/mana/ego? I worked around that by saving them in the Mushclient variables, but I'd like to know what went wrong there. Also, strangely enough, for the time variables, it's time_justnow instead of time_now which has the problem, which seems to be the opposite of the other variables.

I must admit, I copied quite a lot of stuff without understanding what they mean, such as the very first statement 'if not X then ', as well as the self.variable parts. I'm also trying to figure out the 'for X, X in pairs' lines and what they mean, but they seem to be out of my depth for now. That said, I learnt how to make a module of my own. smile.gif
I'm also looking through the Lua websites Zarquan linked, which helped me understand what local meant.
Esano2009-04-09 02:23:17
Because your declaration statements are health = health. If health isn't defined, you're trying to call a null. You have a declaration statement inside a table, but that only applies to that table (you'd need to call and assign them with : decorateprompt )

Try
CODE
if health then
  health = health
else
  health = 0
end

Or something similar.
Isuka2009-04-09 03:13:12
QUOTE (Esano @ Apr 8 2009, 07:23 PM) <{POST_SNAPBACK}>
Because your declaration statements are health = health. If health isn't defined, you're trying to call a null. You have a declaration statement inside a table, but that only applies to that table (you'd need to call and assign them with : decorateprompt )

Try
CODE
if health then
  health = health
else
  health = 0
end

Or something similar.


You can actually use
health = health or 0
Unknown2009-04-09 03:14:49
QUOTE (Isuka @ Apr 9 2009, 11:13 AM) <{POST_SNAPBACK}>
You can actually use
health = health or 0

Hrm where do I place that? At the start of my capture fuction? At the start of the script?
Isuka2009-04-09 03:25:52
Oh, I see the problem. You're not actually passing the function any values, because you're not enclosing the backreferences in quotation marks.

decorateprompt:capture(%1, %2, %3, %4, %5, %6)
should actually be
decorateprompt:capture("%1", "%2", "%3", "%4", "%5", "%6")

you can also remove this section entirely:
CODE
health = health
mana = mana
ego = ego
power = power
endurance = endurance
willpower = willpower

as it doesn't actually do anything but set a variable to itself.

Isuka2009-04-09 03:41:11
On a further look (my first was just a glance through) you have a more serious problem.

Here's what you're doing: you're calling a function that pulls existing values for your vitals, and values for your new vitals. That is fine, but you're then trying to evaluate them in a completely different function. Because of this, you're trying to compare values that no longer exist (a function variable only exists while the function is running, and is deleted once it's finished. This is called "Scope")

You can essentially move the entire function :capture over to the main processing function, and get the variables through wildcards rather than passing by value.

you can change your prompt trigger to this
CODE

     enabled="y"
   keep_evaluating="y"
   match="^(?P\\d+)h\\, (?P\\d+)\\m\\, (?P\\d+)e\\, (?P\\d+)p\\, (?P\\d+)en\\, (?P\\d+)w(?:\\, \\d+mo)? (.*?\\-)(?:\\((?:\\d+ \\- \\w+|Done\\.)\\)\\s*)?$"
   name="prompt_dec__"
   omit_from_log="y"
   omit_from_output="y"
   regexp="y"
   script="decorate_prompt"
   send_to="12"
   sequence="1000"
  >
  

and your script file to this:
CODE
--]

if not decorateprompt then  
  decorateprompt = {
    health = 0,
    mana = 0,
    ego = 0,
    power = 0,
    endurance = 0,
    willpower = 0,
    time_justnow = 0
  }
end

function decorate_prompt(name, line, wildcards, styles)
    last_health = GetVariable("health")
    last_mana = GetVariable("mana")
    last_ego = GetVariable("ego")
    last_power = GetVariable("power")
    last_endurance = GetVariable("endurance")
    last_willpower = GetVariable("willpower")
    
    health = wildcards.health
    mana = wildcards.mana
    ego = wildcards.ego
    power = wildcards.power
    endurance = wildcards.endurance
    willpower = wildcards.willpower

    SetVariable("health", health)
    SetVariable("mana", mana)
    SetVariable("ego", ego)
    SetVariable("power", power)
    SetVariable("endurance", endurance)
    SetVariable("willpower", willpower)

   for _, v in ipairs(styles) do
     ColourTell(RGBColourToName(v.textcolour), RGBColourToName (v.backcolour), v.text)
   end

   time_justnow = GetVariable("time")
   time_now = GetInfo(232)
   SetVariable("time", time_now)


   ColourTell("dimgray", "", string.format(" ", time_now - time_justnow))

     if last_health > health then
        ColourTell("lightcoral", "", string.format(" ", last_health - health))
     else
        ColourTell("lightgreen", "", string.format(" ", health - last_health))
     end

     if last_mana > mana then
        ColourTell("lightcoral", "", string.format(" ", last_mana - mana))
     else
        ColourTell("lightgreen", "", string.format(" ", mana - last_mana))
     end

     if last_ego > ego then
        ColourTell("lightcoral", "", string.format(" ", last_ego - ego))
     else
        ColourTell("lightgreen", "", string.format(" ", ego - last_ego))
     end

     if last_power > power then
        ColourTell("lightcoral", "", string.format(" ", last_power - power))
     else
        ColourTell("lightgreen", "", string.format(" ", power - last_power))
     end

     if last_endurance > endurance then
        ColourTell("lightcoral", "", string.format(" ", last_endurance - endurance))
     else
        ColourTell("lightgreen", "", string.format(" ", endurance - last_endurance))
     end

     if last_willpower > willpower then
        ColourTell("lightcoral", "", string.format(" ", last_willpower - willpower))
     else
        ColourTell("lightgreen", "", string.format(" ", willpower - last_willpower))
     end


   Note("")

end


That should be a bit less processor intensive, and a bit easier to read.
Unknown2009-04-09 03:44:04
Ah, I see.

Edit: Hrm, I tried your advice, in addition to adding the health = health or 0, but I still get a nil.

Edit: Erm, this was before your post above. Lemme look through that.
Unknown2009-04-09 09:13:07
Woooo! Thanks Isuka, now just 'health' works. Although, I did put back the elseif statements, as I don't want them to show up if there is no change.

Now my question is, how come last_health worked before, but health didn't? When you mean function variables, do you mean the stuff that is inside the function blah:stuff()?
Unknown2009-04-09 11:09:14
last_health worked because it was creating a global variable. health didn't work because it was referencing the parameter, which is only scoped locally in that function. You may notice that in my scripts I use the self.var syntax to make the variables persist between function calls to that module. It's rather unnecessary to store all these as world variables, since they're transient and don't need to be saved between sessions.
Unknown2009-04-09 12:58:59
Ah, so that's what self. means? So does it mean that I can use 'last_health' in another module, and it'll get that last_health value?

So lemme get all this straight:
Local variables persist only until it sees an end, right?
Function variables persists until end of function.
Self variable persist until end of module.
Global variables persist until end of session.
World variables persist forever.

Did I get all that right?
Unknown2009-04-09 13:41:40
Pretty close. "self" variables are really just indices in the module table. The use of self to refer to the current table is what they call syntactic sugar, meaning that it's just another way to write something you could already do in the language.

These two are basically equivalent constructs:
CODE
function module:func()
  self.something = 2
end
module:func()

CODE
function module.func(self)
  self.something = 2
end
module.func(module)


And "function variables" are referred to as arguments or parameters.

If you ever do use the self.something = value syntax, you may only refer to that something with the self reference inside of that module. To access the value outside of the module, use the module's actual name in place of self. (There is no public, private, etc in Lua.)
Aramel2009-04-11 12:42:25
Sometimes my MUSHclient will just randomly omit a line from the output. I'm pretty sure it's not a trigger, since it still happens when I disable triggers, and triggers that are supposed to fire on the omitted lines don't do so, so I'm guessing that the omission happens before it gets to the triggers. I'm not sure how to fix it, though.
Esano2009-04-11 14:04:26
Are you running something like mudbot?
Aramel2009-04-11 22:24:45
Yeah.
Sidd2009-04-11 22:52:37
Here is a question,

I want to take all my in game channels, like CT, GT, CLT, CGT etc, and place it in another window, anyone know where I can find a good help file or something that can help me do this? Thanks
Isuka2009-04-12 02:52:52
I don't know of anything pre-written. I use miniwindows in a plugin to seperate the text when I feel like it, but I haven't figured out a proper way to get it to scroll yet.

You can also use a dummy world.
Unknown2009-04-12 08:46:49
I save them in my variables and has an alias to display them. Unwieldy, but it works. Still trying to figure out Lua to make a more elegant method.
Isuka2009-04-12 16:56:59
Anyone know if there's a way to grab the wrap-width value (MUSH's, not Lusternia's) within mushclient? I use algoritms to determine center of screen, and it'd be handy not to have to hard-code that.
Rika2009-04-12 20:55:50
QUOTE (Isuka @ Apr 13 2009, 04:56 AM) <{POST_SNAPBACK}>
Anyone know if there's a way to grab the wrap-width value (MUSH's, not Lusternia's) within mushclient? I use algoritms to determine center of screen, and it'd be handy not to have to hard-code that.


Bottom of Appearance > Output?