2015-11-29 00:05:37 +00:00
|
|
|
ctf_stats = {}
|
|
|
|
|
2019-08-28 16:05:59 +00:00
|
|
|
local _needs_save = false
|
2017-10-12 23:09:25 +00:00
|
|
|
local storage = minetest.get_mod_storage()
|
|
|
|
local data_to_persist = { "matches", "players" }
|
|
|
|
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.prev_match_summary = storage:get_string("prev_match_summary")
|
2019-03-17 01:37:20 +00:00
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
function ctf_stats.load_legacy()
|
2017-10-12 23:09:25 +00:00
|
|
|
local file = io.open(minetest.get_worldpath() .. "/ctf_stats.txt", "r")
|
2018-01-09 02:40:18 +00:00
|
|
|
if not file then
|
|
|
|
return false
|
|
|
|
end
|
2017-10-12 23:09:25 +00:00
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
local table = minetest.deserialize(file:read("*all"))
|
|
|
|
file:close()
|
|
|
|
if type(table) ~= "table" then
|
|
|
|
return false
|
|
|
|
end
|
2017-11-07 00:32:20 +00:00
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
ctf.log("ctf_stats", "Migrating stats...")
|
|
|
|
ctf_stats.matches = table.matches
|
|
|
|
ctf_stats.players = table.players
|
2017-11-07 00:32:20 +00:00
|
|
|
|
2018-01-09 02:40:18 +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
|
2017-11-07 00:32:20 +00:00
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
player_stats.wins = player_stats.wins or {}
|
|
|
|
if player_stats.blue_wins then
|
|
|
|
player_stats.wins.blue = player_stats.blue_wins
|
|
|
|
player_stats.blue_wins = nil
|
2017-10-12 23:09:25 +00:00
|
|
|
end
|
2018-01-09 02:40:18 +00:00
|
|
|
if player_stats.red_wins then
|
|
|
|
player_stats.wins.red = player_stats.red_wins
|
|
|
|
player_stats.red_wins = nil
|
2015-11-29 00:05:37 +00:00
|
|
|
end
|
2018-01-09 02:40:18 +00:00
|
|
|
player_stats.wins.blue = player_stats.wins.blue or 0
|
|
|
|
player_stats.wins.red = player_stats.wins.red or 0
|
2015-11-29 00:05:37 +00:00
|
|
|
end
|
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
ctf_stats.matches.wins = ctf_stats.matches.wins or {
|
|
|
|
red = ctf_stats.matches.red_wins or 0,
|
|
|
|
blue = ctf_stats.matches.blue_wins or 0,
|
|
|
|
}
|
|
|
|
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2018-01-09 02:41:46 +00:00
|
|
|
|
|
|
|
os.remove(minetest.get_worldpath() .. "/ctf_stats.txt")
|
2018-01-09 02:40:18 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function ctf_stats.load()
|
|
|
|
if not ctf_stats.load_legacy() then
|
|
|
|
for _, key in pairs(data_to_persist) do
|
|
|
|
ctf_stats[key] = minetest.parse_json(storage:get_string(key))
|
2018-01-03 00:23:38 +00:00
|
|
|
end
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2018-01-03 00:23:38 +00:00
|
|
|
end
|
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
-- Make sure all tables are present
|
|
|
|
ctf_stats.players = ctf_stats.players or {}
|
2017-10-12 23:09:25 +00:00
|
|
|
ctf_stats.matches = ctf_stats.matches or {
|
|
|
|
wins = {
|
|
|
|
blue = 0,
|
2018-01-09 02:40:18 +00:00
|
|
|
red = 0,
|
2017-10-12 23:09:25 +00:00
|
|
|
},
|
2018-01-09 02:40:18 +00:00
|
|
|
skipped = 0,
|
2015-11-29 00:05:37 +00:00
|
|
|
}
|
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 = {}
|
|
|
|
}
|
|
|
|
|
2018-04-18 20:49:47 +00:00
|
|
|
ctf_stats.start = os.time()
|
|
|
|
|
2018-01-09 02:40:18 +00:00
|
|
|
-- Strip players which have no score
|
|
|
|
for name, player_stats in pairs(ctf_stats.players) do
|
|
|
|
if not player_stats.score or player_stats.score <= 0 then
|
|
|
|
ctf_stats.players[name] = nil
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2018-04-19 00:01:19 +00:00
|
|
|
else
|
|
|
|
player_stats.bounty_kills = player_stats.bounty_kills or 0
|
2018-01-09 02:40:18 +00:00
|
|
|
end
|
|
|
|
end
|
2015-11-29 00:05:37 +00:00
|
|
|
end
|
|
|
|
|
2019-08-28 16:05:59 +00:00
|
|
|
function ctf_stats.save()
|
|
|
|
if not _needs_save then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
_needs_save = false
|
|
|
|
|
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
|
|
|
|
|
2019-08-28 16:05:59 +00:00
|
|
|
minetest.after(13, ctf_stats.save)
|
|
|
|
end
|
|
|
|
minetest.after(13, ctf_stats.save)
|
2015-11-29 00:05:37 +00:00
|
|
|
|
2018-01-02 23:51:38 +00:00
|
|
|
function ctf_stats.player_or_nil(name)
|
|
|
|
return ctf_stats.players[name], ctf_stats.current.red[name] or ctf_stats.current.blue[name]
|
|
|
|
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,
|
2018-04-18 23:57:21 +00:00
|
|
|
bounty_kills = 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
|
|
|
|
|
2019-11-27 06:00:39 +00:00
|
|
|
function ctf_stats.get_ordered_players()
|
|
|
|
local players = {}
|
|
|
|
|
|
|
|
-- Copy player stats into new empty table
|
|
|
|
for pname, pstat in pairs(ctf_stats.players) do
|
|
|
|
pstat.name = pname
|
|
|
|
pstat.color = nil
|
|
|
|
table.insert(players, pstat)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Sort table in the order of descending scores
|
|
|
|
table.sort(players, function(one, two)
|
|
|
|
return one.score > two.score
|
|
|
|
end)
|
|
|
|
|
|
|
|
return players
|
|
|
|
end
|
|
|
|
|
|
|
|
function ctf_stats.get_target(name, param)
|
|
|
|
param = param:trim()
|
|
|
|
|
|
|
|
-- If param is not empty, check if it's a number or a string
|
|
|
|
if param ~= "" then
|
|
|
|
-- Order of the following checks are as given below:
|
|
|
|
--
|
|
|
|
-- * `param` is returned as a string if player's stats exists
|
|
|
|
-- * If no matching stats exist, `param` is checked if it's a number
|
|
|
|
-- * If `param` isn't a number, it is assumed to be invalid, and nil is returned
|
|
|
|
-- * If `param` is a number, `param` is checked if out of bounds
|
|
|
|
-- * If `param` is not out of bounds, `param` is returned as a number, else nil
|
|
|
|
--
|
|
|
|
-- This order of checks is important because, in the case of `param` matching
|
|
|
|
-- both a number and a player name, it would be considered as a player name.
|
|
|
|
|
|
|
|
-- Check if param matches a player name
|
|
|
|
if ctf_stats.players[param] then
|
|
|
|
return param
|
|
|
|
else
|
|
|
|
-- Check if param is a number
|
|
|
|
local rank = tonumber(param)
|
|
|
|
if rank then
|
|
|
|
-- Check if param is within range
|
|
|
|
-- TODO: Fix this hack by maintaining two tables - an ordered list, and a hashmap
|
|
|
|
if rank <= 0 or rank > #ctf_stats.get_ordered_players() or
|
|
|
|
rank ~= math.floor(rank) then
|
|
|
|
return nil, "Invalid number or number out of bounds!"
|
|
|
|
else
|
|
|
|
return rank
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return nil, "Invalid player name specified!"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-12-05 18:33:38 +00:00
|
|
|
function ctf_stats.is_pro(name)
|
|
|
|
local stats = ctf_stats.player(name)
|
|
|
|
local kd = stats.kills / (stats.deaths == 0 and 1 or stats.deaths)
|
2019-12-15 19:47:19 +00:00
|
|
|
return stats.score >= 10000 and kd >= 1.5
|
2019-12-05 18:33:38 +00:00
|
|
|
end
|
|
|
|
|
2015-11-29 00:05:37 +00:00
|
|
|
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,
|
2018-04-18 22:00:15 +00:00
|
|
|
bounty_kills = 0,
|
2015-11-29 00:05:37 +00:00
|
|
|
}
|
|
|
|
end)
|
|
|
|
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_team = "-"
|
|
|
|
ctf_stats.winner_player = "-"
|
2018-04-18 20:49:47 +00:00
|
|
|
|
2018-11-20 13:21:42 +00:00
|
|
|
table.insert(ctf_flag.registered_on_capture, 1, 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
|
2019-12-15 13:29:37 +00:00
|
|
|
main.score = main.score + 50
|
2015-12-03 23:57:28 +00:00
|
|
|
match.captures = match.captures + 1
|
2019-12-15 13:29:37 +00:00
|
|
|
match.score = match.score + 50
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2015-12-03 23:46:52 +00:00
|
|
|
end
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_player = name
|
2019-03-19 17:04:41 +00:00
|
|
|
|
|
|
|
hud_score.new(name, {
|
|
|
|
name = "ctf_stats:flag_capture",
|
|
|
|
color = "0xFF00FF",
|
2019-12-15 13:29:37 +00:00
|
|
|
value = 50
|
2019-03-19 17:04:41 +00:00
|
|
|
})
|
2015-12-03 23:46:52 +00:00
|
|
|
end)
|
|
|
|
|
2015-11-29 00:05:37 +00:00
|
|
|
ctf_match.register_on_winner(function(winner)
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2017-10-12 23:09:25 +00:00
|
|
|
ctf_stats.matches.wins[winner] = ctf_stats.matches.wins[winner] + 1
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_team = winner
|
2018-11-14 12:48:05 +00:00
|
|
|
|
|
|
|
-- Show match summary
|
|
|
|
local fs = ctf_stats.get_formspec_match_summary(ctf_stats.current,
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_team, ctf_stats.winner_player, os.time() - ctf_stats.start)
|
|
|
|
|
2018-11-14 12:48:05 +00:00
|
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
|
|
|
minetest.show_formspec(player:get_player_name(), "ctf_stats:eom", fs)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Set prev_match_summary and write to mod_storage
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.prev_match_summary = fs
|
2018-11-14 12:48:05 +00:00
|
|
|
storage:set_string("prev_match_summary", fs)
|
2015-11-29 00:05:37 +00:00
|
|
|
end)
|
|
|
|
|
2018-11-14 12:48:05 +00:00
|
|
|
ctf_match.register_on_skip_map(function()
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2018-11-14 12:48:05 +00:00
|
|
|
ctf_stats.matches.skipped = ctf_stats.matches.skipped + 1
|
|
|
|
|
|
|
|
-- Show match summary
|
|
|
|
local fs = ctf_stats.get_formspec_match_summary(ctf_stats.current,
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_team, ctf_stats.winner_player, os.time() - ctf_stats.start)
|
|
|
|
|
2018-11-14 12:48:05 +00:00
|
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
2015-12-03 23:46:52 +00:00
|
|
|
minetest.show_formspec(player:get_player_name(), "ctf_stats:eom", fs)
|
|
|
|
end
|
2015-11-29 00:05:37 +00:00
|
|
|
|
2018-11-14 12:48:05 +00:00
|
|
|
-- Set prev_match_summary and write to mod_storage
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.prev_match_summary = fs
|
2018-11-14 12:48:05 +00:00
|
|
|
storage:set_string("prev_match_summary", fs)
|
|
|
|
end)
|
|
|
|
|
|
|
|
ctf_match.register_on_new_match(function()
|
2015-11-29 00:05:37 +00:00
|
|
|
ctf_stats.current = {
|
|
|
|
red = {},
|
|
|
|
blue = {}
|
|
|
|
}
|
2019-11-25 05:01:53 +00:00
|
|
|
ctf_stats.winner_team = "-"
|
|
|
|
ctf_stats.winner_player = "-"
|
2018-04-18 20:49:47 +00:00
|
|
|
ctf_stats.start = os.time()
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2015-11-29 00:05:37 +00:00
|
|
|
end)
|
|
|
|
|
2019-11-24 20:38:15 +00:00
|
|
|
-- ctf_map can't be added as a dependency, as that'd result
|
|
|
|
-- in cyclic dependencies between ctf_map and ctf_stats
|
|
|
|
minetest.after(0, function()
|
|
|
|
ctf_map.register_on_map_loaded(function(map)
|
|
|
|
ctf_stats.current.map = map.name
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
|
2015-11-29 00:05:37 +00:00
|
|
|
ctf_flag.register_on_pick_up(function(name, flag)
|
|
|
|
local main, match = ctf_stats.player(name)
|
2015-11-29 23:55:27 +00:00
|
|
|
if main and match then
|
2017-10-12 23:09:25 +00:00
|
|
|
main.attempts = main.attempts + 1
|
2019-12-15 13:29:37 +00:00
|
|
|
main.score = main.score + 20
|
2015-11-29 23:55:27 +00:00
|
|
|
match.attempts = match.attempts + 1
|
2019-12-15 13:29:37 +00:00
|
|
|
match.score = match.score + 20
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2015-11-29 23:55:27 +00:00
|
|
|
end
|
2019-03-19 17:04:41 +00:00
|
|
|
|
|
|
|
hud_score.new(name, {
|
|
|
|
name = "ctf_stats:flag_pick_up",
|
|
|
|
color = "0xAA00AA",
|
2019-12-15 13:29:37 +00:00
|
|
|
value = 20
|
2019-03-19 17:04:41 +00:00
|
|
|
})
|
2015-11-29 00:05:37 +00:00
|
|
|
end)
|
|
|
|
|
|
|
|
ctf_flag.register_on_precapture(function(name, flag)
|
|
|
|
local tplayer = ctf.player(name)
|
2018-04-06 13:04:56 +00:00
|
|
|
local main, _ = ctf_stats.player(name)
|
2015-11-29 23:55:27 +00:00
|
|
|
if main then
|
2017-10-12 23:09:25 +00:00
|
|
|
main.wins[tplayer.team] = main.wins[tplayer.team] + 1
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2015-11-29 23:55:27 +00:00
|
|
|
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",
|
2018-02-11 15:44:10 +00:00
|
|
|
"default:sword_bronze",
|
|
|
|
"default:sword_mese",
|
|
|
|
"default:sword_diamond",
|
2018-02-18 08:30:50 +00:00
|
|
|
"default:pick_mese",
|
|
|
|
"default:pick_diamond",
|
|
|
|
"default:axe_mese",
|
|
|
|
"default:axe_diamond",
|
|
|
|
"default:shovel_mese",
|
|
|
|
"default:shovel_diamond",
|
2017-10-12 23:09:25 +00:00
|
|
|
"shooter:grenade",
|
|
|
|
"shooter:shotgun",
|
|
|
|
"shooter:rifle",
|
|
|
|
"shooter:machine_gun",
|
|
|
|
}
|
2018-02-15 08:04:34 +00:00
|
|
|
|
2017-10-12 23:09:25 +00:00
|
|
|
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
|
2017-10-12 23:57:09 +00:00
|
|
|
ctf.log("ctf_stats", "Player " .. victim .. " has made " .. reward ..
|
|
|
|
" score worth of kills since last death")
|
2017-10-12 23:09:25 +00:00
|
|
|
|
2018-02-15 08:04:34 +00:00
|
|
|
-- 30 * K/D ratio, with variable based on player's score
|
2017-10-13 01:05:21 +00:00
|
|
|
local kdreward = 30 * vmain.kills / (vmain.deaths + 1)
|
|
|
|
local max = vmain.score / 6
|
2017-10-12 23:09:25 +00:00
|
|
|
if kdreward > max then
|
|
|
|
kdreward = max
|
|
|
|
end
|
2017-10-13 01:05:21 +00:00
|
|
|
if kdreward > 80 then
|
|
|
|
kdreward = 80
|
2017-10-12 23:09:25 +00:00
|
|
|
end
|
2017-10-12 23:57:09 +00:00
|
|
|
reward = reward + kdreward
|
2017-10-12 23:09:25 +00:00
|
|
|
|
2018-02-15 08:04:34 +00:00
|
|
|
-- Limited to 0 <= X <= 200
|
|
|
|
if reward > 200 then
|
|
|
|
reward = 200
|
2017-10-13 01:05:21 +00:00
|
|
|
elseif reward < 14 then
|
|
|
|
reward = 14
|
2017-10-12 23:09:25 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Half if no good weapons
|
2019-03-17 01:37:20 +00:00
|
|
|
local inv = minetest.get_inventory({ type = "player", name = victim })
|
2017-10-12 23:09:25 +00:00
|
|
|
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)
|
2018-11-29 15:52:43 +00:00
|
|
|
-- Suicide is not encouraged here at CTF
|
|
|
|
if victim == killer then
|
|
|
|
return
|
|
|
|
end
|
2015-12-04 00:15:03 +00:00
|
|
|
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
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2019-03-17 01:35:51 +00:00
|
|
|
|
|
|
|
reward = math.floor(reward * 100) / 100
|
|
|
|
|
|
|
|
hud_score.new(killer, {
|
|
|
|
name = "ctf_stats:kill_score",
|
|
|
|
color = "0x00FF00",
|
|
|
|
value = reward
|
|
|
|
})
|
2015-12-04 00:15:03 +00:00
|
|
|
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())
|
2015-11-29 23:55:27 +00:00
|
|
|
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
|
2019-08-28 16:05:59 +00:00
|
|
|
_needs_save = true
|
2015-11-29 23:55:27 +00:00
|
|
|
end
|
2015-11-29 00:05:37 +00:00
|
|
|
end)
|
|
|
|
|
|
|
|
ctf_stats.load()
|
2015-12-03 23:46:52 +00:00
|
|
|
|
2019-03-17 01:37:20 +00:00
|
|
|
dofile(minetest.get_modpath("ctf_stats") .. "/gui.lua")
|
2019-11-25 05:01:53 +00:00
|
|
|
dofile(minetest.get_modpath("ctf_stats") .. "/chat.lua")
|