• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Average hits per second (Counting hits)

Paulix

Active Member
Joined
Sep 13, 2012
Messages
129
Solutions
7
Reaction score
26
I'm trying to create a weapon to count how many attacks per second the player can deal using it, but since os.time() only return seconds, I dont know exactly what to do, can someone help me?
Idk the tfs version, but tibia version is 8.6, but im not new in proggraming, just a rude idea would help me a lot

Lua:
function onUseWeapon(cid, var)
    local avg = 0.000
    local attime = os.time()
    local oltime = getCreatureStorage(cid, 50033)
    local hits = getCreatureStorage(cid, 50032)
   
    if attime-oltime >= 3 then
        doCreatureSetStorage(cid, 50033, attime)
        doCreatureSetStorage(cid, 50032, 1)
    end
   
    if oltime == attime then
        doCreatureSetStorage(cid, 50032, hits+1)
        avg = hits/1
    elseif oltime ~= attime then
        avg = hits/1
        doCreatureSetStorage(cid, 50033, attime)
        doCreatureSetStorage(cid, 50032, 1)
    end

    doSendAnimatedText(getPlayerPosition(cid), ""..string.format("%.3f", avg), COLOR_RED)
    doCombat(cid, combat, var)
   
    return 1
end
 
Do like Doctor's and Nurses.
Count how many times it triggers over 15 seconds.

Hit 120 times over 15 seconds?
120/15 = hits per second
 
Do like Doctor's and Nurses.
Count how many times it triggers over 15 seconds.

Hit 120 times over 15 seconds?
120/15 = hits per second
yeah, but how can I count exactly 15 seconds? since I cant check if player attacked on beggining or end of a second
 
here you go friend
tried to explain it a bit too with comments
this could be improved if you care about small bits of memory being taken up for no reason, since cids become invalid once the creature logs out or dies, counting[cid] would just sit there forever until it gets deleted
if you care about that i can make it clean the table for you but for now it's w/e
Lua:
local counting = {}

local seconds = 15

function onUseWeapon(cid, var)
    counting[cid] = counting[cid] or {start = os.time(), attackCount = 0} -- if the player doesnt have an index in counting create one
    if (counting[cid].start + seconds) > os.time() then -- check if end time is higher than current time
        count.attackCount = count.attackCount + 1 -- increase attack count since it's not time to show the average yet
        return doCombat(cid, combat, var)
    end

    doSendAnimatedText(getThingPosition(cid), string.format("%.3f", counting[cid].attackCount / seconds), TEXTCOLOR_RED)
    counting[cid].attackCount = 0 -- reset attack count so it can start counting again
    counting[cid].start = os.time() + seconds -- reset start time so it can start counting again

    return doCombat(cid, combat, var)
end
 
Lua:
local counting = {}

local seconds = 15

