local data=love.data local gc=love.graphics local tc=love.touch local playerData local ins,rem=table.insert,table.remove local SCR=SCR local VK=virtualkey local onVirtualkey=onVirtualkey local pressVirtualkey=pressVirtualkey local updateVirtualkey=updateVirtualkey local hideChatBox local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=550,hide=function()return hideChatBox end} local function switchChat() hideChatBox=not hideChatBox end local playerInitialized local playing local heartBeatTimer local lastUpstreamTime local upstreamProgress local lastBackTime=0 local noTouch,noKey=false,false local touchMoveLastFrame=false local scene={} function scene.sceneBack() WS.send("play","Q") WSCONN=false LOG.print(text.wsDisconnected,"warn") love.keyboard.setKeyRepeat(true) end function scene.sceneInit() love.keyboard.setKeyRepeat(false) hideChatBox=true playerInitialized=false textBox:clear() playerData={} resetGameData("n",playerData) noTouch=not SETTING.VKSwitch playing=false lastUpstreamTime=0 upstreamProgress=1 heartBeatTimer=0 end function scene.touchDown(x,y) if noTouch then return end local t=onVirtualkey(x,y) if t then PLAYERS[1]:pressKey(t) pressVirtualkey(t,x,y) end end function scene.touchUp(x,y) if noTouch then return end local t=onVirtualkey(x,y) if t then PLAYERS[1]:releaseKey(t) end end function scene.touchMove() if noTouch or touchMoveLastFrame then return end touchMoveLastFrame=true local L=tc.getTouches() for i=#L,1,-1 do L[2*i-1],L[2*i]=SCR.xOy:inverseTransformPoint(tc.getPosition(L[i])) end for n=1,#VK do local B=VK[n] if B.ava then for i=1,#L,2 do if(L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then goto continue end end PLAYERS[1]:releaseKey(n) end ::continue:: end end function scene.keyDown(key) if key=="escape"then if TIME()-lastBackTime<1 then SCN.back() else lastBackTime=TIME() LOG.print(text.sureQuit,COLOR.orange) end elseif key=="\\"then switchChat() elseif playing then if noKey then return end local k=keyMap.keyboard[key] if k and k>0 then PLAYERS[1]:pressKey(k) VK[k].isDown=true VK[k].pressTime=10 end elseif key=="space"then if not PLAYERS[1].ready then WS.send("play","R") end end end function scene.keyUp(key) if noKey then return end local k=keyMap.keyboard[key] if k and k>0 then PLAYERS[1]:releaseKey(k) VK[k].isDown=false end end function scene.gamepadDown(key) if key=="back"then if TIME()-lastBackTime<1 then WSCONN=false SCN.back() else lastBackTime=TIME() LOG.print(text.sureQuit,COLOR.orange) end else if noKey then return end local k=keyMap.joystick[key] if k and k>0 then PLAYERS[1]:pressKey(k) VK[k].isDown=true VK[k].pressTime=10 end end end function scene.gamepadUp(key) if noKey then return end local k=keyMap.joystick[key] if k and k>0 then PLAYERS[1]:releaseKey(k) VK[k].isDown=false return end end function scene.socketRead(mes) local cmd=mes:sub(1,1) local args=SPLITSTR(mes:sub(2),";") if cmd=="J"then if playerInitialized then local L=SPLITSTR(args[1],",") textBox:push{ COLOR.lR,L[1], COLOR.dY,"#"..L[2].." ", COLOR.Y,text.joinRoom, } end for i=1,#args do local L=SPLITSTR(args[i],",") ins(playerData,{name=L[1],id=L[2],sid=L[3],conf=L[4],ready=L[5]=="1"}) end playerInitialized=true SFX.play("click") if not playing then resetGameData("qn",playerData) end elseif cmd=="L"then textBox:push{ COLOR.lR,args[1], COLOR.dY,"#"..args[2].." ", COLOR.Y,text.leaveRoom, } for i=1,#playerData do if playerData[i].id==args[2]then rem(playerData,i) break end end for i=1,#PLAYERS do if PLAYERS[i].userID==args[2]then rem(PLAYERS,i) break end end for i=1,#PLAYERS.alive do if PLAYERS.alive[i].userID==args[2]then rem(PLAYERS.alive,i) break end end initPlayerPosition(true) elseif cmd=="T"then local _,text=pcall(data.decode,"string","base64",args[3]) if not _ then text=args[3]end textBox:push{ COLOR.W,args[1], COLOR.dY,"#"..args[2].." ", COLOR.sky,text } elseif cmd=="C"then if tostring(USER.id)~=args[2]then for i=1,#playerData do if playerData[i].id==args[2]then playerData[i].conf=args[4] playerData[i].p:setConf(args[4]) return end end resetGameData("qn",playerData) end elseif cmd=="S"then if playing and args[1]~=PLAYERS[1].subID then for _,P in next,PLAYERS do if P.subID==args[1]then local _,stream=pcall(data.decode,"string","base64",args[2]) if _ then pumpRecording(stream,P.stream) else LOG.print("Bad stream from "..P.userName.."#"..P.userID) end end end end elseif cmd=="R"then local L=PLAYERS.alive for i=1,#L do if L[i].subID==args[1]then L[i].ready=true SFX.play("reach",.6) break end end elseif cmd=="B"then if not playing then playing=true lastUpstreamTime=0 upstreamProgress=1 resetGameData("n",playerData,tonumber(args[1])) else LOG.print("Redundant signal: B(begin)",30,COLOR.green) end elseif cmd=="F"then playing=false resetGameData("n",playerData) for i=1,#playerData do if playerData[i].sid==args[1]then TEXT.show(text.champion:gsub("$1",playerData[i].name.."#"..playerData[i].id),640,260,80,"zoomout",.26) break end end else LOG.print("Illegal message: ["..mes.."]",30,COLOR.green) end end function scene.update(dt) local _ local GAME=GAME if not WSCONN and not SCN.swapping then SCN.back()end if not playing then heartBeatTimer=heartBeatTimer+dt if heartBeatTimer>42 then heartBeatTimer=0 WS.send("play","P") end return end touchMoveLastFrame=false updateVirtualkey() GAME.frame=GAME.frame+1 --Counting, include pre-das if checkStart()then return end --Update players for p=1,#PLAYERS do PLAYERS[p]:update(dt)end --Warning check checkWarning() --Upload stream if GAME.frame-lastUpstreamTime>8 then local stream stream,upstreamProgress=dumpRecording(GAME.rep,upstreamProgress) if #stream>0 then WS.send("stream",data.encode("string","base64",stream)) else ins(GAME.rep,GAME.frame) ins(GAME.rep,0) end lastUpstreamTime=PLAYERS[1].alive and GAME.frame or 1e99 end end function scene.draw() drawFWM() --Players for p=hideChatBox and 1 or 2,#PLAYERS do PLAYERS[p]:draw() end --Virtual keys drawVirtualkeys() --Warning drawWarning() --New message if textBox.new and hideChatBox then setFont(30) gc.setColor(1,TIME()%.4<.2 and 1 or 0,0) gc.print("M",460,15) end end scene.widgetList={ textBox, WIDGET.newKey{name="ready",x=640,y=440,w=200,h=80,color="yellow",font=40,code=pressKey"space",hide=function()return playing or not hideChatBox or PLAYERS[1].ready end}, WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=switchChat}, WIDGET.newKey{name="quit",fText="X",x=900,y=35,w=60,font=40,code=pressKey"escape"}, } return scene