XP Tracker

by Unknown

Back to Mechanic's Corner.

Unknown2010-10-06 03:12:22
I've been reading the Lua tutorials, so I wanted to create a project for me to practice what I've learnt. One idea I had was to create something that tracked the xp gain we can check during this month. So, here goes:

The aliases:
CODE


match="xpreset"
enabled="y"
send_to="12"
sequence="100"
>
xp:reset()

match="xpshow"
enabled="y"
send_to="12"
sequence="100"
>
xp:show()




The triggers:
CODE

     enabled="y"
   expand_variables="y"
   match="^(.+) sighs dramatically and searches (?:his|her) pockets\\, looking for something to give you\\.$|^(.+)puffs up (?:his|her) chest and a crazy gleam enters (?:her|his) eyes as (?:she|he) vigorously agrees with you that (?:his|her) intelligence and strength far surpass anyone else\\'s\\.$|^(.+) wildly looks around\\, (?:his|her) left eye suddenly developing a nervous twitch\\, and asks you to keep a look out for \\'them\\'\\.$|^(.+) drops down on (?:his|her) knees and worships the very ground you walk on\\!$|^(.+) breaks down and sobs\\, telling you how true it is that (?:she|he) is nothing but a pathetic fraud\\.$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  
EnableTrigger ("AfterXP", 1)
Send("weekrank")
if string.len("%1") > 0 then
SetVariable("GainedXPFrom", "%1(Influence)")
elseif string.len("%2") > 0 then
SetVariable("GainedXPFrom", "%2(Influence)")
elseif string.len("%3") > 0 then
SetVariable("GainedXPFrom", "%3(Influence)")
elseif string.len("%4") > 0 then
SetVariable("GainedXPFrom", "%4(Influence)")
elseif string.len("%5") > 0 then
SetVariable("GainedXPFrom", "%5(Influence)")
end

  
     expand_variables="y"
   match="^You are placed (?:.+) in the ongoing weekly contest with (\\d+) experience points\\.$"
   name="AfterXP"
   omit_from_log="y"
   omit_from_output="y"
   regexp="y"
   send_to="14"
   sequence="100"
  >
  SetVariable("AfterXP", "%1")
a = GetVariable("BeforeXP")
b = GetVariable("AfterXP")
c = b - a
SetVariable("GainedXP", c)
Note("Experience gained: " .. GetVariable("GainedXP"))
SetVariable("BeforeXP", "%1")
tar = GetVariable("GainedXPFrom")
xp:add_name(tar)
xp:count(tar)
EnableTrigger("AfterXP", 0)

  
     expand_variables="y"
   match="^You are placed (?:.+) in the ongoing weekly contest with (\\d+) experience points\\.$"
   name="BeforeXP"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  SetVariable("BeforeXP", "%1")
EnableTrigger("BeforeXP", 0)

  
     enabled="y"
   match="^You have slain (.+?)\\.$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  
SetVariable("GainedXPFrom", "%1")
EnableTrigger ("AfterXP", 1)
Send("weekrank")

  


The script itself:
CODE

--]

require "serialize"

if not xp then -- Avoid re-initialization issues
xp = {}
end

function xp:add_name(name)
if not my_xp then
local var = GetVariable("my_xp")
if var then
loadstring(var)()
else
my_xp = {}
end
end
my_xp = (my_xp or "sum = 0") .. "+" .. GetVariable("GainedXP")

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

function xp:count(name)
if not my_xp_count then
local var = GetVariable("my_xp_count")
if var then
loadstring(var)()
else
my_xp_count = {}
end
end
my_xp_count = (my_xp_count or 0) + 1

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

function xp:show()
if not my_xp then
local var = GetVariable("my_xp")
if var then
loadstring(var)()
else
my_xp = {}
end
end
if not my_xp_count then
local var = GetVariable("my_xp_count")
if var then
loadstring(var)()
else
my_xp_count = {}
end
end
for k,_ in pairs(my_xp) do
ColourNote("white", "", k)
local f = loadstring(my_xp)
f()
units = my_xp_count
mean = sum / units
totalxp = GetVariable("AfterXP")
percentage = sum / totalxp * 100
ColourNote("silver", "", "Number of kills/influence: " .. units)
ColourNote("silver", "", "Sum = " .. sum)
ColourNote("silver", "", "Percentage of total XP: " .. string.format("%3.2f", percentage) .. "%")
ColourNote("silver", "", "Average = " .. mean)
Note("")
end
if IsConnected() then
Send("")
end
end

function xp:reset()
mp_xp = nil
my_xp_count = nil
my_xp = {}
my_xp_count = {}
end

return xp


