So that you don't need to re-create the list of players constantly, which will reduce overhead. (time it takes for your computer to do the calculations)
I think that the list of players should be done in login, logout and level advance functions.
Not in onThink.
in pre tfs 1.0x servers each section (actions/globalevents/creatureevents/et cetera) is localised, and cannot share tables with each other. (trust me, I've tried)
The only way to change it like you propose is to use storage values, and then use onThink to send the animations to the players with the correct storage values.
Honestly, it's probably the better solution, just a bit more time consuming to create initially..
But that's assuming a few things.
Counter-point 1, this is assuming players are not being assholes.
Example: Logging in & out constantly.
Counter-point 2, this is assuming the server is a low-rate exploration server.
Example: Highrate server, where player levels are constantly changing.
Example: War-based server, where player levels are changing constantly, and players are dying, which causes a logout and login as well as an advance function to trigger.
Those are the bigger examples, but there are some smaller things you could look at as well.
When these above events are happening, the overhead to the server would be huge, especially if you multiply the amount of players online doing the same 'destructive' behaviour.
For these reasons, I believe it's best to have a consistent triggering of the event, instead of low and high spikes of activity.
------------------------------
As for my script, if you are not worried about getting the most up-to-date information, we could change it to update the player highscores every 5 minutes, for example, to reduce the amount of overhead the script causes.
(So it checks for first to fifth place once per 5 minutes, and then sends the animations to the players for a full 5 minutes, before checking for player highscores again.)
(Note: If a highscoring player logs out or dies inbetween the 5 minute checks, they will no longer have the effect, until the next 5 minute check.)
So, same as before.
5 * 60 = 300 seconds
But, if it counts in milliseconds, use 300 * 1000 = 300000
XML:
<globalevent name="highscore_animation" interval="300" event="script" value="highscore_animation.lua"/>
Lua:
local config = { -- player with high scores get these effects, based on their ranking
[1] = CONST_ME_HEARTS, -- first place
[2] = CONST_ME_CRAPS,
[3] = CONST_ME_FIREWORK_BLUE,
[4] = CONST_ME_FIREWORK_YELLOW,
[5] = CONST_ME_FIREWORK_RED -- fifth place
}
local function compare(a, b)
return a[1] > b[1]
end
local function send_effect(cid, rank, amount)
if not isPlayer(cid) then
return true
end
doSendMagicEffect(getCreaturePosition(cid), config[rank])
if amount > 0 then
addEvent(send_effect, 2000, cid, rank, amount - 1)
end
end
function onThink(cid, interval, lastExecution)
local player_data, temp1, temp2 = {}, 0, 1
for _, pid in ipairs(getPlayersOnline()) do
player_data[#player_data + 1] = {getPlayerLevel(pid), pid}
end
table.sort(player_data, compare)
for i = 1, #player_data do
if temp1 == 0 or temp1 == player_data[i][1] then
addEvent(send_effect, 0, player_data[i][2], temp2, 150)
elseif temp2 < 5 then
addEvent(send_effect, 0, player_data[i][2], temp2 + 1, 150)
temp2 = temp2 + 1
else
break
end
temp1 = player_data[i][1]
end
return true
end