Help - Search - Members - Calendar
Full Version: Lua's Nil Value Variables In Mushclient
Achaea's Forums > Off-Topic > Tech Support > Client Help
Belus
I've spent the last couple days trying to get some basic things working in Mushclient with Lua, but there's something basic still eluding me.

I have mutli-line and conditional triggers down. And I can get very basic aliases to work, though only when using send to script and the Send() function.

These seem to be working now
CODE
    <alias name="Targetting" match="^t (\w+)$" enabled="y" echo_alias="n" group="General" regexp="y" send_to="12" expand_variables="y">
        <send>SetVariable("target", "%1")\nworld.Send("st t %1")</send></alias>
    <alias name="Garrote" match="^g$" enabled="y" echo_alias="n" group="General" regexp="y" send_to="12" expand_variables="y">
        <send>world.Send("garrote @target")</send></alias>
but when I try to do anything more complex with a variable it doesn't store.

I prefer to build systems in Textpad and import them because it's easier for me to follow. I've been attempting to build a plugin that will take care of the basic things I do in Zmud, but it's been difficult.

I've tried copying the methods of other Lua plugins, but for some reason I can't manipulate variables.

These are the bits I'm working with right now
CODE
    <trigger
        name="prompt"
        match="^(\d+)h\, (\d+)m [cexkdb@]*\-"
        enabled="y"
        group="Basic"
        regexp="y"
        send_to="12"
        sequence="100"
        expand_variables="y"
        keep_evaluating="y">
            <send>
            stats.health = %1
            stats.mana = %2
            sip ()
            </send>
        </trigger>
    <trigger
        name="GainSipBalance"
        match="You may drink another health or mana elixir\.$"
        enabled="y"
        group="AutoSipper"
        regexp="y"
        send_to="14"
        sequence="100"
        expand_variables="y">
            <send>
            Note("Setting sip balance true.")
            balances.hm = true
            Note("@balances.hm")
            </send>
        </trigger>
<script>
<![CDATA[

stats = {
  health = 1, maxhealth = 1,
  mana   = 1, maxmana   = 1,
  }

balances = {
  hm = true,
  }

function sip ()
    
    Note("Entered sip function")
    
    if stats.heatlh == nil then
        Note("stats.health is nil")
    end -- if
    
    local health = GetVariable("stats.health")
    local mana = GetVariable("stats.mana")
    local balance = GetVariable("balances.hm")
        
    Note("Sip: set local variables")
    
    if health == nil then
        Note("health is nil")
    else
        Note("health is:" .. health)
        Note("mana is:" .. mana)
        Note("balances.hm is:" .. balance)
    end -- if
    
    if balance and health<2800 then
        Send("drink health")
        Note("drink health")
    elseif balance and mana<3100 then
        Send("drink mana")
        Note("drink mana")
    end -- if
    
    Note("After if")
    
end -- function sip
]]>        
</script>


But testing it in Mushclient only produces
CODE
You may drink another health or mana elixir.
Setting sip balance true.
.hm
2000h, 3894m exd-
Entered sip function
stats.health is nil
Sip: set local variables
health is nil
After if


What am I doing wrong with Lua's tables that prevents them from holding data?
And, is this table of send #'s still correct? I'm sending things to speedwalk and it's executing scripts.


CODE
1     world (the MUD)
2     command (the command window)
3     output (directly to the output window, as a note to yourself)
4     status (to the status line)
5     notepad - new (create a new notepad window)
6     notepad - append (append to a notepad window)
7     log file (directly to the log file)
8     notepad - replace (replace an existing notepad window)
9     world - speedwalk delay (queue for delayed send at the speedwalk rate)
10     variable (set a variable, whose name you provide in the variable box)
11     execute (execute through normal command parser, so aliases, speedwalks etc. will be executed)
12     speedwalk (send to world after converting speedwalk string)
13     script (execute as a script command in the current scripting language)
14     world - immediate (to the MUD immediately, even if you are speedwalking)
Eldar
I don't really use MUSH, mostly I've just messed around with it to see what all it can do. But, for whatever help it may provide you, here's the prompt trigger from Trevize's MUSH autosipper:

