capturetheflag/mods/ctf_stats/init.lua

230 lines
5.5 KiB
Lua
Raw Normal View History

2015-11-29 00:05:37 +00:00
ctf_stats = {}
2017-10-12 23:09:25 +00:00
local storage = minetest.get_mod_storage()
local data_to_persist = { "matches", "players" }
2015-11-29 00:05:37 +00:00
function ctf_stats.load()
2017-10-12 23:09:25 +00:00
local file = io.open(minetest.get_worldpath() .. "/ctf_stats.txt", "r")
2015-11-29 00:05:37 +00:00
if file then
local table = minetest.deserialize(file:read("*all"))
2017-10-12 23:09:25 +00:00
file:close()
2015-11-29 00:05:37 +00:00
if type(table) == "table" then
2017-10-12 23:09:25 +00:00
ctf.log("ctf_stats", "Migrating stats...")
2015-11-29 00:05:37 +00:00
ctf_stats.matches = table.matches
ctf_stats.players = table.players
2017-10-12 23:09:25 +00:00
for name, player_stats in pairs(ctf_stats.players) do
if not player_stats.score or player_stats.score < 0 then
player_stats.score = 0
end
if player_stats.score > 300 then
player_stats.score = (player_stats.score - 300) / 30 + 300
end
if player_stats.score > 800 then
player_stats.score = 800
end
end
ctf.needs_save = true
end
os.remove(minetest.get_worldpath() .. "/ctf_stats.txt")
else
for _, key in pairs(data_to_persist) do
ctf_stats[key] = minetest.parse_json(storage:get_string(key))
2015-11-29 00:05:37 +00:00
end
end
2017-10-12 23:09:25 +00:00
ctf_stats.matches = ctf_stats.matches or {
wins = {
blue = 0,
red = 0,
},
2015-11-29 00:05:37 +00:00
skipped = 0
}
2017-10-12 23:09:25 +00:00
ctf_stats.current = ctf_stats.current or {
2015-11-29 00:05:37 +00:00
red = {},
blue = {}
}
2017-10-12 23:09:25 +00:00
ctf_stats.players = ctf_stats.players or {}
2015-11-29 00:05:37 +00:00
end
ctf.register_on_save(function()
2017-10-12 23:09:25 +00:00
for _, key in pairs(data_to_persist) do
storage:set_string(key, minetest.write_json(ctf_stats[key]))
2015-11-29 00:05:37 +00:00
end
return nil
end)
2017-10-12 23:09:25 +00:00
-- Returns a tuple: `player_stats`, `match_player_stats`
2015-11-29 00:05:37 +00:00
function ctf_stats.player(name)
2017-10-12 23:09:25 +00:00
local player_stats = ctf_stats.players[name]
if not player_stats then
player_stats = {
2015-12-03 23:57:28 +00:00
name = name,
2017-10-12 23:09:25 +00:00
wins = {
red = 0,
blue = 0,
},
2015-11-29 00:05:37 +00:00
kills = 0,
deaths = 0,
2015-12-03 23:57:28 +00:00
captures = 0,
2017-10-12 00:19:23 +00:00
attempts = 0,
2017-10-12 23:09:25 +00:00
score = 0,
2015-11-29 00:05:37 +00:00
}
2017-10-12 23:09:25 +00:00
ctf_stats.players[name] = player_stats
2015-11-29 00:05:37 +00:00
end
2017-10-12 23:09:25 +00:00
local match_player_stats =
ctf_stats.current.red[name] or ctf_stats.current.blue[name]
2015-11-29 00:05:37 +00:00
2017-10-12 23:09:25 +00:00
return player_stats, match_player_stats
2015-11-29 00:05:37 +00:00
end
ctf.register_on_join_team(function(name, tname)
2017-10-12 23:09:25 +00:00
ctf_stats.current[tname][name] = ctf_stats.current[tname][name] or {
2015-11-29 00:05:37 +00:00
kills = 0,
2017-10-12 23:09:25 +00:00
kills_since_death = 0,
2015-11-29 00:05:37 +00:00
deaths = 0,
2015-12-03 23:46:52 +00:00
attempts = 0,
2017-10-12 23:09:25 +00:00
captures = 0,
score = 0,
2015-11-29 00:05:37 +00:00
}
end)
ctf_match.register_on_skip_map(function()
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
2015-11-29 00:05:37 +00:00
ctf_stats.matches.skipped = ctf_stats.matches.skipped + 1
end)
2015-12-03 23:46:52 +00:00
ctf_flag.register_on_capture(function(name, flag)
2015-12-03 23:57:28 +00:00
local main, match = ctf_stats.player(name)
if main and match then
2017-10-12 23:09:25 +00:00
main.captures = main.captures + 1
main.score = main.score + 20
2015-12-03 23:57:28 +00:00
match.captures = match.captures + 1
2017-10-12 23:09:25 +00:00
match.score = match.score + 20
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
2015-12-03 23:46:52 +00:00
end
end)
2015-11-29 00:05:37 +00:00
ctf_match.register_on_winner(function(winner)
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
2017-10-12 23:09:25 +00:00
ctf_stats.matches.wins[winner] = ctf_stats.matches.wins[winner] + 1
2015-11-29 00:05:37 +00:00
end)
ctf_match.register_on_new_match(function()
2015-12-03 23:46:52 +00:00
local fs = ctf_stats.get_formspec_match_summary(ctf_stats.current)
local players = minetest.get_connected_players()
for _, player in pairs(players) do
minetest.show_formspec(player:get_player_name(), "ctf_stats:eom", fs)
end
2015-11-29 00:05:37 +00:00
ctf_stats.current = {
red = {},
blue = {}
}
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
2015-11-29 00:05:37 +00:00
end)
ctf_flag.register_on_pick_up(function(name, flag)
local main, match = ctf_stats.player(name)
if main and match then
2017-10-12 23:09:25 +00:00
main.attempts = main.attempts + 1
main.score = main.score + 5
match.attempts = match.attempts + 1
2017-10-12 23:09:25 +00:00
match.score = match.score + 5
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
end
2015-11-29 00:05:37 +00:00
end)
ctf_flag.register_on_precapture(function(name, flag)
local tplayer = ctf.player(name)
local main, match = ctf_stats.player(name)
if main then
2017-10-12 23:09:25 +00:00
main.wins[tplayer.team] = main.wins[tplayer.team] + 1
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
end
2015-11-29 00:05:37 +00:00
return true
end)
2017-10-12 23:09:25 +00:00
local good_weapons = {
"default:sword_steel",
"shooter:grenade",
"shooter:shotgun",
"shooter:rifle",
"shooter:machine_gun",
}
local function invHasGoodWeapons(inv)
for _, weapon in pairs(good_weapons) do
if inv:contains_item("main", weapon) then
return true
end
end
return false
end
local function calculateKillReward(victim, killer)
local vmain, victim_match = ctf_stats.player(victim)
-- +5 for every kill they've made since last death in this match.
local reward = victim_match.kills_since_death * 5
ctf.log("ctf_stats", "Player " .. victim .. " has made " .. reward .. " kills since last death")
-- 15 * kd ration, with variable based on player's score
local kdreward = 15 * vmain.kills / (vmain.deaths + 1)
local max = vmain.score / 10
if kdreward > max then
kdreward = max
end
if kdreward > 40 then
kdreward = 40
end
-- Limited to 0 <= X <= 100
if reward > 100 then
reward = 100
elseif reward < 0 then
reward = 0
end
-- Half if no good weapons
local inv = minetest.get_inventory({ type="player", name = victim })
if not invHasGoodWeapons(inv) then
ctf.log("ctf_stats", "Player " .. victim .. " has no good weapons")
reward = reward * 0.5
else
ctf.log("ctf_stats", "Player " .. victim .. " has good weapons")
end
return reward
end
2015-12-04 00:15:03 +00:00
ctf.register_on_killedplayer(function(victim, killer)
local main, match = ctf_stats.player(killer)
if main and match then
2017-10-12 23:09:25 +00:00
local reward = calculateKillReward(victim, killer)
main.kills = main.kills + 1
main.score = main.score + reward
2015-12-04 00:15:03 +00:00
match.kills = match.kills + 1
2017-10-12 23:09:25 +00:00
match.score = match.score + reward
match.kills_since_death = match.kills_since_death + 1
2015-12-04 00:15:03 +00:00
ctf.needs_save = true
end
end)
2015-11-29 00:05:37 +00:00
minetest.register_on_dieplayer(function(player)
local main, match = ctf_stats.player(player:get_player_name())
if main and match then
main.deaths = main.deaths + 1
match.deaths = match.deaths + 1
2017-10-12 23:09:25 +00:00
match.kills_since_death = 0
2015-12-03 23:57:28 +00:00
ctf.needs_save = true
end
2015-11-29 00:05:37 +00:00
end)
ctf_stats.load()
2015-12-03 23:46:52 +00:00
dofile(minetest.get_modpath("ctf_stats").."/gui.lua")