PDA

View Full Version : XP per minute counter


Sprocket
10-20-2004, 01:00 PM
A feature I would really love to see is an indicator of XP over time.

XP per minute - would rock for tweaking monster killing strategy, minimizing downtime etc.

XP per hour - would help show you if you are wasting too much time on quests etc.


The value could be displayed either as XP/time or as Level Percentage/time.

Sprocket
Guild of SUN
EU Beta PvP Server

sarf
10-20-2004, 01:11 PM
Have you tried activating the Clock in Cosmos and mousing over it? It has XP / hour. It's an old version of Telo's Clock (check out his AddOns thread on the official forum).

XP per minute sounds like it should be a visible counter (like FPS or something).

It should be possible to do this seperately, however. I'll look into doing standalone windows that can be dragged (might be some new items in Cosmos that I can use), but I need to finish some of my old AddOn projects first.
I have a few on tap as it is - CooldownCount is still under development as is TextBarRight and OneHitWonder.... however, OHW is not likely to ever be "finished" (I need to get a Rogue and Warrior up to level 30 first, which is unlikely to happen considering I spend 40% of my time in WoW developing AddOns :( ).

I will look into doing a small XP / minute AddOn.

Bugzilla entry:
http://www.cosmosui.org/cgi-bin/bugzilla/show_bug.cgi?id=146

Sarf
---
reality.sys corrupted. universe halted. reboot (y/n)?

dsk
10-28-2004, 07:35 PM
Totally new to scripting and just got some minor C++ knowledge.
I'm not in beta and have never tried WoW so can't test if this works or not.

I'm working on a script or whatever you call it that will display XP per minute.
This value will be an average over a certain time(300s in this example).
Haven't looked into on how to display this on screen yet so that's added later.

I will add a XP last hour and a current XP rate per hour.
This is what I've got so far... probably not even working in game but it's atleast a start:


-- config
local timeReset = 300;

-- local variables
local xpRateReset= 0;
local xpStart = 0;
local xpCurrent = UnitXP("player");
local xpRateMin;
local timeSession;
local timeReset;
local timeStart=GetTime();
local xpRateSecond;



function xpRate()
xpRateReset = 0;
if ( xpStart = xpCurrent ) then
xpRateReset = xpRateMin;
end
if ( timeSession < timeReset ) then
timeSession = 1 + (GetTime() - timeStart); --time since xp counter started
xpRateSecond = ( xpCurrent - xpStart ) / timeSession; --xp per second
xpRateMin = xpRateSecond * 60 + xpRateReset; -- xp per minute
end
elseif ( timeSession > timeReset ) then
xpStart = UnitXP("player");
end

end

sarf
10-28-2004, 07:56 PM
Another solution:

local XP_Array = {};

local XP_Limit = 300;
local XP_Index = 1;

function AddXPValue()
XP_Index = XP_Index + 1;
if ( XP_Index > XP_Limit ) then
XP_Index = 1;
end
XP_Array[XP_Index] = UnitXP("player");
end

function GetXPPerPeriod(period)
if ( not period ) then
period = 60;
end
local xp = 0;
local lowLimit = 1;
if ( XP_Index > period ) then
lowLimit = XP_Index - period;
end
for i = lowLimit, XP_Index do
if ( XP_Array[i] ) then
xp = xp + XP_Array[i];
end
end
local numberOfPointsCollected = XP_Index;
if ( numberOfPointsCollected < period ) then
local size = table.getn(XP_Array);
local lowLimit= numberOfPointsCollected - size;
for i = lowLimit, size do
if ( XP_Array[i] ) then
xp = xp + XP_Array[i];
end
end
end
return xp;
end

function GetXPPerMinute()
return GetXPPerPeriod(60);
end
local XP_LastUpdate = 0;

-- this should be called in an <OnUpdate> script tag somewhere
function SomeAddOn_OnUpdate(elapsed)
local curTime = GetTime();
if ( curTime > (XP_LastUpdate + 1) ) then
XP_LastUpdate = curTime;
AddXPValue();
end
end
Note that this code is purely coded from the seat of my pants.

Sarf
---
COMPROMISE, n. Such an adjustment of conflicting interests as gives each adversary the satisfaction of thinking he has got what he ought not to have, and is deprived of nothing except what was justly his due.

dsk
10-28-2004, 09:14 PM
Nice code sarf... don't understand all of it though but by using arrays it should give a more accurate value.
Gonna try something different than what I did first... off to bed and then work tomorrow so wont be until late tomorrow I can start coding.

I once again feel motivated to do some programming again. :D

dsk
10-29-2004, 07:06 PM
Need some help with a "for" function... would this work:


a=0
b=4
for ( a < b )
a = a + 1;
end

--or is this "while" better

a=0
b=4
while ( a < b ) do
a = a + 1;
end

Will it loop until a=4 ?
As said... I'm a newbie when it comes to coding.

-edit-
Think I found the answer myself... better to use while in this case.

sarf
10-31-2004, 08:14 PM
local a=0;
local b=4;
for a = 0,b,1 do
-- stuff
end

This code will iterate from 0, to b and use 1 as a step.

Hope this helps.

Sarf
---
Yield to oncoming traffic.

dsk
11-01-2004, 10:30 AM
Thanks sarf.. I've done a new xp counter wich I think should work. Need to test it when open beta starts.


This one's supposed to do the calculations if there's been a change in the player experience(player killed a mob). Each time a player has killed a mob the experience and killtime from that mob is inserted into an array.
The size(number of kills) of the array can be changed if you want a more long term average.
The code also includes a killcount wich is going to be resetable.
The addon will show(when finished);
* Experience per minute (xp/min) and (xp/hour)
* Time elapsed since last kill(seconds)
* Average killtime(kills/min) and (kills/hour)
* Killcount since player logged in(or resetted the counter)
* Average damage done per mob(might be useful in groups)

I'll add features once the current code has been tested and verified.



local xpArray = {};
local timeArray = {};
local xpCurr = UnitXP("player");
local timeStart = GetTime();
local killCount = 0;
local xpSlotMax = numberOfKills - 1;
local xpSlotCurr = 0;


--place inside OnUpdate()
if ( counterStarted ) then
xpSum = 0;
timeCurr = GetTime();
xpCurr = UnitXP("player");
if ( xpCurr != xpLast ) then
xpArray[xpSlotCurr] = xpCurr - xpLast;
timeArray[xpSlotCurr] = timeCurr - timeLast;
xpLast = UnitXP("player");
timeLast = GetTime();
while ( xpSlot != xpSlotMax + 1) then
xpSum = xpSum + xpArray[xpSlot];
xpSlot = xpSlot + 1;
timeTotal = timeTotal + timeArray[timeSlot];
timeSlot = timeSlot + 1;
end
xpSlot = 0;
xpRateSecond = xpSum / (GetTime() - timeTotal);
xpRateMinute = xpRateSecond * 60;
if ( xpSlotCurr < xpSlotMax ) then
xpSlotCurr = xpSlotCurr + 1;
else
xpSlotCurr = 0;
end
killCount = killCount + 1;

end
end


I'll stop adding things to this now... need to look into on how to display the values in-game.

sarf
11-01-2004, 11:41 AM
Note that to accurately measure, it is necessary to update the current average even when you do not earn experience.

I would therefore recommend that you divide the code into two pieces, one piece that added new experience (which should be available as an event somehow, but can be dealt with in the update function when necessary otherwise) and another which calculated the new average. This would mean that you'd have a "warm-up" and "cooldown" period in the XP counter, but that is OK.

To display the XP average, you have two ways, basically.

One is to display it as a tooltip. This is very easy to do, but has some other issues (basically, updating one tooltip "destroys" other tooltips, as was the case with the QuestMinion and the money associated with selling stuff).

The other way is to do a window. This is not very hard to do, but it is more work than adding a simple tooltip.

I'd recommend that you check out how DPSPLUS/CombatStats add display their things. Adapting that to suit you should be rather simple.

Sarf
---
AMBIDEXTROUS, adj. Able to pick with equal skill a right-hand pocket or a left.

dsk
11-02-2004, 12:48 AM
Thanks for the hints sarf... it looks like I have to learn how to make windows then. Btw, is it possible to make borderless and transparent windows?

Is there any tutorial on how to make windows or where should I start looking?
It's kinda hard learning something when you can't test if things work or not. :D

I'll leave the calculations as it is now as I'd rather learn to make a complete addon rather than adding features right now. :) I'll think of changing the way it measures but by using per kill update I think it should display a correct value after just a couple kills(to include downtime) but I haven't played WoW yet so it might have to be changed if there's a big difference on how much XP you gain each mob.