CODE
  <trigger
   enabled="y"
   group="system_vitals"
   keep_evaluating="y"
   match="^(\d+)h\, (\d+)m\(?:, \d+e\)?(?:, \d+w)? [cexkdb@]*\-"
   name="prompt"
   regexp="y"
   send_to="14"
   sequence="25"
  >
  <send>stats.health = %1
stats.mana = %2
heartbeat ()</send>
  </trigger>


Maybe the expand_variables or keep_evaluating flags are causing issues? I really don't know enough about MUSH to be much more helpful.

Edit: Wow...where did that ugly spacing come from? blink.gif
Gorlasintan
QUOTE
if stats.heatlh == nil then


You spelled 'health' wrong.

EDIT: That's the first if. I'm still looking at the rest. However, this particular error makes it seem as though stats.health is nil, when in reality, it may not be.

EDIT2: I think the other problem is this:

QUOTE
local health = GetVariable("stats.health")
local mana = GetVariable("stats.mana")
local balance = GetVariable("balances.hm")


The GetVariable function retrieves values from MushClient variables, not the script variables.

It should just be

QUOTE
local health = stats.health
local mana = stats.mana
local balance = balances.hm


These two issues together end up making everything come out wrong.

EDIT3: Lua's 'if then elseif then else end' setup annoys me. The 'then' and 'end' should be implicit. >:(

EDIT4: Hi Rakon.
Penquin
You need to escape the variables in quotes, from my first glance:
QUOTE
<trigger
name="prompt"
match="^(\d+)h\, (\d+)m [cexkdb@]*\-"
enabled="y"
group="Basic"
regexp="y"
send_to="12"
sequence="100"
expand_variables="y"
keep_evaluating="y">
<send>
stats.health = "%1"
stats.mana = "%2"
sip ()
</send>
</trigger>


What are you trying to do that's more complex with variables??

MUSHclient variables are ALWAYS stored as strings, you'll need to use them as such.
Lua's NIL isn't equal to 0, it's more equal to non exsistant. So if you're testing if a variable exist, using nil, it'll probably work as expected. However if you're testing if a variable has a value to it , then test for the value.


CODE
stats = {
  health = 1, maxhealth = 1,
  mana   = 1, maxmana   = 1,
  }

balances = {
  hm = true,
  }

function sip ()
    
    Note("Entered sip function")
    
    if stats.heatlh == nil then
        Note("stats.health is nil")
    end -- if
    
    local health = stats.health
    local mana = stats.mana
    local balance = balances.hm



This seems....wrong.

GetVariable() is a MUSHclient function that gets the variable named, from the MUSHclient WORLD. You define stats array in LUA variable, therefore you need to use the LUA variable to access this.


So change your functions and variables to use all LUA or, all MUSHclient. You can't try to set one and use the other interchangeably.

