local client = require("client") local util = require("util") local ui = require("ui") local dialog = require("dialog") local socket = require("socket") local L = require("lang").get local C = ui.color local teams = { { id = "attack", name = "ATK", col = C(0xEF8131) }, { id = "defend", name = "DEF", col = C(0x6F8AAC) }, { id = "third_party", name = "PO3", col = C(0xF1E816) }, } local color = { greyed = C(0x606060), hover = C(0x404040), normal = C(0x000000), me = C(0x000000), } local function make_selection(lobby, key, dir) local list = key == "team" and teams or lobby.game.client.content[key.."s"] local current = lobby.game.client.player[key] local index if current then index = util.find_index_by(list, "id", current) elseif not current then index = 1 if dir == 1 then dir = 0 end end index = (index-1+dir)%#list+1 client.select(lobby.game.client, key, list[index].id) end local function insert_row(columns, elems, cell) cell = cell or function(x) return x end local size = 0 for i = 1, #columns do if elems[i] then size = math.max(size, ui.min_size(elems[i], "y")) end end for i = 1, #columns do table.insert(columns[i], cell({ { size = { y = size } }, elems[i] })) end end local function clear_table(t) while #t > 0 do table.remove(t) end end local function invite_display(lobby) local copy_btn = ui.copy_button(function() return lobby.game.server.invite end, 25) local reveal_btn = ui.click(ui.center_x(ui.text(L("dialog.lobby.invite_reveal"), 30, C(0x000000))), function(self) self.active = false end) for _, b in ipairs({ reveal_btn, copy_btn }) do b.line = C(0x000000) b.line_width = 4 b.fill_hover = C(0x8080a0) b.fill_normal = C(0xEFE3AF) end local code = ui.text(code, 30, color.normal) local elem = ui.align_right(ui.stack_x( ui.center_y(ui.text(L("dialog.lobby.invite"), 30, color.normal)), { code, reveal_btn }, ui.pad_x(8), copy_btn )) function elem:show() if lobby.game.server then code.text:set(lobby.game.server.invite) else elem.active = false end end return elem end local function text(x, col) return ui.text(x, 30, col or C(0x000000)) end local function fill_player_columns(lobby, columns) local info = lobby.game.client.info local me = lobby.game.client.player local teams_by_id = util.index_by(teams, "id") for _, c in ipairs(columns) do clear_table(c) end local function cell(x) return { line = C(0x000000), line_width = 4, line_segments = { 1, 3 }, ui.pad_x(10, ui.pad_y(10, x)) } end local function player_name(name, me, active) return text(name, (me and color.me) or (active and color.normal) or color.greyed) end for _, p in ipairs(info.players) do local name_cell = player_name(p.name, p == me, p.active) local team_cell = p.team and ui.align_left({ fill = teams_by_id[p.team].col, text(teams_by_id[p.team].name, C(0x000000)) }) or {} local faction_cell = p.faction and text(lobby.game.client.factions_by_id[p.faction].name) or {} local ready = text(L("dialog.lobby.ready")) local ready_size = ready.text:getHeight() local ready_elem = ui.pad_x(5, ready, { fill = p.ready and C(0x1EB251) or C(0xEF1B22), line = C(0x000000), line_width = 4, size = { x = ready_size, y = ready_size }, }) if p == me then ready_elem = ui.click(ready_elem, function() client.select(lobby.game.client, "ready", not lobby.game.client.player.ready) end) end local ready_cell = ui.align_right(ready_elem) insert_row(columns, { name_cell, team_cell, faction_cell, ready_cell }, cell) end if not info.started then insert_row(columns, { player_name(L("dialog.lobby.empty_slot")) }, cell) end end local function player_display(lobby) local columns = ui.stack_x() for i = 1, 4 do local column = ui.stack_y() column.flex = ({ 2, nil, nil, 3 })[i] table.insert(columns, column) end local player_columns = {} for i = 1, #columns do local angle = -75/180*math.pi local column = ui.stack_y() column.line = C(0x000000) column.line_width = 4 column.angle = { x = { i ~= 1 and angle, i ~= #columns and angle } } column.flex = 1 column.debug = "col_"..i table.insert(player_columns, column) end local button_image = {} local function header(id) local t = text(L("dialog.lobby", id)) local function vbtn(sym, dir) local image = ui.image("assets/icon/angle_"..sym..".png", "scale", { y = t.text:getHeight() }) image.color_hover = color.hover image.color_normal = color.normal table.insert(button_image, image) return ui.click(image, function() if not lobby.game.client.info.started then make_selection(lobby, id, dir) end end) end return ui.pad_x(2, ui.stack_x(vbtn("left", -1), ui.flex(1, ui.center_x(t)), vbtn("right", 1))) end insert_row(columns, { nil, header("team"), header("faction"), nil }) insert_row(columns, player_columns) function columns:show() fill_player_columns(lobby, player_columns) if lobby.game.client.info.started then for _, img in ipairs(button_image) do img.color = color.greyed end end end return columns end local function countdown_display(lobby) local text = ui.text("", 40, C(0x000000)) function text:update() if lobby.countdown_time then text.visible = true local secs = math.max(0, math.ceil(lobby.countdown_time - socket.gettime())) if secs ~= lobby.countdown_secs then text.text:set(L("dialog.lobby.countdown") .. " " .. secs .. "...") lobby.countdown_secs = secs end if secs == 0 then lobby.countdown_time = nil end else text.visible = false end end return ui.align_right(ui.align_top(ui.pad_x(10, ui.pad_y(10, text)))) end local function dialog_lobby(lobby) local invite = invite_display(lobby) local players = player_display(lobby) local countdown = countdown_display(lobby) local box = ui.gradient(135, 0.3, { C(0x0060AA), C(0x0060AA), C(0xDFDB4B), C(0xB36910), C(0xB36910) }, { line = C(0x000000), line_width = 4, ui.stack_x(ui.flex(1, ui.stack_y(ui.pad_y(10), invite, players)), ui.pad_x(15)) }) local dg = ui.new({ ui.image("assets/bg/rainbow_six_siege_x_clash.jpg", "cover"), ui.stack_x( ui.flex(1), ui.flex(1, ui.stack_y( ui.flex(1), ui.center_x(ui.text(L("dialog.lobby.players"), 150, C(0x000000))), ui.flex(2, box) )), ui.flex(1) ), countdown }) function dg:show() invite:show() players:show() end return dg end local function show(lobby) dialog.show(lobby.ui) end local function set_countdown(lobby, time) if time then lobby.countdown_time = socket.gettime()+time else lobby.countdown_time = nil end end local function create(game) local lobby = { game = game } lobby.ui = dialog_lobby(lobby) lobby.show = show lobby.countdown = set_countdown return lobby end return { create = create, }