Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ Making a table for spells

Making a table for spells

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  

Posted by Tiopon   USA  (71 posts)  Bio
Date Thu 12 Mar 2009 06:03 PM (UTC)
Message
Hi... me again... this time I decided to try to see if I could make things work more like the suggestions in the other post about variables, or at least begin to work towards that... the issue is that I'm trying to do some slightly odd things, I think, and I'm not sure exactly whether or not they're supported. Anyways, here's the code I've worked out so far... 3 triggers, and an alias. First the triggers.


<triggers>
  <trigger
   lines_to_match="3"
   match="\n\nYour aura is"
   multi_line="y"
   name="spell_stopper"
   regexp="y"
   send_to="12"
   sequence="40"
  >
  <send>
-- don't need to track inventories any more
EnableTrigger ("spell_line", false)
EnableTrigger ("spell_stopper", false)

-- in case no table yet
spell_table = spell_table or {}

table.sort (spell_table)
SetVariable ("spell_table", serialize.save ("spell_table"))</send>
  </trigger>
  <trigger
   match="([a-z]*)([\s]*)([a-z_\']*)([\s]*)([0-9]*)([\s]*)([a-z_\-]*)([\s]*)([a-zA-Z]*)"
   name="spell_line"
   regexp="y"
   send_to="12"
   sequence="50"
  >
  <send>
spell_table.%1 = {}
spell_table.%1.initials = "%1"
spell_table.%1.name = "%3"
spell_table.%1.time = %5
spell_table.%1.cost = "%7"
spell_table.%1.count = "%9"
</send>
  </trigger>
  <trigger
   enabled="y"
   group="Multi Line"
   lines_to_match="2"
   keep_evaluating="y"
   match="Abbr  Name                      Time Cost              Skill     \n\=\=\=\=\= \=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\= \=\=\=\= \=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\= \=\=\=\=\=\=\=\=\=\=\Z"
   multi_line="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
spell_table = {}
EnableTrigger ("spell_line", true)
EnableTrigger ("spell_stopper", true)
</send>
  </trigger>
</triggers>


And the alias:


<aliases>
  <alias
   match="spelltable"
   enabled="y"
   send_to="12"
   ignore_case="y"
   sequence="100"
  >
  <send>print ("Your spells are:")

for _, item in ipairs (spell_table) do
  print (item)
end -- for
</send>
  </alias>
</aliases>


Right now, I have this automatically serializing, so I can see that it's properly working... Basically, I have it match the top line of description for spells, then parsing each row, which goes in like this...
lowercase letters, lowercase letters with apostrophes and underscores, numbers, lowercase letters with hyphens, and upper and lowercase letters.