sarf
11-02-2004, 06:14 AM
Hmm... there's few AddOns which use a simple window, but... check out Vickel (ExampleAddOn), I think it uses windows. Windows are by default borderless and transparent I think.

Sarf
---
If you can't convince them, confuse them.

dsk
11-04-2004, 02:26 PM
I gave up making addons by now... need to wait until there's more tutorials.
What I need to learn but have no idea how to:
1. Register with cosmos
2. Make a Checkbox(enable/disable addon)
3. Config slider (2-20)
4. Display the value(xp rate) next to the DPS counter or below HP/Energy bar.

I'm back to play WoW stress test now...

sarf
11-04-2004, 04:57 PM
For 1&2, check out my BaseMod (http://www.fukt.bth.se/~k/wow/scripts/BaseMod/).

For 3, check out some of my other AddOns (http://www.fukt.bth.se/~k/wow/scripts/) (registering a slider basically just means adding more variables).

For 4, check out how DPSPLUS / CombatStats does it.

Sarf
---
We learn from history that we do not learn anything from history.

simmoi
12-16-2004, 06:44 PM
anyone intersted in picking this up? =/
-xp per minute
-xp last hour

simmoi
12-17-2004, 05:44 PM
heres some code for xp per min, works pretty well
localization.lua update

-- Version : English - Telo

CLOCK = "Clock";
BINDING_HEADER_CLOCK = "Clock Keys";
BINDING_NAME_TOGGLECLOCK = "Toggle Clock";
TIME_PLAYED_SESSION = "Time played this session: %s"; -- The amount of time played this session
CLOCK_TIME_DAY = "%d day";
CLOCK_TIME_HOUR = "%d hour";
CLOCK_TIME_MINUTE = "%d minute";
CLOCK_TIME_SECOND = "%d second";
EXP_PER_HOUR_LEVEL = "Experience per hour this level: %.2f";
EXP_PER_HOUR_SESSION = "Experience per hour this session: %.2f";
EXP_PER_MIN_SESSION = "Experiance per min this session: %.2f";
EXP_TO_LEVEL = "Experience to level: %d (%.2f%% to go)";
TIME_TO_LEVEL_LEVEL = "Time to level at this level's rate: %s";
TIME_TO_LEVEL_SESSION = "Time to level at this session's rate: %s";
TIME_INFINITE = "infinite";
HEALTH_PER_SECOND = "Health regenerated per second: %d";
MANA_PER_SECOND = "Mana regenerated per second: %d";
NONCOMBAT_TRAVEL_PERCENTAGE = "Time spent traveling this session: %.2f%%";
NONCOMBAT_TRAVEL_DISTANCE = "Distance traveled this session: %.2f";
TRAVEL_SPEED = "Travel speed as a percentage of run speed: %.2f%%";

-- all options called CLOCK_OPTION_* were added 2004-10-20 by sarf - they'll need to be translated.

CLOCK_OPTION_HEADER = "Clock";
CLOCK_OPTION_HEADER_INFO = "This is an in-game clock.";

CLOCK_OPTION_ENABLE = "Enable the clock";
CLOCK_OPTION_ENABLE_INFO = "This will display the in-game clock with a nice mouseover.\nThe mouseover contains lots of interesting data and info.";

CLOCK_OPTION_TIME_OFFSET = "Game time offset";
CLOCK_OPTION_TIME_OFFSET_INFO = "This is the offset from the server time\nto your local time.";
CLOCK_OPTION_TIME_OFFSET_SLID_1 = "Offset";
CLOCK_OPTION_TIME_OFFSET_SLID_2 = " hour(s)";

CLOCK_OPTION_TWENTYFOUR_HOURS = "Use 24-hour time format";
CLOCK_OPTION_TWENTYFOUR_HOURS_INFO = "If checked, time will be displayed\nin twenty-four hour format (also called military time by some).";

CLOCK_OPTION_RESET_POSITION = "Reset clock position";
CLOCK_OPTION_RESET_POSITION_INFO = "Resets the position of the clock to its default.";
CLOCK_OPTION_RESET_POSITION_NAME = "Reset";

CLOCK_OPTION_RESET_DATA = "Reset the clock data";
CLOCK_OPTION_RESET_DATA_INFO = "Resets the data gathered by the clock.";
CLOCK_OPTION_RESET_DATA_NAME = "Reset";

if ( GetLocale() == "frFR" ) then
-- Traduction par Vjeux
BINDING_NAME_TOGGLECLOCK = "Afficher l'Horloge";

CLOCK = "Horloge";
TIME_PLAYED_SESSION = "Temps joué sur cette session : %s";
CLOCK_TIME_DAY = "%d jour";
CLOCK_TIME_HOUR = "%d heure";
CLOCK_TIME_MINUTE = "%d minute";
CLOCK_TIME_SECOND = "%d seconde";
EXP_PER_HOUR_LEVEL = "Expérience/heure ce niveau : %.2f";
EXP_PER_HOUR_SESSION = "Expérience/heure sur cette session : %.2f";
EXP_PER_MIN_SESSION = "Experiance per min this session: %.2f";
HEALTH_PER_SECOND = "Régénération de vie/seconde : %d";
MANA_PER_SECOND = "Régénération de mana/seconde : %d";
EXP_TO_LEVEL = "Expérience pour monter de niveau : %d (%.2f%% restants)";
TIME_TO_LEVEL_LEVEL = "Temps pour monter à la vitesse de ce niveau : %s";
TIME_TO_LEVEL_SESSION = "Temps pour monter à la vitesse de cette session : %s";
TIME_INFINITE = "infini";
NONCOMBAT_TRAVEL_PERCENTAGE = "Temps passé à voyager cette session : %.2f%%";
NONCOMBAT_TRAVEL_DISTANCE = "Distance parcourue cette session : %.2f";
TRAVEL_SPEED = "Vitesse actuelle : %.2f%%";

elseif ( GetLocale() == "deDE" ) then
-- Translation by ???? and pc

BINDING_NAME_TOGGLECLOCK = "Uhr Umschalter";
CLOCK = "Uhr";
TIME_PLAYED_SESSION = "Gespielte Zeit diese Sitzung %s";
CLOCK_TIME_DAY = "%d tag";
CLOCK_TIME_HOUR = "%d stunde";
CLOCK_TIME_MINUTE = "%d minute";
CLOCK_TIME_SECOND = "%d sekunde";
EXP_PER_HOUR_LEVEL = "Erfahrung pro Stunde dieses Level : %.2f";
EXP_PER_HOUR_SESSION = "Erfahrung pro Stunde diese Sitzung: %.2f";
EXP_PER_MIN_SESSION = "Experiance per min this session: %.2f";
HEALTH_PER_SECOND = "Leben regeneriert pro Sekunde : %d";
MANA_PER_SECOND = "Mana regeneriert pro Sekunde: %d";
EXP_TO_LEVEL = "Erfahrung pro Level: %d (noch %.2f%%)";
TIME_TO_LEVEL_LEVEL = "Zeit um Level aufzusteigen (unter Beibehaltung der Aufstiegsgeschwindigkeit des aktuellen Levels): %s";
TIME_TO_LEVEL_SESSION = "Zeit um Level auzusteigen (unter Beibehaltung der Aufstiegsgeschwindigkeit dieser Sitzung): %s";
TIME_INFINITE = "Unedlich";
NONCOMBAT_TRAVEL_PERCENTAGE = "Verbrachte Zeit auf Reise: %.2f%%";
NONCOMBAT_TRAVEL_DISTANCE = "Zurückgelegte Enfernung diese Sitzung: %.2f";
TRAVEL_SPEED = "Reisegeschwindigkeit (in Prozent von Renngeschwindigkeit): %.2f%%";


end


clock.lua function Clock_SetTooltip()

function Clock_SetTooltip()
local total, level, session;
local xpPerHourLevel, xpPerHourSession;
local xpPerMinSession;
local xpTotal, xpCurrent, xpToLevel;
local text;

total = format(TEXT(TIME_PLAYED_TOTAL), Clock_FormatTime(TotalTimePlayed + ElapsedSinceLastPlayedMessage));
level = format(TEXT(TIME_PLAYED_LEVEL), Clock_FormatTime(LevelTimePlayed + ElapsedSinceLastPlayedMessage));
session = format(TEXT(TIME_PLAYED_SESSION), Clock_FormatTime(SessionTimePlayed));

if( NeedPlayedMessage == 1 ) then
text = session;
else
text = total.."\n"..level.."\n"..session;
end

if( (LevelTimePlayed + ElapsedSinceLastPlayedMessage > 0) or SessionTimePlayed > 0 ) then
text = text.."\n";
end
if( LevelTimePlayed + ElapsedSinceLastPlayedMessage > 0 ) then
xpPerHourLevel = UnitXP("player") / ((LevelTimePlayed + ElapsedSinceLastPlayedMessage) / 3600);
text = text.."\n"..format(TEXT(EXP_PER_HOUR_LEVEL), xpPerHourLevel);
else
xpPerHourLevel = 0;
end

if( SessionTimePlayed > 0 ) then

xpPerHourSession = localSessionXP / (SessionTimePlayed / 3600);
text = text.."\n"..format(TEXT(EXP_PER_HOUR_SESSION), xpPerHourSession);

xpPerMinSession = localSessionXP / (SessionTimePlayed / 60);
text = text.."\n"..format(TEXT(EXP_PER_MIN_SESSION), xpPerMinSession);

else
xpPerHourSession = 0;
xpPerMinSession = 0;
end