function onUseWeapon(cid, var)
    counting[cid] = counting[cid] or {start = os.time(), attackCount = 0} -- if the player doesnt have an index in counting create one
    if (counting[cid].start + seconds) > os.time() then -- check if end time is higher than current time
        count[COLOR=#ff0000]ing[/COLOR].attackCount = count[COLOR=#ff0000]ing[/COLOR].attackCount + 1 -- increase attack count since it's not time to show the average yet
        return doCombat(cid, combat, var)
    end

    doSendAnimatedText(getThingPosition(cid), string.format("%.3f", counting[cid].attackCount / seconds), TEXTCOLOR_RED)
    counting[cid].attackCount = 0 -- reset attack count so it can start counting again
    counting[cid].start = os.time() + seconds -- reset start time so it can start counting again

    return doCombat(cid, combat, var)
end
I had to add the red parts cause count doesnt exist on code, but it still returning some kind of error on this line:

Code:
counting.attackCount = counting.attackCount + 1 -- increase attack count since it's not time to show the average yet

attempt to perform arithmetic on field 'attackCount' (a nil value)

I just dont get the difference between counting[cid] and counting, since you used it both ways
 
I had to add the red parts cause count doesnt exist on code, but it still returning some kind of error on this line:

Code:
counting.attackCount = counting.attackCount + 1 -- increase attack count since it's not time to show the average yet

attempt to perform arithmetic on field 'attackCount' (a nil value)

I just dont get the difference between counting[cid] and counting, since you used it both ways

counting is the table
counting[x] is a value in the table, x is the index.
So if the player id is 1 then counting would have a value with the index 1, in this case the value is a table, since it contains more then 1 item (attackCount, start, again) etc

Just google Lua tables if you wanna learn more; lua-users wiki: Tables Tutorial
 
I had to add the red parts cause count doesnt exist on code, but it still returning some kind of error on this line:

Code:
counting.attackCount = counting.attackCount + 1 -- increase attack count since it's not time to show the average yet

attempt to perform arithmetic on field 'attackCount' (a nil value)

I just dont get the difference between counting[cid] and counting, since you used it both ways
i forgot, braindead rn sorry
change it to counting[cid].attackCount on both
the difference is counting holds all the data for each player so it can keep counting attacks and store the ending time that we need to compare current time with
counting[cid] holds those
for example it would look like this inside
Lua:
local counting = {
    [876234] = {start = 1498000632, attackCount = 5},
    [876236] = {start = 1498000638, attackCount = 5}
    -- will store many more inside but these 2 are just examples of how it works
}
 
here is the code I made based on what Xikini said
Lua:
function onUseWeapon(cid, var)
   local avg = 0.000
   local attime = os.time()
   local oltime = getCreatureStorage(cid, 50033)
   local hits = getCreatureStorage(cid, 50032)
   local blind = getCreatureStorage(cid, 50005)
   local chance = getExtra(cid, EXTRA_CHANCE)
  
   if attime-oltime >= 16 then
       doCreatureSetStorage(cid, 50033, attime)
       doCreatureSetStorage(cid, 50032, 0)
       print("start")
   end
  
   oltime = getCreatureStorage(cid, 50033)
   hits = getCreatureStorage(cid, 50032)
  
   if attime-oltime >= 15 then
       doCreatureSetStorage(cid, 50032, hits+1)
       avg = hits/15
       doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "you hit "..hits.." times in 15 seconds, with an avg of "..string.format("%.2f",avg).." hits per second")
       doCreatureSetStorage(cid, 50033, attime)
       doCreatureSetStorage(cid, 50032, 0)
       print("stop")
   else
       doCreatureSetStorage(cid, 50032, hits+1)
   end

   return doCombat(cid, combat, var)
end

and here is static script, both workings on my server

Lua:
local counting = {}
local seconds = 15
function onUseWeapon(cid, var)
    counting[cid] = counting[cid] or {start = os.time(), attackCount = 0} -- if the player doesnt have an index in counting create one
    if (counting[cid].start + seconds) > os.time() then -- check if end time is higher than current time
        counting[cid].attackCount = counting[cid].attackCount + 1 -- increase attack count since it's not time to show the average yet
        return doCombat(cid, combat, var)
    end
   doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "you hit "..counting[cid].attackCount.." times in "..seconds.." seconds, with an avg of "..string.format("%.2f",counting[cid].attackCount / seconds).." hits per second")
    counting[cid].attackCount = 0 -- reset attack count so it can start counting again
    counting[cid].start = os.time() + seconds -- reset start time so it can start counting again
    return doCombat(cid, combat, var)
end

the problem is that they have a bit of inconsistency, since it never counts the full 15 seconds, we always end up with 1 hit less than it should here is an example
J4xnf5C.png
 
use os.mtime()

This counts in miliseconds instead of full seconds.

MUCH more accurate.
If that is an actual lua function, I'm about to fucking shoot someone. lmao

mm Okay. So it definitely gives milliseconds, but it gives a huge number.
Between spam clicks, I got these numbers..
Code:
1498077188711
1498077188901
1498077189091
1498077189281
1498077189472
1498077189662
How would one go about using this properly?
I guess I could find out the time it takes for a script to complete..
Well, everything except for my most complex scripts returns 0, and the complex one's return 1 millisecond.
So that's pretty cool to know.

Alright, so I kinda know how to use it now.

Welp,
Even searching google, knowing the function, there's very little information about it, and the actual lua guide online doesn't say it exists. T.T

Thank you.
 
Welp,
Even searching google, knowing the function, there's very little information about it, and the actual lua guide online doesn't say it exists. T.T
Because it is not standard lua function. It's in TFS sources.
It's unix time counted as milliseconds.

the problem is that they have a bit of inconsistency, since it never counts the full 15 seconds, we always end up with 1 hit less than it should here is an example
Start counting from 1.
Lua:
    counting[cid] = counting[cid] or {start = os.time(), attackCount = 1} -- if the player doesnt have an index in counting create one
Lua:
    counting[cid].attackCount = 1 -- reset attack count so it can start counting again
 
Back
Top