This part seems to work, according to my serialization... what I'd really like for it to do though, is to properly display (my alias is all sorts of screwed up), use the proper names instead of the initials, and if possible to look up my current variables for the count. The issue is that I have to run the variables through a cleaner to make them actually save properly, because they include apostrophes and other things that don't work right as MUSHclient variable names (or apparently lua table names, based on earlier errors, which is why I'm using the initials instead of the actual spell name for my tables). I'm using the following bit of code to actually set my variables:


<triggers>
  <trigger
   enabled="y"
   match="^(&gt; )?\* You think your ([a-z#_\' -]*) skill has improved\. \*"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>local SkillName = string.gsub("%2", "[ '#-]", "_")
SetVariable(SkillName .. "_skill", (GetVariable(SkillName .. "_skill") or 0) + 1)
Execute("skill " .. SkillName)
SetChanged (true)
Save("")</send>
  </trigger>
</triggers>


As you can see, it's doing a gsub to take the skill name (spells are a subset of skill, but they improve in the same display method) and take out any spaces, apostrophes, number signs, or hyphens, and turn them into underscores, which MUSHclient actually likes... the issue is, how do I tell lua that I'm actually giving it a variable name to save instead of just giving it a static part... When I tried to use SkillName or SpellName (I changed the gsub for the spell trigger) to do this, it just made that the entry for the table...

As well, my lookup isn't working. This is the most working it's been... it now shows the names of each of the tables and the raw data... here's an example:

w table: 0237F300

Problem is, when I tried to have it show item.name, for example, it doesn't give me anything at all... serialize lets me see that it is actually saving properly, it's just not retrieving it.

Was well I'd like for it to also look up the variable using either the var function or GetVariable client function and save that instead of the text, at least until I update them and get them to save into the table if I can get both of the upper two issues working properly. While having it display both the text and number wouldn't be a problem, I'd prefer to do that as a check later, so that I can have it make the skill display brightly if my counts are off... I care more about the actual number then the somewhat descriptive name for it. If I have the local variable thing working, I think I can probably figure this out, but currently it's not working properly.

Thanks... this is the start of a relatively major new tabling project for me. Serialization appears to be working wonderfully, and was especially useful for setting up the proper regexp strings to make the trigger match up.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #1 on Thu 12 Mar 2009 08:35 PM (UTC)
Message
Quote:

w table: 0237F300


My quick answer here is to tprint (table print) it, rather than print it.

eg.


require "tprint"
tprint (some_table)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #2 on Thu 12 Mar 2009 08:47 PM (UTC)

Amended on Thu 12 Mar 2009 09:14 PM (UTC) by Tiopon

Message
Changing the print to tprint (after requiring it) gives me the following now:
Error number: 0
Event:        Run-time error
Description:  [string "Alias: "]:3: bad argument #1 to 'ipairs' (table expected, got nil)
stack traceback:
    [C]: in function 'ipairs'
    [string "Alias: "]:3: in main chunk
Called by:    Immediate execution


Also, directly sending the table to it (with "/tprint (spell_table)") gives the following error:
Error number: 0
Event:        Run-time error
Description:  C:\Program Files (x86)\MUSHclient\lua\tprint.lua:30: bad argument #1 to 'pairs' (table expected, got nil)
stack traceback:
	[C]: in function 'pairs'
	C:\Program Files (x86)\MUSHclient\lua\tprint.lua:30: in function 'tprint'
	[string "Command line"]:1: in main chunk
Called by:    Immediate execution
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #3 on Thu 12 Mar 2009 09:14 PM (UTC)
Message
Sounds like the table doesn't exist right now. Try changing your alias to:



require "tprint"

spell_table = spell_table or {}

for _, item in ipairs (spell_table) do
  tprint (item)
end -- for

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #4 on Thu 12 Mar 2009 09:24 PM (UTC)
Message
Doesn't display anything, but the following gives me the full listing...

/print (serialize.save ("spell_table"))


I'm just trying to actually figure out how to pull out stuff from it. Here's the way that the serialized version looks:

spell_table = {}
  spell_table.yfb = {}
    spell_table.yfb.name = "yellow_fire_bolt"
    spell_table.yfb.cost = "yellow"
    spell_table.yfb.count = "Proficient"
    spell_table.yfb.initials = "yfb"
    spell_table.yfb.time = 2


So I know that it's there in the lua world... I'm just not sure of how to properly make it display.
Top

Posted by WillFa   USA  (525 posts)  Bio
Date Reply #5 on Thu 12 Mar 2009 11:23 PM (UTC)
Message

require 'var'
var.savedtable = serialize.save("spell_table")
--save it to a MC variable that gets written in the .mcl file.


tblvar = assert(loadstring(var.savedtable))()
--put the string into a lua variable.
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #6 on Thu 12 Mar 2009 11:31 PM (UTC)

Amended on Thu 12 Mar 2009 11:32 PM (UTC) by Tiopon

Message
Well, I did get it to save using this:
SetVariable ("spell_table", serialize.save ("spell_table"))
which is how I know that the trigger is working, but really I could care less about serialization at the moment, since it's dynamically generating the list every time I look at my spells. The issue is more, how can I pull/display data from the table first... If I can't display it, nothing else really matters. It's great that I can look at how cool it is in the variables page, but if I can't see it anywhere else...

The second major question is how can I set a lua variable based on changing a variable name (take my skill name and remove the possible "'# -" symbols and turn them into underscores instead), then update the table based on information pulled from that.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #7 on Fri 13 Mar 2009 12:05 AM (UTC)
Message
Quote:

for _, item in ipairs (spell_table) do
tprint (item)
end -- for


It should really be 'pairs (spell_table)' not 'ipairs (spell_table)'.

The "ipairs" function only iterates over items with numeric keys, and "yfb" is not a numeric key.

Not quite sure what you mean by your second question, but you can index into a table with a variable. eg.


spell = "yfb"

print (spell_table [spell].name)


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #8 on Fri 13 Mar 2009 12:17 AM (UTC)
Message
Spiffy, changing ipairs to pairs made the first work, or at least begin to display, to where I can now start playing with it...
Quote:
Your spells are:
"name"="yellow_fire_bolt"
"cost"="yellow"
"count"="Proficient"
"initials"="yfb"
"time"=2


I took the ipairs code off of the inventory parser in the FAQ (question 37), as that seemed the most similar to what I was trying to accomplish. That was the source of a lot of this, actually... Heh. Seems I do want print not tprint though, since I'm wanting to parse it after... Allows me to do this instead of having it display all the info:
Quote:
Your spells are:
yellow_fire_bolt yfb 2 yellow Proficient
so I can display just the initials or any other part, if it hits me.

Anyways, on to checking if the value saves properly in brackets... hopefully I should be able to send a new, more properly working script-set here in a few minutes...
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #9 on Fri 13 Mar 2009 12:27 AM (UTC)
Message
Okay... sort of works better... it will actually look up my variables now, but it won't save to the modified variable name... it's displaying like this now:
Your spells are:
yellow_fire_bolt yfb 2 yellow 215
which is exactly what I want, but the problem is that it's still saving to the initials... so I can only use this for the spells, which do have short alpha names, and not for the skills, which are more picky. Anyways, here's that trigger part as it stands:
<triggers>
  <trigger
   match="([a-z]*)([\s]*)([a-z_\']*)([\s]*)([0-9]*)([\s]*)([a-z_\-]*)([\s]*)([a-zA-Z]*)"
   name="spell_line"
   regexp="y"
   send_to="12"
   sequence="50"
  >
  <send>local SpellName = string.gsub("%3", "[ '#-]", "_")

spell_table.%1 = {}
spell_table.%1.initials = "%1"
spell_table.%1.name = "%3"
spell_table.%1.time = %5
spell_table.%1.cost = "%7"
spell_table.%1.count = GetVariable (SpellName .. "_skill")
</send>
  </trigger>
</triggers>


What I was trying to do was change the
spell_table.%1 = {}
into something like
spell_table.SpellName = {}
or
spell_table.[SpellName] = {}
or is this not so easy to do? The problem with the first is that it takes 'SpellName' as its name for each, and I end up with only a single spell saved. The second one gives me an error... Is there a way to force lua to take something as a lua variable instead of as pure text?
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #10 on Fri 13 Mar 2009 12:36 AM (UTC)
Message
Quote:

or
spell_table.[SpellName] = {}


You added a dot. The syntax is:


spell_table [SpellName] = {}



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #11 on Fri 13 Mar 2009 12:44 AM (UTC)
Message
Excellent! Sorry about that... I made a note to remove it, and forgot it when I was manually changing the trigger. So here's how it's saving now (which is how I wanted it to):
spell_table = {}
  spell_table.yellow_fire_bolt = {}
    spell_table.yellow_fire_bolt.name = "yellow_fire_bolt"
    spell_table.yellow_fire_bolt.cost = "yellow"
    spell_table.yellow_fire_bolt.count = "215"
    spell_table.yellow_fire_bolt.initials = "yfb"
    spell_table.yellow_fire_bolt.time = 2


Display works like this:
Your spells are:
yellow_fire_bolt yfb 2 yellow 215


And the code used to create this will be in the next message, so I don't end up making it more difficult for anyone who wants something similar to copy-paste. Thanks so much for all the work you put into MUSHclient. Been a happy user for 4-5 years now, I think, just never went into the actual scripting... was happy using the MUSHclient triggers/aliases in general.
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #12 on Fri 13 Mar 2009 01:02 AM (UTC)
Message
Actually, hit one last (I hope) snag... the fourth column actually does throw spaces in sometimes, but only in rare cases. Before, it would give me results like this:
Quote:
warm w 1 dim 44
when it should really be
Quote:
warm w 1 dim-red 44
or
Quote:
warm w 1 dim_red 44
(haven't decided which substitution I like more quite yet). Anyways, using a string substitution on it, it initially grabed this:
Quote:
warm w 1 dim_red___________ 44
which obviously wasn't right. What I really want it to do is only match when there's more then 1 space and turn it into nothing... the closest I got was this:
local SpellCost = string.gsub("%7", "  ", "")
SpellCost = string.gsub(SpellCost, " ", "_")
Which sometimes works, and gives me the following:
Quote:
warm w 1 dim_red_ 44
which is miles better then the original, missing words, or the second, with long bars, but still has the trailing underscore. Is there any easy way to grab spaces only if there's multiple of them?
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #13 on Fri 13 Mar 2009 03:43 AM (UTC)

Amended on Fri 13 Mar 2009 03:44 AM (UTC) by Nick Gammon

Message
Do you mean just trailing spaces? If so, anchor it, like this:


print ("'" .. (string.gsub ("nick gammon    ", "%s+$", "")) .. "'")  --> 'nick gammon'


However a pattern to match 2 or more spaces would be: %s%s+

That is, a space, followed by one or more spaces.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tiopon   USA  (71 posts)  Bio
Date Reply #14 on Fri 13 Mar 2009 05:32 AM (UTC)
Message
All trailing spaces is perfect... Thanks!

So here goes the final (until I decide to merge this with skills and/or compare for proper matchings, sometimes more then one improve happens and it detatches) version of my spell table triggers and alias. First, the triggers:
<triggers>
  <trigger
   lines_to_match="3"
   match="\n\nYour aura is"
   multi_line="y"
   name="spell_stopper"
   regexp="y"
   send_to="12"
   sequence="40"
  >
  <send>
-- don't need to track inventories any more
EnableTrigger ("spell_line", false)
EnableTrigger ("spell_stopper", false)

-- in case no table yet
spell_table = spell_table or {}

table.sort (spell_table)
SetVariable ("spell_table", serialize.save ("spell_table"))</send>
  </trigger>
  <trigger
   match="([a-z]*)([\s]*)([a-z_\']*)([\s]*)([0-9]*)([\s]*)([a-z_\ -]*)([\s]*)([a-zA-Z]*)"
   name="spell_line"
   regexp="y"
   send_to="12"
   sequence="50"
  >
  <send>local SpellName = string.gsub("%3", "[ '#-]", "_")
local SpellCost = string.gsub("%7", "%s+$", "")

spell_table[SpellName] = {}
spell_table[SpellName].initials = "%1"
spell_table[SpellName].name = "%3"
spell_table[SpellName].time = %5
spell_table[SpellName].cost = SpellCost
spell_table[SpellName].level = "%9"
spell_table[SpellName].count = GetVariable (SpellName .. "_skill")
</send>
  </trigger>
  <trigger
   enabled="y"
   group="Multi Line"
   lines_to_match="2"
   keep_evaluating="y"
   match="Abbr  Name                      Time Cost              Skill     \n\=\=\=\=\= \=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\= \=\=\=\= \=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\= \=\=\=\=\=\=\=\=\=\=\Z"
   multi_line="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
spell_table = {}
EnableTrigger ("spell_line", true)
EnableTrigger ("spell_stopper", true)
</send>
  </trigger>
</triggers>


And the alias to display, now giving both my counts and the description:
<aliases>
  <alias
   match="spelltable"
   enabled="y"
   send_to="12"
   ignore_case="y"
   sequence="100"
  >
  <send>print ("Your spells are:")

for _, item in pairs (spell_table) do
  print (item.initials, item.name, item.time, item.cost, item.count, item.level)
end -- for
</send>
  </alias>
</aliases>


Thanks so much for all the help getting this to actually work!
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


49,035 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.