I will explain how it works and how you can add the new APM counter to your mod. The gadget is based on the FPS counter gadget made by Floris, every player's machine broadcasts their APM statistics to each other player in real time, and this make the data publicly available during the match.
line 59 _, mc, kp, _, _ = GetPlayerStatistics(myPlayerID) undocumented engine function, this provides the total sum of all mouseclicks and keypresses at the time it is called
line 60 SendLuaRulesMsg("$" .. (math.ceil((((mc + kp) * 60) / (math.max(GetGameSeconds(), 60))) - 0.5))) calculate the APM statistics and broadcast them so can be receive by a widget
gadget: apm_broadcast.lua, add to luarules\gadgets
Code: Select all
function gadget:GetInfo()
return {
name = "APM Broadcast",
desc = "Broadcasts APM",
author = "Floris",
date = "July,2016",
license = "GNU GPL, v2 or later",
layer = 0,
enabled = true
}
end
local GetMyPlayerID = Spring.GetMyPlayerID
--------------------------------------------------------------------------------
-- config
--------------------------------------------------------------------------------
local sendPacketEvery = 2
--------------------------------------------------------------------------------
-- synced
--------------------------------------------------------------------------------
if gadgetHandler:IsSyncedCode() then
function gadget:RecvLuaMsg(msg, playerID)
if msg:sub(1, 1) == "$" then
SendToUnsynced("apmBroadcast", playerID, tonumber(msg:sub(2)))
return true
end
end
else
--------------------------------------------------------------------------------
-- unsynced
--------------------------------------------------------------------------------
local GetLastUpdateSeconds = Spring.GetLastUpdateSeconds
local SendLuaRulesMsg = Spring.SendLuaRulesMsg
local myPlayerID = GetMyPlayerID()
local updateTimer = 0
local GetPlayerStatistics = Spring.GetPlayerStatistics
local GetGameSeconds = Spring.GetGameSeconds
function gadget:Initialize()
gadgetHandler:AddSyncAction("apmBroadcast", handleApmEvent)
end
function gadget:Shutdown()
gadgetHandler:RemoveSyncAction("apmBroadcast")
end
function handleApmEvent(_, playerID, apm)
if Script.LuaUI("ApmEvent") then
Script.LuaUI.ApmEvent(playerID, apm)
end
end
function gadget:Update()
if not Spring.GetSpectatingState() then
updateTimer = updateTimer + GetLastUpdateSeconds()
if updateTimer > sendPacketEvery then
_, mc, kp, _, _ = GetPlayerStatistics(myPlayerID)
SendLuaRulesMsg("$" .. (math.ceil((((mc + kp) * 60) / (math.max(GetGameSeconds(), 60))) - 0.5)))
updateTimer = 0
end
end
end
end
In BA the APM is added to the widget gui_advplayerslist.lua in \luaui\widgets, here are the relevant parts:
Code: Select all
function widget:Initialize()
widgetHandler:RegisterGlobal('ApmEvent', ApmEvent)
end
function widget:Shutdown()
widgetHandler:DeregisterGlobal('ApmEvent')
end
local lastApmData = {}
function ApmEvent(playerID, apm)
lastApmData[player[playerID].team] = apm
end
function DrawID(playerID, posY, dark)
local apm = 0
if((lastApmData[playerID] ~= nil)) then
apm = lastApmData[playerID]
end
if(apm>998) then
apm = 999
end
Spring.Echo(apm)
end