As a side note, once I see the code for those Triggers, EVERYTHING else that I use I will be able to convert myself. Most of the code I use is involved in those 2 triggers. If I can lick those, I'll be able to do whatever it is I need to do.
Good idea. Let's do a "before" and "after". First thing I'll do is format with a bit of indenting, and take them out of the XML format, so we can see "<" as itself rather than < (just to make it easier to read) ...
First trigger, reformatted in VBscript
world.setvariable "EXPTOLEVEL", "%1"
world.setvariable "XPNEW", "%1"
dim EXPTICK, TICK, TICKERNEW, TICKERBLANK, EXPTOLEVEL, EXPFROMLEVEL, count
dim XPOLD, XPNEW, XPDIFF
XPOLD = CInt(world.getvariable ("XPOLD"))
XPNEW = CInt(world.getvariable ("XPNEW"))
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
world.setvariable "XPOLD", XPNEW
world.setvariable "XPDIFF", XPDIFF
elseif XPDIFF > 0 then
world.setvariable "XPOLD", XPNEW
world.setvariable "XPDIFF", XPDIFF
end if
EXPTOLEVEL = CInt(world.getvariable ("EXPTOLEVEL"))
EXPFROMLEVEL = (100 - EXPTOLEVEL)
world.setvariable "EXPFROMLEVEL", EXPFROMLEVEL
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1 to CInt(world.getvariable ("EXPFROMLEVEL"))
TICKERBLANK = (TICKERBLANK + TICKERNEW)
next
for count = 1 to CInt(world.getvariable ("EXPTOLEVEL"))
EXPTICK = (EXPTICK + TICK)
next
dim space
space = " "
world.infoclear
world.InfoBackground "black"
world.InfoFont "Arial", 12, 1
world.infocolour "white"
world.info "("
if CInt(world.getvariable ("aaHP")) < 100 then
world.info space
world.infocolour "white"
world.info world.getvariable ("aaHP") & "%"
else
world.infocolour "white"
world.info world.getvariable ("aaHP") & "%"
end if
world.infocolour "red"
world.info "HP"
world.infocolour "white"
world.info "|"
if CInt(world.getvariable("aaMana")) < 100 then
world.info space
world.info world.getvariable ("aaMana")
else
world.info world.getvariable ("aaMana")
end if
world.info "%"
world.infocolour "olive"
world.info "Mana"
world.infocolour "white"
world.info "|"
if CInt(world.getvariable ("aaMove")) < 100 then
world.info space
world.info world.getvariable ("aaMove")
else
world.info world.getvariable ("aaMove")
end if
world.info "%"
world.infocolour "darkcyan"
world.info "Move"
world.infocolour "white"
world.info ") ("
world.infocolour "lightgreen"
world.info world.getvariable ("aaHunger")
world.infocolour "white"
world.info ") "
world.info "XTL: ["
if CInt(world.getvariable ("EXPTOLEVEL")) < 5 then
world.InfoColour "red"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 10 then
world.InfoColour "lawngreen"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 20 then
world.InfoColour "green"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 30 then
world.InfoColour "darkorange"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 40 then
world.InfoColour "orange"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 50 then
world.InfoColour "goldenrod"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 60 then
world.InfoColour "gold"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 70 then
world.InfoColour "yellow"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 80 then
world.InfoColour "blue"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
elseif CInt(world.getvariable ("EXPTOLEVEL")) < 90 then
world.InfoColour "mediumblue"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
else
world.infocolour "darkblue"
world.InfoFont "Arial", 12, 0
world.info EXPTICK
end if
world.infocolour "dimgray"
world.info TICKERBLANK
world.InfoColour "white"
world.InfoFont "Arial", 12, 1
world.info "] ("
world.infocolour "yellow"
if CInt(world.getvariable ("EXPTOLEVEL")) < 100 then
world.info space
world.info world.getvariable ("EXPTOLEVEL")
else
world.info world.getvariable ("EXPTOLEVEL")
end if
world.infocolour "white"
world.info "%) Last ("
world.infocolour "yellow"
world.info world.getvariable ("XPDIFF")
world.infocolour "white"
world.info "%) Level: "
world.infocolour "yellow"
if world.getvariable ("level2") = "subhero" then
world.info world.getvariable ("Level")
else
world.infocolour "red"
world.info world.getvariable ("level2") & world.getvariable ("level")
end if
world.EnableGroup "SHighlight", 0
The next thing I want to do is get rid of the "world." prefix, which is not necessary in VBscript or Lua, and just causes extra clutter and typing, and more importantly, fix the capitalisation of your script commands.
Whereas VBscript is not case-sensitive, Lua is. So things like "world.note" will not work, it must be "world.Note".
To save myself a certain amount of tedium, and possible errors, I wrote a small Lua script to do that for me ...
Script function capitalisation fixer
function fixscript (s)
fixed = string.gsub (s, "world%.([%a%u]+)", function (w)
for v in world do
if string.upper (v) == string.upper (w) then
return v;
end -- if
end -- for
return w
end) -- of gsub function
print (fixed)
end -- fixscript
What this does is a single call of string.gsub (global substitute) looking for a word consisting of upper or lower-case letters. When found it calls the anonymous function passing down the word.
The function scans all known functions (in the world table) and tries to match the word in your script, converted to upper case, to the known function, also converted to upper case. If a match is found it returns the correctly capitalised word. If not (ie. it is one of your script variables) it simply returns the same word.
To use this I call it, passing the entire script as a multi-line string. The results appear in the output window, where I can copy and paste them back into the script file.
The double brackets are important before and after, they indicate a multi-line quoted string.
ie.
fixscript [[
... your script here, copied and pasted ...
]]
VBscript with "world." removed and functions correctly capitalised
SetVariable "EXPTOLEVEL", "%1"
SetVariable "XPNEW", "%1"
dim EXPTICK, TICK, TICKERNEW, TICKERBLANK, EXPTOLEVEL, EXPFROMLEVEL, count
dim XPOLD, XPNEW, XPDIFF
XPOLD = CInt(GetVariable ("XPOLD"))
XPNEW = CInt(GetVariable ("XPNEW"))
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
SetVariable "XPOLD", XPNEW
SetVariable "XPDIFF", XPDIFF
elseif XPDIFF > 0 then
SetVariable "XPOLD", XPNEW
SetVariable "XPDIFF", XPDIFF
end if
EXPTOLEVEL = CInt(GetVariable ("EXPTOLEVEL"))
EXPFROMLEVEL = (100 - EXPTOLEVEL)
SetVariable "EXPFROMLEVEL", EXPFROMLEVEL
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1 to CInt(GetVariable ("EXPFROMLEVEL"))
TICKERBLANK = (TICKERBLANK + TICKERNEW)
next
for count = 1 to CInt(GetVariable ("EXPTOLEVEL"))
EXPTICK = (EXPTICK + TICK)
next
dim space
space = " "
InfoClear
InfoBackground "black"
InfoFont "Arial", 12, 1
InfoColour "white"
Info "("
if CInt(GetVariable ("aaHP")) < 100 then
Info space
InfoColour "white"
Info GetVariable ("aaHP") & "%"
else
InfoColour "white"
Info GetVariable ("aaHP") & "%"
end if
InfoColour "red"
Info "HP"
InfoColour "white"
Info "|"
if CInt(GetVariable("aaMana")) < 100 then
Info space
Info GetVariable ("aaMana")
else
Info GetVariable ("aaMana")
end if
Info "%"
InfoColour "olive"
Info "Mana"
InfoColour "white"
Info "|"
if CInt(GetVariable ("aaMove")) < 100 then
Info space
Info GetVariable ("aaMove")
else
Info GetVariable ("aaMove")
end if
Info "%"
InfoColour "darkcyan"
Info "Move"
InfoColour "white"
Info ") ("
InfoColour "lightgreen"
Info GetVariable ("aaHunger")
InfoColour "white"
Info ") "
Info "XTL: ["
if CInt(GetVariable ("EXPTOLEVEL")) < 5 then
InfoColour "red"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 10 then
InfoColour "lawngreen"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 20 then
InfoColour "green"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 30 then
InfoColour "darkorange"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 40 then
InfoColour "orange"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 50 then
InfoColour "goldenrod"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 60 then
InfoColour "gold"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 70 then
InfoColour "yellow"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 80 then
InfoColour "blue"
InfoFont "Arial", 12, 0
Info EXPTICK
elseif CInt(GetVariable ("EXPTOLEVEL")) < 90 then
InfoColour "mediumblue"
InfoFont "Arial", 12, 0
Info EXPTICK
else
InfoColour "darkblue"
InfoFont "Arial", 12, 0
Info EXPTICK
end if
InfoColour "dimgray"
Info TICKERBLANK
InfoColour "white"
InfoFont "Arial", 12, 1
Info "] ("
InfoColour "yellow"
if CInt(GetVariable ("EXPTOLEVEL")) < 100 then
Info space
Info GetVariable ("EXPTOLEVEL")
else
Info GetVariable ("EXPTOLEVEL")
end if
InfoColour "white"
Info "%) Last ("
InfoColour "yellow"
Info GetVariable ("XPDIFF")
InfoColour "white"
Info "%) Level: "
InfoColour "yellow"
if GetVariable ("level2") = "subhero" then
Info GetVariable ("Level")
else
InfoColour "red"
Info GetVariable ("level2") & GetVariable ("level")
end if
EnableGroup "SHighlight", 0
Now, time to start doing it in Lua. The major things to change now are:
Function calls need to be in parenthese (like Jscript), so that:
SetVariable "XPOLD", XPNEW
becomes
SetVariable ("XPOLD", XPNEW)
I did a regular-expression to do that in my editor, and then highlighted the individual lines (or batches of lines).
You don't declare variables in Lua, so the "dim" lines went away.
CInt (convert to integer) becomes "tonumber", which does the same thing. A quick find-and-replace fixed that.
"end if" is simply "end". I did a find-and-replace to make it "end -- if" - the hyphens are a comment, and the comment makes it more obvious what we are ending.
For loops have a slightly different syntax.
I changed, for example:
for count = 1 to tonumber (GetVariable ("EXPFROMLEVEL"))
...
next
to
for count = 1, tonumber (GetVariable ("EXPFROMLEVEL")) do
...
end -- for
String concatenation is done with ".." rather than "&"
eg..
Info (GetVariable ("aaHP") & "%")
becomes:
Info (GetVariable ("aaHP") .. "%")
The equality test is "==" not "=" (like in JScript or C) so for example:
if GetVariable ("level2") = "subhero" then
becomes:
if GetVariable ("level2") == "subhero" then
Lua version - compiles without errors ...
SetVariable ("EXPTOLEVEL", "%1")
SetVariable ("XPNEW", "%1")
XPOLD = tonumber (GetVariable ("XPOLD"))
XPNEW = tonumber (GetVariable ("XPNEW"))
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
SetVariable ("XPOLD", XPNEW)
SetVariable ("XPDIFF", XPDIFF)
elseif XPDIFF > 0 then
SetVariable ("XPOLD", XPNEW)
SetVariable ("XPDIFF", XPDIFF)
end -- if
EXPTOLEVEL = tonumber (GetVariable ("EXPTOLEVEL"))
EXPFROMLEVEL = (100 - EXPTOLEVEL)
SetVariable ("EXPFROMLEVEL", EXPFROMLEVEL)
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1, tonumber (GetVariable ("EXPFROMLEVEL")) do
TICKERBLANK = (TICKERBLANK + TICKERNEW)
end -- for
for count = 1, tonumber (GetVariable ("EXPTOLEVEL")) do
EXPTICK = (EXPTICK + TICK)
end -- for
space = " "
InfoClear ()
InfoBackground ("black")
InfoFont ("Arial", 12, 1)
InfoColour ("white")
Info ("(")
if tonumber (GetVariable ("aaHP")) < 100 then
Info (space)
InfoColour ("white")
Info (GetVariable ("aaHP") .. "%")
else
InfoColour ("white")
Info (GetVariable ("aaHP") .. "%")
end -- if
InfoColour ("red")
Info ("HP")
InfoColour ("white")
Info ("|")
if tonumber (GetVariable("aaMana")) < 100 then
Info (space)
Info (GetVariable ("aaMana"))
else
Info (GetVariable ("aaMana"))
end -- if
Info ("%")
InfoColour ("olive")
Info ("Mana")
InfoColour ("white")
Info ("|" )
if tonumber (GetVariable ("aaMove")) < 100 then
Info (space)
Info (GetVariable ("aaMove"))
else
Info (GetVariable ("aaMove"))
end -- if
Info ("%")
InfoColour ("darkcyan")
Info ("Move")
InfoColour ("white")
Info (") (")
InfoColour ("lightgreen")
Info (GetVariable ("aaHunger"))
InfoColour ("white")
Info (") ")
Info ("XTL: [")
if tonumber (GetVariable ("EXPTOLEVEL")) < 5 then
InfoColour ("red")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 10 then
InfoColour ("lawngreen")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 20 then
InfoColour ("green")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 30 then
InfoColour ("darkorange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 40 then
InfoColour ("orange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 50 then
InfoColour ("goldenrod")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 60 then
InfoColour ("gold")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 70 then
InfoColour ("yellow")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 80 then
InfoColour ("blue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 90 then
InfoColour ("mediumblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
else
InfoColour ("darkblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
end -- if
InfoColour ("dimgray")
Info (TICKERBLANK)
InfoColour ("white")
InfoFont ("Arial", 12, 1)
Info ("] (" )
InfoColour ("yellow" )
if tonumber (GetVariable ("EXPTOLEVEL")) < 100 then
Info (space)
Info (GetVariable ("EXPTOLEVEL"))
else
Info (GetVariable ("EXPTOLEVEL"))
end -- if
InfoColour ("white")
Info ("%) Last (" )
InfoColour ("yellow")
Info (GetVariable ("XPDIFF"))
InfoColour ("white")
Info ("%) Level: ")
InfoColour ("yellow")
if GetVariable ("level2") == "subhero" then
Info (GetVariable ("Level"))
else
InfoColour ("red")
Info (GetVariable ("level2") .. GetVariable ("level"))
end -- if
EnableGroup ("SHighlight", 0)
Note, there are still run-time problems, see the next post.
Having changed the above I now got runtime errors. The distinction is that Lua first does a syntax check, and then if that is OK, it actually attempts to run the code.
Things like bad arithmetic only show up at runtime, as Lua has untyped variables. For example:
b = "x"
a = b + 2
This is only a runtime error, as it doesn't know at compile time that you will attempt to add 2 to a string.
The first errors I got were "attempting to do arithmetic on a nil value", caused by the lines:
To work around that, I used a Lua trick of using the short-circuit evaluation of an "or" ...
XPOLD = tonumber (GetVariable ("XPOLD")) or 0
XPNEW = tonumber (GetVariable ("XPNEW")) or 0
What this does is take the variable, however if it is not present (ie. nil) then it substitutes zero.
I got an error on this line:
EXPTICK = (EXPTICK + TICK)
Again, for string concatenation you need ".." and not "+".
EXPTICK = (EXPTICK .. TICK)
I had a few problems with "doing arithmetic on nil values", principally caused by missing variables. This might not be an issue for you, if the variables exist in advance, but a workaround is something like this:
Change:
if tonumber (GetVariable ("aaHP")) < 100 then
to:
if tonumber (GetVariable ("aaHP")) or 0 < 100 then
Again, this substitutes zero if the variable doesn't exist.
Similarly, near the bottom:
Change:
Info (GetVariable ("level2") .. GetVariable ("level"))
to:
Info ((GetVariable ("level2") or "") .. (GetVariable ("level") or ""))
Below is the script converted to Lua, which compiles and runs OK (I'm not sure about all the figures, I think I need some more variables for it to work perfectly) ...
Lua version - compiles and runs ...
SetVariable ("EXPTOLEVEL", "%1")
SetVariable ("XPNEW", "%1")
XPOLD = tonumber (GetVariable ("XPOLD")) or 0
XPNEW = tonumber (GetVariable ("XPNEW")) or 0
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
SetVariable ("XPOLD", XPNEW)
SetVariable ("XPDIFF", XPDIFF)
elseif XPDIFF > 0 then
SetVariable ("XPOLD", XPNEW)
SetVariable ("XPDIFF", XPDIFF)
end -- if
EXPTOLEVEL = tonumber (GetVariable ("EXPTOLEVEL"))
EXPFROMLEVEL = (100 - EXPTOLEVEL)
SetVariable ("EXPFROMLEVEL", EXPFROMLEVEL)
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1, tonumber (GetVariable ("EXPFROMLEVEL")) do
TICKERBLANK = (TICKERBLANK .. TICKERNEW)
end -- for
for count = 1, tonumber (GetVariable ("EXPTOLEVEL")) do
EXPTICK = (EXPTICK .. TICK)
end -- for
space = " "
InfoClear ()
InfoBackground ("black")
InfoFont ("Arial", 12, 1)
InfoColour ("white")
Info ("(")
if tonumber (GetVariable ("aaHP")) or 0 < 100 then
Info (space)
InfoColour ("white")
Info (GetVariable ("aaHP") or "" .. "%")
else
InfoColour ("white")
Info (GetVariable ("aaHP") or "" .. "%")
end -- if
InfoColour ("red")
Info ("HP")
InfoColour ("white")
Info ("|")
if tonumber (GetVariable("aaMana")) or 0 < 100 then
Info (space)
Info (GetVariable ("aaMana"))
else
Info (GetVariable ("aaMana"))
end -- if
Info ("%")
InfoColour ("olive")
Info ("Mana")
InfoColour ("white")
Info ("|" )
if tonumber (GetVariable ("aaMove")) or 0 < 100 then
Info (space)
Info (GetVariable ("aaMove"))
else
Info (GetVariable ("aaMove"))
end -- if
Info ("%")
InfoColour ("darkcyan")
Info ("Move")
InfoColour ("white")
Info (") (")
InfoColour ("lightgreen")
Info (GetVariable ("aaHunger"))
InfoColour ("white")
Info (") ")
Info ("XTL: [")
if tonumber (GetVariable ("EXPTOLEVEL")) < 5 then
InfoColour ("red")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 10 then
InfoColour ("lawngreen")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 20 then
InfoColour ("green")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 30 then
InfoColour ("darkorange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 40 then
InfoColour ("orange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 50 then
InfoColour ("goldenrod")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 60 then
InfoColour ("gold")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 70 then
InfoColour ("yellow")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 80 then
InfoColour ("blue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (GetVariable ("EXPTOLEVEL")) < 90 then
InfoColour ("mediumblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
else
InfoColour ("darkblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
end -- if
InfoColour ("dimgray")
Info (TICKERBLANK)
InfoColour ("white")
InfoFont ("Arial", 12, 1)
Info ("] (" )
InfoColour ("yellow" )
if tonumber (GetVariable ("EXPTOLEVEL")) < 100 then
Info (space)
Info (GetVariable ("EXPTOLEVEL"))
else
Info (GetVariable ("EXPTOLEVEL"))
end -- if
InfoColour ("white")
Info ("%) Last (" )
InfoColour ("yellow")
Info (GetVariable ("XPDIFF"))
InfoColour ("white")
Info ("%) Level: ")
InfoColour ("yellow")
if GetVariable ("level2") == "subhero" then
Info (GetVariable ("Level"))
else
InfoColour ("red")
Info ((GetVariable ("level2") or "") .. (GetVariable ("level") or ""))
end -- if
EnableGroup ("SHighlight", 0)
... let's change all GetVariable/SetVariable to use the var idea ...
var.EXPTOLEVEL = "%1"
var.XPNEW = "%1"
XPOLD = tonumber (var.XPOLD) or 0
XPNEW = tonumber (var.XPNEW) or 0
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
elseif XPDIFF > 0 then
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
end -- if
EXPTOLEVEL = tonumber (var.EXPTOLEVEL)
EXPFROMLEVEL = (100 - EXPTOLEVEL)
var.EXPFROMLEVEL = EXPFROMLEVEL
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1, tonumber (var.EXPFROMLEVEL) do
TICKERBLANK = (TICKERBLANK .. TICKERNEW)
end -- for
for count = 1, tonumber (var.EXPTOLEVEL) do
EXPTICK = (EXPTICK .. TICK)
end -- for
space = " "
InfoClear ()
InfoBackground ("black")
InfoFont ("Arial", 12, 1)
InfoColour ("white")
Info ("(")
if tonumber (var.aaHP) or 0 < 100 then
Info (space)
InfoColour ("white")
Info (var.aaHP or "" .. "%")
else
InfoColour ("white")
Info (var.aaHP or "" .. "%")
end -- if
InfoColour ("red")
Info ("HP")
InfoColour ("white")
Info ("|")
if tonumber (var.aaMana) or 0 < 100 then
Info (space)
Info (var.aaMana)
else
Info (var.aaMana)
end -- if
Info ("%")
InfoColour ("olive")
Info ("Mana")
InfoColour ("white")
Info ("|" )
if tonumber (var.aaMove) or 0 < 100 then
Info (space)
Info (var.aaMove)
else
Info (var.aaMove)
end -- if
Info ("%")
InfoColour ("darkcyan")
Info ("Move")
InfoColour ("white")
Info (") (")
InfoColour ("lightgreen")
Info (var.aaHunger)
InfoColour ("white")
Info (") ")
Info ("XTL: [")
if tonumber (var.EXPTOLEVEL) < 5 then
InfoColour ("red")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 10 then
InfoColour ("lawngreen")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 20 then
InfoColour ("green")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 30 then
InfoColour ("darkorange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 40 then
InfoColour ("orange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 50 then
InfoColour ("goldenrod")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 60 then
InfoColour ("gold")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 70 then
InfoColour ("yellow")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 80 then
InfoColour ("blue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif tonumber (var.EXPTOLEVEL) < 90 then
InfoColour ("mediumblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
else
InfoColour ("darkblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
end -- if
InfoColour ("dimgray")
Info (TICKERBLANK)
InfoColour ("white")
InfoFont ("Arial", 12, 1)
Info ("] (" )
InfoColour ("yellow" )
if tonumber (var.EXPTOLEVEL) < 100 then
Info (space)
Info (var.EXPTOLEVEL)
else
Info (var.EXPTOLEVEL)
end -- if
InfoColour ("white")
Info ("%) Last (" )
InfoColour ("yellow")
Info (var.XPDIFF)
InfoColour ("white")
Info ("%) Level: ")
InfoColour ("yellow")
if var.level2 == "subhero" then
Info (var.Level)
else
InfoColour ("red")
Info ((var.level2 or "") .. (var.level or ""))
end -- if
EnableGroup ("SHighlight", 0)
This looks a bit less cluttered. It relies upon this being in your main script file:
var = {} -- variables table
-- warning - parenthesis must be on same line as setmetatable
setmetatable (var,
{
-- called to access an entry
__index =
function (t, name)
return GetVariable (name)
end;
-- called to change or delete an entry
__newindex =
function (t, name, val)
local result
if val == nil then -- nil deletes it
result = DeleteVariable (name)
else
result = SetVariable (name, tostring (val))
end
-- warn if they are using bad variable names
if result == error_code.eInvalidObjectLabel then
error ("Bad variable name '" .. name .. "'")
end
end;
})
We still have a lot of "tonumber" in it. Perhaps a rejig of the "var" table will eliminate them?
Let's give ourselves three pseudo-tables.
var - for straight variables of any type
nvar - for numeric variables.
Getting a variable from this table will automatically convert it to a number, and substitute zero if not there.
svar - for string variables.
Getting a variable from this table will automatically substitute an empty string if the variable is not there.
Here is the code for the new tables (put that in your global script file) ...
var = {} -- variables table
nvar = {} -- number variables table
svar = {} -- string variables table
-- function called to change variables
function changevar (t, name, val)
local result
if val == nil then -- nil deletes it
result = DeleteVariable (name)
else
result = SetVariable (name, tostring (val))
end
-- warn if they are using bad variable names
if result == error_code.eInvalidObjectLabel then
error ("Bad variable name '" .. name .. "'")
end
end -- function changevar
setmetatable (var,
{
__index =
function (t, name)
return GetVariable (name)
end;
__newindex = changevar;
}
)
setmetatable (nvar,
{
__index =
function (t, name)
return tonumber (GetVariable (name)) or 0
end;
__newindex = changevar;
}
)
setmetatable (svar,
{
__index =
function (t, name)
return GetVariable (name) or ""
end;
__newindex = changevar;
}
)
Now we can get rid of all the "tonumber" references in the script, and the "or 0" stuff which was in case the variable did not exist ...
Lua script using nvar and svar for variable access
var.EXPTOLEVEL = "%1"
var.XPNEW = "%1"
XPOLD = nvar.XPOLD
XPNEW = nvar.XPNEW
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
elseif XPDIFF > 0 then
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
end -- if
EXPTOLEVEL = nvar.EXPTOLEVEL
EXPFROMLEVEL = (100 - EXPTOLEVEL)
var.EXPFROMLEVEL = EXPFROMLEVEL
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
for count = 1, nvar.EXPFROMLEVEL do
TICKERBLANK = (TICKERBLANK .. TICKERNEW)
end -- for
for count = 1, nvar.EXPTOLEVEL do
EXPTICK = (EXPTICK .. TICK)
end -- for
space = " "
InfoClear ()
InfoBackground ("black")
InfoFont ("Arial", 12, 1)
InfoColour ("white")
Info ("(")
if nvar.aaHP < 100 then
Info (space)
InfoColour ("white")
Info (svar.aaHP .. "%")
else
InfoColour ("white")
Info (svar.aaHP .. "%")
end -- if
InfoColour ("red")
Info ("HP")
InfoColour ("white")
Info ("|")
if nvar.aaMana < 100 then
Info (space)
Info (svar.aaMana)
else
Info (svar.aaMana)
end -- if
Info ("%")
InfoColour ("olive")
Info ("Mana")
InfoColour ("white")
Info ("|" )
if nvar.aaMove < 100 then
Info (space)
Info (svar.aaMove)
else
Info (svar.aaMove)
end -- if
Info ("%")
InfoColour ("darkcyan")
Info ("Move")
InfoColour ("white")
Info (") (")
InfoColour ("lightgreen")
Info (svar.aaHunger)
InfoColour ("white")
Info (") ")
Info ("XTL: [")
if nvar.EXPTOLEVEL < 5 then
InfoColour ("red")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif nvar.EXPTOLEVEL < 10 then
InfoColour ("lawngreen")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif nvar.EXPTOLEVEL < 20 then
InfoColour ("green")
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
elseif nvar.EXPTOLEVEL < 30 then
InfoColour ("darkorange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 40 then
InfoColour ("orange")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 50 then
InfoColour ("goldenrod")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 60 then
InfoColour ("gold")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 70 then
InfoColour ("yellow")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 80 then
InfoColour ("blue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
elseif nvar.EXPTOLEVEL < 90 then
InfoColour ("mediumblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
else
InfoColour ("darkblue")
InfoFont ("Arial", 12, 0)
Info (EXPTICK)
end -- if
InfoColour ("dimgray")
Info (TICKERBLANK)
InfoColour ("white")
InfoFont ("Arial", 12, 1)
Info ("] (" )
InfoColour ("yellow" )
if nvar.EXPTOLEVEL < 100 then
Info (space)
Info (svar.EXPTOLEVEL)
else
Info (svar.EXPTOLEVEL)
end -- if
InfoColour ("white")
Info ("%) Last (" )
InfoColour ("yellow")
Info (svar.XPDIFF)
InfoColour ("white")
Info ("%) Level: ")
InfoColour ("yellow")
if svar.level2 == "subhero" then
Info (svar.Level)
else
InfoColour ("red")
Info (svar.level2 .. svar.level)
end -- if
EnableGroup ("SHighlight", 0)
Finally let's do a bit more tidying up. One thing you do a lot is use InfoColour followed by Info. We can make a local function to do that (infoct), thus saving typing. Also we can use string.rep to make a repeated string (for your bars).
Final Lua version
do
local function infoct (c, t)
assert (c and t, "Info Colour and text must be specified")
InfoColour (c)
Info (t)
end -- function infoct
var.EXPTOLEVEL = "%1"
var.XPNEW = "%1"
XPOLD = nvar.XPOLD
XPNEW = nvar.XPNEW
XPDIFF = (XPOLD - XPNEW)
if XPDIFF < 0 then
XPDIFF = (XPDIFF + 100)
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
elseif XPDIFF > 0 then
var.XPOLD = XPNEW
var.XPDIFF = XPDIFF
end -- if
EXPTOLEVEL = nvar.EXPTOLEVEL
EXPFROMLEVEL = (100 - EXPTOLEVEL)
var.EXPFROMLEVEL = EXPFROMLEVEL
TICKERNEW = "|"
TICKERBLANK = ""
TICK = "|"
EXPTICK = ""
TICKERBLANK = string.rep (TICKERNEW, nvar.EXPFROMLEVEL)
EXPTICK = string.rep (TICK, nvar.EXPTOLEVEL)
space = " "
InfoClear ()
InfoBackground ("black")
InfoFont ("Arial", 12, 1)
-- ---------- HP ---------------
infoct ("white", "(")
if nvar.aaHP < 100 then
Info (space)
end -- if
Info (svar.aaHP .. "%")
infoct ("red", "HP")
infoct ("white", "|")
-- ---------- Mana ---------------
if nvar.aaMana < 100 then
Info (space)
end -- if
Info (svar.aaMana .. "%")
infoct ("olive", "Mana")
infoct ("white", "|")
-- ---------- Move ---------------
if nvar.aaMove < 100 then
Info (space)
end -- if
Info (svar.aaMove .. "%")
infoct ("darkcyan", "Move")
infoct ("white", ") (")
infoct ("lightgreen", svar.aaHunger)
-- ---------- XTL ---------------
infoct ("white", ") XTL: [")
if nvar.EXPTOLEVEL < 5 then
InfoColour ("red")
elseif nvar.EXPTOLEVEL < 10 then
InfoColour ("lawngreen")
elseif nvar.EXPTOLEVEL < 20 then
InfoColour ("green")
elseif nvar.EXPTOLEVEL < 30 then
InfoColour ("darkorange")
elseif nvar.EXPTOLEVEL < 40 then
InfoColour ("orange")
elseif nvar.EXPTOLEVEL < 50 then
InfoColour ("goldenrod")
elseif nvar.EXPTOLEVEL < 60 then
InfoColour ("gold")
elseif nvar.EXPTOLEVEL < 70 then
InfoColour ("yellow")
elseif nvar.EXPTOLEVEL < 80 then
InfoColour ("blue")
elseif nvar.EXPTOLEVEL < 90 then
InfoColour ("mediumblue")
else
InfoColour ("darkblue")
end -- if
InfoFont ("Arial", 12, 0)
Info ( EXPTICK)
infoct ("dimgray", TICKERBLANK)
InfoFont ("Arial", 12, 1)
infoct ("white", "] (" )
InfoColour ("yellow" )
if nvar.EXPTOLEVEL < 100 then
Info (space)
end -- if
Info (svar.EXPTOLEVEL)
infoct ("white", "%) Last (" )
infoct ("yellow", svar.XPDIFF)
infoct ("white", "%) Level: ")
InfoColour ("yellow")
if svar.level2 == "subhero" then
Info (svar.Level)
else
InfoColour ("red")
Info (svar.level2 .. svar.level)
end -- if
EnableGroup ("SHighlight", 0)
end -- do
"You don't declare variables in Lua, so the "dim" lines went away."
You don't have to in VBScript or most others either. It is still done by convention to pre-declare global variables or to make it easier to keep track of what variables you are using, since you can stick all the 'dim' statements at the start of a script/function.
"Things like bad arithmetic only show up at runtime, as Lua has untyped variables."
Ok.. This is one major strike against it imho. I am tired of languages you can't define the types for. You get the same rediculous runtime issues in VBScript, for precisely the same reason. Strict typing helps avoid mistakes, it isn't a 'feature' as far as I am concerned for a language to be missing it. There is after all a reason why most languages have strict types. ;)
Anyway, nice to know before hand that these issues exist.
No, you don't have to declare them in VBscript, unless you use "option explicit". I was explaining why those lines had to go.
Lua gives you the flexibility to do that or not. As the Lua author points out in his book, you can add explicit variables if you want to.
In chapter 14.2 of his book (or see the equivalent in the online manual) he points out that you can make a metatable for the global environment, that will catch attempts to access non-existent variables and throw an error.
Then to create variables in the first place you add a method "declare" that creates them. This effectively gives you "dim" and "option explicit" back.
Quote:
This is one major strike against it imho. I am tired of languages you can't define the types for. You get the same rediculous runtime issues in VBScript, for precisely the same reason.
Well, Lua has automatic type conversion, so most of the problems go away, depending on the arithmetic operator. For example, adding is for numbers, right? So if you add together two things it tries to convert them to numbers, unlike VBscript which gives strange behaviour.
eg.
Lua:
Note ("10" + "5") --> result 15
VBscript:
Note "10" + "5" ' result 105
Lua has a separate operator for concatenation, so if that is what you want, you use the appropriate operator.
Similarly in Lua, if you want to concatenate, numbers get converted to strings:
Note (10 .. 5) --> 105
In most cases you are controlling the data, so you know what type it is anyway (and if you use the explicit declarations idea, you shouldn't get nil data).
If you aren't sure you can find the type:
Note (type ("10")) --> string
And in my example above, you can make a special table (like nvar) that takes things like strings from GetVariable and converts them to numbers for you.
If you are writing pre-canned functions, then it is a simple matter to check the types of the variables as they are being passed in, eg.
function foo (x, y)
assert (type (x) == "string", "X must be a string")
assert (type (y) == "number", "Y must be a number")
end -- foo
Admittedly this is a runtime check, not a compile-time check, but in things like "send to script" the difference is moot, as they aren't compiled anyway until runtime (that is, until the trigger fires).
My other comment about explicitly typed languages is this. Although I like the idea personally, it tends to cut down on coding errors, in a scripting environment you tend to simply move the problem.
Say we have a trigger script. The stuff arriving is text anyway, so in order to store it into a (typed) variable we need a runtime conversion, and that conversion may still fail.
eg. int x = ConvertToNumber (wildcard (5))
So, we still have the possibility of runtime errors, we have just moved where they occur around a bit.
Nothing saying you will have to switch to Lua anyway.
If you have a feature you want, make it a plugin. Thats the beauty of the plugin system, different script languages.
So you can (in certain cases) have the majority of your scripts/etc in one language that you are comfortable with, and then have a plugin to say... make another window, in lua. You just call the plugin (from the script, in VB) and then the lua stuff (which you didnt write per say, you took it from nicks example and adapted it, or whatever) will get called.
Its the equivalent of calling a subroutine in VBScript, except youre calling a subroutine in a plugin (which is language independant).
Of course, thats assuming Nick will still answer questions in the other language forum sections ;)
That's amazing... The only problem is now that it's converted I don't have the slightest idea what to do with it.
In the VBscript version, I had 2 triggers, even though I could have condensed it down to 1.
The first set all my variables, and the second ran the script and made the infobar.
Do I place this script code in a trigger?
Or in the script file?
If in the trigger, which one?
The old variable trigger?(The second xml format trigger in my first posting)
Or in the execute trigger, the one with all the infobar code?
Also, In the sandbox in the global preferences, do I need to add the script file?(vaguely recalling something in another post: dofile something or other).
Believe it or not, I actually understand the scripting and how the language works, the problem I'm having, like I did with vbscript when I started with it, is how to tie MC and Lua together.
I can code the script, but how do I make it work with MC?
I only converted one trigger, you said if you saw how it was done you could do the rest.
The trigger itself will be the same, just in the "send" box replace the VBscript stuff with the Lua stuff.
Then you would change the scripting language to Lua and instead of myfile.vbs for your script commands that are not "send to script" use myfile.lua.
It's not supposed to be that complicated. Just do whatever you used to do in VBscript, just using Lua as the language.
However you can't have some triggers using Lua and others using VBscript. If you have a lot you'll have to convert them all, OR put the Lua ones into a plugin.
Plugins can have a different language from the main file.
Don't just change over for the sake of it, if it is all working now I wouldn't bother changing.
Don't touch the global preferences unless you have a reason to. All I was saying was that if you wanted to have a script shared between every world you could put that into a file, and then just put:
dofile "myfile.lua"
into the global preferences.
However just stick to what you normally do - put the script file name into the box per world, in the scripting prefs.
That's what I thought originally, but when I setup the triggers, the regular expressing XTL trigger, It didn't work. I setup the variable trigger, it wasn't working
Also, I have Lua scripting enabled, however... when the triggers that send to script go off I get an error:
Send-to-script cannot execute because scripting is not enabled.
Also, ontop of that... when I reload the script, or make changes to it.
Error number: 0
Event: Run-time error
Description: [string "Script file"]:9: attempt to index global `var' (a nil value)
Called by: Immediate execution
The runtime error disables the script, so it won't work. The runtime error talks about "var" being nil, which I presume is because you didn't add the extra code to your script file. I mentioned on page 1 of this thread:
Quote:
This looks a bit less cluttered. It relies upon this being in your main script file:
The "this" I talk about (directly below that statement) is necessary to make "var" work. It is on the posting, and also in the exampscript.lua file that ships with recent versions of MUSHclient.
Ok, I changed the script file to the examscript file that comes with 3.58, The script loaded this time around... But I got a different error...
Quote: Error number: 0
Event: Run-time error
Description: [string "Trigger: InfobarScript"]:11: attempt to index global `nvar' (a nil value)
Called by: Immediate execution
The Variable trigger, works quite well now that I got the scripting enabled properly.
But as you can see, there's an error there.
Quote: Don't just change over for the sake of it, if it is all working now I wouldn't bother changing.
I like the versitility of Lua over VBscript. Like the whole idea of being able to run a looping script in the background. That will come in very hand in the near future. I'm also thinking of checking out that whole notepad idea again, instead of using your multi-line infobar. I'm not to sure if that little window is capable of doing what I want, so I'll give notepads another shot.
The main issue I had, was in using multiple notepads. I couldn't figure out how to make the triggers use one notepad for 1 trigger, and a new notepad for a different trigger... Oh well, I'll get it eventually. Plus, I like the idea of changing the colours of the notepads.
Ok, I added that part, I still get a run-time error.
I added:
var = {} -- variables table
-- warning - parenthesis must be on same line as setmetatable
setmetatable (var,
{
-- called to access an entry
__index =
function (t, name)
return GetVariable (name)
end;
-- called to change or delete an entry
__newindex =
function (t, name, val)
local result
if val == nil then -- nil deletes it
result = DeleteVariable (name)
else
result = SetVariable (name, tostring (val))
end
-- warn if they are using bad variable names
if result == error_code.eInvalidObjectLabel then
error ("Bad variable name '" .. name .. "'")
end
end;
})
Like you said... I think I might still be missing something.
The error:
Quote: Error number: 0
Event: Run-time error
Description: [string "Trigger: InfobarScript"]:11: attempt to index global `nvar' (a nil value)
Called by: Immediate execution
var = {} -- variables table
nvar = {} -- number variables table
svar = {} -- string variables table
-- function called to change variables
function changevar (t, name, val)
local result
if val == nil then -- nil deletes it
result = DeleteVariable (name)
else
result = SetVariable (name, tostring (val))
end
-- warn if they are using bad variable names
if result == error_code.eInvalidObjectLabel then
error ("Bad variable name '" .. name .. "'")
end
end -- function changevar
setmetatable (var,
{
__index =
function (t, name)
return GetVariable (name)
end;
__newindex = changevar;
}
)
setmetatable (nvar,
{
__index =
function (t, name)
return tonumber (GetVariable (name)) or 0
end;
__newindex = changevar;
}
)
setmetatable (svar,
{
__index =
function (t, name)
return GetVariable (name) or ""
end;
__newindex = changevar;
}
)
Found the second part, I missed. I added that in as well, and it worked like a charm. Ok, now in my last posting I put up some of the code from the prior page, my question is: Is that first var () code debunk, due to the second but of var(), nvar(), and svar() code? Meaning, is ut redundant?
Yes, the first one is redundant because the second one replaces it. For a start, there is a new:
var = {}
This replaces whatever the first one might have done.
As for the word replacement script, you mean the one that fixes the capitalisation? That is on the first page of this thread. There is no link, it just about 8 lines of code.
You can copy and paste that into a command window (prefixing with the script prefix, usually "/") or use the "Immediate" window, or put it into the script file. All of these methods alter the "global script space" and are interchangeable.
You can experiment with this. Try doing something like:
a = 5
in the immediate window, and then in the command window type:
/print (a)
You should see 5 printed, which shows they are sharing the same script space.
I believe the example you used was the word "was", which you changed to "*WAS*" Or something like that, I searched the forums, but I haven't had any luck with it.
I know it's in there somewhere, I saw the posting about it.
function my_trigger (name, line, wildcards, styles)
for _, v in pairs (styles) do
ColourNote (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "will", "*WILL*")))
end
end
First, could you explain this a little bit, the whole styles aspect of it that is.
Secondly, will this work as well?
Quote:
for _, v in pairs (styles) do
ColourNote (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "will", "*WILL*")))
end
Placed in a trigger as send to script?
Haven't tested it, don't have the time right now, perhaps later on after work.
Ok, now that I have time to play around, this is my results.
-=Immortals=-
[ Eternal ] [AFK] Altair got owned by the dentist, (censored*)... got another round coming
*I censored the cuss word*
Now then... I wanted to replace the name Altair with Dummy, as a joke mind you, just to test it. It was the first name on the Immortal list, so poor Altair got to be the test dummy.
Now then, I successfully got the above mentioned script to replace the name... HOWEVER! It didn't come out quite as planned.
This was the result:
-=Immortals=-
[
Et
ern
al
]
[
AFK
]
Dummy got owned by the dentist, (censored)... got another round coming
UGLAH!
I should note however that there is a lot of colourized text in that. I'll break it down.
"[" is normal text colour
"Et" is dark cyan
"ern" is light cyan
"al" is dark cyan
"]" normal text colour
"[" dark blue
"AFK" light blue
"]" dark blue
The rest was in normal text colour.
It works great, but for some reason it doesn't like changes in text colour. XML trigger to follow.
Now, the \r\n is to make a new line? Doesn't seem to work properly, I keep getting errors.
Quote: Still, changing to ColourTell should do it, followed by a final ColourNote to finish off the line.
Not sure where you gotta put the final ColourNote in there, it's seeming to be working just fine with only ColourNote.
Quote: If you want to do it that way, it has to go into the script file. As Flannel says, the alternative is to use the preprocessing at the packet level.
reprocessing on the packet level would work, but I don't want to mess with the ANSI coding on it, I like the colours as it is for now. Perhaps in the future.
Quote: No, it won't work in "send to script".
For one thing, notes done in "send to script" are not displayed, if the line is omitted from output.
For another thing, there is no fourth argument in "send to script". It isn't called as a function with arguments.
If you want to do it that way, it has to go into the script file. As Flannel says, the alternative is to use the preprocessing at the packet level.
That isn't a problem for me, the question is of course, how do we modify a table/metatable from an alias?
Quote: Everything below this quote is an off shoot of our discussion about replacing text.
First. Alias to add word replacements into a script file.
Alias match on: set replace text "*" "*"
That's all I got so far(Upon editing, re-editing, and editing the edits... I note that this isn't accurate any longer, but the alias is still important.)
I think a merger of two idea's here will work well. Can you use a table to define the replace text? Hack code job to follow the real code:
function ToTextReplace (name, line, wildcards, styles)
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "Altair", "Dummy")))
end
end
Ok, time for a buncha pseudo-code of my own creation, of course it'll be wrong, but you'll get the idea
function textreplace (name, line, wildcards, styles)
Ok, first compare the wildcard to the text.list table, does any of them match the criteria?
Yes, Ok, then set it as text.match(see below)
text.match = text.list.1
Compare the text.list table, to the text.replace table.
Match them up accordingly, and set text.replacetext to the corresponding text.list match.
text.replacetext = text.replace.1
Continue with rest of the code, but with the modification as follows
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, text.match, text.replacetext)))
end
else -- Pseudo code is basically an if statement.
end -- if statement
end -- function
I'm certain there is an easier way, I'm can't seem to think of it at the moment, but this seems pretty straight foreward.
Make a table with the matches, make that table with the replace text, when a trigger, which is setup by the alias, goes off, it runs the script, which checks the lists(gonna find out who's naughty or nice), converts into text.match and text.replacetext, and substitutes it. Hell, I got most of the idea down, the problem is coding it, which I'm not sure about.
Alias sets up trigger to match on the match word.
Alias adds to tables text.list and text.replace
Trigger goes off, runs through script.
Script checks its text.list table, converts to text.match(for the match)
Script checks its text.replace table, converts the corresponding replace text to text.replacetext
Script runs through the gambit, and bam, you have a fully customizable auto-word replacement script.
A second alias, would remove the Trigger, and the appropriate information within the tables.
You want to switch his name with 'dummy'. You CAN do that with the packet callback thing. You dont have to change/mess with the colors either. You can just subsitute text for text.
I checked out that AppendToNotepad... Works, but not quite the way the helpfile shows ...
That works for me. What was the error? In Lua (not other languages) you can have multiple arguments after the notepad name, and they all appear in the notepad. And yes, \r\n is a carriage-return linefeed.
Quote:
Not sure where you gotta put the final ColourNote in there, it's seeming to be working just fine with only ColourNote.
I thought you were getting a line per style. The ColourTell stays on the same line. A final ColourNote (after the loop) would start a new line.
Tables can be basically two things (or both), a list of things keyed by number, as you illustrate above, or an associative array. Here is an example of doing a list:
Given our table of replacement words, we can rewrite the gsub nice and simply:
t =
{
Altair = 'Moe',
Ceriloch = 'Larry',
Ragnar = 'Curly'
}
line = "Altair went for a walk, he met Ceriloch but Ragnar surprised them"
repl = string.gsub (line, "(%a+)", function (w)
if t [w] then
return t [w]
else
return w
end -- if
end) -- function
print (repl)
-- Output:
Moe went for a walk, he met Larry but Curly surprised them
What this is doing is searching for a word (%a+) and if found looking it up in the associative array. If found, it uses the replacement, if not, it returns the original word.
Quote: That works for me. What was the error? In Lua (not other languages) you can have multiple arguments after the notepad name, and they all appear in the notepad. And yes, \r\n is a carriage-return linefeed.
Error number: 0
Event: Compile error
Description: [string "Trigger: "]:1: unfinished string near `"More stuff
'
Called by: Immediate execution
I used the sample code in the helpfile, and I just put it in send to script. That was the error I got.
I didn't even bother to change it to what it's supposed to be, if the helpfile example didn't work for me, then I know the setup I was going to use wasn't going to work either.
Regarding that associative array, I hear ya. I know exactly what you mean. When I was reading the manual late last night, I saw the difference.
The only problem with what you put up, and there's nothing wrong with it, but it's missing something.
if I make an alias to add a name into the array, which is piece of cake
Alias: add "*" "*"
send to script: t ['%1'] = '%2'
That will add a new name and replace text into the array, but it's in memory, it's not actually hardcoded, so when you quit out, you're going to lose that array.
So, how about OnWorldConnect you load the saved array
and OnWorldDisconnect you serialize the memory array, that'll save it as a variable... That'll work I think. Actually, I think that'll be less work than trying to code it as changing the scriptfile itself.... Yeah, I like that.
OK, I see what is happening. That trigger is a bit of a trap. The example code works pasted into the command window, however in the "send to script" box it seems MUSHclient is preprocessing the \r\n before passing it to Lua (or any script language). Thus it effectively makes it:
function textreplace (name, line, wildcards, styles)
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "Altair", "Dummy")))
end
end
Was the original code... Now, I'm kinda confused, granted I haven't slept in over 24 hours, so that could be it... but I'm not making the connection how to go from:
t =
{
Altair = 'Moe',
Ceriloch = 'Larry',
Ragnar = 'Curly'
}
line = "Altair went for a walk, he met Ceriloch but Ragnar surprised them"
repl = string.gsub (line, "(%a+)", function (w)
if t [w] then
return t [w]
else
return w
end -- if
end) -- function
print (repl)
-- Output:
Moe went for a walk, he met Larry but Curly surprised them
To using both in conjunction...
I'm still kinda stumped on the trigger aspect. I really don't want 50 million single triggers. I was thinking of something along the lines of (fdhgh|arhh|ahathaeh|bob|fdahah|great) And when I add a new word, to be replaced, it adds into the trigger, but I don't remember how to do that... I know the code is in the forums, I've used it before, but it's a bit beyond my current ability in Lua.
That will add a new name and replace text into the array, but it's in memory, it's not actually hardcoded, so when you quit out, you're going to lose that array.
So, how about OnWorldConnect you load the saved array
and OnWorldDisconnect you serialize the memory array ...
Yes, exactly. See my posts in the Lua section for doing that.
The matching on multiple (and dynamic) things can be done with expand variables and a variable that contains a regexp for what you want to match on.
bob|joe becomes
bob|joe|billy when you add to it. So its a simple string concatenation. You can do 95% of it without using any form of scripting (just the inbuilt functions) you only need the lua code to add "|[name]" to the variable.
I have added a couple of new things to MUSHclient 3.60. The first one lets you do a script just before MUSHclient saves its world to disk. This is a logical spot to serialize from internal variables to the external variables.
The second is a function that lets you set the "world has changed" flag, to make sure the saving is done in the first place.
I added this short script to my script file to make it work:
function OnWorldSave ()
var.skills = serialize ('skills')
end -- function
That caused the skills to be serialized. Then in the world open:
function OnWorldOpen ()
loadstring (var.skills)
end
I think this alias is going to be a lot more complex than we both think it's going to be.
Ok, really tired, I can't even think of how to do what Flannel said...
Mainly, I got the SetVariable ("replacetext", "@replacetext" .. "%1")
But that's all I got so far... and I know I have to put in the "|" in there, and I'm drawing a blank as to how to do that. I know I gotta script this into it as well:
Quote: I have added a couple of new things to MUSHclient 3.60. The first one lets you do a script just before MUSHclient saves its world to disk. This is a logical spot to serialize from internal variables to the external variables.
yeah, I used to have a timer that did that every 5 minutes or so, but I don't remember the exact syntax... Not to mention when, I re-scripted it after my computer meltdown, it didn't save in the spot that I wanted it too, it kept saving in C:\My Documents, which I didn't want, I wanted it saved in D:\Program Files\MUSHclient\worlds
The only issue I see with that is a possible nil return when there is no variable there in the first place.
run it through a script(you're gonna be scripting in it already to set the table element):
if GetVariable ("replacetext") == nil then
SetVariable ("replacetext", "%1")
else
SetVariable ("replacetext", "@replacetext" .. "|" .. "%1")
end -- if
On a side note, I was just thinking of my infobar script, I could do away with variables completely, I think. Use table's to store the information, nothing would really change, but instead of saving to the variable list, it would be updating the table... Then along with all my other tables, when I save the world, or whatever, it'll save that into a single variable, which will reload itself aferwards. Man, I like this table thing... I never understood it in VBscript before, but Lua seems pretty straight forward in how the tables work.
Yeah, that's true, it would be easier to stick with tables, but that doesn't change the fact that I need a regexp trigger to match against the table...
That reminds me, if we get the replace text thing working perfectly, then they'll be one last issue, it's CAPS sensitive. even if you're matching ignore case, it won't work. I tested that earlier when I first started playing with it.
and I dont see how sticking with tables would help.
Youd need to have a table to keep your targets, as well as a MC variable.
Edit:
I see, youre using the table to store the information for the switch. So you add to the table, and then regenerate your MC variable. Wouldnt the output be both columns though?
As for a long term storage solution, which could just be a MC variable for each thing (name, and replacement names), or you can store it in a database.
function textreplace (name, line, wildcards, styles)
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "Altair", "Dummy")))
end
end
We have success, this works, Altair(script version) == Altair(Trigger Version)
Ok, lets change it now. Now we match on "altair"
altair(Trigger with ignore case) does not match Altair in the script
Flip it around again, Make the Trigger Altair, and the script altair, it doesn't match up.
Now if you match on altair, and you type say altair, then it will work, if you type: say Altair, no dice, it won't work...
So what I mean is that the code that you put up is case senstive, even thought the trigger says it's not supposed to be... That might be a slight bug... Perhaps. I don't know.
make it regexp and lowercase wilds, and what not. Anyways, you have to keep replacing the trigger that matches the replacetext that you want. Otherwise setting up the variable is useless, and like Nick said, we don't even need the variable really, we can script it right into a table and that will speed things up.
But then you have a trigger for each name.
Which you might as well ditch the table for, and hard code it directly into the trigger (no more lookup, just a subroutine which replaces X with Y).
You can have a trigger match ANY name in your table (which is also in your variable) using expand variables and a variable-regexp. So the same trigger matches constantly, and you dont use AddTrigger anywhere.
Oh, youre hard-coding the variable into the trigger. The problem with that is then you have to add the parenthesis to the outsides of the list. Which, is doable.
You would lose the information about the trigger (number of matches and such) which may or may not be an issue.
And I'd imagine setting the variable takes less time than adding a trigger. You'd need to set the MC variable eventually to save your list between sessions (or use a database, but I think a database might be overkill).
Well, you do need an external variable eventually, but either way, when you use the alias to add names and replace text, you also have to add the trigger match to it's own table, else you can't do anything with it.
It's like having a car, and having a tin of gas, but no way to put the gas in the car. That trigger is the tube that lets you put the gas in the car. The car is the trigger, and the alias is the fuel... Hey, that's a pretty nifty analogy.
Anyways, you can do it 1 of 2 ways, with or without a variable. Serializing the tables is easy, I have it happening every 30 seconds(with a world save)
The tricky part of this whole process is translating the table to the script. We got 2 pieces of code, and I don't know how to link them together to get the effect we want.
Yes, Serializing, but instead of adding it to a trigger, you can store it in the variable.
The trigger WILL still match with using the variable as match text (see link below). If you want to use your analogy, the funnel is the variable. Well, and the can, for long term storage.
If you store it in the variable, and at the same time you update a second variable of conversions, both of which are overwritten with the serialization, then you wont have to worry about storing it to a variable later, and you can save the world as soon as you finish editing the variables. To make sure you never lose anything.
You wont have to save the world (and write to the variable) every 30 seconds, only when needed, which will save considerable computation time, if you have it happening twice a minute currently.
And then when you open the world, you extract that information to the table, and never worry about losing anything.
That way you only have your table existing in the variables (one for before, one for after) and the script environment. Instead of variables (storing it for long term), your script environment, AND the match text of the trigger.
If you're keeping your variable up to date already, why are you wasting your time with the addtrigger?
Tell ya what, lemme get about 15 hours of sleep, and I'll get back to you. It's 10pm EST, Monday night, I've been up since 12pm EST, Sunday afternoon. Getting close to 36 hours up, 12 of it at work, 3 of it traveling, the rest at the computer.
I see what your saying. I don't know if it's better or not. I haven't thought about it, can't really think about it right now... Let me get back to you....
Ok, basically you're doing the same thing I am, just in reverse.
Interesting, it has possibilities. Ultimately, do I write the code for the addtrigger, and be done with it? It's not that much more complicated than writing a Variable. As for CPU and Memory, Athlon XP 2600+, with 512 PC2700 DDR 333Mhz FSB. Not too woried... I can loop up to 10,000 commands at once before I even start to notice a glitch, at 100,000 commands I get a second or two pause, and at 1,000,000 MC locks up, but the computer is just fine.
That works quite well, I can add into the text {} table with that.
Now all I need to do is link up the 2 pieces of code I have.
This is the code to do the replace and output on the same line:
function textreplace (name, line, wildcards, styles)
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, "Altair", "Dummy")))
end
end
This code is the one that the trigger actually changes the the text:
t =
{
Altair = 'Moe', ---- Used here as an example
Ceriloch = 'Larry', ---- this would actually be an
Ragnar = 'Curly' ---- internal table
}
line = "Altair went for a walk, he met Ceriloch but Ragnar surprised them"
repl = string.gsub (line, "(%a+)", function (w)
if t [w] then
return t [w]
else
return w
end -- if
end) -- function
print (repl)
I just don't know how to link the two together, once that happens, we'll be golden I believe.
I got it ALL working, just gotta set up the replace script for my skills now.
function textreplace (name, line, wildcards, styles)
loadstring (GetVariable ("text"))
line = wildcards[1]
repl = string.gsub (line, "(%a+)", function (w)
if text [w] then
return text [w]
else
return w
end -- if
end) -- function
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, line, repl)))
end
end
With that you use:
<triggers>
<trigger
custom_colour="2"
enabled="y"
expand_variables="y"
ignore_case="y"
keep_evaluating="y"
match="(@!replacetext)"
omit_from_output="y"
regexp="y"
repeat="y"
script="textreplace"
sequence="100"
>
</trigger>
</triggers>
Now, When you're me, you have a script serializing every 30 seconds or so, so don't set a replace text that you don't want, cause it can be a pain in the arse to get it out of the table once it's in. Now then, the next thing is to make an alias to do that for us. I'll do that later tonight after work.
One problem left... That'll be fixed in 3.60 when Nick releases it, untill then the variable doesn't seem to want to stay saved when you close the program out.
Yes, you can, but I did it that way, don't ask me why. I just did. It took me a few tries to figure out how to get it to work, once I got it working, I left it as it was. No need to change something once it's working.
Flannel, since you showed me how to use the variable trigger, how do I remove a specific name from the variable if I want to remove it from the list?
repl = string.gsub (line, "(%a+)", function (w)
if text [w] then
return text [w]
else
return w
end -- if
end) -- function
for _, v in pairs (styles) do
ColourTell (RGBColourToName (v.textcolour),
RGBColourToName (v.backcolour),
(string.gsub (v.text, line, repl)))
end
I am glad to hear it is working, but again I think you have combined a couple of my ideas into one.
What you are doing above is two gsubs, one for the entire line, and one per style. I would do one or the other. This will only work if the entire line is a single style (ie. a single colour).
The second gsub is trying to match the entire line, and replacing it with the replacement line, this will only work if the entire line is one style.
Im not quite sure what all you have to work with, however...
You just have to remove the name (and the | either before or after). Do you already have a table of the names? Just remove the name from the table (which you still have, I believe) and then regenerate the variable.
That regeneration might be easier than trying to find, and then determine what to remove (since if its the first name, youll have to remove the | afterwards, but if its the last, youll have to remove the | beforehand, so regeneration might be better. It will also solve any problems you might have with the data unsynching from each other).
Quote: I am glad to hear it is working, but again I think you have combined a couple of my ideas into one.
Yep, I did, was the only way I could figure out how to get it to work.
I knew the first half of the code would change the line into the new words, and I knew the second half of the code would do the ColourTell.
I knew I could always match the apropriate capitolization if I used the line for the match, and the apropriate replace text with the repl, so it's not pretty, but it works.