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 ➜ New to Lua, Error

New to Lua, Error

Posting of new messages is disabled at present.

Refresh page


Posted by Crea3644   (13 posts)  Bio
Date Tue 06 Jun 2006 03:42 PM (UTC)
Message
Lol, That was easy, looked again and it popped right out at me,

Needed caps on Note and Send
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #1 on Tue 06 Jun 2006 03:52 PM (UTC)
Message
Ok So now I am having the problem of regardles of what my ZStr variable is set at the script is always ending with the Strength No Good note...

The Output I need to match on is:

Your character's base stats have been rerolled...
New Previous
Strength 9 14
Dexterity 12 13
Intelligence 15 15
Wisdom 15 13
Charisma 14 13
Constitution 17 14
Luck 13 13

So The Previous Column doesn't matter, What I need is for it to store the numbers in the New column, compare them to the numbers I preset that I am trying to get.
And either decide that Yes they match which goes ahead and alerts me or excutes a set of commands (something of that sort, undecided on that still) or Decides, Nope The New numbers are not sufficent and then sends the command Reroll to the game.

I believe the way I have it setup is that it checks each number one by one and as soon as one is not up to par it aborts the rest of the checks and goes to reroll with a single note of why it had to reroll

The only other problem of note is How to tell the script to run, I either have to match on the Luck Line, and run it from there, (not sure if I might run into complications with matching too much on that line) or else I figured maybe I could use a DoAfter and match on the "Your character's base stats have been rerolled..." line, just use the doafter to give the script/mud enough time to show the stats and get them stored.



Here is everyone I got put together so far..
(next post)


Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #2 on Tue 06 Jun 2006 04:53 PM (UTC)
Message
<triggers>
<trigger
enabled="y"
group="Stats"
match="Charisma * *"
name="Cha"
send_to="9"
sequence="100"
variable="Cha"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Constitution * *"
name="Con"
send_to="9"
sequence="100"
variable="Con"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Dexterity * *"
name="Dex"
send_to="9"
sequence="100"
variable="Dex"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Intelligence * *"
name="Int"
send_to="9"
sequence="100"
variable="Int"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Luck * *"
name="Lck"
send_to="9"
sequence="100"
variable="Lck"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Strength * *"
name="Str"
send_to="9"
sequence="100"
variable="Str"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Wisdom * *"
name="Wis"
send_to="9"
sequence="100"
variable="Wis"
>
<send>%1</send>
</trigger>
<trigger
enabled="y"
group="Stats"
match="Your character's base stats have been rerolled..."
name="Start"
script="ReRoll_Check"
sequence="100"
>
</trigger>
</triggers>



*** The trigger calling the script, yes I know is wrong and will be checking old data, but just using it to test the script part then will figure out how to call the script at the proper time after
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #3 on Tue 06 Jun 2006 04:53 PM (UTC)
Message
<aliases>
<alias
name="Wanted_Cha"
match="SetCha *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZCha"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Con"
match="SetCon *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZCon"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Dex"
match="SetDex *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZDex"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Int"
match="SetInt *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZInt"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Lck"
match="SetLck *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZLck"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Str"
match="SetStr *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZStr"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
<alias
name="Wanted_Wis"
match="SetWis *"
enabled="y"
echo_alias="y"
group="Stats"
variable="ZWis"
omit_from_command_history="y"
send_to="9"
ignore_case="y"
sequence="100"
>
<send>%1</send>
</alias>
</aliases>


<variables>
<variable name="Cha">10</variable>
<variable name="Con">12</variable>
<variable name="Dex">13</variable>
<variable name="Int">17</variable>
<variable name="Lck">13</variable>
<variable name="Str">15</variable>
<variable name="Wis">15</variable>
<variable name="ZCha">18</variable>
<variable name="ZCon">18</variable>
<variable name="ZDex">18</variable>
<variable name="ZInt">18</variable>
<variable name="ZLck">18</variable>
<variable name="ZStr">9</variable>
<variable name="ZWis">18</variable>
</variables>
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #4 on Tue 06 Jun 2006 04:54 PM (UTC)
Message
and of course the script::

function ReRoll_Check (thename, theoutput, thewildcards)

local Str
local ZStr
local Dex
local ZDex
local Int
local ZInt
local Wis
local ZWis
local Cha
local ZCha
local Con
local ZCon
local Lck
local ZLck

