Mushclient Questions

by Esano

Back to Mechanic's Corner.

Unknown2010-10-06 13:40:18
I'm trying to do this:

test = GetVariable("testvariable")
loadstring(test .. " = {}")()
print(test)

However, I get this error:
Run-time error
World: Treant
Immediate execution
:2: attempt to call a nil value
stack traceback:
:2: in main chunk



However, when I run this:
test = "something"
loadstring(test .. " = {}")()
print(something)

I get this:
table: 06834F90

So, yay, loadstring does let me create tables. But I don't want to have to specify the contents of the variable all the time, so I tried this:
test = "something"
loadstring(test .. " = {}")()
print(test)

I get : something
Hrm, I know that test is still = "something", which is why I get that result, but is there any way to have something that will substitute for whatever is in my variable?
Unknown2010-10-06 13:57:25
The kills module that you borrowed from actually does serialization and deserialization, since it stores all your kills in a Lua table.
Unknown2010-10-06 14:05:25
Actually, I'm trying to create a table based on whatever the variable is.
So, if GetVariable("testvariable") is abc,
I want to do:
abc = {}

I know that the kills module has serialization and deserialization, I borrowed it heavily when doing the xp tracker, and was immensely helpful. I would have missed out all the failsafes that you put into the deserialization if I did it from scratch. It was also where I learnt how useful the line 'if not' is.
Unknown2010-10-06 14:10:45
What you're doing there should work, but if the variable doesn't exist or has an invalid value, you'll run into problems. So, you need to ensure that it exists and is valid somehow.

It might be better to state your goal, where you're going with this, to see if there's a better way to handle it. For example, making a "master" table and storing your data as keys with sub-tables as the values, so you can then reference the data using strings.
Unknown2010-10-06 14:50:55
OK, here's what I've managed to get working so far:
I'm trying to compare the XP gain from weekrank with the percentage XP gain from score, and then get the XP required to get 100% for that level. I managed to do that.
CODE
function xp:compare()
if not my_xp_perc then
    local var = GetVariable("my_xp_perc")
    if var then
      loadstring(var)()
    else
      my_xp_perc = {}
    end
  end
    if not my_xp_perc_whole then
    local var = GetVariable("my_xp_perc_whole")
    if var then
      loadstring(var)()
    else
      my_xp_perc_whole = {}
    end
  end

local p = GetVariable("GainedPercXP")
local n = GetVariable("GainedXP")

table.insert(my_xp_perc, n, p)
  SetVariable("my_xp_perc", serialize.save("my_xp_perc", my_xp_perc))
for k,v in pairs(my_xp_perc) do
whole = ( 100 / v ) * k
table.insert(my_xp_perc_whole, whole)
end

  SetVariable("my_xp_perc_whole", serialize.save("my_xp_perc_whole", my_xp_perc_whole))
end

function xp:showperc()
  if not my_xp_perc_whole then
    local var = GetVariable("my_xp_perc_whole")
    if var then
      loadstring(var)()
    else
      my_xp_perc_whole = {}
    end
  end
for i,v in ipairs(my_xp_perc_whole) do
addedup = (addedup or 0) + v
end
local x = # my_xp_perc_whole
z = addedup / x
addedup = 0
ColourNote("white", "", "Amount of XP required for level: " .. z)
end



However, I'm trying to do it so that each level has its own table, and each level is the value of a master table.

So, my_xp_perc is the master table.
I would insert each level as the key of the master table, with the value being a sub table.
Within each sub table would be what I have done above.

That was for the storing part. I have a very rough idea of how to retrieve it to print it out:
CODE
for level,v in pairs(my_xp_perc_whole) do
  for i,v in ipairs(level) do
  addedup = (addedup or 0) + v
  end