CODE
stats = {
  health = toint(GetVariable('health')), maxhealth = toint(GetVariable('mhealth'),
  mana   = toint(GetVariable('mana')), maxmana   =  toint(GetVariable('mmana')),
  }

balances = {
  hm = GetVariable('hm'),
  }

function sip ()
    
    Note("Entered sip function")
    
    if stats.heatlh == nil then
        Note("stats.health is nil")
    end -- if
    
    local health = stats.health
    local mana = stats.mana
    local balance = balances.hm

  Note("Sip: set local variables")
    
    if health == nil then
        Note("health is nil")
    else
        Note("health is:" .. tostr(health))
        Note("mana is:" .. tostr(mana))
        Note("balances.hm is:" .. tostr(balance))
    end -- if
    
    if balance and health<2800 then
        Send("drink health")
        Note("drink health")
    elseif balance and mana<3100 then
        Send("drink mana")
        Note("drink mana")
    end -- if
    
    Note("After if")
    
end -- function sip


Notice you define the variables in the array as the values from a MUSHclient variable, parsing them as an INT for the LUA script.
Gorlasintan
QUOTE (Penquin @ Aug 1 2009, 09:27 PM) *
You need to escape the variables in quotes, from my first glance:
QUOTE
<trigger
name="prompt"
match="^(\d+)h\, (\d+)m [cexkdb@]*\-"
enabled="y"
group="Basic"
regexp="y"
send_to="12"
sequence="100"
expand_variables="y"
keep_evaluating="y">
<send>
stats.health = "%1"
stats.mana = "%2"
sip ()
</send>
</trigger>



With the little dabbling I did in MUSH, I found that was only needed when you're pulling out string values for variables. Numeric variables would work fine, so long as you're assigning them to a script variable (which he's doing).
Belus
Ah! I was unaware of the distinction between MUSH variables and those in Lua. That makes a bit more sense and it's something I'll look out for.

Is there a way to store Lua variables to MUSH (ie make them global)?

Is "target" in my above examples a MUSH variable or is it only in the plugin? I don't see it come up as a variable in the Configuration window of MUSH.

The plugin has <variables><variable name="target">rat</variable></variables> and I can update "target" with the alias in the first post, however if I try /Note("@target") in the command box it does not expand the variable.
It seems impossible for plugins to talk to each other without going through MUSH, but I haven't found away for MUSH to get information from my plugin.

Edit: With the advice and comments I got above, it looks to be working a bit better.

CODE
    <trigger
        name="prompt"
        match="^(\d+)h\, (\d+)m [cexkdb@]*\-"
        enabled="y"
        group="Basic"
        regexp="y"
        send_to="12"
        sequence="100"
        expand_variables="y"
        keep_evaluating="y">
            <send>
            stats.health = %1
            stats.mana = %2
            sip ()
            </send>
        </trigger>
    <trigger
        name="GainSipBalance"
        match="You may drink another health or mana elixir\.$"
        enabled="y"
        group="AutoSipper"
        regexp="y"
        send_to="14"
        sequence="100"
        expand_variables="y">
            <send>
            Note("Setting sip balance true.")
            balances.hm = "true"
            Note(balances.hm)
            </send>
        </trigger>

function sip ()
    
    Note("Entered sip function")
    
    if stats.health == nil then
        Note("stats.health is nil")
    end -- if
    
    local health = stats.health
    local mana = stats.mana
    local balance = balances.hm
        
    Note("Sip: set local variables")
    
    if health == nil then
        Note("health is nil")
    else
        Note("health is: " .. health)
        Note("mana is: " .. mana)
        Note("balances.hm is: " .. balance)
    end -- if
    
    if balance and health<2800 then
        Send("drink health")
        Note("drink health")
    elseif balance and mana<3100 then
        Send("drink mana")
        Note("drink mana")
    end -- if
    
    Note("After if")
    
end -- function sip
CODE
You may drink another health or mana elixir.
Setting sip balance true.
true
2000h, 3894m exd-
Entered sip function
Sip: set local variables
health is: 2000
mana is: 3894
balances.hm is: true
drink health
After if


Thanks for pointing out those details!
Trevize
QUOTE (Belus @ Aug 1 2009, 11:57 PM) *
Is there a way to store Lua variables to MUSH (ie make them global)?

Lua variables are global unless you declare local. If you mean serializing (storing Lua tables in MUSHclient variables so it keeps them between sessions) then yes, there are ways. This is the script I use to do that:

CODE
table.save = function (mushvar, luavar, luavarname)
  if type (luavar) == "table" then
    local var = luavarname .. " = {}\r\n"
    for k, v in pairs (luavar) do
      if type (v) == "boolean" or type (v) == "number" or type (v) == "string" then
        if type (k) == "string" then k = string.format ("%q", k) end
        local key = "[" .. k .. "]"
        local val
        if type (v) == "string" then val = string.format ("%q", v) else val = tostring (v) end
        var = var .. luavarname .. key .. " = " .. val .. "\r\n"
      elseif type (v) == "table" then
        local keyname = k
        if type (keyname) == "string" then keyname = string.format ("%q", keyname) end
        var = var .. table.save (false, luavar[k], luavarname .. "[" ..keyname .. "]")
      end -- if
    end -- for
    if mushvar then SetVariable (mushvar, var) else return var end
  end -- if
end -- func

table.load = function (name)
  if GetVariable (name) then
    loadstring (GetVariable (name)) ()
    return true
  end -- if
end -- func


All you have to do is call table.save and table.load. To call table.save, it takes three parameters.

1. A string with the MUSHclient variable name you want to save it as.
2. The lua table you want to save.
3. A string with the name of the lua table you want to save. (should look like 2, just surrounded in quotes)

To load, just call table.load with one parameter - a string with the name of the MUSHclient variable saved with table.save.

Example call:

CODE
-- ================
--  list generator
-- ================

listgen = {
  lists = {},

  -- the rest of the script here for listgen

  save = function ()
    table.save ("listgen", listgen.lists, "listgen.lists")
  end, -- func
  }

table.load ("listgen")


With the above, it will attempt to load upon startup, and can be saved with a call to listgen.save. It saves the table listgen.lists into the MUSHclient variable listgen.

QUOTE (Belus @ Aug 1 2009, 11:57 PM) *
Is "target" in my above examples a MUSH variable or is it only in the plugin? I don't see it come up as a variable in the Configuration window of MUSH.

A plugin variable is separate from the main world, in both Lua and MUSHclient vars. You can use GetPluginVariable in the main world or another plugin to get a MUSH var that's in a plugin or the world.

QUOTE (Belus @ Aug 1 2009, 11:57 PM) *
The plugin has <variables><variable name="target">rat</variable></variables> and I can update "target" with the alias in the first post, however if I try /Note("@target") in the command box it does not expand the variable.

You cannot expand MUSHclient variables on the command line. Only one aliases and triggers for the script box, and only in triggers in regex pattern matching. Instead, you should use Note (GetVariable ("target")). But as I said, since it's in a plugin, that won't work. You would have to do Note (GetPluginVariable ("pluginname", "target")), substituting pluginname with the ID of the plugin.
Belus
Thanks, Trevize. I've been dissecting your plugins in my attempts to figure this all out.

I had a lot of trouble using boolean variables in my triggers and aliases. MUSH didn't like variable = true, and Lua doesn't like variable = "true". I've settled on just using 1 and 0 to avoid the headache.

Do you happen to know a resource which can more thoroughly explain the send="12" option in triggers and aliases? Three years ago I found a table of where each number corresponded to, but it doesn't seem accurate anymore.

edit: Question about send="12" is answered two posts down.
Gorlasintan
QUOTE (Belus @ Aug 2 2009, 03:22 PM) *
Do you happen to know a resource which can more thoroughly explain the send="12" option in triggers and aliases? Three years ago I found a table of where each number corresponded to, but it doesn't seem accurate anymore.

This should be listed in the MUSH help files somewhere.
Belus
QUOTE (Gorlasintan @ Aug 2 2009, 01:39 PM) *
QUOTE (Belus @ Aug 2 2009, 03:22 PM) *
Do you happen to know a resource which can more thoroughly explain the send="12" option in triggers and aliases? Three years ago I found a table of where each number corresponded to, but it doesn't seem accurate anymore.
This should be listed in the MUSH help files somewhere.


The only place I've found it is in the "Edit Alias" help file which inconveniently just bullets out the options.
CODE
·     world (the MUD)
·     command (the command window)
·     output (directly to the output window, as a note to yourself)
·     status (to the status line)
·     notepad - new (create a new notepad window)
·     notepad - append (append to a notepad window)
·     log file (directly to the log file)
·     notepad - replace (replace an existing notepad window)
·     world - speedwalk delay (queue for delayed send at the speedwalk rate)
·     variable (set a variable, whose name you provide in the variable box)
·     execute (execute through normal command parser, so aliases, speedwalks etc. will be executed)
·     speedwalk (send to world after converting speedwalk string)
·     script (execute as a script command in the current scripting language)
·     world - immediate (to the MUD immediately, even if you are speedwalking)


edit: Found a different one which I assume is more up to date. It was in the GetTriggerOption help file
CODE
"0"    - send to MUD
"1"    - put in command window        
"2"    - display in output window    
"3"    - put in status line          
"4"    - new notepad                  
"5"    - append to notepad            
"6"    - put in log file              
"7"    - replace notepad              
"8"    - queue it                    
"9"    - set a variable              
"10"    - re-parse as command          
"11"    - send to MUD as speedwalk    
"12"    - send to script engine        
"13"    - send without queuing
"14"    - send to script engine - after omitting from output
Trevize
QUOTE (Belus @ Aug 2 2009, 04:22 PM) *
Thanks, Trevize. I've been dissecting your plugins in my attempts to figure this all out.

I had a lot of trouble using boolean variables in my triggers and aliases. MUSH didn't like variable = true, and Lua doesn't like variable = "true". I've settled on just using 1 and 0 to avoid the headache.

Any type of setting that would need true or false should be a Lua variable.

Also, instead of
CODE
if x == true then

you can, in Lua, use
CODE
if x then

since all values except false and nil are considered true.

Also note that 0 is true, not false, in Lua.

The only use I have for MUSHclient variables are for use in the trigger patterns, and serialized Lua variables that I want to persist between sessions.

If you -really- want to use MUSHclient variables and Lua variables for true or false, make a function like this:
CODE
istrue = function  (x)
  if x == true or x == "true" then
    return true
  else
    return false
  end -- if
end -- func

Then call if like this:
CODE
if istrue (combat) then

CODE
if istrue (GetVariable ("combat")) then

CODE
if istrue ("@combat") then
Trevize
QUOTE (Belus @ Aug 2 2009, 05:11 PM) *
QUOTE (Gorlasintan @ Aug 2 2009, 01:39 PM) *
QUOTE (Belus @ Aug 2 2009, 03:22 PM) *
Do you happen to know a resource which can more thoroughly explain the send="12" option in triggers and aliases? Three years ago I found a table of where each number corresponded to, but it doesn't seem accurate anymore.
This should be listed in the MUSH help files somewhere.


The only place I've found it is in the "Edit Alias" help file which inconveniently just bullets out the options.
CODE
·     world (the MUD)
·     command (the command window)
·     output (directly to the output window, as a note to yourself)
·     status (to the status line)
·     notepad - new (create a new notepad window)
·     notepad - append (append to a notepad window)
·     log file (directly to the log file)
·     notepad - replace (replace an existing notepad window)
·     world - speedwalk delay (queue for delayed send at the speedwalk rate)
·     variable (set a variable, whose name you provide in the variable box)
·     execute (execute through normal command parser, so aliases, speedwalks etc. will be executed)
·     speedwalk (send to world after converting speedwalk string)
·     script (execute as a script command in the current scripting language)
·     world - immediate (to the MUD immediately, even if you are speedwalking)


edit: Found a different one which I assume is more up to date. It was in the GetTriggerOption help file
CODE
"0"    - send to MUD
"1"    - put in command window        
"2"    - display in output window    
"3"    - put in status line          
"4"    - new notepad                  
"5"    - append to notepad            
"6"    - put in log file              
"7"    - replace notepad              
"8"    - queue it                    
"9"    - set a variable              
"10"    - re-parse as command          
"11"    - send to MUD as speedwalk    
"12"    - send to script engine        
"13"    - send without queuing
"14"    - send to script engine - after omitting from output


Better yet, MUSHclient comes with a Lua table with all that in it. smile.gif You just need to do sendto.script or whatever.

You don't have to make it, since it comes with it, but for reference here's what the table looks like:
CODE
sendto = {}
sendto.world = 0
sendto.command = 1
sendto.output = 2
sendto.status = 3
sendto.notepad = 4
sendto.notepadappend = 5
sendto.logfile = 6
sendto.notepadreplace = 7
sendto.commandqueue = 8
sendto.variable = 9
sendto.execute = 10
sendto.speedwalk = 11
sendto.script = 12
sendto.immediate = 13
sendto.scriptafteromit = 14
Belus
This is what I had:
CODE
    <trigger name="You_Drink" match="You take a drink from (?:a|an) \w+ vial\.$" enabled="y" group="AutoSipper" regexp="y" send_to="12" sequence="100" expand_variables="y">
            <send>
            if system.sipping then
                EnableTimer("Failsafe_Sipping", false)
                ResetTimer("Failsafe_Sipping")
                EnableTrigger("Lose_Sip_Balance", true)
                EnableTrigger("Confirm_Sip_Balance", true)
            else
                ColourNote("red", "black", "Did not expect to drink!")
                EnableTrigger("Lose_Sip_Balance", false)
                EnableTrigger("Confirm_Sip_Balance", false)
            end
            system.sipping = false
            </send>
        </trigger>

But MUSH would yell at me every time it fired because there were no quotes for system.sipping = false, even though Lua was happy with if system.sipping then

This seems to work just as well. Lua doesn't know any better and MUSH is happy to assign an integer without quotes.
CODE
    <trigger name="You_Drink" match="You take a drink from (?:a|an) \w+ vial\.$" enabled="y" group="AutoSipper" regexp="y" send_to="12" sequence="100" expand_variables="y">
            <send>
            if system.sipping == 1 then
                EnableTimer("Failsafe_Sipping", false)
                ResetTimer("Failsafe_Sipping")
                EnableTrigger("Lose_Sip_Balance", true)
                EnableTrigger("Confirm_Sip_Balance", true)
            else
                ColourNote("red", "black", "Did not expect to drink!")
                EnableTrigger("Lose_Sip_Balance", false)
                EnableTrigger("Confirm_Sip_Balance", false)
            end
            system.sipping = 0
            </send>
        </trigger>


edit: With that Lua table, are you saying that send_to="sendto.script" is valid?
Trevize
QUOTE (Belus @ Aug 2 2009, 07:47 PM) *
edit: With that Lua table, are you saying that send_to="sendto.script" is valid?

No, because it's in the XML. It'll work anywhere in the Lua script, though without quotes.
Belus
I'm attempting to add a couple macros to my system and I'd like them to call a Lua script. However, if the AcceleratorTo command is not commented out while installing the plugin, I get the following error in my function envenom.

-- AcceleratorTo ("Numpad0", envenom(aconite, curare, herb), 12)

CODE
function envenom(venom1, venom2, illusiontype)
    if system.debug == 1 then Note("Offense function envenom") end
    Send("secrete " .. venom1 .. " on dirk")
    Send("secrete " .. venom2 .. " on dirk")
    table.insert(dirkvenoms, 1, venom1)
    table.insert(dirkvenoms, 1, venom2)
    table.insert(illusions, 1, illusiontype)
end -- fuction envenom

And the error:
CODE
Offense function envenom
Run-time error
Plugin: Offense (called from world: Achaea)
Immediate execution
[string "Plugin"]:211: attempt to concatenate local 'venom1' (a nil value)
stack traceback:
        [string "Plugin"]:211: in function 'envenom'
        [string "Plugin"]:233: in main chunk
Error context in script:
207 : end -- function illusion
208 :
209 : function envenom(venom1, venom2, illusiontype)
210 :  if system.debug == 1 then Note("Offense function envenom") end
211*:  Send("secrete " .. venom1 .. " on dirk")
212 :  Send("secrete " .. venom2 .. " on dirk")
213 :  table.insert(dirkvenoms, 1, venom1)
214 :  table.insert(dirkvenoms, 1, venom2)
215 :  table.insert(illusions, 1, illusiontype)


I've tried putting both double quotes ", and single quotes ' around the function in the AcceleratorTo command without luck. But I don't think any quotes are neccessary based on the Mushclient help file, which uses
CODE
AcceleratorTo ("Ctrl+E", string.rep ('-', 60), sendto.output)  -- 60 hyphens in output window
as a Lua example

Additionally I get this error when using a previously loaded macro
CODE
Run-time error
World: Achaea
Immediate execution
[string "Accelerator: Numpad0"]:1: attempt to call global 'envenom' (a nil value)
stack traceback:
        [string "Accelerator: Numpad0"]:1: in main chunk


How can I get the macro to call the envenom function successfully?
Gorlasintan
I'm 99% sure you can't directly call a script from a macro. You need to set an alias to call the script, and then use the macro to call the alias.
Soludra
Gorlasintan: Well, you can call a script fine with AcceleratorTo, so you're wrong on that count. smile.gif Run this in the ctrl+I window, and then hit numpad-0 a few times, and 'hi' will appear on the screen for each time you hit numpad0:
CODE
AcceleratorTo ("Numpad0", "print('hi')", 12)



Belus: Your problem is that the arguments are evaluated before they're passed to AcceleratorTo. So envenom(aconite, curare, herb) is actually a function call of its own, and the result is what you're passing in its place to AcceleratorTo. That's obviously not what you want. This is what you want:

CODE
AcceleratorTo ("Numpad0", "envenom('aconite', 'curare', 'herb')", 12)


This sends the string (i.e. the literal text you typed) to AcceleratorTo, which is what AcceleratorTo wanted anyways: a string to parse and run later on. I also quoted 'aconite' and the others, because without quotes, it thinks they're variables, and attempts to pass their values in. Of course, since they're not variables in the first place, more than likely their values will be nil (nothing), which envenom() won't appreciate. Quoting them will, again, send what you typed as you typed it.

EDIT: Also, notice that I use single-quotes inside the double-quoted argument to AcceleratorTo. If I did "foo("bar")", Lua will think that "foo(" is the string, and it won't know what the humgii you mean by bar")" after that. Using different kinds of quotes is the only (easy) way to do it properly.
Gorlasintan
QUOTE (Soludra @ Aug 19 2009, 12:04 AM) *
Gorlasintan: Well, you can call a script fine with AcceleratorTo, so you're wrong on that count. smile.gif

There is something that you cannot use in MUSHclient macros!

I just don't remember what.
Soludra
QUOTE (Gorlasintan @ Aug 18 2009, 10:05 PM) *
There is something that you cannot use in MUSHclient macros!

I just don't remember what.


You are utterly and completely right when it comes to macros. However, these aren't macros. They're accelerators. Yes, they do the same thing, but I'm getting to that. Macros have their own section in the Configuration window, and can only be applied to a small handful of key combinations. Plus, they can only use basic commands/aliases. Accelerators can do much more. That 12 that's being passed to AcceleratorTo, it means "send to script". Macros are sent to world/execute, and that can't be changed. AcceleratorTo can send anywhere a trigger or alias could from their Send To dropdowns.
Gorlasintan
That seems unnecessarily complex.
Soludra
I agree.
Wyd
You can call scripts/aliases in macro's - you just need to set the script prefex, and then call it as a script.

For example, if you've got a function Garrote(), and your script prefex is "/", then "/Garrote()" will call the function. For aliases, you can use "/Execute("<alias here with arguments>")".
Soludra
QUOTE (Gorlasintan @ Aug 18 2009, 10:14 PM) *
That seems unnecessarily complex.

Belus
Since this thread has drifted into a repository for my questions, I just want to record here that this post about making a function to mimic %ismember() was increadibly helpful.
Belus
Hmmm...


I have a large (3500 line) external script file which is successfully loaded in Game -> Configure -> Scripts and the macros contained in it can call the plugin aliases I've set up to receive them. However I'm also trying to pass information from the plugin back to the script. Specifically I'm trying to use triggers/aliases to call external script functions and change the external script variables. Additionally I'd like to use external script variables to do the simpler logic within the plugin. However, the plugin is not aware of the script's existence (and maybe vice-versa).

I've tried using <include name="script.lua"/> without success.

My plugin is structured like:
CODE
<alias
  group="Offense_General"
  name="Targetting"
  match="^t (\w+)$"
  enabled="y"
  echo_alias="n"
  regexp="y"
  send_to="12"
  expand_variables="y">
    <send>
    SetVariable("target", "%1")
    targetting(%1)
  </send>
</alias>

<alias
  group="Offense_System"
  name="Dstab"
  match="^dstab$"
  enabled="y"
  echo_alias="n"
  regexp="y"
  send_to="12">
  <send>
    dstab(target.name)
  </send>
</alias>


And the external script file contains
CODE
function targetting(who)
    if system.debug == 1 then Note("ln3176: Entered function - targetting(" .. who .. ")") end
    if IsLogOpen() then WriteLog("offensive function called: targetting(" .. who .. ")") end
    if target.name ~= who then
        target.rebounding = 1
        target.sileris = 1
    end -- if new target
    target.name = who
    SendNoEcho("settarget t " .. who)
end -- function targetting

function dstab(name)
    if system.debug == 1 then Note("ln3350: Entered function - dstab(" .. name .. ")") end
    if IsLogOpen() then WriteLog("offensive function called: dstab(" .. name .. ")") end
    if target.rebounding == 0 then
        Send("dstab " .. name)
        EnableTrigger("Dstab", true)
    else
        Send("flay " .. name .. " rebounding")
    end -- if rebounding
end -- function dstab


But the result is:
CODE
Run-time error
Plugin: Belus (called from world: Achaea)
Immediate execution
[string "Alias: Targetting"]:2: attempt to call global 'targetting' (a nil value)
stack traceback:
        [string "Alias: Targetting"]:2: in main chunk

Run-time error
Plugin: Belus (called from world: Achaea)
Immediate execution
[string "Alias: Dstab"]:1: attempt to index global 'target' (a nil value)
stack traceback:
        [string "Alias: Dstab"]:1: in main chunk



edit: Why do I have pretty much every action going through an external script?
It allows me to call functions from the command line, something I don't think is possible if the script is part of the plugin.
Trevize
Misunderstood. Are you actually trying to include your MUSHclient script file in the plugin? It won't work like that.

QUOTE (Belus @ Aug 25 2009, 10:55 PM) *
edit: Why do I have pretty much every action going through an external script?

It allows me to call functions from the command line, something I don't think is possible if the script is part of the plugin.

It's not really an 'external' script. It's just stored in a different file, so it's easier to use. Your script file is loaded into the world, accessible by world aliases and triggers. A plugin can have its own script, but a plugin and world can't normally talk to each other, each is in its own 'space'. Here's an example of a script in a plugin:

CODE
<script>
<![CDATA[

ansicolor = function (fore, back)
  local bold = false
  local fore = tonumber (fore) or 7
  if fore >= 0 and fore <= 7 then
    fore = fore + 30
  elseif fore >= 8 and fore <= 15 then
    fore = fore + 22
    bold = true
  else
    fore = 37
  end -- if
  local back = tonumber (back) or 0
  if back > 0 and back <= 7 then
    back = back + 40
  else
    back = 40
  end -- if
  if not bold then
    return ANSI (0, fore, back)
  else
    return ANSI (0, fore, 1, back)
  end -- if
end -- func

prompt = {}
prompt.data = false
prompt.draw = function ()
  if prompt.data then
    for k,v in ipairs (prompt.data) do
      ColourTell (RGBColourToName (v.textcolour),
                  RGBColourToName (v.backcolour),
                  v.text)
    end -- for
  end -- if
  Note ("")
end -- func

]]>
</script>
Belus
QUOTE (Trevize @ Aug 25 2009, 08:02 PM) *
Misunderstood. Are you actually trying to include your MUSHclient script file in the plugin? It won't work like that.


I'd like to be able to access my functions and variables in the external script from the plugin, rather than putting all 3500 lines between the <script> </script> tags of the plugin.

One reason for this is that I can have multiple plugins work off the same variables, such as recovering balance, without having to have local triggers and variables.

edit: I'm just calling it the external script because it's the file referenced in Configuration -> Scripting -> Scripts

I read something about require(script.lua) in between the script tags, but couldn't get any iteration to work.
Trevize
QUOTE (Belus @ Aug 25 2009, 11:09 PM) *
QUOTE (Trevize @ Aug 25 2009, 08:02 PM) *
Misunderstood. Are you actually trying to include your MUSHclient script file in the plugin? It won't work like that.


I'd like to be able to access my functions and variables in the external script from the plugin, rather than putting all 3500 lines between the <script> </script> tags of the plugin.

One reason for this is that I can have multiple plugins work off the same variables, such as recovering balance, without having to have local triggers and variables.

edit: I'm just calling it the external script because it's the file referenced in Configuration -> Scripting -> Scripts

I read something about require(script.lua) in between the script tags, but couldn't get any iteration to work.

They will need to be either in your world, or in the plugin. One can't easily access the other, nor can multiple plugins access each other easily - the exception is MUSH variables. GetPluginVariable is useful there.

If you want two files for the plugin, make one with the <script> and </script> as well as the cdata, save it as a .xml file, then xml include that. But you can't have your script file and the plugin working in the same 'space'.
Belus
QUOTE (Trevize @ Aug 25 2009, 09:13 PM) *
If you want two files for the plugin, make one with the <script> and </script> as well as the cdata, save it as a .xml file, then xml include that. But you can't have your script file and the plugin working in the same 'space'.


That's not what I wanted to hear, but I understand.

Do you know a way to access plugin functions from the command line other than through aliases?
I could make a "-test function" alias to run simulated calls but that's getting really messy.
Trevize
QUOTE (Belus @ Aug 26 2009, 12:28 AM) *
That's not what I wanted to hear, but I understand.

Do you know a way to access plugin functions from the command line other than through aliases?
I could make a "-test function" alias to run simulated calls but that's getting really messy.

No. But you could make a single alias that can call functions in a plugin using CallPlugin. Set up a lua table to grab all plugin IDs and names and put them in a table of name=id pairs, then your alias can work like... runplugin <plugin> <function>.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.