diff --git a/Zframework/file.lua b/Zframework/file.lua index b0689752..e6ea1177 100644 --- a/Zframework/file.lua +++ b/Zframework/file.lua @@ -44,15 +44,20 @@ function FILE.save(data,name,mode) data=tostring(data) end + if mode:find'd'and fs.getInfo(name)then + MES.new('error',text.saveError_duplicate) + return + end local F=fs.newFile(name) F:open'w' local success,mes=F:write(data) F:flush()F:close() - if not success then + if success then + return true + else MES.new('error',text.saveError..(mes or"unknown error")) MES.traceback() end - return success end function FILE.clear(path) if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end diff --git a/Zframework/websocket_thread.lua b/Zframework/websocket_thread.lua index 5a436c1f..523c5fc4 100644 --- a/Zframework/websocket_thread.lua +++ b/Zframework/websocket_thread.lua @@ -57,6 +57,7 @@ do--Connect error((code or"XXX")..":"..(res and res.reason or"Server Error")) end end + SOCK:settimeout(0) end local YIELD=coroutine.yield diff --git a/conf.lua b/conf.lua index b804ef00..7b908fbf 100644 --- a/conf.lua +++ b/conf.lua @@ -1,5 +1,5 @@ VERSION={ - build=352, + build=353, code=1600, short="V0.16.0", string="Alpha V0.16.0", diff --git a/parts/data.lua b/parts/data.lua index 83bc32e6..770014d9 100644 --- a/parts/data.lua +++ b/parts/data.lua @@ -1,6 +1,3 @@ -local loveCompress=love.data.compress -local loveDecompress=love.data.decompress - local int=math.floor local char,byte=string.char,string.byte local ins=table.insert @@ -239,10 +236,13 @@ function DATA.pasteQuestArgs(str) end --[[ - Table data format: + Replay file: + a zlib-compressed json table + + Replay data format (table): {frame,event, frame,event, ...} - Byte data format: (1 byte each period) + Replay data format (byte): (1 byte each period) dt, event, dt, event, ... all data range from 0 to 127 large value will be encoded as 1xxxxxxx(high)-1xxxxxxx-...-0xxxxxxx(low) @@ -357,7 +357,7 @@ do--function DATA.saveReplay() local fileName=os.date("replay/%Y_%m_%d_%H%M%S.rep") if not love.filesystem.getInfo(fileName)then love.filesystem.write(fileName, - loveCompress('string','zlib', + love.data.compress('string','zlib', JSON.encode{ date=os.date("%Y/%m/%d %H:%M:%S"), mode=GAME.curModeName, @@ -378,14 +378,18 @@ do--function DATA.saveReplay() end end function DATA.parseReplay(fileName,ifFull) - local fileData,success,metaData,rep - + local fileData --Read file fileData=love.filesystem.read(fileName) + return DATA.parseReplayData(fileName,fileData,ifFull) +end +function DATA.parseReplayData(fileName,fileData,ifFull) + local success,metaData,rep + if not(fileData and #fileData>0)then goto BREAK_cannotParse end --Decompress file - success,fileData=pcall(loveDecompress,'string','zlib',fileData) + success,fileData=pcall(love.data.decompress,'string','zlib',fileData) if not success then goto BREAK_cannotParse end --Load metadata @@ -421,5 +425,4 @@ function DATA.parseReplay(fileName,ifFull) available=false, } end - return DATA \ No newline at end of file diff --git a/parts/language/dict_en.lua b/parts/language/dict_en.lua index 87ccae1d..c5868f43 100644 --- a/parts/language/dict_en.lua +++ b/parts/language/dict_en.lua @@ -365,7 +365,7 @@ return{ {"BiRS", "birs biasrs biasrotationsystem", "term", - "*Techmino exclusive*\n\nBias Rotation System, Techmino's original rotation system based on XRS and SRS.\nIt sets an offset to rotation if you hold left/right/soft drop when you rotate.\nIf rotation fails when downwards offset is applied, it tries again without the downwards offset.\nThen it tries without left/right offset.\nIf it fails, then rotation will not occur.\n\nCompared to XRS, BiRS only uses a single kick table, making it easier to memorize; also keeps the climbing-over-terrain feature of SRS.\n\nThe final kick offset's euclidean distance can't be larger than sqrt(5) and if there is a horizontal offset, the final kick offset can't be in the opposite direction.",--todo + "*Techmino exclusive*\n\nBias Rotation System, Techmino's original rotation system based on XRS and SRS.\nIt sets an offset to rotation if you hold left/right/soft drop when you rotate.\nIf rotation fails when downwards offset is applied, it tries again without the downwards offset.\nThen it tries without left/right offset.\nIf it fails, then rotation will not occur.\n\nCompared to XRS, BiRS only uses a single kick table, making it easier to memorize; also keeps the climbing-over-terrain feature of SRS.\n\nThe final kick offset's euclidean distance can't be larger than sqrt(5) and if there is a horizontal offset, the final kick offset can't be in the opposite direction.", }, {"C2RS", "c2rs", @@ -395,7 +395,7 @@ return{ {"XRS", "xrs", "term", - "X rotation system, a rotation system used in T-ex.\n\nIt introduced a feature to \"use another kick table if you hold a direction key\", making it possible for players to tell the game where they want the piece to go.",--todo + "X rotation system, a rotation system used in T-ex.\n\nIt introduced a feature to \"use another kick table if you hold a direction key\", making it possible for players to tell the game where they want the piece to go.", }, {"Back to Back", diff --git a/parts/language/lang_en.lua b/parts/language/lang_en.lua index 97383ed2..4a1e3306 100644 --- a/parts/language/lang_en.lua +++ b/parts/language/lang_en.lua @@ -56,14 +56,14 @@ return{ ai_fixed="The AI is incompatible with fixed sequences.", ai_prebag="The AI is incompatible with custom sequences which have nontetramino.", ai_mission="The AI is incompatible with custom missions.", - saveDone="Data Saved", - saveError="Failed to save:", - loadError="Failed to load:", switchSpawnSFX="Please turn on the spawn SFX .", ranks={"D","C","B","A","S"}, - needRestart="Retry for the changes to take effect.", + saveDone="Data Saved", + saveError="Failed to save:", + saveError_duplicate="Duplicate filename", + loadError="Failed to load:", exportSuccess="Exported successfully", importSuccess="Imported successfully", dataCorrupted="Data corrupted", @@ -99,7 +99,7 @@ return{ wsConnecting="Websocket Connecting", wsFailed="WebSocket Connection Failed", - wsClose="WebSocket Closed: ", + wsClose="WebSocket Closed:", netTimeout="Network connection timeout", onlinePlayerCount="Online", diff --git a/parts/language/lang_es.lua b/parts/language/lang_es.lua index 5fd0c2fd..645c0199 100644 --- a/parts/language/lang_es.lua +++ b/parts/language/lang_es.lua @@ -46,13 +46,13 @@ return{ ai_fixed="La IA no es compatible con secuencias de piezas prefijadas.", --ai_prebag="The AI is incompatible with custom sequences which have nontetramino.",a IA no es compatible con secuencias de piezas personalizadas.", ai_mission="La IA no es compatible con misiones personalizadas.", - saveDone="Datos guardados", - saveError="Error al guardar:", - loadError="Error al cargar:", switchSpawnSFX="Habilita los sonidos de aparición de las piezas ;)", - needRestart="Reinicia Techmino para que los cambios tengan efecto.", + saveDone="Datos guardados", + saveError="Error al guardar:", + -- saveError_duplicate="Duplicate filename", + loadError="Error al cargar:", exportSuccess="Exportado con éxito", importSuccess="Importado con éxito", dataCorrupted="Los datos están corruptos.", @@ -88,7 +88,7 @@ return{ wsConnecting="Websocket Conectando", wsFailed="WebSocket conexión fallida", - wsClose="WebSocket cerrado: ", + wsClose="WebSocket cerrado:", netTimeout="Tiempo de conexión agotado", onlinePlayerCount="En línea", @@ -100,7 +100,7 @@ return{ connStream="CONECTANDO", waitStream="ESPERANDO", spectating="Especteando", - chatRemain="Usuarios en línea: ", + chatRemain="Usuarios en línea:", chatStart="------Comienzo del historial------", chatHistory="------Nuevos mensajes------", @@ -688,7 +688,7 @@ return{ ['pc_n']= {"Desafío de PCs", "Normal", "¡Consigue los PCs que puedas en 100 líneas!"}, ['pc_h']= {"Desafío de PCs", "Difícil", "¡Consigue los PCs que puedas en 100 líneas!"}, ['pc_l']= {"Desafío de PCs", "Lunático", "¡Consigue los PCs que puedas en 100 líneas!"}, - ['pc_inf']= {"Desafío de PCs Infinito","", "Consigue todos los PCs que puedas."}, + ['pc_inf']= {"Desafío de PCs Infinito","", "Consigue todos los PCs que puedas."}, ['tech_n']= {"Tech", "Normal", "¡Mantén el B2B!"}, ['tech_n_plus']= {"Tech", "Normal+", "¡Sólo se permiten Spins y PCs!"}, ['tech_h']= {"Tech", "Difícil", "¡Mantén el B2B!"}, diff --git a/parts/language/lang_fr.lua b/parts/language/lang_fr.lua index 986bf196..129b2f1c 100644 --- a/parts/language/lang_fr.lua +++ b/parts/language/lang_fr.lua @@ -47,13 +47,13 @@ return{ ai_fixed="L'IA est incompatible avec les séquences fixes.", --ai_prebag="The AI is incompatible with custom sequences which have nontetramino.",'IA est incompatible avec les séquences personnalisées.", ai_mission="L'IA est incompatible avec les missions personnalisées.", - saveDone="Données sauvegardées", - saveError="Sauvegarde échouée : ", - loadError="Lecture échouée : ", switchSpawnSFX="Activez les effets sonores d'apparition des pièces pour jouer", - needRestart="Fonctionnera dès la prochaine partie", + saveDone="Données sauvegardées", + saveError="Sauvegarde échouée : ", + -- saveError_duplicate="Duplicate filename", + loadError="Lecture échouée : ", exportSuccess="Exporté avec succès", importSuccess="Importé avec succès", dataCorrupted="Données corrompues", @@ -89,7 +89,7 @@ return{ -- wsConnecting="Websocket Connecting", wsFailed="WebSocket connection échouée", - -- wsClose="WebSocket Closed: ", + -- wsClose="WebSocket Closed:", -- netTimeout="Network connection timeout", -- onlinePlayerCount="Online", diff --git a/parts/language/lang_pt.lua b/parts/language/lang_pt.lua index 0d816cbf..cb9fd1ab 100644 --- a/parts/language/lang_pt.lua +++ b/parts/language/lang_pt.lua @@ -47,13 +47,13 @@ return{ ai_fixed="A inteligência é incompatível com sequências fixas.", --ai_prebag="The AI is incompatible with custom sequences which have nontetramino.", inteligência é incompatível com sequências fixas.", ai_mission="A inteligência é incompatível com missões costumizadas.", - saveDone="Data Salva", - saveError="Falha ao salvar:", - loadError="Falha ao ler:", switchSpawnSFX="Switch on spawn SFX to play", - needRestart="Funciona após reiniciar", + saveDone="Data Salva", + saveError="Falha ao salvar:", + -- saveError_duplicate="Duplicate filename", + loadError="Falha ao ler:", exportSuccess="Exportado com sucesso", importSuccess="Importado com sucesso", dataCorrupted="Data corrompida", @@ -89,7 +89,7 @@ return{ -- wsConnecting="Websocket Connecting", wsFailed="WebSocket falha na conexão", - wsClose="WebSocket closed: ", + wsClose="WebSocket closed:", -- netTimeout="Network connection timeout", -- onlinePlayerCount="Online", diff --git a/parts/language/lang_symbol.lua b/parts/language/lang_symbol.lua index 8df94369..7ee3a585 100644 --- a/parts/language/lang_symbol.lua +++ b/parts/language/lang_symbol.lua @@ -34,11 +34,12 @@ return{ ai_fixed="X!!!", ai_prebag="X!!!", ai_mission="X!!!", + needRestart="!!*#R#*!!", + saveDone="~~~", saveError="x!:", + saveError_duplicate="X←→X ?", loadError="x!:", - - needRestart="!!*#R#*!!", exportSuccess="~Out~", importSuccess="~In~", dataCorrupted="XXXXX", diff --git a/parts/language/lang_zh.lua b/parts/language/lang_zh.lua index fa719637..3a2ca64b 100644 --- a/parts/language/lang_zh.lua +++ b/parts/language/lang_zh.lua @@ -56,14 +56,14 @@ return{ ai_fixed="不能同时开启AI和固定序列", ai_prebag="不能同时开启AI和含有非四连块的自定义序列", ai_mission="不能同时开启AI和自定义任务", - saveDone="保存成功!", - saveError="保存失败:", - loadError="读取失败:", switchSpawnSFX="请开启方块出生音效", ranks={"D","C","B","A","S"}, - needRestart="重新开始以生效", + saveDone="保存成功!", + saveError="保存失败:", + saveError_duplicate="文件名重复", + loadError="读取失败:", exportSuccess="导出成功", importSuccess="导入成功", dataCorrupted="数据损坏", @@ -99,7 +99,7 @@ return{ wsConnecting="正在连接", wsFailed="连接失败", - wsClose="连接被断开: ", + wsClose="连接被断开:", netTimeout="连接超时", onlinePlayerCount="在线人数", @@ -899,6 +899,7 @@ return{ "俄罗斯方块完全可以作为电竞游戏", "发现有个\"隐形\"皮肤了吗", "方块不能吃", + "方块不是你生活的全部,适当走出去看看", "方块教会我们,合群了就会消失,...", "方块默认出现的方向都是重心在下哦", "方块能吃吗", @@ -911,6 +912,7 @@ return{ "感谢Phigros提供部分tip模板(", "刚接触方块的话多玩玩就行,40行两分钟以外没啥好针对性练习的", "刚开始练全隐形可以尽量堆平,留一列消四", + "隔壁不在乎玩家意见但是我们在乎,没人提过的合理建议一定会回应", "隔断消除即将到来!", "各种画面细节选项都可以在设置里找到哦", "更换方块皮肤也许能帮助提升成绩?不懂,玄学", @@ -1120,6 +1122,7 @@ return{ {C.C,""}, {C.C,"15puzzle好玩!"}, {C.C,"魔方好玩!"}, + {C.C,"噗哟噗哟好玩!"}, {C.C,"扫雷好玩!"}, {C.C,"Celeste好玩!"}, {C.C,"CYAN"}, diff --git a/parts/modes/stack_100l.lua b/parts/modes/stack_100l.lua index 2d01366e..e4008211 100644 --- a/parts/modes/stack_100l.lua +++ b/parts/modes/stack_100l.lua @@ -4,7 +4,10 @@ return{ drop=60,lock=60, freshLimit=15, fieldH=100, + highCam=true, fillClear=false, + seqData={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, + sequence='bag', bg='none',bgm='there', }, mesDisp=function(P) @@ -17,11 +20,11 @@ return{ getRank=function(P) local B=P.stat.piece return - B>=260 and 5 or - B>=254 and 4 or - B>=250 and 3 or - B>=243 and 2 or - B>=235 and 1 or + B>=215 and 5 or + B>=208 and 4 or + B>=200 and 3 or + B>=190 and 2 or + B>=180 and 1 or 0 end, } \ No newline at end of file diff --git a/parts/modes/stack_20l.lua b/parts/modes/stack_20l.lua index 52a74d01..1a4e3d39 100644 --- a/parts/modes/stack_20l.lua +++ b/parts/modes/stack_20l.lua @@ -3,6 +3,7 @@ return{ env={ drop=60,lock=60, freshLimit=15, + highCam=true, fillClear=false, bg='none',bgm='there', }, diff --git a/parts/modes/stack_40l.lua b/parts/modes/stack_40l.lua index bc39cd8e..02229a66 100644 --- a/parts/modes/stack_40l.lua +++ b/parts/modes/stack_40l.lua @@ -4,7 +4,9 @@ return{ drop=60,lock=60, freshLimit=15, fieldH=40, + highCam=true, fillClear=false, + seqData={1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, bg='none',bgm='there', }, mesDisp=function(P) @@ -17,11 +19,11 @@ return{ getRank=function(P) local B=P.stat.piece return - B>=105 and 5 or - B>=101 and 4 or - B>=97 and 3 or - B>=94 and 2 or - B>=90 and 1 or + B>=90 and 5 or + B>=87 and 4 or + B>=83 and 3 or + B>=78 and 2 or + B>=70 and 1 or 0 end, } \ No newline at end of file diff --git a/parts/net.lua b/parts/net.lua index 8a2f0070..1ae639c7 100644 --- a/parts/net.lua +++ b/parts/net.lua @@ -317,7 +317,7 @@ function NET.createRoom(roomName,description,capacity,roomType,roomData,password end end function NET.enterRoom(room,password) - if NET.lock('enterRoom',2)then + if NET.lock('enterRoom',6)then SFX.play('reach',.6) WS.send('play',JSON.encode{ action=2, diff --git a/parts/player/player.lua b/parts/player/player.lua index 317c9d44..0d2d1f4f 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -8,7 +8,7 @@ local max,min,modf=math.max,math.min,math.modf local ins,rem=table.insert,table.remove local resume,yield,status=coroutine.resume,coroutine.yield,coroutine.status -local SFX,BGM,VOC,VIB,SYSFX,SKIN=SFX,BGM,VOC,VIB,SYSFX,SKIN +local SFX,BGM,VOC,VIB,SYSFX=SFX,BGM,VOC,VIB,SYSFX local FREEROW,TABLE,TEXT,NET,TASK=FREEROW,TABLE,TEXT,NET,TASK local PLAYERS,PLY_ALIVE,GAME=PLAYERS,PLY_ALIVE,GAME @@ -1931,6 +1931,7 @@ function Player:act_hold() if self.control then if self.waiting==-1 then self:hold() + self.keyPressing[8]=false end end end diff --git a/parts/player/seqGenerators.lua b/parts/player/seqGenerators.lua index cdbf7211..7898acf8 100644 --- a/parts/player/seqGenerators.lua +++ b/parts/player/seqGenerators.lua @@ -222,11 +222,11 @@ return function(P)--Return a piece-generating function for player P elseif type(s)=='string'and seqGenerators[s]then return seqGenerators[s] else - MES.new( + MES.new('warn', type(s)=='string'and "No sequence mode called "..s or - "Wrong sequence generator", - 'warn') + "Wrong sequence generator" + ) P.gameEnv.sequence='bag' return seqGenerators.bag end diff --git a/parts/scenes/customGame.lua b/parts/scenes/customGame.lua index 49885b3a..5f984776 100644 --- a/parts/scenes/customGame.lua +++ b/parts/scenes/customGame.lua @@ -84,7 +84,7 @@ function scene.keyDown(key,isRep) elseif key=="m"then SCN.go('custom_mission','swipeD') elseif key=="delete"then - if sure>20 then + if sure>.3 then TABLE.cut(FIELD)TABLE.cut(BAG)TABLE.cut(MISSION) FIELD[1]=DATA.newBoard() freshMiniFieldVisible() @@ -96,7 +96,7 @@ function scene.keyDown(key,isRep) BG.set(CUSTOMENV.bg) BGM.play(CUSTOMENV.bgm) else - sure=50 + sure=1 end elseif key=="f1"then SCN.go('mod','swipeD') @@ -133,8 +133,8 @@ function scene.keyDown(key,isRep) end end -function scene.update() - if sure>0 then sure=sure-1 end +function scene.update(dt) + if sure>0 then sure=sure-dt end end function scene.draw() @@ -184,7 +184,7 @@ function scene.draw() --Confirm reset if sure>0 then - gc.setColor(1,1,1,sure*.02) + gc.setColor(1,1,1,sure) gc.draw(TEXTURE.sure,920,50) end gc.translate(0, WIDGET.scrollPos) diff --git a/parts/scenes/custom_field.lua b/parts/scenes/custom_field.lua index d20fde2f..c22e642f 100644 --- a/parts/scenes/custom_field.lua +++ b/parts/scenes/custom_field.lua @@ -172,12 +172,12 @@ function scene.keyDown(key) pTouch(penX,penY) end elseif key=="delete"then - if sure>20 then + if sure>.3 then for y=1,20 do for x=1,10 do FIELD[page][y][x]=0 end end sure=0 SFX.play('finesseError',.7) else - sure=50 + sure=1 end elseif key=="j"then demo=not demo @@ -256,8 +256,8 @@ function scene.keyUp(key) end end -function scene.update() - if sure>0 then sure=sure-1 end +function scene.update(dt) + if sure>0 then sure=sure-dt end end function scene.draw() @@ -427,8 +427,8 @@ function scene.draw() --Confirm reset if sure>0 then - gc.setColor(1,1,1,sure*.02) - gc.draw(TEXTURE.sure,1070,490) + gc.setColor(1,1,1,sure) + mDraw(TEXTURE.sure,990,530,nil,1.2) end --Block name diff --git a/parts/scenes/custom_mission.lua b/parts/scenes/custom_mission.lua index e8984292..bfc0aad2 100644 --- a/parts/scenes/custom_mission.lua +++ b/parts/scenes/custom_mission.lua @@ -62,13 +62,13 @@ function scene.keyDown(key) end end elseif key=="delete"then - if sure>20 then + if sure>.3 then TABLE.cut(MISSION) cur=0 sure=0 SFX.play('finesseError',.7) else - sure=50 + sure=1 end elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then if #MISSION>0 then @@ -116,8 +116,8 @@ function scene.keyDown(key) end end -function scene.update() - if sure>0 then sure=sure-1 end +function scene.update(dt) + if sure>0 then sure=sure-dt end end function scene.draw() @@ -184,8 +184,8 @@ function scene.draw() --Confirm reset if sure>0 then - gc.setColor(1,1,1,sure*.02) - gc.draw(TEXTURE.sure,980,600) + gc.setColor(1,1,1,sure) + mDraw(TEXTURE.sure,1000,640,nil,.9) end end diff --git a/parts/scenes/custom_sequence.lua b/parts/scenes/custom_sequence.lua index 3fe04337..c9c72afd 100644 --- a/parts/scenes/custom_sequence.lua +++ b/parts/scenes/custom_sequence.lua @@ -67,13 +67,13 @@ function scene.keyDown(key) end end elseif key=="delete"then - if sure>20 then + if sure>.3 then TABLE.cut(BAG) cur=0 sure=0 SFX.play('finesseError',.7) else - sure=50 + sure=1 end elseif key=="="then local l={1,2,3,4,5,6,7} @@ -124,8 +124,8 @@ function scene.keyDown(key) end end -function scene.update() - if sure>0 then sure=sure-1 end +function scene.update(dt) + if sure>0 then sure=sure-dt end end function scene.draw() @@ -187,8 +187,8 @@ function scene.draw() --Confirm reset if sure>0 then - gc.setColor(1,1,1,sure*.02) - gc.draw(TEXTURE.sure,1050,430,nil,.6) + gc.setColor(1,1,1,sure) + mDraw(TEXTURE.sure,1000,460,nil,.8) end end diff --git a/parts/scenes/net_league.lua b/parts/scenes/net_league.lua index e6ef71ec..5c2ef79d 100644 --- a/parts/scenes/net_league.lua +++ b/parts/scenes/net_league.lua @@ -16,7 +16,7 @@ function scene.draw() end scene.widgetList={ WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=goScene'setting_game'}, - WIDGET.newKey{name="match",x=640,y=500,w=760,h=140,font=60,code=function()MES.new('warn',"Coming soon 开发中,敬请期待")end}, + WIDGET.newKey{name="match",x=640,y=500,w=760,h=140,font=60,code=function()MES.new('warn',text.notFinished)end}, WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene}, } diff --git a/parts/scenes/net_menu.lua b/parts/scenes/net_menu.lua index 8b18d519..832fd1f6 100644 --- a/parts/scenes/net_menu.lua +++ b/parts/scenes/net_menu.lua @@ -18,7 +18,7 @@ end scene.widgetList={ WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=goScene'setting_game'}, WIDGET.newButton{name="league", x=640, y=180,w=350,h=120,font=40,color='D',code=goScene'net_league'}, - WIDGET.newButton{name="ffa", x=640, y=360,w=350,h=120,font=40,color='D',code=function()MES.new('warn',"Coming soon 开发中,敬请期待")--[[NET.enterRoom({name="ffa"})]]end}, + WIDGET.newButton{name="ffa", x=640, y=360,w=350,h=120,font=40,color='D',code=function()MES.new('warn',text.notFinished)--[[NET.enterRoom({name="ffa"})]]end}, WIDGET.newButton{name="rooms", x=640, y=540,w=350,h=120,font=40,code=goScene'net_rooms'}, WIDGET.newButton{name="logout", x=880, y=40,w=180,h=60,color='dR', code=function() diff --git a/parts/scenes/net_rooms.lua b/parts/scenes/net_rooms.lua index 82c0ff0a..a96d018e 100644 --- a/parts/scenes/net_rooms.lua +++ b/parts/scenes/net_rooms.lua @@ -59,23 +59,28 @@ function scene.sceneInit() end function scene.keyDown(key) - if key=="r"then - if fetchTimer<=7 then - fetchRoom() - end - elseif key=="s"then - SCN.go('setting_game') - elseif key=="n"then - SCN.go('net_newRoom') - elseif key=="escape"then - SCN.back() - elseif roomList:getLen()>0 and key=="return"then - local R=roomList:getSel() - if NET.getlock('fetchRoom')or not R then return end - if R.roomInfo.version==VERSION.room then - NET.enterRoom(R,passwordBox.value) + if NET.getlock('enterRoom')then return end + if WIDGET.sel~=passwordBox then + if key=="r"then + if fetchTimer<=7 then + fetchRoom() + end + elseif key=="s"then + SCN.go('setting_game') + elseif key=="n"then + SCN.go('net_newRoom') + elseif key=="escape"then + SCN.back() + elseif roomList:getLen()>0 and key=="return"then + local R=roomList:getSel() + if NET.getlock('fetchRoom')or not R then return end + if R.roomInfo.version==VERSION.room then + NET.enterRoom(R,passwordBox.value) + else + MES.new('error',"Version doesn't compatible 版本不兼容") + end else - MES.new('error',"Version doesn't compatible 版本不兼容") + WIDGET.keyPressed(key) end else WIDGET.keyPressed(key) @@ -96,6 +101,14 @@ function scene.draw() gc_setColor(1,1,1,.12) gc_arc('fill','pie',250,630,40,-1.5708,-1.5708-.6283*fetchTimer) + --Joining mark + if NET.getlock('enterRoom')then + gc.setColor(1,1,1) + gc.setLineWidth(15) + local t=TIME()*6.26%6.2832 + gc.arc('line','open',640,360,80,t,t+4.26) + end + --Room list local R=roomList:getSel() if R then @@ -135,7 +148,7 @@ scene.widgetList={ WIDGET.newKey{name="refresh", x=250,y=630,w=140,h=120,code=fetchRoom,hideF=function()return fetchTimer>7 end}, WIDGET.newKey{name="new", x=510,y=630,w=260,h=120,code=pressKey"n"}, WIDGET.newKey{name="join", x=780,y=630,w=140,h=120,code=pressKey"return",hideF=function()return roomList:getLen()==0 or NET.getlock('enterRoom')end}, - WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene}, + WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=pressKey"escape"}, } return scene \ No newline at end of file diff --git a/parts/scenes/replays.lua b/parts/scenes/replays.lua index 5931935f..ac8da485 100644 --- a/parts/scenes/replays.lua +++ b/parts/scenes/replays.lua @@ -1,8 +1,9 @@ local gc=love.graphics local gc_setColor=gc.setColor -local gc_draw,gc_rectangle=gc.draw,gc.rectangle +local gc_rectangle=gc.rectangle local gc_print,gc_printf=gc.print,gc.printf +local kb=love.keyboard local setFont=setFont local listBox=WIDGET.newListBox{name="list",x=50,y=50,w=1200,h=520,lineH=40,drawF=function(rep,id,ifSel) @@ -54,6 +55,7 @@ local function replay(fileName) loadGame(rep.mode,true) resetGameData('r') + PLAYERS[1].username=rep.player GAME.init=false GAME.saved=true GAME.fromRepMenu=true @@ -65,6 +67,10 @@ end function scene.sceneInit() sure=0 listBox:setList(REPLAY) + local hide=listBox:getLen()==0 + for i=3,5 do + scene.widgetList[i].hide=hide + end end function scene.keyDown(key) @@ -73,12 +79,42 @@ function scene.keyDown(key) if rep then replay(rep.fileName) end - elseif key=="escape"then - SCN.back() + elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then + local rep=listBox:getSel() + if rep then + if rep.available and rep.fileName then + local repStr=FILE.load(rep.fileName) + if repStr then + love.system.setClipboardText(love.data.encode('string','base64',repStr)) + MES.new('info',text.exportSuccess) + else + MES.new('error',text.replayBroken) + end + else + MES.new('error',text.replayBroken) + end + end + elseif key=="v"and kb.isDown("lctrl","rctrl")or key=="cV"then + local repStr=love.system.getClipboardText() + local res,fileData=pcall(love.data.decode,'string','base64',repStr) + if res then + local fileName=os.date("replay/%Y_%m_%d_%H%M%S_import.rep") + local rep=DATA.parseReplayData(fileName,fileData,false) + if rep.available then + if FILE.save(fileData,fileName,'d')then + table.insert(REPLAY,1,rep) + MES.new('info',text.importSuccess) + end + else + MES.new('error',text.dataCorrupted) + end + else + MES.new('error',text.dataCorrupted) + end elseif key=="delete"then local rep=listBox:getSel() if rep then - if sure>20 then + if sure>.3 then sure=0 listBox:remove() love.filesystem.remove(rep.fileName) @@ -90,31 +126,34 @@ function scene.keyDown(key) end SFX.play('finesseError',.7) else - sure=50 + sure=1 end end + elseif key=="escape"then + SCN.back() else WIDGET.keyPressed(key) end end -function scene.update() - if sure>0 then sure=sure-1 end +function scene.update(dt) + if sure>0 then sure=sure-dt end end function scene.draw() --Confirm delete if sure>0 then - gc_setColor(1,1,1,sure*.02) - gc_draw(TEXTURE.sure,910,610) + gc_setColor(1,1,1,sure) + mDraw(TEXTURE.sure,930,640,nil,.9) end end scene.widgetList={ listBox, - WIDGET.newButton{name="play",x=700,y=640,w=170,h=80,color='lY',code=pressKey"return",hideF=function()return listBox:getLen()==0 end,fText=DOGC{50,50,{'fPoly',10,0,49,24,10,49}}}, - WIDGET.newButton{name="delete",x=850,y=640,w=80,h=80,color='lR',code=pressKey"delete",hideF=function()return listBox:getLen()==0 end,fText=DOGC{50,50,{'setLW',8},{'line',5,5,45,45},{'line',5,45,45,5}}}, - WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene}, + WIDGET.newButton{name="export",x=200,y=640,w=70,color='lG',code=pressKey"cC",fText=DOGC{50,50,{'fRect',8,44,34,4},{'fRect',22,17,6,23},{'fPoly',25,5,10,20,40,20}}}, + WIDGET.newButton{name="import",x=300,y=640,w=70,color='lN',code=pressKey"cV",fText=DOGC{50,50,{'fRect',8,44,34,4},{'fRect',22,5,6,23},{'fPoly',25,40,10,25,40,25}}}, + WIDGET.newButton{name="play",x=700,y=640,w=170,h=80,color='lY',code=pressKey"return",fText=DOGC{50,50,{'fPoly',10,0,49,24,10,49}}}, + WIDGET.newButton{name="delete",x=850,y=640,w=80,h=80,color='lR',code=pressKey"delete",fText=DOGC{50,50,{'setLW',8},{'line',5,5,45,45},{'line',5,45,45,5}}}, WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,fText=TEXTURE.back,code=backScene}, } diff --git a/parts/updateLog.lua b/parts/updateLog.lua index 7059d481..edf90eee 100644 --- a/parts/updateLog.lua +++ b/parts/updateLog.lua @@ -42,9 +42,10 @@ return STRING.split([=[ 新BGM:Secret8th Remix(用于master-hard) 新增小亚(xiaoya)语音包 旋转系统新增BiRS(Bias RS)(实验性),ASC,ASCplus(添加180度踢墙,实验性) - 新增noInitSZO模式参数,自动跳过开局SZO(目前仅用于马拉松/20G模式) #121 + 可以通过剪切板导入/导出录像 自定义游戏的序列任务场地等数据退出保存 第一次启动会自动进入语言设置菜单 #150 + 新增noInitSZO模式参数,自动跳过开局SZO(目前仅用于马拉松/20G模式) #121 改动: 更换更简洁的加载动画,合并intro场景 调整TRS中S5和Z5的踢墙表,增加Ospin时SZ按反的尝试