local x = # level
z = addedup / x
addedup = 0
print("Amount of XP required for level " .. GetVariable("CurrentLevel") .. ": " .. z)
end
Unknown2010-10-06 15:09:56
I don't have any comments on this code, specifically, but keep in mind that the weekrank command is only around while these contests are active and that the values don't account for any XP boosts you may have at the time.
Unknown2010-10-06 15:15:16
Yeah, I do know that this will only work during this October, and that XP bonuses are not accounted for (which is why I'm asking Simple Questions so that I can adjust the modifiers in).

Mostly, this is a project for me to work on my Lua, and also to see how many guards I have to influence to gain 100%. happy.gif
Zhov2010-10-06 16:18:52
QUOTE (Caerulo @ Oct 6 2010, 10:50 AM) <{POST_SNAPBACK}>
CODE
for level,v in pairs(my_xp_perc_whole) do
  for i,v in ipairs(level) do
  addedup = (addedup or 0) + v
  end
local x = # level
z = addedup / x
addedup = 0
print("Amount of XP required for level " .. GetVariable("CurrentLevel") .. ": " .. z)
end

I don't have time at the moment to glance over the whole thing, but I noticed a (very) minor thing. Since you said it's a practice in Lua, I figured I'd mention it.

In
CODE
for level,v in pairs(my_xp_perc_whole) do
you don't use the v. You soon after declare
CODE
for i,v in ipairs(level) do
and use the v from that. You can omit the second variable in a for ... pairs loop, so I'd make it
CODE
for level in pairs(my_xp_perc_whole) do


I can look over it in detail later, and offer any opinions.
Unknown2010-10-06 16:41:47
QUOTE (zhov @ Oct 7 2010, 12:18 AM) <{POST_SNAPBACK}>
I don't have time at the moment to glance over the whole thing, but I noticed a (very) minor thing. Since you said it's a practice in Lua, I figured I'd mention it.

In
CODE
for level,v in pairs(my_xp_perc_whole) do
you don't use the v. You soon after declare
CODE
for i,v in ipairs(level) do
and use the v from that. You can omit the second variable in a for ... pairs loop, so I'd make it
CODE
for level in pairs(my_xp_perc_whole) do


I can look over it in detail later, and offer any opinions.

Oh, but how does the code know that level is referring to the keys, and not the values?
Unknown2010-10-06 16:45:00
The first variable always refers to the keys. If you want the values and don't need the keys you substitute a single underscore for the first variable name (as a placeholder).

CODE
for _,val in pairs(t) do
  print(val)
end
Unknown2010-10-06 19:15:57
OK, now I've figured out how to insert a variable as a table. Now, how do I insert into that variable?

I want something that does:
CODE
function xp:test(level)
test = {}
test = {}
n = "something"
p = "something else"
table.insert(level, n, p)
end

But in the above case, Lua interprets level as a string, not as a table, so I am unable to do a table.insert.

But if I do:
CODE
function xp:test(level)
test = {}
test = {}
for k,v in pairs(test) do
print(k,v)
end
end

I get
84 table: 070D9A68

Which meas that the sub table had been created.
Unknown2010-10-06 19:17:00
table.insert is for numerically indexed tables. What you want is just to create a new entry with a string key.

CODE
test = p
Unknown2010-10-06 19:22:33
Oh, thanks! My test function works! Now to check if my actual function works.

EDIT: With some tweaking, my script works! Now, to add in the modifiers and I'll be almost done. All that I have think about is what happens if I gain 0.00% XP gain because the XP gain was too small to even give 0.01%.
Mirami2010-10-07 04:04:06
Is there a fast and easy way to disable all but a select few triggers?
Zhov2010-10-07 21:27:54
QUOTE (Romertien @ Oct 7 2010, 12:04 AM) <{POST_SNAPBACK}>
Is there a fast and easy way to disable all but a select few triggers?

There is not a fast and easy way. You could disable all triggers, but easily disable all save a few, no.

Off the top of my head, one way would only work if you have them all named, or if the 'select few triggers' are the unnamed ones. You could iterate over GetTriggerList(), disabling all save for ones you specify, that have names. All values in the returned table that don't begin in *trigger have a name. The reason it won't work without named triggers is that you cannot disable triggers without names, using EnableTrigger. You could write something more complex to get all trigger groups, I suppose, and disable that way..

But in the end, no, it's not really feasible.

One way to achieve a similar effect is to make every action trigger (one that responds by sending something to the MUD) conditional. Something like...
CODE
if act then
  --actions here
end -- if


Then set act to be true... change it to false when you don't want triggers to do anything. Setting it up could be somewhat time-consuming though, depending on how many triggers you have.

What I do, personally, is put all triggers in groups. This has two effects - first, I can easily sort them by group, and find what I want. Two, I also create a table of trigger groups, and can enable/disable what I want at will. In fact, nothing except my system is enabled unless I specifically turn it on.
Mirami2010-10-07 23:32:22
So, assuming all of the triggers I wanted to keep were in one group (which they are), what would the optimal solution be to disable all the rest?
Unknown2010-10-08 00:14:07
Ideally, the ones you wanted to DISable would be in a single group, but what you can do in your case is iterate over the GetTriggerList() to disable all of them individually and then just EnableTriggerGroup for that one group you want to keep.

And, yes, there is a good reason I name every single alias and trigger I create.
Zhov2010-10-08 17:06:59
QUOTE (Zarquan @ Oct 7 2010, 08:14 PM) <{POST_SNAPBACK}>
Ideally, the ones you wanted to DISable would be in a single group

That would work perfectly. Or at least, have several groups and a table of trigger groups to iterate over.
Mirami2010-10-08 20:28:21
Yay, more questions.

Let's say I want to make a trigger that takes an aetherspace trading line, say, this one:

CODE
Blue Cognito ROCK      57         1.0 tons   703 gp


And I want to capture the last two numbers (The tons and the gp), how would I go about it? I can't seem to figure out how to get the regex to capture '1.0' sad.gif
Unknown2010-10-08 20:43:49
Just the part for the 1.0 would look something like this:
CODE
(\\d+\\.\\d)