So, why did I do this? Well, I'm not a data kind of person, but I do know that there are people out there who are. So maybe, we could get concrete numbers as to exactly how much better is say, empowering guards compared to Tosha monks, or Toronada Tidal Flats better than vermin-ing. We could also have people of different circles kill/influence the same thing, and see if it scales to our level.



So, it works! However, a few problems for me despite that:
1. My original intention to do such a project was to avoid relying on the Mushclient variables (GetVariable, SetVariable, etc) too much as I wanted to learn about scoping. However, I felt that I still relied to much on the Mushclient variables.

2. My original concept was this:
Each mob would be a table inside the table my_xp, and each time I killed/influenced it, I would table.insert the xp gain into it.
When I do xp show, I would use something like
for k,v in pairs(name), do
sum = (sum or 0) + v
count = # name

The problem was, I couldn't do name = GetVariable("GainedXPFrom") and have the script substitute name for whichever mob I am killing/influencing.
Also, I had problems inserting a table into an existing table. I know it is possible because I tried out the tutorial, but somehow I couldn't replicate it for this script.

3. Lastly, I wanted to create a script all of my own, but I got stuck as to how to start the script, so I gave up and used Zarquan's Treant kill-tracker as my template. Although I did not achieve this target, I did manage to achieve something else, which was to slightly better understand his code.




Other Improvements:
1. To be able to take questing (eg. pilgrims) or aetherhunting into consideration.
2. I'd love to be able to compare the xp gain to the experience percentage change, and see how much xp is needed for a certain level. Perhaps with sufficient data, some maths buff out there can derive the xp required to level formula.
3. Turn it into a plugin so that more people can use it easily.


Thanks for reading, and I'd love to have any suggestions or improvements.
Calixa2010-10-06 07:03:12
Ain't working for me. Could you paste your list of variables as well, got a hunch that might be it.
Unknown2010-10-06 09:29:59
Variables:
CODE



905200
905200
2420
A Red Hand of the Illuminati (Influence)
my_xp = {}
my_xp = "sum = 0+20+0"
my_xp = "sum = 0+2340+2430+2450+2390+2370+2350+2350+2310+2350+2350+2420"
my_xp = "sum = 0+2340+2350+2390+2320+2420+2400+2400+2370+2400+2370+2400+2430+2450+2390+2430+234
0+2370+2450+2310+2290+2420"

my_xp_count = {}
my_xp_count = 2
my_xp_count = 11
my_xp_count = 21



However, doesn't Mushclient create a new variable when you SetVariable when it doesn't exist?


EDIT: I forgot to give one instruction on how to get it working.

Enable the trigger BeforeXP, do a weekrank and then disable the trigger. That'll create and set your BeforeXP variable. The rest of the variables should create themselves when they get triggered.

Also, what isn't working? If it is working, when you kill/influence a mob, you get a line which tells you how much xp you have gained from that mob. When you do the alias xpshow, you get a summary of everything tracked thus far.
Calixa2010-10-06 09:54:29
Ok, I followed your instructions, and nothing. Added the variables, still nothing. I just get a blank line when typing xpshow and nothing is being outputted after a kill or influence.

The BeforeXP got set and the GainedXPFrom variable is being updated, but the rest isn't changing at all.
Unknown2010-10-06 10:02:46
Hrm, in your world's script file, did you add a require "xp" line in it?
I'm not quite sure what else could be the problem, as I copied and pasted the entire thing, removing only stuff like my autobasher/influencer.
Calixa2010-10-06 10:05:57
QUOTE
enabled="y"
match="^You have slain (.+?)\\.$"
regexp="y"
send_to="12"
sequence="100"
>

SetVariable("GainedXPFrom", "%1")

EnableTrigger ("AfterXP", 1)
Send("weekrank")


Found the error, see the bolded bit. The two lines after it didn't get added due to that. Might want to correct that, now the script is working. Lovely wub.gif
Unknown2010-10-06 10:13:52
Now that's strange, as I just copied the XML, and I didn't even edit that trigger. But, yay for finding and making it work!

Also, I am quite suprised to have this results:

A Red Hand of the Illuminati (Influence)
Number of kills/influence: 29
Sum = 69140
Percentate of total XP: 6.57%
Average = 2384.1379310345

A monk disciple in grey robes(Influence)
Number of kills/influence: 36
Sum = 81360
Percentate of total XP: 7.73%
Average = 2260

Amazingly, monks are just barely below guards, while brothers and the Masters all thrash the guards in terms of xp.
Also, I managed to get 0 xp for a lizard when testing the killling trigger.


Oh yeah, and ignore the percentage for now if you had had gained xp before tracking. It'll only start showing proper percentage when the next week begins.

Edit: Ergh, found a typo as seen above. Change Percentate to Percentage. Fixed in the first post.
Calixa2010-10-06 18:39:50
Not too surprising since guards are stationary so you can near-afk it with a looping script.