Str = GetVariable ("Str")
ZStr = GetVariable ("ZStr")
Dex = GetVariable ("Dex")
ZDex = GetVariable ("ZDex")
Int = GetVariable ("Int")
ZInt = GetVariable ("ZInt")
Wis = GetVariable ("Wis")
ZWis = GetVariable ("ZWis")
Cha = GetVariable ("Cha")
ZCha = GetVariable ("ZCha")
Con = GetVariable ("Con")
ZCon = GetVariable ("ZCon")
Lck = GetVariable ("Lck")
ZLck = GetVariable ("ZLck")
if ZStr == nil then
Note ("ZStr is not defined")
end
if ZDex == nil then
Note ("ZDex is not defined")
end
if ZInt == nil then
Note ("ZInt is not defined")
end
if ZWis == nil then
Note ("ZWis is not defined")
end
if ZCha == nil then
Note ("ZCha is not defined")
end
if ZCon == nil then
Note ("ZCon is not defined")
end
if ZLck == nil then
Note ("ZLck is not defined")
end

if Str == nil then
Note ("Str is not defined")
elseif Str >= ZStr then
Note "Strength is Good"
else
Note "Strength No Good"
Send "ReRoll"
return
end

if Dex == nil then
Note ("Dex is not defined")
elseif Dex >= ZDex then
Note "Dexterity is Good"
else
Note "Dexterity No Good"
Send "ReRoll"
return
end

if Int == nil then
Note ("Int is not defined")
elseif Int >= ZInt then
Note "Intelligence is Good"
else
Note "Intelligence No Good"
Send "ReRoll"
return
end

if Wis == nil then
Note ("Wis is not defined")
elseif Wis >= ZWis then
Note "Wisdom is Good"
else
Note "Wisdom No Good"
Send "ReRoll"
return
end

if Cha == nil then
Note ("Cha is not defined")
elseif Cha >= ZCha then
Note "Charisma is Good"
else
Note "Charisma No Good"
Send "ReRoll"
return
end

if Con == nil then
Note ("Con is not defined")
elseif Con >= ZCon then
Note "Constitution is Good"
else
Note "Constitution No Good"
Send "ReRoll"
return
end

if Lck == nil then
Note ("Lck is not defined")
elseif Lck >= ZLck then
Note "Luck is Good"
else
Note "Luck No Good"
Send "ReRoll"
return
end

end

Top

Posted by Ked   Russia  (524 posts)  Bio
Date Reply #5 on Tue 06 Jun 2006 05:02 PM (UTC)
Message
The way things like that are normally done. You need to figure out 3 portions of MUD's output: the openning line, the data chunk, the closing line.

You already have the openning line: "Your character's base stats have been rerolled..." or maybe the "New Previous" one.

The data chunk is comprised of the all the stat lines.

The closing line can be either a prompt, or if the stat lines always appear in the same order - you can use the last stat line as the closing one, or if there's always the same number of stat lines - you can keep count of how many stats have been processed and finish processing after you receive the last line.

With all that figured out (presuming that the closing line is actually a line that can be triggered), you make 3 triggers - one for each kind of line. Initially they are all disabled. When you send the "reroll" command, you enable the openning trigger. When that trigger fires it disables itself and enables the other two triggers. The data trigger fires repeatedly, saving stats somewhere. Finally, the closing trigger fires, disables both itself and the data trigger, and calls a function that does all the calculations.

That way you don't need a DoAfter - everything happens automatically, as text arrives from the MUD. Here's an example (the Luck line is used for closing):


<triggers>
<trigger
 name="start_roll"
 enabled="n"
 match="^\s*New\s+Previous\s*$"
 regexp="y"
 sequence="100"
 send_to="12"
><send>EnableTrigger("start_roll", false)
EnableTriggerGroup("CountRoll", true)
</send></trigger>
<trigger
 enabled="n"
 match="^\s*(Strength|Dexterity|Intelligence|Wisdom|Charisma|Constitution|Luck)\s+(\d+)\s+(\d+)\s*$"
 regexp="y"
 send_to="12"
 sequence="1"
 group="CountRoll"
><send>if stats == nil then stats = {} end
stats["%1"] = %2
</send></trigger>
<trigger
 enabled="n"
 match="^\s*Luck\s+\d+\s+\d+\s*$"
 regexp="y"
 group="CountRoll"
 sequence="2"
 send_to="12"
