-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgame_track_sabotage.lua
More file actions
148 lines (131 loc) · 4.35 KB
/
Copy pathgame_track_sabotage.lua
File metadata and controls
148 lines (131 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
function widget:GetInfo()
return {
name = "Track Sabotage",
desc = "Track when players destroy eco buildings in PvE",
author = "manshanko",
date = "2025-04-04",
home = "https://github.com/manshanko/bar-widgets",
layer = 2,
}
end
local echo = Spring.Echo
local format = string.format
local AreTeamsAllied = Spring.AreTeamsAllied
local MarkerAddPoint = Spring.MarkerAddPoint
local GetUnitPosition = Spring.GetUnitPosition
local GetGameSeconds = Spring.GetGameSeconds
local GetPlayerList = Spring.GetPlayerList
local GetPlayerInfo = Spring.GetPlayerInfo
local UnitDefs = UnitDefs
local EXPORT_DIR = "userdata"
local PLAYERS = {}
local LOG = {}
local FF_COUNT = {}
local ECO_DEFS = {}
local BUILDER_DEFS = {}
local MY_TEAM = Spring.GetMyTeamID()
local GAME_DATE
-- 30 game frames per second
local DEBOUNCE = 300
local GAME_FRAME = 0
for unit_def_id, unit_def in pairs(UnitDefs) do
if (unit_def.energyMake > 0
or unit_def.energyUpkeep < 0
or unit_def.extractsMetal > 0
or (unit_def.customParams and unit_def.customParams.energymultiplier)
or (unit_def.customParams and unit_def.customParams.energyconv_efficiency))
and unit_def.isBuilding
and not unit_def.isBuilder
then
ECO_DEFS[unit_def_id] = unit_def
end
if unit_def.isBuilder then
BUILDER_DEFS[unit_def_id] = unit_def
end
end
local LAST_FRAME = -DEBOUNCE
function widget:UnitDestroyed(unit_id, unit_def_id, unit_team, attacker_id, attacker_def_id, attacker_team)
if attacker_team
and attacker_team >= 0
and unit_team ~= attacker_team
and attacker_team ~= MY_TEAM
and AreTeamsAllied(unit_team, attacker_team)
and ECO_DEFS[unit_def_id]
-- ignore builders since it could be reclaim
and not BUILDER_DEFS[attacker_def_id]
then
local attacker_players = GetPlayerList(attacker_team)
if #attacker_players == 0 then
-- only AI
return
end
if LAST_FRAME > (GAME_FRAME - DEBOUNCE) then
return
end
LAST_FRAME = GAME_FRAME
local attacker_name
if #attacker_players == 1 then
local name = GetPlayerInfo(attacker_players[1])
FF_COUNT[name] = (FF_COUNT[name] and FF_COUNT[name] + 1) or 1
attacker_name = name
else
attacker_name = "["
local first = true
for _, player_id in ipairs(attacker_players) do
local name = GetPlayerInfo(player_id)
FF_COUNT[name] = (FF_COUNT[name] and FF_COUNT[name] + 1) or 1
if first then
first = false
attacker_name = attacker_name .. name
else
attacker_name = attacker_name .. ", " .. name
end
end
attacker_name = attacker_name .. "]"
end
local unit_name = UnitDefs[unit_def_id].translatedHumanName
local attacker_unit_name = UnitDefs[attacker_def_id].translatedHumanName
local text = format("%s killed by %s from %s",
unit_name,
attacker_unit_name,
attacker_name)
LOG[#LOG + 1] = {
time = GetGameSeconds(),
text = text,
}
local x, y, z = GetUnitPosition(unit_id)
MarkerAddPoint(x, y, z, text, true)
end
end
function widget:GameFrame(frame)
GAME_FRAME = frame
end
function widget:Initialize()
-- https://en.wikipedia.org/wiki/ISO_8601
GAME_DATE = os.date("%Y%m%dT%H%M%S")
for _, player_id in ipairs(GetPlayerList(-1)) do
PLAYERS[#PLAYERS + 1] = GetPlayerInfo(player_id)
end
end
function widget:Shutdown()
if #LOG > 0 then
if not VFS.FileExists(EXPORT_DIR) then
Spring.CreateDir(EXPORT_DIR)
end
local name = format("%s/%s.json", EXPORT_DIR, GAME_DATE)
local json = Json.encode({
players = PLAYERS,
counts = FF_COUNT,
pings = LOG,
})
local file, err = io.open(name, "w")
if err then
echo("[game_track_sabotage][ERROR] Failed to open file: " .. err)
return
end
--Spring.Log()
--echo("[game_track_sabotage] Saving data to \"" .. name .. "\"")
file:write(json)
file:close()
end
end