2018-06-27 15:48:04 +02:00
|
|
|
local Event = require 'utils.event'
|
|
|
|
local Global = require 'utils.global'
|
|
|
|
local Gui = require 'utils.gui'
|
2019-01-30 05:52:43 +02:00
|
|
|
local Rank = require 'features.rank_system'
|
2019-02-02 05:24:32 +02:00
|
|
|
local Donator = require 'features.donator'
|
2018-11-11 09:20:07 +02:00
|
|
|
local PlayerStats = require 'features.player_stats'
|
2018-11-26 03:07:03 +02:00
|
|
|
local Utils = require 'utils.core'
|
2018-11-11 09:20:07 +02:00
|
|
|
local Report = require 'features.report'
|
2018-09-23 00:25:13 +02:00
|
|
|
local Game = require 'utils.game'
|
2019-01-15 15:27:48 +02:00
|
|
|
local table = require 'utils.table'
|
2019-01-30 05:52:43 +02:00
|
|
|
local Color = require 'resources.color_presets'
|
2018-06-27 15:48:04 +02:00
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local poke_messages = require 'resources.poke_messages'
|
2018-06-29 00:50:38 +02:00
|
|
|
local player_sprites = require 'resources.player_sprites'
|
2018-06-28 19:28:47 +02:00
|
|
|
|
2019-01-21 21:28:21 +02:00
|
|
|
local random = math.random
|
2019-02-13 14:38:24 +02:00
|
|
|
local get_rank_color = Rank.get_rank_color
|
|
|
|
local get_rank_name = Rank.get_rank_name
|
|
|
|
local get_player_rank = Rank.get_player_rank
|
|
|
|
local donator_is_donator = Donator.is_donator
|
2019-01-21 21:28:21 +02:00
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local poke_cooldown_time = 240 -- in ticks.
|
2018-06-29 00:50:38 +02:00
|
|
|
local sprite_time_step = 54000 -- in ticks
|
2018-06-28 15:49:22 +02:00
|
|
|
local symbol_asc = ' ▲'
|
|
|
|
local symbol_desc = ' ▼'
|
2018-12-29 19:39:20 +02:00
|
|
|
local focus_color = Color.dark_orange
|
2019-02-13 14:38:24 +02:00
|
|
|
local donator_color = Color.donator
|
|
|
|
|
|
|
|
local rank_column_width = 100
|
2018-06-29 00:50:38 +02:00
|
|
|
|
|
|
|
local inv_sprite_time_step = 1 / sprite_time_step
|
2019-02-13 14:38:24 +02:00
|
|
|
local donator_label_caption = {'', '(', {'ranks.donator_abbreviation'}, ')'}
|
2018-06-27 15:48:04 +02:00
|
|
|
|
|
|
|
local player_poke_cooldown = {}
|
|
|
|
local player_pokes = {}
|
|
|
|
local player_settings = {}
|
2018-06-28 19:28:47 +02:00
|
|
|
local no_notify_players = {}
|
2018-06-27 15:48:04 +02:00
|
|
|
|
|
|
|
Global.register(
|
2018-06-28 19:28:47 +02:00
|
|
|
{
|
|
|
|
player_poke_cooldown = player_poke_cooldown,
|
|
|
|
player_pokes = player_pokes,
|
|
|
|
player_settings = player_settings,
|
|
|
|
no_notify_players = no_notify_players
|
|
|
|
},
|
2018-06-27 15:48:04 +02:00
|
|
|
function(tbl)
|
|
|
|
player_poke_cooldown = tbl.player_poke_cooldown
|
2018-06-30 16:17:24 +02:00
|
|
|
player_pokes = tbl.player_pokes
|
2018-06-27 15:48:04 +02:00
|
|
|
player_settings = tbl.player_settings
|
2018-06-28 19:28:47 +02:00
|
|
|
no_notify_players = tbl.no_notify_players
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
)
|
|
|
|
|
|
|
|
local main_button_name = Gui.uid_name()
|
|
|
|
local main_frame_name = Gui.uid_name()
|
2018-06-29 00:50:38 +02:00
|
|
|
local notify_checkbox_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local sprite_heading_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
local player_name_heading_name = Gui.uid_name()
|
|
|
|
local time_heading_name = Gui.uid_name()
|
|
|
|
local rank_heading_name = Gui.uid_name()
|
|
|
|
local distance_heading_name = Gui.uid_name()
|
2018-08-01 17:35:48 +02:00
|
|
|
local coin_heading_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
local deaths_heading_name = Gui.uid_name()
|
|
|
|
local poke_name_heading_name = Gui.uid_name()
|
2018-08-13 18:48:58 +02:00
|
|
|
local report_heading_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local sprite_cell_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
local player_name_cell_name = Gui.uid_name()
|
|
|
|
local time_cell_name = Gui.uid_name()
|
|
|
|
local rank_cell_name = Gui.uid_name()
|
|
|
|
local distance_cell_name = Gui.uid_name()
|
2018-08-01 17:35:48 +02:00
|
|
|
local coin_cell_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
local deaths_cell_name = Gui.uid_name()
|
|
|
|
local poke_cell_name = Gui.uid_name()
|
2018-08-13 17:40:52 +02:00
|
|
|
local report_cell_name = Gui.uid_name()
|
2018-06-27 15:48:04 +02:00
|
|
|
|
|
|
|
local function lighten_color(color)
|
|
|
|
color.r = color.r * 0.6 + 0.4
|
|
|
|
color.g = color.g * 0.6 + 0.4
|
|
|
|
color.b = color.b * 0.6 + 0.4
|
2018-06-28 15:49:22 +02:00
|
|
|
color.a = 1
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
2017-07-19 02:04:41 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function format_distance(tiles)
|
|
|
|
return math.round(tiles * 0.001, 1) .. ' km'
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-08-07 14:09:41 +02:00
|
|
|
local function do_poke_spam_protection(player)
|
2018-06-28 19:28:47 +02:00
|
|
|
if player.admin then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2018-08-07 14:09:41 +02:00
|
|
|
local tick = player_poke_cooldown[player.index] or 0
|
2018-06-28 19:28:47 +02:00
|
|
|
|
|
|
|
if tick < game.tick then
|
2018-08-07 14:09:41 +02:00
|
|
|
player_poke_cooldown[player.index] = game.tick + poke_cooldown_time
|
2018-06-28 19:28:47 +02:00
|
|
|
return true
|
|
|
|
else
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-28 15:49:22 +02:00
|
|
|
local function apply_heading_style(style)
|
|
|
|
style.font_color = focus_color
|
|
|
|
style.font = 'default-bold'
|
2019-02-26 19:36:20 +02:00
|
|
|
style.horizontal_align = 'center'
|
2018-06-28 15:49:22 +02:00
|
|
|
end
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local column_builders = {
|
2018-06-29 00:50:38 +02:00
|
|
|
[sprite_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
local ticks = player.online_time
|
2018-06-30 17:46:40 +02:00
|
|
|
local level = math.floor(ticks * inv_sprite_time_step) + 1
|
2018-06-29 00:50:38 +02:00
|
|
|
level = math.min(level, #player_sprites)
|
|
|
|
|
|
|
|
return level
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a < b
|
2018-06-29 00:50:38 +02:00
|
|
|
end,
|
|
|
|
draw_heading = function(parent)
|
|
|
|
local label = parent.add {type = 'label', name = sprite_heading_name, caption = ' '}
|
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
|
|
|
label_style.width = 32
|
|
|
|
|
|
|
|
return label
|
|
|
|
end,
|
|
|
|
draw_cell = function(parent, cell_data)
|
|
|
|
local label =
|
|
|
|
parent.add {
|
|
|
|
type = 'sprite',
|
|
|
|
name = sprite_cell_name,
|
|
|
|
sprite = player_sprites[cell_data]
|
|
|
|
}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 32
|
|
|
|
|
|
|
|
return label
|
|
|
|
end
|
|
|
|
},
|
2018-06-27 15:48:04 +02:00
|
|
|
[player_name_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
return player
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a.name:lower() < b.name:lower()
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.name_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = player_name_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 150
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-06-28 15:49:22 +02:00
|
|
|
local color = cell_data.color
|
|
|
|
lighten_color(color)
|
2018-06-29 00:50:38 +02:00
|
|
|
local name = cell_data.name
|
2018-06-28 15:49:22 +02:00
|
|
|
local label =
|
|
|
|
parent.add {
|
2018-06-27 15:48:04 +02:00
|
|
|
type = 'label',
|
|
|
|
name = player_name_cell_name,
|
2018-06-29 00:50:38 +02:00
|
|
|
caption = name,
|
|
|
|
tooltip = name
|
2018-06-27 15:48:04 +02:00
|
|
|
}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
label_style.font_color = color
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'left'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 150
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
|
|
|
[time_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
return player.online_time
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a < b
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.time_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = time_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 125
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-08-13 17:03:37 +02:00
|
|
|
local text = Utils.format_time(cell_data)
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
local label = parent.add {type = 'label', name = time_cell_name, caption = text}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'left'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 125
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
|
|
|
[rank_heading_name] = {
|
2019-02-13 14:38:24 +02:00
|
|
|
create_data = function(player)
|
|
|
|
local player_name = player.name
|
|
|
|
return {
|
|
|
|
rank = get_player_rank(player_name),
|
|
|
|
is_donator = donator_is_donator(player_name)
|
|
|
|
}
|
|
|
|
end,
|
2018-06-27 15:48:04 +02:00
|
|
|
sort = function(a, b)
|
2019-02-17 17:56:18 +02:00
|
|
|
local a_rank, b_rank = a.rank, b.rank
|
|
|
|
if a_rank == b_rank then
|
2019-02-23 16:39:59 +02:00
|
|
|
return b.is_donator and not a.is_donator
|
2019-02-17 17:56:18 +02:00
|
|
|
end
|
|
|
|
return a_rank < b_rank
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.rank_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = rank_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2019-02-13 14:38:24 +02:00
|
|
|
label_style.width = rank_column_width
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2019-02-13 14:38:24 +02:00
|
|
|
local is_donator = cell_data.is_donator
|
|
|
|
local rank = cell_data.rank
|
|
|
|
if is_donator then
|
|
|
|
local flow = parent.add {type = 'flow', name = rank_cell_name, direction = 'horizontal'}
|
|
|
|
local flow_style = flow.style
|
2019-02-26 19:36:20 +02:00
|
|
|
flow_style.horizontal_align = 'left'
|
2019-02-13 14:38:24 +02:00
|
|
|
flow_style.width = rank_column_width
|
2018-06-28 15:49:22 +02:00
|
|
|
|
2019-02-13 14:38:24 +02:00
|
|
|
local label_rank = flow.add {type = 'label', caption = get_rank_name(rank)}
|
|
|
|
label_rank.style.font_color = get_rank_color(rank)
|
|
|
|
|
|
|
|
local label_donator = flow.add {type = 'label', caption = donator_label_caption}
|
|
|
|
label_donator.style.font_color = donator_color
|
|
|
|
|
|
|
|
return flow
|
|
|
|
else
|
|
|
|
local label = parent.add {type = 'label', name = rank_cell_name, caption = get_rank_name(rank)}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'left'
|
2019-02-13 14:38:24 +02:00
|
|
|
label_style.font_color = get_rank_color(rank)
|
|
|
|
label_style.width = rank_column_width
|
|
|
|
|
|
|
|
return label
|
|
|
|
end
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
|
|
|
[distance_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
return PlayerStats.get_walk_distance(player.index)
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a < b
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.distance_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = distance_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 70
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-06-27 15:48:04 +02:00
|
|
|
local text = format_distance(cell_data)
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
local label = parent.add {type = 'label', name = distance_cell_name, caption = text}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 70
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
2018-08-01 17:35:48 +02:00
|
|
|
[coin_heading_name] = {
|
2018-06-27 15:48:04 +02:00
|
|
|
create_data = function(player)
|
|
|
|
local index = player.index
|
|
|
|
return {
|
2018-08-01 17:35:48 +02:00
|
|
|
coin_earned = PlayerStats.get_coin_earned(index),
|
|
|
|
coin_spent = PlayerStats.get_coin_spent(index)
|
2018-06-27 15:48:04 +02:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-08-01 17:35:48 +02:00
|
|
|
local a_coin_earned, b_coin_earned = a.coin_earned, b.coin_earned
|
|
|
|
if a_coin_earned == b_coin_earned then
|
|
|
|
return a.coin_spent < b.coin_spent
|
2018-06-28 15:49:22 +02:00
|
|
|
else
|
2018-08-01 17:35:48 +02:00
|
|
|
return a_coin_earned < b_coin_earned
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.coins_caption', sort_symbol}
|
2018-06-29 01:44:20 +02:00
|
|
|
local label =
|
|
|
|
parent.add {
|
|
|
|
type = 'label',
|
2018-08-01 17:35:48 +02:00
|
|
|
name = coin_heading_name,
|
2019-03-30 17:17:29 +02:00
|
|
|
caption = caption,
|
2018-08-01 17:35:48 +02:00
|
|
|
tooltip = 'Coins earned / spent.'
|
2018-06-29 01:44:20 +02:00
|
|
|
}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 80
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-08-01 17:35:48 +02:00
|
|
|
local text = table.concat({cell_data.coin_earned, '/', cell_data.coin_spent})
|
2018-06-28 15:49:22 +02:00
|
|
|
|
2018-08-01 17:35:48 +02:00
|
|
|
local label = parent.add {type = 'label', name = coin_cell_name, caption = text}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 80
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
|
|
|
[deaths_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
local player_index = player.index
|
|
|
|
return {
|
|
|
|
count = PlayerStats.get_death_count(player_index),
|
2018-12-06 13:18:52 +02:00
|
|
|
causes = PlayerStats.get_all_death_counts_by_cause(player_index)
|
2018-06-27 15:48:04 +02:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a.count < b.count
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.deaths_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = deaths_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 60
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2018-06-29 00:50:38 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-06-27 15:48:04 +02:00
|
|
|
local tooltip = {}
|
|
|
|
for name, count in pairs(cell_data.causes) do
|
|
|
|
table.insert(tooltip, name)
|
|
|
|
table.insert(tooltip, ': ')
|
|
|
|
table.insert(tooltip, count)
|
|
|
|
table.insert(tooltip, '\n')
|
|
|
|
end
|
|
|
|
table.remove(tooltip)
|
|
|
|
tooltip = table.concat(tooltip)
|
|
|
|
|
2018-06-28 15:49:22 +02:00
|
|
|
local label =
|
|
|
|
parent.add {type = 'label', name = deaths_cell_name, caption = cell_data.count, tooltip = tooltip}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 60
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
},
|
|
|
|
[poke_name_heading_name] = {
|
|
|
|
create_data = function(player)
|
2018-06-28 19:28:47 +02:00
|
|
|
return {poke_count = player_pokes[player.index] or 0, player = player}
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
2018-07-01 15:06:57 +02:00
|
|
|
return a.poke_count < b.poke_count
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol, data)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.poke_caption', sort_symbol}
|
|
|
|
local label = parent.add {type = 'label', name = poke_name_heading_name, caption = caption}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-06-29 00:50:38 +02:00
|
|
|
label_style.width = 60
|
|
|
|
|
|
|
|
data.poke_buttons = {}
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end,
|
|
|
|
draw_cell = function(parent, cell_data, data)
|
2018-06-29 00:50:38 +02:00
|
|
|
local player = cell_data.player
|
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local parent_style = parent.style
|
|
|
|
parent_style.width = 64
|
2019-02-26 19:36:20 +02:00
|
|
|
parent_style.horizontal_align = 'center'
|
2018-06-28 19:28:47 +02:00
|
|
|
|
|
|
|
local label = parent.add {type = 'button', name = poke_cell_name, caption = cell_data.poke_count}
|
2018-06-28 15:49:22 +02:00
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-06-28 19:28:47 +02:00
|
|
|
label_style.minimal_width = 32
|
|
|
|
label_style.height = 24
|
|
|
|
label_style.font = 'default-bold'
|
|
|
|
label_style.top_padding = 0
|
|
|
|
label_style.bottom_padding = 0
|
|
|
|
label_style.left_padding = 0
|
|
|
|
label_style.right_padding = 0
|
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
data.poke_buttons[player.index] = label
|
|
|
|
|
|
|
|
Gui.set_data(label, {data = data, player = player})
|
2018-06-28 15:49:22 +02:00
|
|
|
|
2018-08-13 18:48:58 +02:00
|
|
|
return label
|
|
|
|
end
|
|
|
|
},
|
|
|
|
[report_heading_name] = {
|
|
|
|
create_data = function(player)
|
|
|
|
return player
|
|
|
|
end,
|
|
|
|
sort = function(a, b)
|
|
|
|
return a.name:lower() < b.name:lower()
|
|
|
|
end,
|
2019-03-30 18:00:49 +02:00
|
|
|
draw_heading = function(parent, sort_symbol)
|
2019-03-30 17:17:29 +02:00
|
|
|
local caption = {'player_list.report_caption', sort_symbol}
|
2018-08-13 19:01:48 +02:00
|
|
|
local label =
|
|
|
|
parent.add {
|
|
|
|
type = 'label',
|
|
|
|
name = report_heading_name,
|
2019-03-30 17:17:29 +02:00
|
|
|
caption = caption,
|
|
|
|
tooltip = {'player_list.report_tooltip'}
|
2018-08-13 19:01:48 +02:00
|
|
|
}
|
2018-08-13 18:48:58 +02:00
|
|
|
local label_style = label.style
|
|
|
|
apply_heading_style(label_style)
|
2018-08-13 19:01:48 +02:00
|
|
|
label_style.width = 58
|
2018-08-13 18:48:58 +02:00
|
|
|
|
|
|
|
return label
|
|
|
|
end,
|
2019-01-15 15:27:48 +02:00
|
|
|
draw_cell = function(parent, cell_data)
|
2018-08-13 18:48:58 +02:00
|
|
|
local parent_style = parent.style
|
2018-08-13 19:01:48 +02:00
|
|
|
parent_style.width = 58
|
2019-02-26 19:36:20 +02:00
|
|
|
parent_style.horizontal_align = 'center'
|
2018-08-13 18:48:58 +02:00
|
|
|
|
|
|
|
local label =
|
|
|
|
parent.add {
|
|
|
|
type = 'sprite-button',
|
|
|
|
name = report_cell_name,
|
|
|
|
sprite = 'utility/force_editor_icon',
|
2019-03-30 17:17:29 +02:00
|
|
|
tooltip = {'player_list.report_button_tooltip', cell_data.name}
|
2018-08-13 18:48:58 +02:00
|
|
|
}
|
|
|
|
local label_style = label.style
|
2019-02-26 19:36:20 +02:00
|
|
|
label_style.horizontal_align = 'center'
|
2018-08-13 18:48:58 +02:00
|
|
|
label_style.minimal_width = 32
|
|
|
|
label_style.height = 24
|
|
|
|
label_style.font = 'default-bold'
|
|
|
|
label_style.top_padding = 0
|
|
|
|
label_style.bottom_padding = 0
|
|
|
|
label_style.left_padding = 0
|
|
|
|
label_style.right_padding = 0
|
|
|
|
|
|
|
|
Gui.set_data(label, cell_data)
|
|
|
|
|
2018-06-28 15:49:22 +02:00
|
|
|
return label
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local function get_default_player_settings()
|
2019-01-15 15:27:48 +02:00
|
|
|
local columns = {
|
2018-11-20 12:46:32 +02:00
|
|
|
sprite_heading_name,
|
|
|
|
player_name_heading_name,
|
|
|
|
time_heading_name,
|
|
|
|
rank_heading_name,
|
|
|
|
distance_heading_name
|
2018-09-11 16:00:49 +02:00
|
|
|
}
|
|
|
|
local offset = 6
|
2018-12-06 13:18:52 +02:00
|
|
|
if global.config.player_list.show_coin_column then
|
2018-09-11 16:00:49 +02:00
|
|
|
columns[6] = coin_heading_name
|
|
|
|
offset = 7
|
|
|
|
end
|
2018-11-20 12:46:32 +02:00
|
|
|
columns[offset] = deaths_heading_name
|
2018-09-11 17:07:07 +02:00
|
|
|
columns[offset + 1] = poke_name_heading_name
|
2018-09-11 16:00:49 +02:00
|
|
|
columns[offset + 2] = report_heading_name
|
|
|
|
return {
|
|
|
|
columns = columns,
|
2018-06-29 00:50:38 +02:00
|
|
|
sort = -3
|
2018-06-28 19:28:47 +02:00
|
|
|
}
|
|
|
|
end
|
2018-06-27 15:48:04 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local function redraw_title(data)
|
|
|
|
local frame = data.frame
|
|
|
|
|
|
|
|
local online_count = #game.connected_players
|
|
|
|
local total_count = PlayerStats.get_total_player_count()
|
|
|
|
|
2019-03-30 17:17:29 +02:00
|
|
|
frame.caption = {'player_list.title', online_count, total_count}
|
2018-06-29 00:50:38 +02:00
|
|
|
end
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function redraw_headings(data)
|
|
|
|
local settings = data.settings
|
|
|
|
local columns = settings.columns
|
2018-06-28 15:49:22 +02:00
|
|
|
local sort = settings.sort
|
|
|
|
local sort_column = math.abs(sort)
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local heading_table_flow = data.heading_table_flow
|
|
|
|
Gui.clear(heading_table_flow)
|
|
|
|
|
|
|
|
local heading_table = heading_table_flow.add {type = 'table', column_count = #columns}
|
|
|
|
|
2018-06-28 15:49:22 +02:00
|
|
|
for i, c in ipairs(settings.columns) do
|
2019-03-30 17:17:29 +02:00
|
|
|
local sort_symbol = ''
|
2018-06-28 15:49:22 +02:00
|
|
|
|
|
|
|
if i == sort_column then
|
2019-03-30 17:17:29 +02:00
|
|
|
sort_symbol = sort > 0 and symbol_asc or symbol_desc
|
2018-06-28 15:49:22 +02:00
|
|
|
end
|
|
|
|
|
2019-03-30 18:00:49 +02:00
|
|
|
local heading = column_builders[c].draw_heading(heading_table, sort_symbol, data)
|
2019-03-30 17:17:29 +02:00
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
Gui.set_data(heading, {data = data, index = i})
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function redraw_cells(data)
|
|
|
|
local settings = data.settings
|
|
|
|
local columns = settings.columns
|
2018-06-28 15:49:22 +02:00
|
|
|
local sort = settings.sort
|
|
|
|
local sort_column = math.abs(sort)
|
|
|
|
local column_name = columns[sort_column]
|
|
|
|
local column_sort = column_builders[column_name].sort
|
|
|
|
|
|
|
|
local comp
|
|
|
|
if sort > 0 then
|
|
|
|
comp = function(a, b)
|
|
|
|
return column_sort(a[sort_column], b[sort_column])
|
|
|
|
end
|
|
|
|
else
|
|
|
|
comp = function(a, b)
|
|
|
|
return column_sort(b[sort_column], a[sort_column])
|
|
|
|
end
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local cell_table_scroll_pane = data.cell_table_scroll_pane
|
|
|
|
Gui.clear(cell_table_scroll_pane)
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local grid = cell_table_scroll_pane.add {type = 'table', column_count = #columns}
|
2018-04-06 21:58:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local list_data = {}
|
|
|
|
for _, p in ipairs(game.connected_players) do
|
|
|
|
local row = {}
|
2017-07-06 19:16:13 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
for _, c in ipairs(columns) do
|
|
|
|
local cell_data = column_builders[c].create_data(p)
|
|
|
|
table.insert(row, cell_data)
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
table.insert(list_data, row)
|
|
|
|
end
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2018-06-28 15:49:22 +02:00
|
|
|
table.sort(list_data, comp)
|
2017-10-15 12:58:24 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
for _, row in ipairs(list_data) do
|
|
|
|
for c_i, c in ipairs(columns) do
|
2018-06-28 15:49:22 +02:00
|
|
|
local flow = grid.add {type = 'flow'}
|
|
|
|
column_builders[c].draw_cell(flow, row[c_i], data)
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
end
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function draw_main_frame(left, player)
|
2018-06-29 00:50:38 +02:00
|
|
|
local player_index = player.index
|
|
|
|
local frame = left.add {type = 'frame', name = main_frame_name, direction = 'vertical'}
|
2017-06-30 18:15:50 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local heading_table_flow = frame.add {type = 'flow'}
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local cell_table_scroll_pane = frame.add {type = 'scroll-pane'}
|
2018-06-29 00:50:38 +02:00
|
|
|
cell_table_scroll_pane.style.maximal_height = 400
|
|
|
|
|
|
|
|
frame.add {
|
|
|
|
type = 'checkbox',
|
|
|
|
name = notify_checkbox_name,
|
|
|
|
state = not no_notify_players[player_index],
|
2019-03-30 17:17:29 +02:00
|
|
|
caption = {'player_list.poke_notify_caption'},
|
|
|
|
tooltip = {'player_list.poke_notify_tooltip'}
|
2018-06-29 00:50:38 +02:00
|
|
|
}
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2019-03-30 17:17:29 +02:00
|
|
|
frame.add {type = 'button', name = main_button_name, caption = {'player_list.close_caption'}}
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local settings = player_settings[player_index] or get_default_player_settings()
|
2018-06-27 15:48:04 +02:00
|
|
|
local data = {
|
2018-06-29 00:50:38 +02:00
|
|
|
frame = frame,
|
2018-06-27 15:48:04 +02:00
|
|
|
heading_table_flow = heading_table_flow,
|
|
|
|
cell_table_scroll_pane = cell_table_scroll_pane,
|
2018-06-29 00:50:38 +02:00
|
|
|
settings = settings
|
2018-06-27 15:48:04 +02:00
|
|
|
}
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
redraw_title(data)
|
2018-06-27 15:48:04 +02:00
|
|
|
redraw_headings(data)
|
|
|
|
redraw_cells(data)
|
2018-06-28 19:28:47 +02:00
|
|
|
|
|
|
|
Gui.set_data(frame, data)
|
2017-06-30 18:15:50 +02:00
|
|
|
end
|
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local function remove_main_frame(frame, player)
|
|
|
|
local frame_data = Gui.get_data(frame)
|
|
|
|
player_settings[player.index] = frame_data.settings
|
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
Gui.destroy(frame)
|
2017-06-30 18:15:50 +02:00
|
|
|
end
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function toggle(event)
|
|
|
|
local player = event.player
|
|
|
|
local left = player.gui.left
|
|
|
|
local main_frame = left[main_frame_name]
|
2017-07-18 23:12:20 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
if main_frame then
|
2018-06-29 00:50:38 +02:00
|
|
|
remove_main_frame(main_frame, player)
|
2018-06-27 15:48:04 +02:00
|
|
|
else
|
|
|
|
draw_main_frame(left, player)
|
|
|
|
end
|
2017-06-30 18:15:50 +02:00
|
|
|
end
|
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local function tick()
|
|
|
|
for _, p in ipairs(game.connected_players) do
|
|
|
|
local frame = p.gui.left[main_frame_name]
|
|
|
|
|
|
|
|
if frame and frame.valid then
|
|
|
|
local data = Gui.get_data(frame)
|
|
|
|
redraw_cells(data)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
local function player_joined(event)
|
2018-09-23 12:46:58 +02:00
|
|
|
local player = Game.get_player_by_index(event.player_index)
|
2018-06-27 15:48:04 +02:00
|
|
|
if not player or not player.valid then
|
|
|
|
return
|
|
|
|
end
|
2017-10-15 12:58:24 +02:00
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local gui = player.gui
|
|
|
|
local top = gui.top
|
2017-10-27 23:18:26 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
if not top[main_button_name] then
|
2018-06-28 19:28:47 +02:00
|
|
|
top.add {type = 'sprite-button', name = main_button_name, sprite = 'entity/player'}
|
|
|
|
end
|
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
for _, p in ipairs(game.connected_players) do
|
|
|
|
local frame = p.gui.left[main_frame_name]
|
2018-06-28 19:28:47 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
if frame and frame.valid then
|
|
|
|
local data = Gui.get_data(frame)
|
|
|
|
redraw_title(data)
|
|
|
|
redraw_cells(data)
|
|
|
|
end
|
2018-06-28 19:28:47 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local function player_left()
|
2018-06-28 19:28:47 +02:00
|
|
|
for _, p in ipairs(game.connected_players) do
|
|
|
|
local frame = p.gui.left[main_frame_name]
|
|
|
|
|
|
|
|
if frame and frame.valid then
|
|
|
|
local data = Gui.get_data(frame)
|
2018-06-29 00:50:38 +02:00
|
|
|
redraw_title(data)
|
2018-06-28 19:28:47 +02:00
|
|
|
redraw_cells(data)
|
|
|
|
end
|
2018-06-27 15:48:04 +02:00
|
|
|
end
|
2017-10-15 12:58:24 +02:00
|
|
|
end
|
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
Event.on_nth_tick(1800, tick)
|
2018-06-29 00:50:38 +02:00
|
|
|
Event.add(defines.events.on_player_joined_game, player_joined)
|
|
|
|
Event.add(defines.events.on_player_left_game, player_left)
|
2017-10-15 12:58:24 +02:00
|
|
|
|
2018-06-27 15:48:04 +02:00
|
|
|
Gui.on_click(main_button_name, toggle)
|
2018-06-28 19:28:47 +02:00
|
|
|
|
2019-03-08 16:36:28 +02:00
|
|
|
Gui.on_checked_state_changed(
|
2018-06-29 00:50:38 +02:00
|
|
|
notify_checkbox_name,
|
|
|
|
function(event)
|
|
|
|
local player_index = event.player_index
|
|
|
|
local checkbox = event.element
|
|
|
|
|
|
|
|
local new_state
|
|
|
|
if checkbox.state then
|
|
|
|
new_state = nil
|
|
|
|
else
|
|
|
|
new_state = true
|
|
|
|
end
|
|
|
|
|
|
|
|
no_notify_players[player_index] = new_state
|
|
|
|
end
|
|
|
|
)
|
|
|
|
|
2018-06-28 19:28:47 +02:00
|
|
|
local function headings_click(event)
|
|
|
|
local heading_data = Gui.get_data(event.element)
|
|
|
|
local data = heading_data.data
|
|
|
|
local settings = data.settings
|
|
|
|
local index = heading_data.index
|
|
|
|
|
|
|
|
local sort = settings.sort
|
|
|
|
local sort_column = math.abs(sort)
|
|
|
|
|
|
|
|
if sort_column == index then
|
|
|
|
sort = -sort
|
|
|
|
else
|
|
|
|
sort = -index
|
|
|
|
end
|
|
|
|
|
|
|
|
settings.sort = sort
|
|
|
|
|
|
|
|
redraw_headings(data)
|
|
|
|
redraw_cells(data)
|
|
|
|
end
|
|
|
|
|
|
|
|
for name, _ in pairs(column_builders) do
|
|
|
|
Gui.on_click(name, headings_click)
|
|
|
|
end
|
|
|
|
|
|
|
|
Gui.on_click(
|
|
|
|
poke_cell_name,
|
|
|
|
function(event)
|
|
|
|
local element = event.element
|
|
|
|
local button_data = Gui.get_data(element)
|
|
|
|
local poke_player = button_data.player
|
|
|
|
local player = event.player
|
|
|
|
|
|
|
|
if poke_player == player then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local poke_player_index = poke_player.index
|
2018-08-07 14:09:41 +02:00
|
|
|
if not do_poke_spam_protection(player) then
|
2018-06-28 19:28:47 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local count = (player_pokes[poke_player_index] or 0) + 1
|
|
|
|
player_pokes[poke_player_index] = count
|
|
|
|
|
2019-01-21 21:28:21 +02:00
|
|
|
local poke_str = poke_messages[random(#poke_messages)]
|
2018-06-28 19:28:47 +02:00
|
|
|
local message = table.concat({'>> ', player.name, ' has poked ', poke_player.name, ' with ', poke_str, ' <<'})
|
|
|
|
|
|
|
|
for _, p in ipairs(game.connected_players) do
|
|
|
|
local frame = p.gui.left[main_frame_name]
|
|
|
|
if frame and frame.valid then
|
|
|
|
local frame_data = Gui.get_data(frame)
|
2018-06-29 00:50:38 +02:00
|
|
|
local poke_bottons = frame_data.poke_buttons
|
|
|
|
|
|
|
|
if poke_bottons then
|
|
|
|
local settings = frame_data.settings
|
2018-06-28 19:28:47 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local columns = settings.columns
|
|
|
|
local sort = settings.sort
|
2018-06-28 19:28:47 +02:00
|
|
|
|
2018-06-29 00:50:38 +02:00
|
|
|
local sorted_column = columns[math.abs(sort)]
|
|
|
|
if sorted_column == poke_name_heading_name then
|
|
|
|
redraw_cells(frame_data)
|
|
|
|
else
|
2018-06-30 17:58:31 +02:00
|
|
|
local poke_button = poke_bottons[poke_player_index]
|
2018-06-29 00:50:38 +02:00
|
|
|
poke_button.caption = count
|
|
|
|
end
|
2018-06-28 19:28:47 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if not no_notify_players[p.index] then
|
|
|
|
p.print(message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
2018-08-13 18:48:58 +02:00
|
|
|
|
|
|
|
Gui.on_click(
|
|
|
|
report_cell_name,
|
|
|
|
function(event)
|
|
|
|
local reporting_player = event.player
|
|
|
|
local reported_player = Gui.get_data(event.element)
|
2018-11-18 21:34:18 +02:00
|
|
|
if reporting_player.admin then
|
|
|
|
Report.jail(reported_player, reporting_player)
|
|
|
|
else
|
|
|
|
Report.spawn_reporting_popup(reporting_player, reported_player)
|
|
|
|
end
|
2018-08-13 18:48:58 +02:00
|
|
|
end
|
|
|
|
)
|
2018-12-16 03:28:00 +02:00
|
|
|
|
|
|
|
Gui.allow_player_to_toggle_top_element_visibility(main_button_name)
|