ExperimentalGear/scripts/multiplayerscreen.lua

864 lines
25 KiB
Lua
Raw Normal View History

2022-05-06 00:05:20 +02:00
local json = require("common.json")
2021-07-25 20:10:06 +02:00
2022-05-06 00:05:20 +02:00
local common = require('common.util');
local Sound = require("common.sound")
2022-03-04 11:16:27 +01:00
local Dim = require("common.dimensions")
local Wallpaper = require("components.wallpaper")
2022-05-06 00:05:20 +02:00
local Background = require('components.background');
local difbar = require("components.diff_rectangle"); --no clue but starting to separating breaks it
2022-02-26 18:26:55 +01:00
local creww = game.GetSkinSetting("single_idol")
local songjacket = require("multi.songjacket")
local m_own_info = require("multi.owninfo")
local m_base_part = require("multi.basepanel")
local m_part = require("multi.mainpanel")
local m_s_part = require("multi.songinfo")
local m_bpm_part = require("multi.bpmpanel")
local m_info_part = require("multi.infopanel")
2022-02-26 18:26:55 +01:00
2022-05-06 00:05:20 +02:00
local temppanels = gfx.CreateSkinImage("song_select/textboard.png", 1); --temp
2022-02-27 18:59:29 +01:00
2022-02-26 18:26:55 +01:00
local headerMatchingImage = gfx.CreateSkinImage("titlescreen/entry.png", 1);
2022-03-25 23:47:24 +01:00
local m_4pb_panels_bottom = gfx.CreateSkinImage("multi/lobby/opponent_bottom_panel.png", 1);
local m_4pb_panels_top = gfx.CreateSkinImage("multi/lobby/opponent_top_panel.png", 1);
2022-02-26 18:26:55 +01:00
local bg = gfx.CreateSkinImage("multi/lobby/bg.png", 1);
local bg_graid1 = gfx.CreateSkinImage("multi/lobby/gradient_bottom.png", 1);
local bg_graid2 = gfx.CreateSkinImage("multi/lobby/gradient_top.png", 1);
local idle = "/idle"
local idolAnimation = gfx.LoadSkinAnimation('crew/anim/'..creww..idle, 1 / 30, 0, true);
2022-02-26 18:26:55 +01:00
local idolAnimTransitionScale = 0;
2022-03-04 08:08:43 +01:00
local leftPanelX = 575;
local leftPanelY = 1472;
2021-07-25 20:10:06 +02:00
local mposx = 0;
local mposy = 0;
local hovered = nil;
local buttonWidth = Dim.design.width*(3/4);
2022-05-06 00:05:20 +02:00
local buttonHeight = 75;
2021-07-25 20:10:06 +02:00
local buttonBorder = 2;
local portrait
2022-05-06 00:05:20 +02:00
local jacket_size;
2022-02-26 18:26:55 +01:00
local BAR_ALPHA = 191;
local HEADER_HEIGHT = 100
local desh = game.GetResolution()
2022-05-06 00:05:20 +02:00
local scale;
2021-07-25 20:10:06 +02:00
game.LoadSkinSample("click-02")
game.LoadSkinSample("click-01")
game.LoadSkinSample("menu_click")
local loading = true;
local rooms = {};
local lobby_users = {};
selected_room = nil;
2021-07-25 20:10:06 +02:00
local user_id = nil;
local all_ready;
local user_ready;
2022-02-26 18:26:55 +01:00
local go;
2021-07-25 20:10:06 +02:00
local hard_mode = false;
local rotate_host = false;
local start_game_soon = false;
local host = nil;
local owner = nil;
local missing_song = false;
local did_exit = false;
2022-02-26 18:26:55 +01:00
local irHeartbeatRequested = false;
irText = ''
2021-07-25 20:10:06 +02:00
local grades = {
2022-02-26 18:26:55 +01:00
{["max"] = 6900000, ["image"] = gfx.CreateSkinImage("common/grades/D.png", 0)},
{["max"] = 7900000, ["image"] = gfx.CreateSkinImage("common/grades/C.png", 0)},
{["max"] = 8600000, ["image"] = gfx.CreateSkinImage("common/grades/B.png", 0)},
{["max"] = 8900000, ["image"] = gfx.CreateSkinImage("common/grades/A.png", 0)},
{["max"] = 9200000, ["image"] = gfx.CreateSkinImage("common/grades/A+.png", 0)},
{["max"] = 9400000, ["image"] = gfx.CreateSkinImage("common/grades/AA.png", 0)},
{["max"] = 9600000, ["image"] = gfx.CreateSkinImage("common/grades/AA+.png", 0)},
{["max"] = 9700000, ["image"] = gfx.CreateSkinImage("common/grades/AAA.png", 0)},
{["max"] = 9800000, ["image"] = gfx.CreateSkinImage("common/grades/AAA+.png", 0)},
{["max"] = 9900000, ["image"] = gfx.CreateSkinImage("common/grades/S.png", 0)}
2021-07-25 20:10:06 +02:00
}
local badges = {
gfx.CreateSkinImage("badges/played.png", 0),
gfx.CreateSkinImage("badges/clear.png", 0),
gfx.CreateSkinImage("badges/hard-clear.png", 0),
gfx.CreateSkinImage("badges/full-combo.png", 0),
gfx.CreateSkinImage("badges/perfect.png", 0)
}
local user_name_key = game.GetSkinSetting('multi.user_name_key')
if user_name_key == nil then
user_name_key = 'nick'
end
local name = game.GetSkinSetting(user_name_key)
if name == nil or name == '' then
name = 'Guest'
end
local normal_font = game.GetSkinSetting('multi.normal_font')
if normal_font == nil then
normal_font = 'NotoSans-Regular.ttf'
end
local mono_font = game.GetSkinSetting('multi.mono_font')
if mono_font == nil then
mono_font = 'NovaMono.ttf'
end
local SERVER = game.GetSkinSetting("multi.server")
2022-02-26 18:26:55 +01:00
local drawIdol = function(deltaTime)
local idolAnimTickRes = gfx.TickAnimation(idolAnimation, deltaTime);
if idolAnimTickRes == 1 then
gfx.GlobalAlpha(idolAnimTransitionScale);
idolAnimTransitionScale = idolAnimTransitionScale + 1 / 60;
if (idolAnimTransitionScale > 1) then
idolAnimTransitionScale = 1;
end
gfx.ImageRect(0, 0, Dim.design.width,desh, idolAnimation, 1, 0);
2022-02-26 18:26:55 +01:00
gfx.GlobalAlpha(1);
end
end
2022-02-27 18:59:29 +01:00
user_setup = function () -- (semi new) user layering
local distance = 350
for i, user in ipairs(lobby_users) do
2022-03-25 23:47:24 +01:00
2022-02-27 18:59:29 +01:00
buttonY = 1142-360/1.2
2022-02-26 18:26:55 +01:00
if owner == user_id and user.id ~= user_id then
2022-02-27 18:59:29 +01:00
draw_button("K",525+distance, buttonY, 100, function()
2022-02-26 18:26:55 +01:00
kick_user(user);
end)
end
2022-03-25 23:47:24 +01:00
if (owner == user_id or host == user_id) and user.id ~= host then
draw_button("H",16, buttonY+250, 50, function()
change_host(user);end)
end
2022-02-26 18:26:55 +01:00
if i == 1 then
2022-03-25 23:47:24 +01:00
draw_user(user, -distance, 1142-360/1.2, 420/1.2, 330/1.2,215,245.5)
2022-02-26 18:26:55 +01:00
elseif i == 2 then
2022-03-25 23:47:24 +01:00
draw_user(user, 16, 1142-360/1.2, 420/1.2, 330/1.2,215,245.5)
2022-02-26 18:26:55 +01:00
elseif i == 3 then
2022-03-25 23:47:24 +01:00
draw_user(user, 16+distance, 1142-360/1.2, 420/1.2, 330/1.2,215,245.5)
2022-02-26 18:26:55 +01:00
elseif i == 4 then
2022-03-25 23:47:24 +01:00
draw_user(user, 16+distance+distance, 1142-360/1.2, 42030//1.2, 31.2,215,245.5)
2022-02-27 18:59:29 +01:00
2022-02-26 18:26:55 +01:00
elseif i > 4 then
draw_user(user, 16+distance+distance+distance+distance, 1142-360/1.2, 420/1.2, 330/1.2, i,215,245.5)
end
end
end
2021-07-25 20:10:06 +02:00
2022-02-26 18:26:55 +01:00
function drawHeader()
gfx.BeginPath()
gfx.FillColor(0, 0, 0, BAR_ALPHA)
gfx.Rect(0, 0, Dim.design.width, HEADER_HEIGHT)
gfx.Fill()
2022-02-26 18:26:55 +01:00
gfx.ClosePath()
2021-07-25 20:10:06 +02:00
gfx.ImageRect(Dim.design.width / 2 - 200, HEADER_HEIGHT / 2 - 20, 400, 40, headerMatchingImage, 1, 0)
2022-02-26 18:26:55 +01:00
end
2021-07-25 20:10:06 +02:00
mouse_clipped = function(x,y,w,h)
return mposx > x and mposy > y and mposx < x+w and mposy < y+h;
end;
-- look into this when people are online
2021-07-25 20:10:06 +02:00
draw_room = function(name, x, y, selected, hoverindex)
local buttonWidth = Dim.design.width/2;
2021-07-25 20:10:06 +02:00
local rx = x - (buttonWidth / 2);
local ty = y - (buttonHeight / 2);
local roomButtonBorder = buttonBorder;
gfx.BeginPath();
gfx.FillColor(0,128,255);
if selected then
gfx.FillColor(0,255,0);
roomButtonBorder = 4;
end
if mouse_clipped(rx,ty-75, buttonWidth, buttonHeight/2) then
2021-07-25 20:10:06 +02:00
hovered = hoverindex;
gfx.FillColor(255,128,0);
end
gfx.Rect(rx - roomButtonBorder,
ty - roomButtonBorder,
buttonWidth + (roomButtonBorder * 2),
buttonHeight + (roomButtonBorder * 2));
gfx.Fill();
gfx.BeginPath();
gfx.FillColor(40,40,40);
gfx.Rect(rx, ty, buttonWidth, buttonHeight);
gfx.Fill();
gfx.BeginPath();
gfx.FillColor(255,255,255);
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE);
gfx.FontSize(40);
gfx.Text(name, x, y);
end;
draw_button = function(name, x, y, buttonWidth, hoverindex)
2022-02-27 18:59:29 +01:00
draw_button_color(name, x, y, buttonWidth, hoverindex, temppanels)
2021-07-25 20:10:06 +02:00
end
2022-02-27 18:59:29 +01:00
draw_button_color = function(name, x, y, buttonWidth, hoverindex,img)
local rx = x;
local ty = y - buttonHeight;
2021-07-25 20:10:06 +02:00
gfx.BeginPath();
gfx.ImageRect(rx,ty,buttonWidth,buttonHeight,img,1,0)
2022-03-25 23:47:24 +01:00
if mouse_clipped(rx,ty, buttonWidth/1.5, buttonHeight*2) then
2021-07-25 20:10:06 +02:00
hovered = hoverindex;
end
gfx.BeginPath();
gfx.FillColor(255,255,255);
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE);
gfx.FontSize(40);
gfx.Text(name, x, y);
end;
draw_checkbox = function(text, x, y, hoverindex, current, can_click)
gfx.BeginPath();
if can_click then
2022-02-27 18:59:29 +01:00
gfx.FillColor(255,255,255,100);
2021-07-25 20:10:06 +02:00
else
2022-02-27 18:59:29 +01:00
gfx.FillColor(100,100,100,100);
2021-07-25 20:10:06 +02:00
end
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER + gfx.TEXT_ALIGN_MIDDLE);
gfx.Text(text, x, y)
local xmin,ymin,xmax,ymax = gfx.TextBounds(x, y, text);
local sx = xmin - 40;
local sy = y - 15;
if can_click and mouse_clipped(xmin-10, ymin, xmax-xmin, ymax-ymin) then
2021-07-25 20:10:06 +02:00
hovered = hoverindex;
end
if current then
-- Draw checkmark
gfx.BeginPath();
2022-02-27 18:59:29 +01:00
gfx.FillColor(0, 236, 0,100);
gfx.Text(text, x, y)
2021-07-25 20:10:06 +02:00
end
end;
2022-03-25 23:47:24 +01:00
draw_user = function(user, x, y , w, h, breadx,bready)
2022-02-26 18:26:55 +01:00
local name = user.name
local showthing = false
2021-07-25 20:10:06 +02:00
if user.id == user_id then
name = name
end
2022-03-25 23:47:24 +01:00
if user.id == host then
name = name..' (host)'
elseif user.missing_map then
name = name..' (NO CHART)'
elseif user.ready then
name = name..' (ready)'
showthing = true
D = 1
elseif not user.ready then
showthing = false
D = 0
end
2022-02-19 02:38:37 +01:00
2022-02-26 18:26:55 +01:00
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_MIDDLE);
gfx.FillColor(255,255,255)
2022-02-19 02:38:37 +01:00
2022-02-26 18:26:55 +01:00
gfx.FontSize(30)
2022-03-25 23:47:24 +01:00
gfx.BeginPath()
gfx.ImageRect(x,y,w,h,m_4pb_panels_bottom,1,0)
gfx.BeginPath()
gfx.ImageRect(x,y,w,h,m_4pb_panels_top,1,0)
gfx.Text(name, x+136, y+51.5)
gfx.Text(msg, x+136, y+25.5)
gfx.FontSize(22)
gfx.Text(irText,x+32, y+225)
2021-07-25 20:10:06 +02:00
2022-02-26 18:26:55 +01:00
if showthing == true then
local jw , jh = gfx.ImageSize(ready_bt);
gfx.BeginPath();
gfx.ImageRect(x+breadx, y+bready, jw/1.18, jh/1.18, ready_bt,1,0);
elseif showthing == false then
local jw , jh = gfx.ImageSize(ready_bt);
gfx.BeginPath();
gfx.ImageRect(x+breadx, y+bready, jw/1.18, jh/1.18, ready_bt,0,0);
2021-07-25 20:10:06 +02:00
end
end;
function render_loading()
if not loading then return end
gfx.Save()
gfx.ResetTransform()
gfx.BeginPath()
gfx.MoveTo(Dim.design.width, desh)
gfx.LineTo(Dim.design.width - 350, desh)
gfx.LineTo(Dim.design.width - 300, desh - 50)
gfx.LineTo(Dim.design.width, desh - 50)
2021-07-25 20:10:06 +02:00
gfx.ClosePath()
gfx.FillColor(33,33,33)
gfx.Fill()
gfx.FillColor(255,255,255)
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
gfx.Text("LOADING...", Dim.design.width - 20, desh - 3)
2021-07-25 20:10:06 +02:00
gfx.Restore()
end
function render_info()
2022-02-26 18:26:55 +01:00
if searchStatus then
2021-07-25 20:10:06 +02:00
gfx.BeginPath()
gfx.FillColor(255,255,255)
gfx.FontSize(20);
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP)
gfx.Text(searchStatus, 3, 3)
end
end
draw_diff_icon = function(diff, x, y, w, h)
difbar.render(deltaTime, x, y, 1, diff.difficulty, diff.level);
2021-07-25 20:10:06 +02:00
end
local doffset = 0;
local timer = 0;
local possy = 1095;
local possx = 150;
2021-07-25 20:10:06 +02:00
draw_diffs = function(diffs, x, y, w, h, selectedDiff)
local diffWidth = w/2
local diffHeight = w/2
2021-07-25 20:10:06 +02:00
local diffCount = #diffs
gfx.Scissor(x+84 + possx,y + possy,w/2.451,h)
2021-07-25 20:10:06 +02:00
for i = math.max(selectedDiff - 2, 1), math.max(selectedDiff - 1,1) do
local diff = diffs[i]
local xpos = x + ((w/2 - diffWidth/2) + (selectedDiff - i + doffset)*(-0.8*diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos + possx, y + possy, diffWidth, diffHeight, false)
2021-07-25 20:10:06 +02:00
end
end
--after selected
for i = math.min(selectedDiff + 2, diffCount), selectedDiff + 1,-1 do
local diff = diffs[i]
local xpos = x + ((w/2 - diffWidth/2) + (selectedDiff - i + doffset)*(-0.8*diffWidth))
if i ~= selectedDiff then
draw_diff_icon(diff, xpos + possx, y + possy, diffWidth, diffHeight, false)
2021-07-25 20:10:06 +02:00
end
end
2021-07-25 20:10:06 +02:00
local diff = diffs[selectedDiff]
local xpos = x + ((w/2 - diffWidth/2) + (doffset)*(-0.8*diffWidth))
draw_diff_icon(diff, xpos + possx, y + possy, diffWidth, diffHeight, true)
2021-07-25 20:10:06 +02:00
gfx.ResetScissor()
2021-07-25 20:10:06 +02:00
end
set_diff = function(oldDiff, newDiff)
game.PlaySample("click-02")
doffset = doffset + oldDiff - newDiff
end;
local selected_room_index = 1;
local ioffset = 0;
function draw_rooms(y, h)
if #rooms == 0 then
return
end
local num_rooms_visible = math.floor(h / (buttonHeight + 10))
local first_half_rooms = math.floor(num_rooms_visible/2)
local second_half_rooms = math.ceil(num_rooms_visible/2) - 1
local start_offset = math.max(selected_room_index - first_half_rooms, 1);
local end_offset = math.min(selected_room_index + second_half_rooms + 2, #rooms);
local start_index_offset = 1;
-- If our selection is near the start or end we have to offset
if selected_room_index <= first_half_rooms then
start_index_offset = 0;
end_offset = math.min(#rooms, num_rooms_visible + 1)
end
if selected_room_index >= #rooms - second_half_rooms then
start_offset = math.max(1, #rooms - num_rooms_visible)
end_offset = #rooms
end
for i = start_offset, end_offset do
local room = rooms[i];
-- if selected room < halfvis then we start at 1
-- if sel > #rooms - halfvis then we start at -halfvis
local offset_index = (start_offset + first_half_rooms) - i + start_index_offset
local offsetY = (offset_index + ioffset) * (buttonHeight + 10);
local ypos = y + (h/2) - offsetY;
local status = room.current..'/'..room.max
if room.ingame then
status = status..' (IN MATCH)'
2021-07-25 20:10:06 +02:00
end
if room.password then
status = status..' <P>'
end
draw_room(room.name .. ': '.. status, Dim.design.width/2, ypos, i == selected_room_index, function()
2021-07-25 20:10:06 +02:00
join_room(room)
end)
end
end
change_selected_room = function(off)
local new_index = selected_room_index + off;
--selected_room_index = 2;
if new_index < 1 or new_index > #rooms then
return;
end
local h = desh - 290;
2021-07-25 20:10:06 +02:00
local num_rooms_visible = math.floor(h / (buttonHeight + 10))
local first_half_rooms = math.floor(num_rooms_visible/2)
local second_half_rooms = math.ceil(num_rooms_visible/2) - 1
if off > 0 and (selected_room_index < first_half_rooms or selected_room_index >= #rooms - second_half_rooms - 1) then
elseif off < 0 and (selected_room_index <= first_half_rooms or selected_room_index >= #rooms - second_half_rooms) then
else
ioffset = ioffset - new_index + selected_room_index;
end
game.PlaySample("menu_click")
selected_room_index = new_index;
end
2022-02-26 18:26:55 +01:00
local IR_HeartbeatResponse = function(res)
if res.statusCode == IRData.States.Success then
irText = res.body.serverName .. ' ' .. res.body.irVersion;
2021-07-25 20:10:06 +02:00
else
2022-02-26 18:26:55 +01:00
game.Log("Can't connect to IR!", game.LOGGER_WARNING)
2021-07-25 20:10:06 +02:00
end
2022-02-26 18:26:55 +01:00
end
2021-07-25 20:10:06 +02:00
2022-02-26 18:26:55 +01:00
local IR_Handle = function()
if not irHeartbeatRequested then
IR.Heartbeat(IR_HeartbeatResponse)
irHeartbeatRequested = true;
end
end
2022-02-26 18:26:55 +01:00
function render_lobby(deltaTime)
local jw , jh = gfx.ImageSize(bg);
gfx.BeginPath();
gfx.ImageRect(0, 0, Dim.design.width, desh, bg,1,0);
2022-02-26 18:26:55 +01:00
drawIdol(deltaTime)
gfx.BeginPath();
gfx.ImageRect(0, 0, Dim.design.width, desh, bg_graid1,1,0);
gfx.ImageRect(0, 0, Dim.design.width, desh, bg_graid2,1,0);
2022-02-26 18:26:55 +01:00
gfx.BeginPath();
m_base_part()
2021-07-25 20:10:06 +02:00
2022-02-26 18:26:55 +01:00
m_own_info()
user_setup()
2021-07-25 20:10:06 +02:00
2022-02-26 18:26:55 +01:00
m_info_part()
m_part()
m_s_part()
m_bpm_part()
songjacket()
2022-03-04 08:08:43 +01:00
end
2021-07-25 20:10:06 +02:00
function render_room_list(deltaTime)
2022-02-26 18:26:55 +01:00
2022-03-04 12:32:45 +01:00
Background.draw(deltaTime)
2022-03-25 23:47:24 +01:00
draw_rooms(175, desh - 290);
2021-07-25 20:10:06 +02:00
-- Draw cover for rooms out of view
gfx.BeginPath()
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
if not loading then
draw_button("Create new room", Dim.design.width/2, desh-40-buttonHeight, Dim.design.width*(3/4), new_room);
2021-07-25 20:10:06 +02:00
end
2022-03-25 23:47:24 +01:00
2021-07-25 20:10:06 +02:00
end
passwordErrorOffset = 0;
function render_password_screen(deltaTime)
gfx.FillColor(255,255,255)
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
gfx.Text("Joining "..selected_room.name.."...", Dim.design.width/2, desh/4)
2021-07-25 20:10:06 +02:00
gfx.FillColor(50,50,50)
gfx.BeginPath()
gfx.Rect(0, desh/2-10, Dim.design.width, 40)
2021-07-25 20:10:06 +02:00
gfx.Fill();
gfx.FillColor(255,255,255)
gfx.Text("Please enter room password:", Dim.design.width/2, desh/2-40)
gfx.Text(string.rep("*",#textInput.text), Dim.design.width/2, desh/2+40)
2021-07-25 20:10:06 +02:00
if passwordError then
gfx.FillColor(255,50,50)
gfx.FontSize(60 + math.floor(passwordErrorOffset*20))
gfx.Text("Invalid password", Dim.design.width/2, desh/2+80)
2021-07-25 20:10:06 +02:00
end
draw_button("Join", Dim.design.width/2, desh*3/4, Dim.design.width/2, mpScreen.JoinWithPassword);
2021-07-25 20:10:06 +02:00
end
function render_new_room_password(delta_time)
gfx.FillColor(255,255,255)
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
gfx.Text("Create New Room", Dim.design.width/2, desh/4)
2021-07-25 20:10:06 +02:00
gfx.FillColor(50,50,50)
gfx.BeginPath()
gfx.Rect(0, desh/2-10, Dim.design.width, 40)
2021-07-25 20:10:06 +02:00
gfx.Fill();
gfx.FillColor(255,255,255)
gfx.Text("Enter room password:", Dim.design.width/2, desh/2-40)
gfx.Text(string.rep("*",#textInput.text), Dim.design.width/2, desh/2+40)
draw_button("Create Room", Dim.design.width/2, desh*3/4, Dim.design.width/2, mpScreen.NewRoomStep);
2021-07-25 20:10:06 +02:00
end
2021-07-25 20:10:06 +02:00
function render_new_room_name(deltaTime)
gfx.BeginPath();
gfx.LoadSkinFont("segoeui.ttf")
2021-07-25 20:10:06 +02:00
gfx.FillColor(255,255,255)
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
gfx.Text("Create New Room", Dim.design.width/2, desh/4)
2021-07-25 20:10:06 +02:00
gfx.Rect(0, desh/2-10, Dim.design.width, 60)
2021-07-25 20:10:06 +02:00
gfx.Text("Please enter room name:", Dim.design.width/2, desh/2-40)
gfx.Text(textInput.text, Dim.design.width/2, desh/2+40)
draw_button("Next", Dim.design.width/2, desh*3/4, Dim.design.width/2, mpScreen.NewRoomStep);
2021-07-25 20:10:06 +02:00
end
function render_set_username(deltaTime)
gfx.FillColor(255,255,255)
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER, gfx.TEXT_ALIGN_BOTTOM)
gfx.FontSize(70)
gfx.Text("First things first...", Dim.design.width/2, desh/4)
2021-07-25 20:10:06 +02:00
gfx.FillColor(50,50,50)
gfx.BeginPath()
gfx.Rect(0, desh/2-10, Dim.design.width, 60)
2021-07-25 20:10:06 +02:00
gfx.Fill();
gfx.FillColor(255,255,255)
gfx.Text("Enter a display name:", Dim.design.width/2, desh/2-40)
gfx.Text(textInput.text, Dim.design.width/2, desh/2+40)
draw_button("Join Multiplayer", Dim.design.width/2, desh*3/4, Dim.design.width/2, function()
2021-07-25 20:10:06 +02:00
loading = true;
mpScreen.SaveUsername()
end);
end
render = function(deltaTime)
2022-03-25 23:47:24 +01:00
IR_Handle()
2022-03-04 11:16:27 +01:00
Dim.updateResolution()
Wallpaper.render()
2022-03-04 08:08:43 +01:00
2022-05-06 00:05:20 +02:00
Dim.transformToScreenSpace()
2022-03-04 08:08:43 +01:00
2021-07-25 20:10:06 +02:00
mposx,mposy = game.GetMousePos();
2022-05-06 00:05:20 +02:00
Sound.stopMusic();
2021-07-25 20:10:06 +02:00
doffset = doffset * 0.9
ioffset = ioffset * 0.9
passwordErrorOffset = passwordErrorOffset * 0.9
timer = (timer + deltaTime)
timer = timer % 2
hovered = nil;
gfx.LoadSkinFont(normal_font);
do_sounds(deltaTime);
-- Room Listing View
if screenState == "inRoom" then
render_lobby(deltaTime);
elseif screenState == "roomList" then
render_room_list(deltaTime);
elseif screenState == "passwordScreen" then
2022-03-25 23:47:24 +01:00
Background.draw(deltaTime)
2021-07-25 20:10:06 +02:00
render_password_screen(deltaTime);
elseif screenState == "newRoomName" then
2022-03-25 23:47:24 +01:00
Background.draw(deltaTime)
2021-07-25 20:10:06 +02:00
render_new_room_name()
elseif screenState == "newRoomPassword" then
2022-03-25 23:47:24 +01:00
Background.draw(deltaTime)
2021-07-25 20:10:06 +02:00
render_new_room_password()
elseif screenState == "setUsername" then
2022-03-25 23:47:24 +01:00
Background.draw(deltaTime)
2021-07-25 20:10:06 +02:00
loading = false;
render_set_username()
end
render_loading();
render_info();
drawHeader()
2021-07-25 20:10:06 +02:00
end
-- Ready up to play
function ready_up()
Tcp.SendLine(json.encode({topic="user.ready.toggle"}))
end
-- Toggle hard gauage
function toggle_hard()
Tcp.SendLine(json.encode({topic="user.hard.toggle"}))
end
-- Toggle hard gauage
function toggle_mirror()
Tcp.SendLine(json.encode({topic="user.mirror.toggle"}))
end
function new_room()
host = user_id
owner = user_id
mpScreen.NewRoomStep()
end
-- Toggle host rotation
function toggle_rotate()
Tcp.SendLine(json.encode({topic="room.option.rotation.toggle"}))
end
-- Change lobby host
function change_host(user)
Tcp.SendLine(json.encode({topic="room.host.set", host=user.id}))
end
-- Kick user
function kick_user(user)
Tcp.SendLine(json.encode({topic="room.kick", id=user.id}))
end
-- Tell the server to start the game
function start_game()
selected_song.self_picked = false
if (selected_song == nil) then
return
end
if (start_game_soon) then
return
end
Tcp.SendLine(json.encode({topic="room.game.start"}))
end
-- Join a given room
function join_room(room)
host = user_id
selected_room = room;
if room.password then
mpScreen.JoinWithPassword(room.id)
else
mpScreen.JoinWithoutPassword(room.id)
end
end
2022-02-26 22:50:50 +01:00
2021-07-25 20:10:06 +02:00
-- Handle button presses to advance the UI
button_pressed = function(button)
2022-02-26 22:50:50 +01:00
2022-03-25 23:47:24 +01:00
if button == game.BUTTON_STA then
2021-07-25 20:10:06 +02:00
if start_game_soon then
return
end
if screenState == "roomList" then
if #rooms == 0 then
new_room()
else
-- TODO navigate room selection
join_room(rooms[selected_room_index])
end
elseif screenState == "inRoom" then
if host == user_id then
if selected_song and selected_song.self_picked then
if all_ready then
start_game()
else
missing_song = false
mpScreen.SelectSong()
end
else
missing_song = false
mpScreen.SelectSong()
end
else
ready_up()
end
end
end
2022-02-26 18:26:55 +01:00
if button == game.BUTTON_BTA then
2021-07-25 20:10:06 +02:00
toggle_hard();
end
2022-02-26 18:26:55 +01:00
if button == game.BUTTON_BTB then
2021-07-25 20:10:06 +02:00
toggle_mirror();
end
2022-02-26 22:50:50 +01:00
if button == game.BUTTON_BTC then
toggle_rotate();
end
2022-02-27 18:59:29 +01:00
if button == game.BUTTON_BTD then
for i, user in ipairs(lobby_users) do
if lobby_users[i] == user then
kick_user(user);
end
end
end
2021-07-25 20:10:06 +02:00
end
-- Handle the escape key around the UI
function key_pressed(key)
if key == 27 then --escape pressed
if screenState == "roomList" then
did_exit = true;
mpScreen.Exit();
return
end
-- Reset room data
screenState = "roomList" -- have to update here
selected_room = nil;
rooms = {};
selected_song = nil
selected_song_index = 1;
jacket = 0;
end
end
-- Handle mouse clicks in the UI
mouse_pressed = function(button)
if hovered then
hovered()
end
return 0
end
function init_tcp()
Tcp.SetTopicHandler("server.info", function(data)
loading = false
user_id = data.userid
end)
-- Update the list of rooms as well as get user_id for the client
Tcp.SetTopicHandler("server.rooms", function(data)
rooms = {}
for i, room in ipairs(data.rooms) do
table.insert(rooms, room)
end
end)
Tcp.SetTopicHandler("server.room.joined", function(data)
selected_room = data.room
end)
local sound_time = 0;
local sound_clip = nil;
local sounds_left = 0;
local sound_interval = 0;
function repeat_sound(clip, times, interval)
sound_clip = clip;
sound_time = 0;
sounds_left = times - 1;
sound_interval = interval;
game.PlaySample(clip)
end
function do_sounds(deltaTime)
if sound_clip == nil then
return
end
sound_time = sound_time + deltaTime;
if sound_time > sound_interval then
sound_time = sound_time - sound_interval;
game.PlaySample(sound_clip);
sounds_left = sounds_left - 1
if sounds_left <= 0 then
sound_clip = nil
end
end
end
local last_song = nil
-- Update the current lobby
Tcp.SetTopicHandler("room.update", function(data)
-- Update the users in the lobby
lobby_users = {}
local prev_all_ready = all_ready;
all_ready = true
for i, user in ipairs(data.users) do
table.insert(lobby_users, user)
if user.id == user_id then
user_ready = user.ready
end
if not user.ready then
all_ready = false
end
end
if user_id == host and #data.users > 1 and all_ready and not prev_all_ready then
repeat_sound("click-02", 3, .1)
end
if data.host == user_id and host ~= user_id then
repeat_sound("click-02", 3, .1)
end
if data.song ~=nil and last_song ~=data.song then
game.PlaySample("menu_click")
last_song = data.song
end
host = data.host
if data.owner then
owner = data.owner
else
owner = host
end
hard_mode = data.hard_mode
mirror_mode = data.mirror_mode
do_rotate = data.do_rotate
if data.start_soon and not start_game_soon then
repeat_sound("click-01", 5, 1)
end
start_game_soon = data.start_soon
end)
end