><send>EnableTriggerGroup("CountRoll", false)
res = true
for k,v in pairs(stats) do
    if v < tonumber(GetVariable("Z" .. k)) then
       Note(k .. " not good.")
       res = false
    end
end
if res == false then
    Send("reroll")
    EnableTrigger("start_roll", true)
end
</send></trigger>
</triggers>


The above requires you to rename your "Z" variables from abbreviated stat names to "Z" plus the name of the stat exactly as it appears in the MUD output, for example, for strenght: ZStrength, for luck: ZLuck, etc.
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #6 on Tue 06 Jun 2006 05:30 PM (UTC)
Message
Ok That makes sense, I don't understand a lot of the code in it though, seems pretty complex to my eyes..
althought reg expression I never really understood all that well

So I imported those 3 triggers, They turn on and off as they should
I created my Z Varibles with the full stat names and set each to 12 for testing duration.

Now my problem is I can't see where/how the middle trigger is supposed to store the New Column Stats,

and as for what the last trigger does other than turn the first one back on if the roll fails I am lost..

for k,v in pairs(stats) do
if v < tonumber(GetVariable("Z" .. k)) then
Note(k .. " not good.")
res = false
end

HUH :P

Kinda looks like a for, next statement to me

k,v in pairs?

lol I feel dumb right now :P
Top

Posted by Shadowfyr   USA  (1,788 posts)  Bio
Date Reply #7 on Tue 06 Jun 2006 05:48 PM (UTC)
Message
It is a sort of for-next.

Parsed into full english it would be:

For every case where "pairs(stats)" contained two values, place those values into "k" and "v", then if "v" < the numeric value of "k", send a Note that says that "k" is not good and set res = false.

Frankly, the version in a lot of other languages is a tad less confusing, since it explicitely implies a different type of process. For instance, in VB it would be something like:

'VB can't pull multiple variables from an array, like Lua,
'so we need to create a temporary variable that already
'has more than one. In theory it should work, in practice
'... I have never actually tried this.
type vk
  v int
  k string
end type

dim temp as vk

for each vk in pairs(stats)
  if ...
next


But the above doesn't work in VBScript, since you can't define "types", nor does it allow you to specify what "type" a variable must be. And I am not 100% sure the above would work anyway, even if it did. Lua though lets you pull multiple variables from an array, but it is a bit vague in its syntax with respect to making it clear that you are doing a "for each x in y" type command. Its one of those cases where imho, they could have traded a bit extra wordiness, to make what is actually going on a bit clearer.
Top

Posted by Ked   Russia  (524 posts)  Bio
Date Reply #8 on Tue 06 Jun 2006 05:59 PM (UTC)
Message
The middle trigger does:


if stats == nil then 
    stats = {} 
end
stats["%1"] = %2


It first checks whether the stats object is "nil", and if yes - assigns a table to it (stats = {}). Nil is Lua's value for "nothing". When the trigger first fires, there is no "stats" object in your script space, so we need to create it explicitely. Once it is created, it'll stay and will remain a table, so we only need to do this once.

Next we assign the contents of the second wildcard to the named index in the stats table. The name of the index is retrieved from the first wildcard. %1 (first wildcard) is quoted to make it a string, and %2 (second wildcard) is not - since it contains a number, that'll be substituted for %2 and Lua will store a numeric value in the table.

The last trigger does:


EnableTriggerGroup("CountRoll", false)
res = true
for k,v in pairs(stats) do
    if v < tonumber(GetVariable("Z" .. k)) then
       Note(k .. " not good.")
       res = false
    end
end
if res == false then
    Send("reroll")
    EnableTrigger("start_roll", true)
end


The first line disables this trigger and the middle one. Then we define a "res" object, which is a boolean type, assigned a true value.

Next if "for". This iterates over every key-value pair in the "stats" table that we created and assigned to in the middle trigger. Each stat["%1"] = %2 that we did there will result in a pair of "k" and "v" values, of which "k" will hold the corresponding "%1" and "v" - %2. So "k" will be repeatedly set to "Strength", "Wisdom", "Luck", etc. And "v" will take on numeric values of those stats.

For each pair we check whether the stat value (v) is less than the value stored in a Mushclient variable with name "Z"+k (so when parsing a Strength index the corresponding Mushclient variable's name will be "ZStrength"). Note that we use tonumber() to convert the variable's value to a number, since it is returned as a string.

If what we want (the Z value) is greater than what we have (the v value) then we set the "res" object, defined earlier outside the for loop to be true, to false and Note that this stat is subpar.

Once the for loop completes, we perform a check on the "res" object. If no stats were below target values then the "res = false" line was never called, thus "res" will remain true as we exit the loop. If it isn't true, then some stats were unsatisfactory, so we re-enable the first trigger and send the "reroll" command, starting over again.

Hope that helps.
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #9 on Tue 06 Jun 2006 06:22 PM (UTC)
Message
Ok I see the problem

\s*Luck\s+\d+\s+\d+\s*$ (the closing trigger)

is not matching.. and that is just gibberish to me :P



Matching on the Word Luck
Which can be preceeded by anything, blank space or characters

will have blank space after it

no idea what the + symbol means

and d is digit?
so any space or character, luck, space, number, space number, space, number, any space or character

So I dunno, looks like it should match to me, but I set each of the 3 triggers to a different color, and the luck part was not changing color, and also the opening trigger was not being re enabled
Top

Posted by Ked   Russia  (524 posts)  Bio
Date Reply #10 on Tue 06 Jun 2006 06:32 PM (UTC)
Message
To Shadowfyr:

That's actually not what pairs() does, if I understood you correctly. You seem to imply that "stats" is an array that may contain objects consisting of two parts, so whenever pairs() encounters such a "duplicate" object, it splits it and returns as two values.

In fact it's a hash table, so pairs() returns an iterator over that table, yielding an "index, table[index]" pair of values on each call.
Top

Posted by Ked   Russia  (524 posts)  Bio
Date Reply #11 on Tue 06 Jun 2006 06:38 PM (UTC)
Message
To Crea:

Hmm, the middle trigger should have a
keep_evaluating="y"
option among all the others. The last trigger isn't matching because it's set to match after the middle one and the middle one blocks it for the Luck line. Copy that option into the trigger, or just set it in the dialogue in Mushclient, and it should start working.

The trigger reads:

Match at beginning of line (^), followed by 0 or more spaces (\s*), followed by "Luck", followed by 1 or more spaces (\s+), followed by 1 or more digits (\d+), followed by 1 or more spaces (\s+), followed by 1 or more digits (\d+), followed by 0 or more spaces, followed by end of line ($).

I had to include the \s* at either end because you are not using the [code][\code] tags around your examples, which makes it impossible to tell the exact formatting :P
Top

Posted by Crea3644   (13 posts)  Bio
Date Reply #12 on Tue 06 Jun 2006 07:42 PM (UTC)
Message
nod nod, I should of clued into that keep evaluating, been awhile though.

Thank you, it works great now. I can't believe how small and simplistic it is compared to how I was trying to do it :)

comes with experince though, hehe
thanks again,
Top

Posted by Nick Gammon   Australia  (23,122 posts)  Bio   Forum Administrator
Date Reply #13 on Tue 06 Jun 2006 09:45 PM (UTC)

Amended on Tue 06 Jun 2006 09:46 PM (UTC) by Nick Gammon

Message

if stats == nil then 
    stats = {} 
end


This works, but what the Lua manual recommends is this shorter syntax:


stats = stats or {}


What this is saying is that if "stats" exists - that is, is not nil (or the boolean value "false"), then it remains itself, otherwise make it a new empty table.





for k,v in pairs(stats) do
if v < tonumber(GetVariable("Z" .. k)) then
Note(k .. " not good.")
res = false
end

HUH :P

Kinda looks like a for, next statement to me

k,v in pairs?


This technique of using "pairs" in a for loop is done a fair bit in Lua. A small code snippet will illustrate what is happening:


t =
 { name = "Nick",
   str = 16,
   dex = 14,
   agi = 17
 }

for k, v in pairs (t) do
  print (k, v)
end -- for loop

Output

str 16
name Nick
dex 14
agi 17



We use the variables k and v to indicate "key" and "value". Each table item has a key (the thing used to look up the value) and the corresponding value which is stored for that key.

Table are an integral part of Lua (even global variables are stored in a global variables table), so understanding how to iterate through a table is really useful.

I have done a post or two about Lua tables, see this one for a start:


http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6036


- Nick Gammon

www.gammon.com.au, www.mushclient.com
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.


38,984 views.

Posting of new messages is disabled at present.

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.