From 28d5136e95a35b166e11ba852b72b4d23c07a777 Mon Sep 17 00:00:00 2001 From: MrZ_26 Date: Thu, 21 May 2020 01:12:17 +0800 Subject: [PATCH] 0.8.19/20: Fantastic Global Update II --- SFX/welcome_sfx.ogg | Bin 34819 -> 34819 bytes VOICE/single_5.ogg | Bin 8928 -> 7110 bytes VOICE/welcome_voc.ogg | Bin 76059 -> 58708 bytes callback.lua | 359 +++------ conf.lua | 14 +- default_data.lua | 44 +- document.txt | 65 +- font.ttf | Bin 966936 -> 967400 bytes main.lua | 17 +- modes/attacker_hard.lua | 8 +- modes/attacker_ultimate.lua | 8 +- modes/drought_lunatic.lua | 6 +- modes/hotseat_2P.lua | 14 - modes/hotseat_3P.lua | 15 - modes/hotseat_4P.lua | 16 - modes/marathon_normal.lua | 4 +- modes/pctrain_lunatic.lua | 62 +- modes/pctrain_normal.lua | 75 +- modes/round_1.lua | 2 +- modes/round_2.lua | 2 +- modes/round_3.lua | 2 +- modes/round_4.lua | 2 +- modes/round_5.lua | 2 +- modes/sprintPenta.lua | 44 ++ modes/sprint_400.lua | 10 +- modes/tech_hard+.lua | 4 +- modes/tech_lunatic+.lua | 4 +- modes/tech_lunatic.lua | 6 +- modes/tech_normal+.lua | 4 +- modes/tech_ultimate+.lua | 4 +- modes/tech_ultimate.lua | 6 - paint.lua | 46 +- parts/PCbase.lua | 74 +- parts/PClist.lua | 84 ++- parts/ai.lua | 4 +- parts/bg.lua | 2 +- parts/bgm.lua | 9 +- parts/file.lua | 33 +- parts/getTip.lua | 50 +- parts/img.lua | 1 + parts/kickList.lua | 439 ++++++++--- parts/languages.lua | 1188 +++++++++++++++++++---------- parts/light.lua | 48 +- parts/list.lua | 29 - parts/mino.lua | 23 +- parts/modes.lua | 18 +- parts/sfx.lua | 3 + parts/spinCenters.lua | 46 +- parts/voice.lua | 15 +- parts/widget.lua | 194 ++++- player.lua | 1417 +++++++++++++++++------------------ scene.lua | 32 +- shader/lightRender.cs | 35 +- shader/shadowMap.cs | 17 +- texture.lua | 19 +- timer.lua | 8 +- toolfunc.lua | 71 +- updateLog.lua | 404 ++++++---- widgetList.lua | 128 ++-- 59 files changed, 3092 insertions(+), 2144 deletions(-) delete mode 100644 modes/hotseat_2P.lua delete mode 100644 modes/hotseat_3P.lua delete mode 100644 modes/hotseat_4P.lua create mode 100644 modes/sprintPenta.lua diff --git a/SFX/welcome_sfx.ogg b/SFX/welcome_sfx.ogg index 57c6ad9a6b3d9929bc0d33e94227fd764725638f..89b6c2afae85d7e0c99a2cf446611753b6ba5ada 100644 GIT binary patch delta 197 zcmZpkz|=f}Ny$iCZK`&G6R0j6fkaDLWw|96%Adeb-_)o0ZOih;RZ$&b62S-F&ZAl?ebFYc$ya diff --git a/VOICE/single_5.ogg b/VOICE/single_5.ogg index b4ce46bdca52605a747e1418544654e7ea4d74c9..43c718659a229cd0005d1419819f747c7abe28d2 100644 GIT binary patch literal 7110 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 literal 8928 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 YoR{*su`=Z8{JbBzzl2c+?rI1F0Q2S9R{#J2 delta 18045 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 then d=d^.5 @@ -262,13 +262,13 @@ function wheelMoved.music(x,y) end function keyDown.music(key) if key=="down"then - sceneTemp=sceneTemp%#musicID+1 + sceneTemp=sceneTemp%BGM.len+1 elseif key=="up"then - sceneTemp=(sceneTemp-2)%#musicID+1 + sceneTemp=(sceneTemp-2)%BGM.len+1 elseif key=="return"or key=="space"then - if BGM.nowPlay~=musicID[sceneTemp]then + if BGM.nowPlay~=BGM.list[sceneTemp]then SFX.play("click") - BGM.play(musicID[sceneTemp]) + BGM.play(BGM.list[sceneTemp]) else BGM.stop() end @@ -277,36 +277,42 @@ function keyDown.music(key) end end +local customSet={ + {3,20,1,1,7,1,1,1,3,4,1,2,3}, + {5,20,1,1,7,1,1,1,8,3,8,3,3}, + {1,22,1,1,7,3,1,1,8,4,1,7,7}, + {3,20,1,1,7,1,1,3,8,3,1,7,8}, + {25,11,8,11,4,1,2,1,8,3,1,4,9}, +} function keyDown.custom(key) local sel=sceneTemp - if key=="left"then + if key=="up"or key=="w"then + sceneTemp=(sel-2)%#customID+1 + elseif key=="down"or key=="s"then + sceneTemp=sel%#customID+1 + elseif key=="left"or key=="a"then customSel[sel]=(customSel[sel]-2)%#customRange[customID[sel]]+1 if sel==12 then BG.set(customRange.bg[customSel[12]]) elseif sel==13 then BGM.play(customRange.bgm[customSel[13]]) end - elseif key=="right"then + elseif key=="right"or key=="d"then customSel[sel]=customSel[sel]%#customRange[customID[sel]]+1 if sel==12 then BG.set(customRange.bg[customSel[sel]]) elseif sel==13 then BGM.play(customRange.bgm[customSel[sel]]) end - elseif key=="down"then - sceneTemp=sel%#customID+1 - elseif key=="up"then - sceneTemp=(sel-2)%#customID+1 - elseif key=="1"then - Widget.custom.set1.code() - elseif key=="2"then - Widget.custom.set2.code() - elseif key=="3"then - Widget.custom.set3.code() - elseif key=="4"then - Widget.custom.set4.code() - elseif key=="5"then - Widget.custom.set5.code() + elseif #key==1 then + local T=tonumber(key) + if T and T>=1 and T<=5 then + for i=1,#customSet[T]do + customSel[i]=customSet[T][i] + end + BG.set(customRange.bg[customSel[12]]) + BGM.play(customRange.bgm[customSel[13]]) + end elseif key=="escape"then SCN.back() end @@ -425,41 +431,29 @@ function keyDown.setting_key(key) SCN.back() end elseif s.kS then - for l=1,8 do - for y=1,20 do - if keyMap[l][y]==key then - keyMap[l][y]="" - goto L - end - end + for y=1,20 do + if keyMap[1][y]==key then keyMap[1][y]=""break end + if keyMap[2][y]==key then keyMap[2][y]=""break end end - ::L:: keyMap[s.board][s.kb]=key SFX.play("reach",.5) s.kS=false - elseif key=="return"then + elseif key=="return"or key=="space"then s.kS=true SFX.play("lock",.5) - elseif key=="up"then + elseif key=="up"or key=="w"then if s.kb>1 then s.kb=s.kb-1 SFX.play("move",.5) end - elseif key=="down"then + elseif key=="down"or key=="s"then if s.kb<20 then s.kb=s.kb+1 SFX.play("move",.5) end - elseif key=="left"then - if s.board>1 then - s.board=s.board-1 - SFX.play("rotate",.5) - end - elseif key=="right"then - if s.board<8 then - s.board=s.board+1 - SFX.play("rotate",.5) - end + elseif key=="left"or key=="a"or key=="right"or key=="d"then + s.board=3-s.board + SFX.play("rotate",.5) end end function gamepadDown.setting_key(key) @@ -472,16 +466,11 @@ function gamepadDown.setting_key(key) SCN.back() end elseif s.jS then - for l=9,16 do - for y=1,20 do - if keyMap[l][y]==key then - keyMap[l][y]="" - goto L - end - end + for y=1,20 do + if keyMap[3][y]==key then keyMap[3][y]=""break end + if keyMap[4][y]==key then keyMap[4][y]=""break end end - ::L:: - keyMap[8+s.board][s.js]=key + keyMap[2+s.board][s.js]=key SFX.play("reach",.5) s.jS=false elseif key=="start"then @@ -497,16 +486,9 @@ function gamepadDown.setting_key(key) s.js=s.js+1 SFX.play("move",.5) end - elseif key=="dpleft"then - if s.board>1 then - s.board=s.board-1 - SFX.play("rotate",.5) - end - elseif key=="dpright"then - if s.board<8 then - s.board=s.board+1 - SFX.play("rotate",.5) - end + elseif key=="dpleft"or key=="dpright"then + s.board=3-s.board + SFX.play("rotate",.5) end end @@ -515,7 +497,7 @@ function mouseDown.setting_touch(x,y,k) sceneTemp.sel=onVK_org(x,y)or sceneTemp.sel end function mouseMove.setting_touch(x,y,dx,dy) - if sceneTemp.sel and ms.isDown(1)and not widget_sel then + if sceneTemp.sel and ms.isDown(1)and not WIDGET.sel then local B=VK_org[sceneTemp.sel] B.x,B.y=B.x+dx,B.y+dy end @@ -538,16 +520,16 @@ function touchUp.setting_touch(id,x,y) end end function touchMove.setting_touch(id,x,y,dx,dy) - if sceneTemp.sel and not widget_sel then + if sceneTemp.sel and not WIDGET.sel then local B=VK_org[sceneTemp.sel] B.x,B.y=B.x+dx,B.y+dy end end function keyDown.pause(key) - if key=="escape"then + if key=="q"then SCN.back() - elseif key=="space"then + elseif key=="escape"then resumeGame() elseif key=="s"then SCN.push() @@ -572,20 +554,21 @@ function touchDown.play(id,x,y) virtualkey[t].pressTime=10 if setting.VKTrack then local B=virtualkey[t] - if setting.VKDodge then--按钮软碰撞(做不来hhh随便做一个,效果还行!) + if setting.VKDodge then--button collision (not accurate) for i=1,#virtualkey do local b=virtualkey[i] - local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--碰撞深度(负数=间隔距离) + local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--hit depth(Neg means distance) if d>0 then - b.x=b.x+(b.x-B.x)*d*b.r*.00005 - b.y=b.y+(b.y-B.y)*d*b.r*.00005 + b.x=b.x+(b.x-B.x)*d*b.r*5e-4 + b.y=b.y+(b.y-B.y)*d*b.r*5e-4 end end end local O=VK_org[t] local _FW,_CW=setting.VKTchW*.1,1-setting.VKCurW*.1 local _OW=1-_FW-_CW - --按钮自动跟随:手指位置,当前位置,原始位置,权重取决于设置 + + --Auto follow: finger, current, origin (weight from setting) B.x,B.y=x*_FW+B.x*_CW+O.x*_OW,y*_FW+B.y*_CW+O.y*_OW end VIB(setting.VKVIB) @@ -622,44 +605,34 @@ function keyDown.play(key) return end local m=keyMap - for p=1,players.human do - for k=1,20 do - if key==m[2*p-1][k]or key==m[2*p][k]then - players[p]:pressKey(k) - if p==1 then - virtualkey[k].isDown=true - virtualkey[k].pressTime=10 - end - return - end + for k=1,20 do + if key==m[1][k]or key==m[2][k]then + players[1]:pressKey(k) + virtualkey[k].isDown=true + virtualkey[k].pressTime=10 + return end end end function keyUp.play(key) local m=keyMap - for p=1,players.human do - for k=1,20 do - if key==m[2*p-1][k]or key==m[2*p][k]then - players[p]:releaseKey(k) - if p==1 then virtualkey[k].isDown=false end - return - end + for k=1,20 do + if key==m[1][k]or key==m[2][k]then + players[1]:releaseKey(k) + virtualkey[k].isDown=false + return end end end function gamepadDown.play(key) if key=="back"then SCN.back()return end local m=keyMap - for p=1,players.human do - for k=1,20 do - if key==m[2*p+7][k]or key==m[2*p+8][k]then - players[p]:pressKey(k) - if p==1 then - virtualkey[k].isDown=true - virtualkey[k].pressTime=10 - end - return - end + for k=1,20 do + if key==m[3][k]or key==m[4][k]then + players[1]:pressKey(k) + virtualkey[k].isDown=true + virtualkey[k].pressTime=10 + return end end end @@ -667,9 +640,9 @@ function gamepadUp.play(key) local m=keyMap for p=1,players.human do for k=1,20 do - if key==m[2*p+7][k]or key==m[2*p+8][k]then - players[p]:releaseKey(k) - if p==1 then virtualkey[k].isDown=false end + if key==m[3][k]or key==m[4][k]then + players[1]:releaseKey(k) + virtualkey[k].isDown=false return end end @@ -701,90 +674,14 @@ function wheelMoved.history(x,y) end function keyDown.history(key) if key=="up"then - sceneTemp[2]=max(sceneTemp[2]-3,1) + sceneTemp[2]=max(sceneTemp[2]-1,1) elseif key=="down"then - sceneTemp[2]=min(sceneTemp[2]+3,#sceneTemp[1]-22) + sceneTemp[2]=min(sceneTemp[2]+1,#sceneTemp[1]) elseif key=="escape"then SCN.back() end end ------------------------------------------------------------- -local function widgetPress(W,x,y) - if W.type=="button"then - W.code() - W:FX() - SFX.play("button") - VOC.play("nya") - elseif W.type=="switch"then - W.code() - SFX.play("move",.6) - elseif W.type=="slider"then - if not x then return end - local p,P=W.disp(),xW.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5) - if p==P then return end - W.code(P) - if W.change then W.change()end - end - if W.hide and W.hide()then widget_sel=nil end -end -local function widgetDrag(W,x,y,dx,dy) - if W.type=="slider"then - local p,P=W.disp(),xW.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5) - if p==P then return end - W.code(P) - if W.change then W.change()end - elseif not W:isAbove(x,y)then - widget_sel=nil - end -end -local function widgetControl_key(i) - if i=="tab"then - if widget_sel then - widget_sel=kb.isDown("lshift")and widget_sel.prev or widget_sel.next or widget_sel - else - widget_sel=select(2,next(Widget[SCN.cur])) - end - elseif i=="space"or i=="return"then - if widget_sel then - widgetPress(widget_sel) - end - elseif i=="left"or i=="right"then - if widget_sel then - local W=widget_sel - if W.type=="slider"then - local p=W.disp() - local P=i=="left"and(p>0 and p-1)or p0 and p-1)or p1 then + if Timer()-lastFreshPow>3 and setting.powerInfo and SCN.cur~="load"then updatePowerInfo() lastFreshPow=Timer() end diff --git a/conf.lua b/conf.lua index c437ea65..041bcba9 100644 --- a/conf.lua +++ b/conf.lua @@ -1,11 +1,11 @@ -gameVersion="Alpha V0.8.18" +gameVersion="Alpha V0.8.20" function love.conf(t) - t.identity="Techmino"--SaveDir name + t.identity="Techmino"--folder name t.version="11.1" t.console=false t.gammacorrect=false - t.appendidentity=true--Search files in source before save directory - t.accelerometerjoystick=false--ios/android加速度计=摇杆 + t.appendidentity=true--search files in source before save directory + t.accelerometerjoystick=false--accelerometer=joystick on ios/android t.audio.mixwithsystem=true local W=t.window @@ -17,12 +17,12 @@ function love.conf(t) W.resizable=true W.fullscreentype="desktop"--"exclusive" W.fullscreen=false - W.vsync=0--∞fps + W.vsync=0--infinite fps W.msaa=false--num of samples to use with multi-sampled antialiasing W.depth=0--bits/samp of depth buffer W.stencil=1--bits/samp of stencil buffer - W.display=1--Monitor ID - W.highdpi=false--High-dpi mode for the window on a Retina display + W.display=1--monitor ID + W.highdpi=false--high-dpi mode for the window on a Retina display W.x,W.y=nil local M=t.modules diff --git a/default_data.lua b/default_data.lua index 099ca1df..e73ac5be 100644 --- a/default_data.lua +++ b/default_data.lua @@ -1,4 +1,5 @@ -setting={ +local s={ + --game das=10,arr=2, sddas=0,sdarr=2, ihs=true,irs=true,ims=true, @@ -8,18 +9,18 @@ setting={ swap=true, fine=false, autoPause=true, - lang=1, skinSet=1, - skin={1,5,2,8,10,3,7}, - face={0,0,0,0,0,0,0}, - --game + skin={1,5,8,2,10,3,7,1,5,5,1,8,2,10,3,7,10,7,8,2,8,2,1,5,3}, + face={}, + --graphic ghost=true,center=true, smooth=true,grid=false, bagLine=false, lockFX=2, dropFX=3, + clearFX=2, shakeFX=2, atkFX=3, frameMul=100, @@ -27,13 +28,14 @@ setting={ text=true, fullscreen=false, bg=true, - --graphic + powerInfo=false, + --sound sfx=10,bgm=7, vib=0,voc=0, stereo=6, - --sound + --virtualkey VKSFX=3,--SFX volume VKVIB=0,--VIB VKSwitch=false,--if disp @@ -43,28 +45,36 @@ setting={ VKCurW=4,--Cur-Pos Weight VKIcon=true,--if disp icon VKAlpha=3, - --control } -stat={ +for i=1,25 do + s.face[i]=0 +end +setting=s + +s={ version=gameVersion, run=0,game=0,time=0, key=0,rotate=0,hold=0, extraPiece=0,extraRate=0, piece=0,row=0,dig=0, atk=0,digatk=0,send=0,recv=0,pend=0, - clear_S={0,0,0,0},clear_B={0,0,0,0,0,0,0}, - spin_S={0,0,0,0},spin_B={0,0,0,0,0,0,0}, - clear={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - spin={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, + clear={},clear_B={},clear_S={0,0,0,0,0}, + spin={},spin_B={},spin_S={0,0,0,0,0}, pc=0,hpc=0,b2b=0,b3b=0,score=0, lastPlay=1,--last played mode ID } +for i=1,25 do + s.clear_B[i]=0 + s.spin_B[i]=0 + s.clear[i]={0,0,0,0,0} + s.spin[i]={0,0,0,0,0} +end +stat=s + keyMap={ - {"left","right","x","z","c","up","down","space","tab","r"}, - {},{},{},{},{},{},{}, + {"left","right","x","z","c","up","down","space","tab","r"},{}, --keyboard - {"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder"}, - {},{},{},{},{},{},{}, + {"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder"},{}, --joystick } for i=1,#keyMap do for j=1,20 do diff --git a/document.txt b/document.txt index 25214daa..c85ff371 100644 --- a/document.txt +++ b/document.txt @@ -1,3 +1,4 @@ +(ENG ver. below) 游戏方法: 系统会提供的一个个四联骨牌("方块",总共7种),玩家需要控制(左右移动和旋转90,180,270度),每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话) 活到最后或者完成目标即胜利. @@ -15,7 +16,8 @@ spin判定: spin1/2/3攻击2/4/6,若mini则减半 B2B:加1(techrash/spin1/spin2)或2(spin3)攻击 B3B:在B2B效果之上消四再加1,spin再加0.5*消行数攻击,二者都+1额外抵挡 - 连击:0,0,1,1,2,2,3,3,4,4,3,2,3,2,3,2,3…(后面都是2) + 堆楼连击:0,0,1,1,2,2,2,3,3,3,4,4,3, 之后都是2 + 挖掘连击:0,0,1,1,2,2,3,3,4,4,4, 之后都是5 特殊消除会增加B2B点数,让之后的特殊消除获得B2B(B3B)增益(详细说明见下文) 半全消("下方有剩余方块"的全消,如果是I消1行则必须不剩余玩家放置的方块):伤害+2,额外抵挡+2 全消:将上述伤害之和开根号,再+6~12(本局内递增)+2额外抵挡(注:本局消行数>4时会将B2B点数拉满) @@ -52,5 +54,62 @@ back to back(B2B)点数说明: 自定义模式说明: 玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来进行拼图模式. 在拼图模式下,按功能键切换是否展示提示.其中打"X"的格子不允许有方块,空的格子可以是任何状态,普通的七种彩色方块必须颜色对应,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利. -附录: -ZXC的Ospin地图:XY0BCgAwCAIR7v9vHtUSt8AS0xKqgpnNGyXkrmFNePf6qi3BbQPrHT2Owxe6D66NeKi86dwB \ No newline at end of file + +Gameplay: + System will offer a series of tetrominoes ("Pieces". There are 7 types), and the player needs to control [them] (move left and right, rotate 90, 180 or 270 degrees), filling a row on the play field will clear it, attack will be sent depending on the type of the line clear (if there is an opponent) + Survive till the last or complete the level's goal to win. + +Rotation system: + Uses Techmino's custom rotation system. Too lazy to write the details + +Spin detection: + Combines immobile and 3-corner detection, and whether a spin is mini also depends on the data used for detection. Also too lazy to write the details + +Attack system: + Regular line clears: + Single/Double/Triple/Techrash sends 0.25/1.25/2.25/4 + Special line clears: + Spin Single/Double/Triple sends 2/4/6, half if Mini + B2B: +1 (Techrash/Spin Single/Spin Double) or +2 (Spin Triple) + B2B2B/B3B: In addition to B2B, +1 if Techrash, +(0.5 * lines cleared) if Spin, and in both cases +1 additional blocking + Wide Combo: 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 3, then 2 afterwards + Dig Combo: 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, then 5 afterwards + Special line clears will increase B2B gauge, making later special line clears have B2B or B2B2B bonus (see below) + Half Perfect Clear (a Perfect Clear "with blocks left below". If it's an I clearing 1 line, then the remaining blocks must not be player-placed): Attack +2, Extra Blocking +2 + Perfect Clear: square root all damage above, then +6 to +12 attack (increases within a round) and +2 extra blocking. (note: if lines cleared in this round >4, then B2B gauge will be filled) + After calculating all above, the damage value will be rounded down then sent + +Score system: + The more impressive you play, the more score you get + +Attack delay: + Attack from Doubles/Triples take effect the faster, then Techrash, Spins send rather slow attack, and high combos will send the slowest + B2B or B2B2B, while they increase lines sent, they also increase the attack delay. Minis will greatly increase delay. + +Countering: + When you send attack, if there is garbage in queue, extra blocking will be used first, then attack, countering the earliest attack at a 1:1 ratio. + Unused extra blocking will be discarded, then remaining attack will be sent to your opponent. + +Back to Back (B2B) gauge: + The B2B gauge ranges from 0 to 1,200. Special line clears are B2B if the gauge is >=40, B2B2B if >1,000. + A regular line clear -250 + Spin Single/Double/Triple +50/100/180 (x40% if Mini) + Techrash +100 + Spin without clearing lines +20, but gauge cannot exceed 1,000 with this method + When gauge is above 1,000, a drop without clearing lines -40 (cannot drop below 1,000 with this method) + +Battle Royale modes: + Many players play within one game (all opponents are bots, not real players). As players get eliminated, blocks fall faster, and garbage take effect faster, as well as rise faster. KO-ing another player grants you one badge plus all badge that player has, increasing your attack power. + Players can select one of 4 attack modes: + 1. Random: Every time you attack, 10% chance to lock onto a random player. + 2. Badges: After you attack or when your target dies, lock onto the player with the most badges. + 3. KOs: After you attack or when your target dies, lock onto the player with the highest field. (This refreshes every second) + 4. Counter: attack all players locking onto yourself. Your attack will be sent to all of them. If you are not targetted, you attack a random player (not locking). + The last survivor wins. + +Custom mode: + You can freely adjust most parameters (not including special effects of other game modes), and you can also draw a field to clear or make a template to build. + In build (puzzle) mode, you can toggle template display with Function key. Cells with a X cannot have blocks; empty cells can be in any state; regular colored cells have to be made of the corresponding block; garbage-colored cells can be any block but not air. Once you make the shape, you will win. + +附录Appendix: +ZXC's cool O-spin map:XY0BCgAwCAIR7v9vHtUSt8AS0xKqgpnNGyXkrmFNePf6qi3BbQPrHT2Owxe6D66NeKi86dwB \ No newline at end of file diff --git a/font.ttf b/font.ttf index a4d35a7289e5b77a19428600184e454147a90a54..88057032e6f07925a109f0868858e11f8f4fe460 100644 GIT binary patch delta 3012 zcmWlb4OmoV7RUd?@G;Ci?|^*Bh_^? z^SxZpsb(Rh*=mQlkj3|u>SdbgnwztZ?0GHbUHN1ag~~Rho5<9J~w1 zh(G;ZwUx`_tKyB=jV$B>frIN*k9N<4#P{54VExL++dchzV1AVhlpo0B@|b*EzA2B$SLFe@ zSMHI!VkmT)jFA!2E<Z>?{&Z>8TSeWuUwd3<#~)wjfVpRdwa;hXPE z^`-cdeMu`C&1I(Byw@x@7no&csaayqGH04o%tCXLSzzXyW6WXZ5Oc7ZV!F(DGtTU9 zI?Wg}+Ke1XxR`YHXG{+fP3e?@;; z-=pu=TlCHP8lJ8%GwZeb`Sr8wr`37yAr4E(z?h`qZAXZl&ft*j=ww!6qWKv;&N4EF2_80ZTlb41VcVsi zK%1Wn7H$jTt^~`UW$Rt@<}F$gIVF5>d3n{q$%#vcO&DPfvMvity>m+T)FBi4*`k!d z&>+^L!`#jx1LJ~4uxrrp*!AIwj+~NUd(fg#@@@$T447R|pg4l8&QwQWZgx@P%DHxD zOkdkHB|bhbG-vYCiNlrt{rmatGs1?(ELojACp#lDrO(uZ6z@k2BF;yZlzMpMkrjnSP>=?Swx@V}8 zkd)-eiy7mrib?O|4vnynbXzjUmOf-a&{M#PYy%rWX?4~ z`LqbiXITu-b{&Oso_j7_fpYN#luOLzE-0V#{fmQ8uJHNGb|_!%h4OVXl&d?Te8bOg z*Fd@EhF`hvgz}vY%8fKA-sG!vB0`XKJhU@}WVgV|>Y>qGs#Ad3fw@si<9plmk1GaQt|1|tuF zayi7POQ11qI@Sidi)(k?0{tbI*$c|60F7rR5OV@Fk;#{!f;`Zqa?oU6R><|ci$GI& zek#uwWrC)qfu_4a{uw2p;ttTvouJt)%)SCD;pB5P(A+xEyzQXUCQuoNncodsz?64_ z7P5ZNVbHyNueb%OWbJ-{+=Za38qlJnpv7EUk_UQVFK8+EF5|_u`5;w->UeMcR`{vG z1bON}+J2Cihjb2Lu$g%rv?2xMO z9JIa*w2?g@i(=M+{>lM1*%+Q_ax)zE@pjPWBG8sbe*arXFf9IUKj?`X&^B&rJ_`DK z2k1!-@(|GO=q_YQ*I-wryF3Hl%p zbdrOg?BVy{kp?=&CLiU4PFI7@aMQwg_}Bg;~RNgT4!A4)OcH!OOnSWjIau zA}V6DpVS@0bO>TH-|yZEG1U!G)CDp97DVxNh?(mkW^t(5Oi3ZcoMwo*XCO)mqHI6Jf+C28 z?CoE872;keLz|DuvkJYVf_J4ymT)_4QsU=vX1NZhao(yYlk3o z4q>wS@-&7$S6qki9fy#tujEjEW)&}7%` u;ftWX0O0?T(06VC delta 2637 zcmWlbe^eD^9>yQys_1-QLSU5$j1-Lui&ZRCDoy;Aq@YxqY(iq<2^lVT?#$@C$BRZv zW`$`RZq`!KMn)YxV$fM@sZ6aUB^O&PG)zr0H7mDBN%!fG5A%M1J>Q49=fd0b_{5qu z6RVR#lcxUgDG-(b{o3Jf4O2|&csk`<3ks5<#G;}obTV~dv*7RBz`TL;yZ z$@*=@Obn*VoLs!za)*bfH!`jP5>rad#f9_djNS+JTPu*Ud3m8*7C8=|AaYC| z`;$rwmnSYsbmBKKK>^?BGBaT1Zmb)D$lL0G^?{AM0@wB-9AWHEfNyp;5YrR|7~xGA zgjJg^#}3_57mhou9;o|kpLfnX?S197dQW@ny|v!zkf%M*b3EHC_e`(UEA|S# z0&kJGz#Hj}@P>QWuMD{*?qc^LccJ^BJKuf4o#*DdIqpn%x;xd)a;LZx+%$Kzo9d2m zuX7XJYu$Kvs5``sb)((EZlv4ag>%KZ>|Atya(;BqI;WhIPPcQ&IpBQcyzji@gl0SU zI0*tJCTk!gPi{MCHtcNt9{n)wma=Z_CdSd z-eb4e+wDgCZF`$tZ@+49w5#nZd#(Mrz1ps@SK2FV+g@fD+xOWyc7{F99&6uf-(siO z!|X(RpdAtXC3rd%+#YNUz7?zwz8*{o-VhuW92rawjtC|O6N2%?ii zm(^g+w{oo-)Tn(v$2%s0$h^I5aRTxc#ZbIqCNbaSeCx2ep5 zrN5URFFjEDa_NhuPn1?7Y)4_{_Lxm&nf)G%&RG|o6GpBg;lxM!k^W==i68^Xpyuct zW6J(@*Ca{vHA(8!d%oM%zB$dlqiSq?^Y~ts9p1d|k_sOa`m71Y{sI^WqR1{7?OS1d zUJK(O^BpPV1dKy{FuoxFZG+KS1>6q9KZXSNlTz(F+-z42h0|#8g0H8z4h?9$E#7<4}Ai>4sce4@t;} zB<4VdMG@w%+W<-03b~$w!(GS-){@zu%ta&HA)}fgH!z>Vz8lF+n;|z-Czbip)W0Rf z!CSc`tqn4UqGPim=@b}u0dhM{WF$bwQ*=TWWFl*s8IU_H(gV43E95RRX$E9+1mx~N zXn{=8kgOWWR4$vw`t&Nu49?Hw{5{2xSw)cSe8|1kkkA}~%;|#UGBG!a(D}SZNL~Zv zzD~&fZIB0OW}zFUD*clh~~hmJUZriwLsRS zLLRGwR5n1?MnKlpK%R($tZ#xmnL~C%HqgLRS%foB*Fv75*=Kqo)m4y^PH8+G1ngfw(P-e%9+pbo`_OgF(H)P*= z$S0kUPm3Y{){r(D|11r%zld-107cp>AfMMk4zlS#j63)|v%v+KB%aK5EQ@rDmoS_WeR zW~iZUP;o6#@jNFaK_yZ+u?y-tA5;=^*Ed0ppjfg+&O?o?g&IYz8$i0DZe;DIEU23| zK&2Kzjjo2er4i~@4V6aSKes}S39&G?0V=%{>b3-^+Y6w^$3jg=g_=l1nJ1v`0WvH$=8 diff --git a/main.lua b/main.lua index f05010f5..e9be8b72 100644 --- a/main.lua +++ b/main.lua @@ -1,10 +1,11 @@ --[[ -第一次搞这么大的工程,参考价值也许不是很大 -如果你有时间并且也热爱俄罗斯方块的话,来看代码或者帮助优化的话欢迎! + Techmino is my first "huge project" + optimization is welcomed if you also love tetromino game ]] math.randomseed(os.time()*626) --Global vars system=love.system.getOS() +game={} mapCam={ sel=nil,--selected mode ID @@ -22,10 +23,7 @@ scr={x=0,y=0,w=0,h=0,rad=0,k=1}--wid,hei,radius,scale K customSel={1,22,1,1,7,3,1,1,8,4,1,1,1} preField={h=20}for i=1,20 do preField[i]={0,0,0,0,0,0,0,0,0,0}end function NULL()end ---[[ -blockSkin,blockSkinMini={},{}--redefined in SKIN.change -widget_sel=nil--selected widget obj -]] +--blockSkin,blockSkinMini={},{}--redefined in SKIN.change --Load modules setFont=require("parts/setfont") @@ -53,14 +51,14 @@ TEXT=require("parts/text") TASK=require("parts/task") BG=require("parts/bg") IMG=require("parts/img") +WIDGET=require("parts/widget") +LIGHT=require("parts/light") -require("parts/light") require("parts/modes") require("default_data") -require("parts/widget") require("parts/ai") require("player") -Widget=require("widgetList") +widgetList=require("widgetList") require("callback") --load files & settings @@ -74,6 +72,7 @@ else setting.VKSwitch=true setting.swap=false setting.vib=2 + setting.powerInfo=true end end LANG.set(setting.lang) diff --git a/modes/attacker_hard.lua b/modes/attacker_hard.lua index 0b6a4bf6..b39966fe 100644 --- a/modes/attacker_hard.lua +++ b/modes/attacker_hard.lua @@ -53,6 +53,12 @@ return{ comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]100 and 4 or W>=80 and 3 or W>=50 and 2 or W>=20 and 1 or W>=5 and 0 + return + W>=100 and 5 or + W>=80 and 4 or + W>=60 and 3 or + W>=40 and 2 or + W>=20 and 1 or + W>=5 and 0 end, } \ No newline at end of file diff --git a/modes/attacker_ultimate.lua b/modes/attacker_ultimate.lua index 88038156..58c940f6 100644 --- a/modes/attacker_ultimate.lua +++ b/modes/attacker_ultimate.lua @@ -66,6 +66,12 @@ return{ comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]40 and 4 or W>=30 and 3 or W>=20 and 2 or W>=10 and 1 or W>=5 and 0 + return + W>=50 and 5 or + W>=40 and 4 or + W>=30 and 3 or + W>=20 and 2 or + W>=10 and 1 or + W>=5 and 0 end, } \ No newline at end of file diff --git a/modes/drought_lunatic.lua b/modes/drought_lunatic.lua index 1858c415..96204fcf 100644 --- a/modes/drought_lunatic.lua +++ b/modes/drought_lunatic.lua @@ -51,9 +51,9 @@ return{ res[A+2]=7 end - --give O when no Δ=0/give T when no Δ=1 - d=0--Δ=0 - A=0--Δ=1 + --give O when no d=0/give T when no d=1 + d=0--d=0 count + A=0--d=1 count for x=2,10 do local _=height[x]-height[x-1] if _==0 then diff --git a/modes/hotseat_2P.lua b/modes/hotseat_2P.lua deleted file mode 100644 index 9e73fa64..00000000 --- a/modes/hotseat_2P.lua +++ /dev/null @@ -1,14 +0,0 @@ -return{ - color=color.white, - env={ - drop=60,lock=60, - freshLimit=15, - bg="none",bgm="way", - }, - load=function() - newPlayer(1,20,15) - newPlayer(2,650,15) - end, - mesDisp=function(P,dx,dy) - end, -} \ No newline at end of file diff --git a/modes/hotseat_3P.lua b/modes/hotseat_3P.lua deleted file mode 100644 index 0b0ad5c6..00000000 --- a/modes/hotseat_3P.lua +++ /dev/null @@ -1,15 +0,0 @@ -return{ - color=color.white, - env={ - drop=60,lock=60, - freshLimit=15, - bg="none",bgm="way", - }, - load=function() - newPlayer(1,20,100,.65) - newPlayer(2,435,100,.65) - newPlayer(3,850,100,.65) - end, - mesDisp=function(P,dx,dy) - end, -} \ No newline at end of file diff --git a/modes/hotseat_4P.lua b/modes/hotseat_4P.lua deleted file mode 100644 index 0d498666..00000000 --- a/modes/hotseat_4P.lua +++ /dev/null @@ -1,16 +0,0 @@ -return{ - color=color.white, - env={ - drop=60,lock=60, - freshLimit=15, - bg="none",bgm="way", - }, - load=function() - newPlayer(1,25,160,.5) - newPlayer(2,335,160,.5) - newPlayer(3,645,160,.5) - newPlayer(4,955,160,.5) - end, - mesDisp=function(P,dx,dy) - end, -} \ No newline at end of file diff --git a/modes/marathon_normal.lua b/modes/marathon_normal.lua index 76c856c8..13f2cf97 100644 --- a/modes/marathon_normal.lua +++ b/modes/marathon_normal.lua @@ -42,8 +42,8 @@ return{ if L>=200 then local T=P.stat.time return - T<=185 and 5 or - T<=250 and 4 or + T<=226 and 5 or + T<=262 and 4 or 3 else return diff --git a/modes/pctrain_lunatic.lua b/modes/pctrain_lunatic.lua index 66d3d0f1..9c1fa544 100644 --- a/modes/pctrain_lunatic.lua +++ b/modes/pctrain_lunatic.lua @@ -5,53 +5,35 @@ local pc_lock={55,50,45,40,36,32,30} local pc_fall={18,16,14,12,10,9,8,7,6} local PCbase=require("parts/PCbase") local PClist=require("parts/PClist") +local PCtype={[0]=1,2,1,3,2,3} + local function task_PC(P) - local _ P.modeData.counter=P.modeData.counter+1 - if P.modeData.counter==21 then - local t=P.stat.pc%2 - local S=P.gameEnv.skin - for i=1,4 do - local r=freeRow.get(0) - for j=1,10 do - _=PCbase[4*t+i][j] - r[j]=S[_]or 0 - end - ins(P.field,1,r) - ins(P.visTime,1,freeRow.get(20)) - end - P.fieldBeneath=P.fieldBeneath+120 - P.curY=P.curY+4 - P:freshgho() + if P.modeData.counter==26 then + local base=PCbase[P.modeData.type] + P:pushLine(base[rnd(#base)],P.modeData.symmetry) return true end end - local function newPC(P) - local r=P.field;r=r[#r] - if r then + local r=P.field + if r[1]then + r=r[#r] local c=0 for i=1,10 do if r[i]>0 then c=c+1 end end - if c<5 then - P:lose() - end + if c<5 then P:lose()end end - if P.stat.piece%4==0 and #P.field==0 then - P.modeData.event=P.modeData.event==0 and 1 or 0 - local r=rnd(#PClist) - local f=P.modeData.event==0 - for i=1,4 do - local b=PClist[r][i] - if f then - if b<3 then b=3-b - elseif b<5 then b=7-b - end - end - P:getNext(b) - end + if #P.field==0 then + local type=PCtype[P.stat.pc]or rnd(2,3) + local L=PClist[type][rnd(#PClist[1])] + local symmetry=rnd()>.5 + P.modeData.type=type + P.modeData.symmetry=symmetry + P:pushNext(L,symmetry) P.modeData.counter=P.stat.piece==0 and 20 or 0 TASK.new(task_PC,P) - local s=P.stat.pc*.5 + + local s=P.stat.pc*.25 if int(s)==s and s>0 then P.gameEnv.drop=pc_drop[s]or 10 P.gameEnv.lock=pc_lock[s]or 20 @@ -94,11 +76,11 @@ return{ getRank=function(P) local L=P.stat.pc return - L>=50 and 5 or - L>=40 and 4 or - L>=30 and 3 or + L>=100 and 5 or + L>=70 and 4 or + L>=40 and 3 or L>=20 and 2 or L>=10 and 1 or - L>=1 and 0 + L>=2 and 0 end, } \ No newline at end of file diff --git a/modes/pctrain_normal.lua b/modes/pctrain_normal.lua index 047c5692..4401c4b8 100644 --- a/modes/pctrain_normal.lua +++ b/modes/pctrain_normal.lua @@ -1,50 +1,41 @@ local rnd=math.random -local ins=table.insert local PCbase=require("parts/PCbase") local PClist=require("parts/PClist") +local PCtype={ +[0]=1,1,1,1,2, + 1,1,1,1,3, + 1,1,1,2, + 1,1,1,3, + 1,1,2, + 1,1,3, + 1,2, + 1,3, + 2, + 3, +} local function task_PC(P) - local _ P.modeData.counter=P.modeData.counter+1 - if P.modeData.counter==21 then - local t=P.stat.pc%2 - local S=P.gameEnv.skin - for i=1,4 do - local r=freeRow.get(0) - for j=1,10 do - _=PCbase[4*t+i][j] - r[j]=S[_]or 0 - end - ins(P.field,1,r) - ins(P.visTime,1,freeRow.get(20)) - end - P.fieldBeneath=P.fieldBeneath+120 - P.curY=P.curY+4 - P:freshgho() + if P.modeData.counter==26 then + local base=PCbase[P.modeData.type] + P:pushLine(base[rnd(#base)],P.modeData.symmetry) return true end end local function newPC(P) - local r=P.field;r=r[#r] - if r then + local r=P.field + if r[1]then + r=r[#r] local c=0 for i=1,10 do if r[i]>0 then c=c+1 end end - if c<5 then - P:lose() - end + if c<5 then P:lose()end end - if P.stat.piece%4==0 and #P.field==0 then - P.modeData.event=P.modeData.event==0 and 1 or 0 - local r=rnd(#PClist) - local f=P.modeData.event==0 - for i=1,4 do - local b=PClist[r][i] - if f then - if b<3 then b=3-b - elseif b<5 then b=7-b - end - end - P:getNext(b) - end + if #P.field==0 then + local type=PCtype[P.stat.pc]or rnd(2,3) + local L=PClist[type][rnd(#PClist[1])] + local symmetry=rnd()>.5 + P.modeData.type=type + P.modeData.symmetry=symmetry + P:pushNext(L,symmetry) P.modeData.counter=P.stat.piece==0 and 20 or 0 TASK.new(task_PC,P) end @@ -54,7 +45,7 @@ return{ env={ next=4, hold=false, - drop=150,lock=150, + drop=120,lock=180, fall=20, sequence="none", dropPiece=newPC, @@ -77,11 +68,11 @@ return{ getRank=function(P) local L=P.stat.pc return - L>=100 and 5 or - L>=60 and 4 or - L>=40 and 3 or - L>=25 and 2 or - L>=15 and 1 or - L>=1 and 0 + L>=260 and 5 or + L>=126 and 4 or + L>=62 and 3 or + L>=26 and 2 or + L>=12 and 1 or + L>=2 and 0 end, } \ No newline at end of file diff --git a/modes/round_1.lua b/modes/round_1.lua index 39b65156..e49bd800 100644 --- a/modes/round_1.lua +++ b/modes/round_1.lua @@ -21,7 +21,7 @@ return{ load=function() newPlayer(1,340,15) newAIPlayer(2,965,360,.5,AITemplate("CC",10,1,true,5000)) - garbageSpeed=1e99 + game.garbageSpeed=1e99 end, mesDisp=function(P,dx,dy) end, diff --git a/modes/round_2.lua b/modes/round_2.lua index f3b28b09..6090ca55 100644 --- a/modes/round_2.lua +++ b/modes/round_2.lua @@ -21,7 +21,7 @@ return{ load=function() newPlayer(1,340,15) newAIPlayer(2,965,360,.5,AITemplate("CC",10,1,true,10000)) - garbageSpeed=1e99 + game.garbageSpeed=1e99 end, mesDisp=function(P,dx,dy) end, diff --git a/modes/round_3.lua b/modes/round_3.lua index c733bd08..acf82722 100644 --- a/modes/round_3.lua +++ b/modes/round_3.lua @@ -21,7 +21,7 @@ return{ load=function() newPlayer(1,340,15) newAIPlayer(2,965,360,.5,AITemplate("CC",10,2,true,12600)) - garbageSpeed=1e99 + game.garbageSpeed=1e99 end, mesDisp=function(P,dx,dy) end, diff --git a/modes/round_4.lua b/modes/round_4.lua index ef5cad8a..9d692a34 100644 --- a/modes/round_4.lua +++ b/modes/round_4.lua @@ -21,7 +21,7 @@ return{ load=function() newPlayer(1,340,15) newAIPlayer(2,965,360,.5,AITemplate("CC",10,3,true,16260)) - garbageSpeed=1e99 + game.garbageSpeed=1e99 end, mesDisp=function(P,dx,dy) end, diff --git a/modes/round_5.lua b/modes/round_5.lua index 71265fdf..89985cc2 100644 --- a/modes/round_5.lua +++ b/modes/round_5.lua @@ -21,7 +21,7 @@ return{ load=function() newPlayer(1,340,15) newAIPlayer(2,965,360,.5,AITemplate("CC",10,3,true,26000)) - garbageSpeed=1e99 + game.garbageSpeed=1e99 end, mesDisp=function(P,dx,dy) end, diff --git a/modes/sprintPenta.lua b/modes/sprintPenta.lua new file mode 100644 index 00000000..e359ad57 --- /dev/null +++ b/modes/sprintPenta.lua @@ -0,0 +1,44 @@ +local gc=love.graphics +local rnd=math.random +return{ + color=color.green, + env={ + drop=60,lock=60, + sequence="bag",bag={8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, + target=40,dropPiece=player.reach_winCheck, + bg="strap",bgm="race", + }, + load=function() + newPlayer(1,340,15) + end, + mesDisp=function(P) + local dx,dy=P.fieldOff.x,P.fieldOff.y + setFont(55) + local r=40-P.stat.row + if r<0 then r=0 end + mStr(r,-81,265) + if r<21 and r>0 then + gc.setLineWidth(4) + gc.setColor(1,r>10 and 0 or rnd(),.5) + gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy) + end + end, + score=function(P)return{P.stat.time,P.stat.piece}end, + scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end, + comp=function(a,b)return a[1]0 and P.lastClear<10 or P.lastClear==74 then P:lose() end @@ -11,7 +11,7 @@ return{ drop=30,lock=60, freshLimit=15, target=200, - dropPiece=tech_check_ultimate, + dropPiece=tech_check_hard, bg="matrix",bgm="secret8th", }, load=function() diff --git a/modes/tech_lunatic+.lua b/modes/tech_lunatic+.lua index 29c6b623..d3dc0ddc 100644 --- a/modes/tech_lunatic+.lua +++ b/modes/tech_lunatic+.lua @@ -1,5 +1,5 @@ local format=string.format -local function tech_check_ultimate(P) +local function tech_check_hard(P) if #P.clearedRow>0 and P.lastClear<10 or P.lastClear==74 then P:lose() end @@ -11,7 +11,7 @@ return{ _20G=true,lock=60, freshLimit=15, target=200, - dropPiece=tech_check_ultimate, + dropPiece=tech_check_hard, bg="matrix",bgm="secret7th", }, load=function() diff --git a/modes/tech_lunatic.lua b/modes/tech_lunatic.lua index d20f33d1..c53bbe73 100644 --- a/modes/tech_lunatic.lua +++ b/modes/tech_lunatic.lua @@ -1,6 +1,6 @@ local format=string.format -local function tech_check_hard(P) - if #P.clearedRow>0 and P.lastClear<10 then +local function tech_check_easy(P) + if #P.clearedRow>0 and P.b2b<40 then P:lose() end end @@ -11,7 +11,7 @@ return{ _20G=true,lock=60, freshLimit=15, target=200, - dropPiece=tech_check_hard, + dropPiece=tech_check_easy, bg="matrix",bgm="secret7th", }, load=function() diff --git a/modes/tech_normal+.lua b/modes/tech_normal+.lua index 24b3e948..7abf06fa 100644 --- a/modes/tech_normal+.lua +++ b/modes/tech_normal+.lua @@ -1,5 +1,5 @@ local format=string.format -local function tech_check_ultimate(P) +local function tech_check_hard(P) if #P.clearedRow>0 and P.lastClear<10 or P.lastClear==74 then P:lose() end @@ -11,7 +11,7 @@ return{ oncehold=false, drop=1e99,lock=1e99, target=200, - dropPiece=tech_check_ultimate, + dropPiece=tech_check_hard, bg="matrix",bgm="newera", }, load=function() diff --git a/modes/tech_ultimate+.lua b/modes/tech_ultimate+.lua index 2bafbb42..6c597e67 100644 --- a/modes/tech_ultimate+.lua +++ b/modes/tech_ultimate+.lua @@ -1,5 +1,5 @@ local format=string.format -local function tech_check_ultimate(P) +local function tech_check_hard(P) if #P.clearedRow>0 and P.lastClear<10 or P.lastClear==74 then P:lose() end @@ -13,7 +13,7 @@ return{ freshLimit=15, target=200, fineKill=true, - dropPiece=tech_check_ultimate, + dropPiece=tech_check_hard, bg="flink",bgm="infinite", }, slowMark=true, diff --git a/modes/tech_ultimate.lua b/modes/tech_ultimate.lua index 078e71e1..27fb28b8 100644 --- a/modes/tech_ultimate.lua +++ b/modes/tech_ultimate.lua @@ -1,9 +1,4 @@ local format=string.format -local function tech_check_hard(P) - if #P.clearedRow>0 and P.lastClear<10 then - P:lose() - end -end return{ color=color.lightYellow, @@ -13,7 +8,6 @@ return{ freshLimit=15, target=200, fineKill=true, - dropPiece=tech_check_hard, bg="flink",bgm="infinite", }, slowMark=true, diff --git a/paint.lua b/paint.lua index 03b08270..8de8b203 100644 --- a/paint.lua +++ b/paint.lua @@ -17,7 +17,7 @@ local modeRankColor={ color.purple, --Special } local rankString={ - "C","B","A","S","SS", + "D","C","B","A","S", } local miniTitle_rect={ {2,0,5,1},{4,1,1,6}, @@ -278,8 +278,8 @@ function Pnt.music() gc.draw(drawableText.musicRoom,22,23) gc.draw(drawableText.nowPlaying,490,390) setFont(30) - for i=1,#musicID do - gc.print(musicID[i],50,90+30*i) + for i=1,BGM.len do + gc.print(BGM.list[i],50,90+30*i) end gc.draw(IMG.titleImage,640,310,nil,1.5,nil,206,35) if BGM.nowPlay then @@ -431,10 +431,10 @@ local dataPos={90,143,-90,143,-200,-13,-90,-169,90,-169,200,-13} function Pnt.pause() local S=sceneTemp local T=S.timer*.02 - if T<1 or gameResult then Pnt.play()end + if T<1 or game.result then Pnt.play()end --Dark BG local _=T - if gameResult then _=_*.7 end + if game.result then _=_*.7 end gc.setColor(.15,.15,.15,_) gc.push("transform") gc.origin() @@ -443,9 +443,9 @@ function Pnt.pause() --Pause Info setFont(25) - if pauseCount>0 then + if game.pauseCount>0 then gc.setColor(1,.4,.4,T) - gc.print(text.pauseCount..":["..pauseCount.."] "..format("%.2f",pauseTime).."s",70,100) + gc.print(text.pauseCount..":["..game.pauseCount.."] "..format("%.2f",game.pauseTime).."s",70,100) end gc.setColor(1,1,1,T) @@ -457,7 +457,7 @@ function Pnt.pause() --Result Text setFont(35) - mText(gameResult and drawableText[gameResult]or drawableText.pause,640,50-10*(5-sceneTemp.timer*.1)^1.5) + mText(game.result and drawableText[game.result]or drawableText.pause,640,50-10*(5-sceneTemp.timer*.1)^1.5) --Infos if frame>180 then @@ -515,9 +515,9 @@ function Pnt.setting_game() mText(drawableText.setting_game,640,15) gc.draw(blockSkin[int(Timer()*2)%11+1],720,540,Timer()%6.28319,2,nil,15,15) end -function Pnt.setting_graphic() +function Pnt.setting_video() gc.setColor(1,1,1) - mText(drawableText.setting_graphic,640,15) + mText(drawableText.setting_video,640,15) end function Pnt.setting_sound() gc.setColor(1,1,1,.8) @@ -598,16 +598,16 @@ function Pnt.setting_key() gc.setColor(1,1,1) setFont(26) - local board=s.board + local b1,b2=keyMap[s.board],keyMap[s.board+2] for N=1,20 do if N<11 then gc.printf(text.acts[N],47,45*N+22,180,"right") - mStr(keyMap[board][N],340,45*N+22) - mStr(keyMap[board+8][N],540,45*N+22) + mStr(b1[N],340,45*N+22) + mStr(b2[N],540,45*N+22) else gc.printf(text.acts[N],647,45*N-428,180,"right") - mStr(keyMap[board][N],940,45*N-428) - mStr(keyMap[board+8][N],1040,45*N-428) + mStr(b1[N],940,45*N-428) + mStr(b2[N],1040,45*N-428) end end gc.setLineWidth(2) @@ -618,9 +618,7 @@ function Pnt.setting_key() gc.line(40,y,1240,y) end setFont(35) - gc.print("Player:",170,590) - gc.print(int(board*.5+.5),300,590) - gc.print(board.."/8",580,590) + gc.print(text.page..s.board,280,590) gc.draw(drawableText.ctrlSetHelp,50,650) end function Pnt.setting_skin() @@ -673,7 +671,7 @@ function Pnt.help() end setFont(19) gc.print(text.used,30,330) - gc.draw(IMG.titleImage,280,610,.1,1+.05*sin(Timer()*2),nil,206,35) + gc.draw(IMG.titleImage,280,610,.1,1+.05*sin(Timer()*2.6),nil,206,35) gc.setLineWidth(3) gc.rectangle("line",18,18,263,263) gc.rectangle("line",1012,18,250,250) @@ -681,10 +679,10 @@ function Pnt.help() gc.draw(IMG.pay2,1014,20) setFont(20) mStr(text.group,640,490) - gc.setColor(1,1,1,sin(Timer()*10)*.4+.6) + gc.setColor(1,1,1,sin(Timer()*20)*.3+.6) setFont(30) - gc.print(text.support,150,283+20,sin(Timer()*2.6)*.02,nil,nil,115,20) - gc.print(text.support,1138,270+20,sin(Timer()*2.83)*.02,nil,nil,115,20) + mStr(text.support,150+sin(Timer()*4)*20,283) + mStr(text.support,1138-sin(Timer()*4)*20,270) end function Pnt.stat() local chart=sceneTemp.chart @@ -737,8 +735,6 @@ function Pnt.history() gc.rectangle("line",30,45,1000,632) setFont(20) local _=sceneTemp - for i=0,min(22,#_[1]-_[2])do - gc.print(_[1][_[2]+i],40,50+27*(i)) - end + gc.print(_[1][_[2]],40,50) end return Pnt \ No newline at end of file diff --git a/parts/PCbase.lua b/parts/PCbase.lua index 8885e881..a20e425f 100644 --- a/parts/PCbase.lua +++ b/parts/PCbase.lua @@ -1,10 +1,68 @@ return{ - {3,3,3,0,0,0,0,0,2,2}, - {3,6,6,0,0,0,0,2,2,5}, - {4,6,6,0,0,0,1,1,5,5}, - {4,4,4,0,0,0,0,1,1,5}, - {1,1,0,0,0,0,0,4,4,4}, - {5,1,1,0,0,0,0,6,6,4}, - {5,5,2,2,0,0,0,6,6,3}, - {5,2,2,0,0,0,0,3,3,3}, + { + { + {4,4,4,3,3,3,7,0,0,0}, + {4,1,6,6,2,3,7,0,0,0}, + {1,1,6,6,2,2,7,0,0,0}, + {1,7,7,7,7,2,7,0,0,0}, + }, + { + {4,4,4,3,3,3,0,0,0,7}, + {4,1,6,6,2,3,0,0,0,7}, + {1,1,6,6,2,2,0,0,0,7}, + {1,7,7,7,7,2,0,0,0,7}, + }, + { + {2,7,7,7,7,1,7,0,0,0}, + {2,2,6,6,1,1,7,0,0,0}, + {3,2,6,6,1,4,7,0,0,0}, + {3,3,3,4,4,4,7,0,0,0}, + }, + { + {2,7,7,7,7,1,0,0,0,7}, + {2,2,6,6,1,1,0,0,0,7}, + {3,2,6,6,1,4,0,0,0,7}, + {3,3,3,4,4,4,0,0,0,7}, + }, + },--3*4 shape + { + { + {1,1,0,0,0,0,0,3,3,3}, + {5,1,1,0,0,0,0,6,6,3}, + {5,5,2,2,0,0,0,6,6,4}, + {5,2,2,0,0,0,0,4,4,4}, + }, + { + {1,1,0,0,0,0,0,4,4,4}, + {5,1,1,0,0,0,0,4,6,6}, + {5,5,2,2,0,0,0,3,6,6}, + {5,2,2,0,0,0,0,3,3,3}, + }, + { + {3,3,3,1,1,0,0,0,0,0}, + {6,6,3,5,1,1,0,0,0,0}, + {6,6,4,5,5,2,2,0,0,0}, + {4,4,4,5,2,2,0,0,0,0}, + }, + { + {4,4,4,1,1,0,0,0,0,0}, + {4,6,6,5,1,1,0,0,0,0}, + {3,6,6,5,5,2,2,0,0,0}, + {3,3,3,5,2,2,0,0,0,0}, + }, + },--7 piece opener(right>)(without i) + { + { + {4,4,4,3,3,3,0,0,0,0}, + {4,1,6,6,2,3,0,0,0,0}, + {1,1,6,6,2,2,0,0,0,0}, + {1,7,7,7,7,2,0,0,0,0}, + }, + { + {2,7,7,7,7,1,0,0,0,0}, + {2,2,6,6,1,1,0,0,0,0}, + {3,2,6,6,1,4,0,0,0,0}, + {3,3,3,4,4,4,0,0,0,0}, + }, + },--6 piece opener } \ No newline at end of file diff --git a/parts/PClist.lua b/parts/PClist.lua index af2a7e4f..495cc126 100644 --- a/parts/PClist.lua +++ b/parts/PClist.lua @@ -1,11 +1,77 @@ return{ - {7,7,4,5},{7,7,6,4},{7,7,2,4},{7,7,1,3},{7,7,5,6},{7,7,5,2},{7,7,5,4},{7,7,5,3}, - {7,4,1,2},{7,3,5,7},{7,5,4,3},{7,5,1,2},{7,1,4,2},{7,4,2,5},{7,6,4,5},{7,5,4,2}, - {7,5,6,4},{7,5,3,6},{7,2,5,6},{7,2,6,4},{7,2,1,3},{7,5,2,7},{7,5,7,2},{7,5,2,3}, - {7,5,3,2},{7,6,5,4},{7,3,1,5},{7,3,2,5},{7,4,1,5},{7,4,5,2},{7,7,3,6},{7,3,7,6}, - {7,3,6,2},{7,3,7,1},{7,6,4,2},{3,2,7,6},{3,2,6,7},{7,7,4,5},{7,5,3,4},{7,3,6,5}, - {7,3,2,5},{7,4,6,5},{7,5,2,3},{7,3,5,7},{7,3,2,5},{7,3,5,1},{7,5,2,3},{3,6,2,5}, - {3,1,2,5},{3,1,1,5},{3,1,5,2},{3,1,5,1},{3,5,1,2},{4,5,3,2},{4,2,6,5},{6,5,3,2}, - {1,4,2,5},{1,5,3,6},{5,2,6,3},{5,2,1,3},{5,2,7,4},{2,4,1,5},{2,4,5,1},{2,1,4,5}, - {2,5,4,3},{2,5,6,7},{7,5,4,2},{4,5,3,5}, + { + {1,3,3},{1,3,4},{1,5,3},{3,1,3},{3,1,4},{3,2,4},{3,3,2},{3,3,5},{3,3,6},{3,3,7}, + {3,4,1},{3,4,5},{3,4,6},{3,5,3},{3,5,4},{3,5,5},{3,6,3},{3,6,4},{3,7,3},{3,7,4}, + {5,3,4},{5,3,5},{5,5,1},{5,5,3},{5,7,3},{6,3,3},{6,3,4},{6,6,7},{6,7,6},{7,3,3}, + {7,3,4},{7,5,3},{7,6,6},{7,7,7}, + },--3*4 shape + { + {5,3,4,4},{5,3,7,7},{5,7,4,4},{4,2,4,4},{3,5,4,4},{3,4,5,4},{3,3,7,4},{7,5,4,4},{1,5,1,1},{1,5,5,5}, + {1,5,7,4},{1,2,4,5},{1,4,5,5},{1,4,5,2},{1,4,2,5},{1,4,4,4},{5,1,4,5},{5,5,4,1},{5,5,4,2},{5,5,4,4}, + {5,4,5,4},{5,4,4,5},{5,4,4,3},{5,7,4,6},{5,7,4,3},{2,5,4,4},{6,4,4,4},{6,7,4,6},{4,1,2,5},{4,1,4,4}, + {4,5,4,5},{4,5,7,7},{4,6,4,4},{4,4,6,4},{4,4,3,5},{4,4,3,6},{4,3,4,5},{4,3,4,6},{4,7,3,4},{4,7,7,5}, + {3,1,4,4},{3,1,4,3},{3,1,3,4},{3,5,5,4},{3,5,4,5},{3,5,7,7},{3,2,5,2},{3,2,4,4},{3,6,4,4},{3,6,3,3}, + {3,4,1,3},{3,4,4,5},{3,4,4,6},{3,4,3,7},{3,3,6,3},{3,7,5,7},{3,7,4,3},{3,7,3,4},{7,5,4,6},{7,5,4,3}, + {7,5,3,4},{7,5,7,1},{7,6,4,6},{7,4,1,5},{7,4,5,6},{7,4,3,4},{7,4,7,5},{7,3,1,5},{7,3,5,7},{7,3,4,4}, + {7,3,3,4},{7,3,7,5},{7,7,4,5},{7,7,7,4},{1,1,5,2},{1,1,7,4},{1,5,1,2},{1,5,1,3},{1,5,5,2},{1,5,2,1}, + {1,5,2,3},{1,5,6,3},{1,5,6,7},{1,5,4,1},{1,5,4,5},{1,5,4,2},{1,5,4,3},{1,5,4,7},{1,5,3,1},{1,5,3,4}, + {1,5,7,2},{1,5,7,6},{1,5,7,7},{1,2,5,1},{1,2,5,4},{1,2,7,4},{1,4,1,5},{1,4,5,1},{1,4,5,4},{1,4,6,5}, + {1,4,4,3},{1,4,3,3},{1,3,1,2},{1,3,5,2},{1,3,4,4},{1,3,4,3},{1,3,3,4},{1,7,1,4},{1,7,5,6},{1,7,5,4}, + {1,7,5,3},{1,7,5,7},{1,7,2,3},{1,7,6,4},{1,7,4,1},{1,7,4,5},{1,7,4,7},{1,7,3,1},{1,7,7,4},{5,1,5,5}, + {5,1,5,2},{5,1,5,4},{5,1,2,3},{5,1,6,3},{5,1,4,1},{5,1,4,2},{5,1,4,7},{5,1,7,2},{5,1,7,4},{5,5,1,5}, + {5,5,1,2},{5,5,1,4},{5,5,5,1},{5,5,5,2},{5,5,5,4},{5,5,5,7},{5,5,2,1},{5,5,2,5},{5,5,6,7},{5,5,4,5}, + {5,5,4,3},{5,5,3,1},{5,5,3,4},{5,5,7,5},{5,5,7,6},{5,2,1,3},{5,2,5,4},{5,2,4,5},{5,2,3,1},{5,2,3,6}, + {5,2,7,1},{5,6,1,3},{5,6,5,7},{5,6,6,1},{5,4,1,5},{5,4,1,7},{5,4,5,1},{5,4,5,5},{5,4,5,2},{5,4,5,3}, + {5,4,2,5},{5,4,4,1},{5,4,4,4},{5,4,3,1},{5,4,3,5},{5,4,3,4},{5,4,7,1},{5,3,5,4},{5,3,5,3},{5,3,2,2}, + {5,3,6,6},{5,3,4,1},{5,3,4,5},{5,3,4,3},{5,3,3,1},{5,3,3,4},{5,3,3,3},{5,7,1,2},{5,7,1,4},{5,7,1,3}, + {5,7,5,5},{5,7,5,7},{5,7,2,1},{5,7,6,4},{5,7,6,7},{5,7,4,1},{5,7,4,2},{5,7,4,7},{5,7,3,1},{5,7,3,2}, + {5,7,3,6},{5,7,3,4},{5,7,3,7},{5,7,7,1},{5,7,7,6},{5,7,7,4},{5,7,7,3},{2,1,5,1},{2,1,4,5},{2,1,7,4}, + {2,5,1,1},{2,5,4,5},{2,5,3,6},{2,4,1,5},{2,4,4,4},{2,4,4,3},{2,3,5,6},{2,7,1,4},{2,7,5,5},{2,7,4,1}, + {2,7,3,7},{2,7,7,3},{6,5,6,1},{6,5,3,1},{6,6,5,1},{6,6,4,5},{6,6,7,4},{6,4,6,5},{6,4,7,5},{6,3,4,3}, + {6,3,3,4},{6,7,6,4},{6,7,4,1},{6,7,4,5},{6,7,4,7},{6,7,7,4},{4,1,1,5},{4,1,5,1},{4,1,5,5},{4,1,5,2}, + {4,1,5,7},{4,1,6,5},{4,1,4,3},{4,1,3,4},{4,1,3,3},{4,1,7,5},{4,5,5,4},{4,5,4,1},{4,5,4,4},{4,5,4,3}, + {4,5,3,1},{4,5,3,5},{4,2,1,5},{4,2,4,3},{4,2,3,4},{4,6,6,5},{4,6,4,3},{4,6,3,4},{4,4,1,4},{4,4,1,3}, + {4,4,5,1},{4,4,5,4},{4,4,5,3},{4,4,2,4},{4,4,4,1},{4,4,4,5},{4,4,4,6},{4,4,7,4},{4,4,7,3},{4,3,6,4}, + {4,3,4,7},{4,3,3,5},{4,3,7,4},{4,7,1,5},{4,7,5,6},{4,7,5,7},{4,7,2,1},{4,7,2,5},{4,7,6,5},{4,7,4,4}, + {4,7,4,3},{3,1,1,2},{3,1,5,1},{3,1,5,2},{3,1,2,1},{3,1,6,5},{3,1,6,7},{3,1,7,6},{3,5,1,2},{3,5,5,1}, + {3,5,5,6},{3,5,5,3},{3,5,2,1},{3,5,2,2},{3,5,6,5},{3,5,6,6},{3,5,4,1},{3,5,4,3},{3,5,3,1},{3,5,3,5}, + {3,5,3,4},{3,5,3,3},{3,2,1,5},{3,2,5,1},{3,2,2,5},{3,6,1,5},{3,6,1,7},{3,6,5,5},{3,6,5,6},{3,6,6,5}, + {3,6,4,3},{3,6,3,4},{3,4,5,3},{3,4,2,4},{3,4,6,4},{3,4,6,3},{3,4,3,1},{3,4,3,5},{3,4,3,2},{3,4,3,6}, + {3,4,7,3},{3,3,1,4},{3,3,5,1},{3,3,5,4},{3,3,5,3},{3,3,6,4},{3,3,4,1},{3,3,4,5},{3,3,4,2},{3,3,4,6}, + {3,3,4,7},{3,3,3,1},{3,3,3,5},{3,3,3,6},{3,7,1,5},{3,7,5,1},{3,7,5,2},{3,7,2,5},{3,7,6,5},{3,7,7,5}, + {7,1,1,4},{7,1,5,6},{7,1,5,4},{7,1,5,3},{7,1,5,7},{7,1,2,3},{7,1,6,4},{7,1,4,1},{7,1,4,5},{7,1,4,7}, + {7,1,3,1},{7,1,7,4},{7,5,1,2},{7,5,1,6},{7,5,1,4},{7,5,1,3},{7,5,1,7},{7,5,5,5},{7,5,5,7},{7,5,2,1}, + {7,5,6,4},{7,5,6,7},{7,5,4,1},{7,5,4,2},{7,5,4,7},{7,5,3,1},{7,5,3,2},{7,5,3,6},{7,5,3,7},{7,5,7,6}, + {7,5,7,4},{7,5,7,3},{7,2,1,4},{7,2,1,3},{7,2,5,5},{7,2,4,1},{7,2,3,7},{7,2,7,3},{7,6,1,4},{7,6,5,4}, + {7,6,6,4},{7,6,4,1},{7,6,4,5},{7,6,4,7},{7,6,7,4},{7,4,5,1},{7,4,5,2},{7,4,5,7},{7,4,2,1},{7,4,2,5}, + {7,4,6,5},{7,4,4,4},{7,4,4,3},{7,3,5,1},{7,3,5,2},{7,3,5,6},{7,3,5,4},{7,3,2,5},{7,3,2,7},{7,3,6,1}, + {7,3,6,5},{7,3,4,3},{7,3,7,2},{7,3,7,6},{7,7,1,4},{7,7,5,1},{7,7,5,6},{7,7,5,4},{7,7,5,3},{7,7,2,3}, + {7,7,6,4},{7,7,6,3},{7,7,4,7},{7,7,3,6}, + },--7 piece opener (right>) + { + {1,1,3,4},{1,1,4,3},{1,2,5,3},{1,2,5,4},{1,3,4,7},{1,3,5,5},{1,3,7,3},{1,3,7,4},{1,4,1,4},{1,4,4,6}, + {1,5,2,3},{1,5,3,2},{1,5,3,5},{1,5,4,7},{1,5,5,2},{1,5,5,4},{1,5,5,5},{1,5,7,3},{1,5,7,4},{1,6,3,3}, + {1,6,5,3},{1,7,3,3},{1,7,3,4},{1,7,5,3},{1,7,5,4},{3,1,3,7},{3,1,4,7},{3,1,5,5},{3,1,6,3},{3,1,7,3}, + {3,1,7,4},{3,2,2,3},{3,2,3,2},{3,2,3,6},{3,2,4,5},{3,2,4,7},{3,2,5,5},{3,2,6,3},{3,2,6,4},{3,2,7,4}, + {3,3,1,5},{3,3,2,6},{3,3,2,7},{3,3,3,3},{3,3,3,4},{3,3,4,3},{3,3,4,4},{3,3,5,3},{3,3,5,4},{3,3,6,1}, + {3,3,6,6},{3,3,6,7},{3,3,7,2},{3,3,7,5},{3,3,7,6},{3,3,7,7},{3,4,1,2},{3,4,1,5},{3,4,1,7},{3,4,2,1}, + {3,4,2,5},{3,4,2,7},{3,4,3,3},{3,4,3,4},{3,4,4,3},{3,4,4,4},{3,4,5,3},{3,4,5,4},{3,4,5,7},{3,4,6,1}, + {3,4,6,2},{3,4,6,7},{3,4,7,1},{3,4,7,2},{3,4,7,5},{3,4,7,6},{3,5,1,2},{3,5,2,3},{3,5,2,5},{3,5,3,2}, + {3,5,3,3},{3,5,3,4},{3,5,4,3},{3,5,4,6},{3,5,4,7},{3,5,5,5},{3,5,5,7},{3,5,6,4},{3,5,7,3},{3,5,7,4}, + {3,5,7,5},{3,6,1,3},{3,6,2,3},{3,6,2,4},{3,6,3,1},{3,6,3,5},{3,6,3,6},{3,6,3,7},{3,6,4,2},{3,6,4,7}, + {3,6,5,4},{3,6,6,3},{3,6,6,4},{3,6,7,3},{3,6,7,4},{3,7,1,3},{3,7,1,4},{3,7,2,4},{3,7,3,2},{3,7,3,5}, + {3,7,3,6},{3,7,3,7},{3,7,4,1},{3,7,4,2},{3,7,4,5},{3,7,4,6},{3,7,5,3},{3,7,5,4},{3,7,5,5},{3,7,6,3}, + {3,7,6,4},{3,7,7,3},{3,7,7,4},{5,1,2,3},{5,1,3,2},{5,1,3,4},{5,1,4,1},{5,1,4,7},{5,1,5,4},{5,1,5,5}, + {5,1,7,4},{5,3,1,2},{5,3,1,4},{5,3,2,5},{5,3,3,3},{5,3,3,4},{5,3,3,6},{5,3,4,3},{5,3,5,2},{5,3,5,4}, + {5,3,5,5},{5,3,5,7},{5,3,7,4},{5,3,7,5},{5,5,1,2},{5,5,1,4},{5,5,3,2},{5,5,3,3},{5,5,3,4},{5,5,3,5}, + {5,5,3,7},{5,5,5,1},{5,5,5,5},{5,5,6,3},{5,5,6,7},{5,5,7,1},{5,5,7,3},{5,5,7,6},{5,6,3,5},{5,6,3,6}, + {5,6,3,7},{5,6,5,3},{5,6,6,3},{5,6,7,3},{5,7,1,4},{5,7,3,4},{5,7,3,5},{5,7,5,1},{5,7,5,3},{5,7,5,6}, + {5,7,6,3},{5,7,7,3},{6,1,3,3},{6,3,3,5},{6,3,3,6},{6,3,3,7},{6,3,4,7},{6,3,6,3},{6,3,6,4},{6,3,7,3}, + {6,3,7,4},{6,5,3,5},{6,5,3,6},{6,5,3,7},{6,5,6,3},{6,5,7,3},{6,6,3,3},{6,6,3,4},{6,6,5,3},{6,6,6,6}, + {6,6,7,7},{6,7,3,3},{6,7,3,4},{6,7,5,3},{6,7,6,7},{6,7,7,6},{7,1,3,3},{7,1,3,4},{7,1,5,3},{7,1,5,4}, + {7,3,1,3},{7,3,1,4},{7,3,2,4},{7,3,3,2},{7,3,3,5},{7,3,3,6},{7,3,3,7},{7,3,4,1},{7,3,4,2},{7,3,4,5}, + {7,3,4,6},{7,3,5,3},{7,3,5,4},{7,3,5,5},{7,3,6,3},{7,3,6,4},{7,3,7,3},{7,3,7,4},{7,5,1,4},{7,5,3,4}, + {7,5,3,5},{7,5,5,1},{7,5,5,3},{7,5,5,6},{7,5,6,3},{7,5,7,3},{7,6,3,3},{7,6,3,4},{7,6,5,3},{7,6,6,7}, + {7,6,7,6},{7,7,3,3},{7,7,3,4},{7,7,5,3},{7,7,6,6},{7,7,7,7}, + },--6 piece opener } \ No newline at end of file diff --git a/parts/ai.lua b/parts/ai.lua index 6deff192..229d76a5 100644 --- a/parts/ai.lua +++ b/parts/ai.lua @@ -77,7 +77,7 @@ if system=="Windows"then collectgarbage() end end --------------------------------------------------⑨Stack setup +-------------------------------------------------9 Stack setup local dirCount={1,1,3,3,3,0,1} local spinOffset={ {[0]=0,1,0,0},--Z @@ -180,7 +180,7 @@ local function getScore(field,cb,cy) HclearScore[clear]--Clearing -hole*70--Hole -cy*50--Height - -sdh--∫Δh + -sdh--Sum of DeltaH or LclearScore[clear] -hole*100 diff --git a/parts/bg.lua b/parts/bg.lua index 1b3c4db0..efaa4d20 100644 --- a/parts/bg.lua +++ b/parts/bg.lua @@ -168,7 +168,7 @@ function BGdraw.matrix() local _=ceil(scr.h/80) for i=1,ceil(scr.w/80)do for j=1,_ do - gc.setColor(1,1,1,sin(matrixT[i][j]*t)*.1+.1) + gc.setColor(1,1,1,sin(i+matrixT[i][j]*t)*.1+.1) gc.rectangle("fill",80*i,80*j,-80,-80) end end diff --git a/parts/bgm.lua b/parts/bgm.lua index ec9f3bdd..323677bf 100644 --- a/parts/bgm.lua +++ b/parts/bgm.lua @@ -5,13 +5,14 @@ local BGM={} -- BGM.suspend=[str:pausing ID] -- BGM.playing=[src:playing SRC] BGM.list={ - "blank","way","newera","infinite","reason", - "race","push","secret7th","secret8th", - "rockblock","cruelty","final","8-bit happiness","end", + "blank","way","race","newera","push", + "reason","infinite","secret7th","secret8th", "shining terminal","oxygen","distortion", + "rockblock","cruelty","final","8-bit happiness","end", } +BGM.len=#BGM.list function BGM.loadOne(_) - _,BGM.list[_]=BGM.list[_] + local _=BGM.list[_] BGM.list[_]=love.audio.newSource("/BGM/".._..".ogg","stream") BGM.list[_]:setLooping(true) BGM.list[_]:setVolume(0) diff --git a/parts/file.lua b/parts/file.lua index 56feb2aa..51d42380 100644 --- a/parts/file.lua +++ b/parts/file.lua @@ -136,10 +136,6 @@ function File.loadData() if s then setfenv(s,{}) local S=s() - if S.version~=gameVersion then - S.version=gameVersion - TEXT.show(text.newVersion,640,200,30,"fly",.3) - end if not S.version or S.version=="Alpha V0.8.15"then S.clear_S={S.clear_1,S.clear_2,S.clear_3,S.clear_4} S.clear={{},{},{},{},{},{},{}} @@ -184,6 +180,35 @@ function File.loadData() S.clear[i][4]=0 end end + if not S.clear_B[8]then + for i=1,7 do + S.clear[i][5]=0 + S.spin[i][5]=0 + end + for i=8,25 do + S.clear[i]={0,0,0,0,0} + S.spin[i]={0,0,0,0,0} + S.spin_B[i]=0 + S.clear_B[i]=0 + end + S.spin_S[5]=0 + S.clear_S[5]=0 + end + if S.version=="Alpha V0.8.18"or S.version=="Alpha V0.8.19"then + S.clear[3],S.clear[4]=S.clear[4],S.clear[3] + S.spin[3],S.spin[4]=S.spin[4],S.spin[3] + S.clear_B[3],S.clear_B[4]=S.clear_B[4],S.clear_B[3] + S.spin_B[3],S.spin_B[4]=S.spin_B[4],S.spin_B[3] + end + if #modeRanks==76 then + for i=1,4 do + table.remove(modeRanks) + end + end + if S.version~=gameVersion then + S.version=gameVersion + TEXT.show(text.newVersion,640,200,30,"fly",.3) + end addToTable(S,stat) end end diff --git a/parts/getTip.lua b/parts/getTip.lua index cd947f37..e1d3fcc6 100644 --- a/parts/getTip.lua +++ b/parts/getTip.lua @@ -13,31 +13,37 @@ if setting.lang==1 then "2+2=Miya", "225238922 哔哩哔哩 干杯~", "适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活", - "合群了就会消失,但是消失不代表没有意义", - "学会使用两个旋转键,三个更好", + "合群了就会消失, 但是消失不代表没有意义", + "学会使用两个旋转键, 三个更好", "更小的DAS和ARR拥有更高的操作上限(如果你还能控制得了的话)", "注意到\"旋转\"到底对方块做了些什么吗?", "20G本质是一套全新的游戏规则", "不要在上课时玩游戏!", - "本游戏难度上限很高,做好心理准备", + "本游戏难度上限很高, 做好心理准备", "本游戏可不是休闲游戏", "调到特殊的日期也不会发生什么的", "3.1415926535897932384", "2.7182818284590452353", "Let-The-Bass-Kick!", "使用love2d引擎制作", - "有疑问?先看设置有没有你想要的", + "有疑问? 先看设置有没有你想要的", "有建议的话可以把信息反馈给作者~", "不要按F10", "秘密数字:626", "CLASSIC SEXY RUSSIAN BLOCKS", "戴上耳机以获得最佳体验", "少女祈祷中", - "LrL,RlR LLr,RRl RRR,LLL RfR,RRf,rFF FFF",--ZSLJTOI - "RUR'U'R'FR2U'R'U'RUR'F'", + "LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF", + "(RUR'U')R'FR2U'R'U'(RUR'F')", "Am G F G", - "Techmino 好玩!", + "联网还没做呢, 别急", + "\"免费吃鸡方块\"", "Techminohaowan", + "Techmino 好玩!", + "tetr.js 也很好玩!", + "jstris 也很好玩!", + "tetr.io 也很好玩!", + "nullpomino 也很好玩!", } elseif setting.lang==2 then L={ @@ -73,11 +79,17 @@ elseif setting.lang==2 then "CLASSIC SEXY RUSSIAN BLOCKS", "戴上耳机以获得最佳体验", "少女祈祷中", - "LrL,RlR LLr,RRl RRR,LLL RfR,RRf,rFF FFF",--ZSLJTOI - "RUR'U'R'FR2U'R'U'RUR'F'", + "LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF", + "(RUR'U')R'FR2U'R'U'(RUR'F')", "Am G F G", - "Techmino 好玩!", + "联网还没做呢, 别急", + "\"免费吃鸡方块\"", "Techminohaowan", + "Techmino 好玩!", + "tetr.js 也很好玩!", + "jstris 也很好玩!", + "tetr.io 也很好玩!", + "nullpomino 也很好玩!", } elseif setting.lang==3 then L={ @@ -114,10 +126,24 @@ elseif setting.lang==3 then "CLASSIC SEXY RUSSIAN BLOCKS", "Headphones for better experience", "少女祈禱中", - "RUR'U'R'FR2U'R'U'RUR'F'", + "(RUR'U')R'FR2U'R'U'(RUR'F')", "Am G F G", - "LrL,RlR LLr,RRl RRR,LLL RfR,RRf,rFF FFF",--ZSLJTOI + "LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF", + "Only offline game now", + "\"Free block game with royale-mode\"", "Techmino is so fun!", + "Who is diao", + "Also try tetr.js!", + "Also try jstris!", + "Also try tetr.io!", + "Also try nullpomino!", } +elseif setting.lang==4 then + L={'!','@','#','$','%','^','&','*','(',')','-','=','_','+','[',']','{','}','\\','|',';',':','\'','"',',','<','.','>','/','?'} + local s="" + for i=1,math.random(16,26)do + s=s..L[math.random(#L)] + end + return s end return L[math.random(#L)] \ No newline at end of file diff --git a/parts/img.lua b/parts/img.lua index 54ced521..69311f8f 100644 --- a/parts/img.lua +++ b/parts/img.lua @@ -1,4 +1,5 @@ local IMG={ + batteryImage="/mess/power.png", titleImage="mess/title.png", coloredTitleImage="mess/title_colored.png", dialCircle="mess/dialCircle.png", diff --git a/parts/kickList.lua b/parts/kickList.lua index 8bb0a0cf..ab656872 100644 --- a/parts/kickList.lua +++ b/parts/kickList.lua @@ -1,125 +1,354 @@ -local map={{},{},{},{},{}} -for x=1,5 do for y=1,5 do map[x][y]={x-3,y-3}end end +local zero={0,0} +local Zero={zero} +local ZERO={[01]=Zero,[10]=Zero,[03]=Zero,[30]=Zero,[12]=Zero,[21]=Zero,[32]=Zero,[23]=Zero,[02]=Zero,[20]=Zero,[13]=Zero,[31]=Zero} + +local map={} +for x=-3,3 do map[x]={}for y=-3,3 do map[x][y]={x,y}end end local function collect(T) - for _,T in next,T do - for k,vec in next,T do - T[k]=map[vec[1]+3][vec[2]+3] + if type(T)=="table"then + for _,T in next,T do + for k,vec in next,T do + T[k]=map[vec[1]][vec[2]] + end end end end + +local function sym(L) + L[23]=L[01]L[32]=L[10] + L[21]=L[03]L[12]=L[30] +end +local function flipList(O) + if not O then return end + local L={} + for i=1,#O do + L[i]={-O[i][1],O[i][2]} + end + return L +end +local function reflect(a,b) + b[03]=flipList(a[01]) + b[01]=flipList(a[03]) + b[30]=flipList(a[10]) + b[32]=flipList(a[12]) + b[23]=flipList(a[21]) + b[21]=flipList(a[23]) + b[10]=flipList(a[30]) + b[12]=flipList(a[32]) + b[02]=flipList(a[02]) + b[20]=flipList(a[20]) + b[31]=flipList(a[13]) + b[13]=flipList(a[31]) +end +local function pushZero(T) + local L + for i=1,#T do + L=T[i] + if type(L)=="table"then + for _,v in next,L do + table.insert(v,1,zero) + end + end + end +end + +local scs=require("parts/spinCenters") +local OspinList={ + {111,5,2, 0,-1,0},{111,5,2,-1,-1,0},{111,5,0,-1, 0,0},--T + {333,5,2,-1,-1,0},{333,5,2, 0,-1,0},{333,5,0, 0, 0,0},--T + {313,1,2,-1, 0,0},{313,1,2, 0,-1,0},{313,1,2, 0, 0,0},--Z + {131,2,2, 0, 0,0},{131,2,2,-1,-1,0},{131,2,2,-1, 0,0},--S + {331,3,2, 0,-1,0},{113,3,0, 0, 0,0},{113,3,2,-1, 0,0},--J + {113,4,2,-1,-1,0},{331,4,0,-1, 0,0},{331,4,2, 0, 0,0},--L + {222,7,2,-1, 0,1},{222,7,2,-2, 0,1},{222,7,2, 0, 0,1},--I + {121,6,0, 1,-1,1},{112,6,0, 2,-1,2},{122,6,0, 1,-2,2},--O + {323,6,0,-1,-1,2},{332,6,0,-2,-1,2},{322,6,0,-1,-2,2},--O +}--{key,id,dir,dx,dy,freeLv(0=unmovable,1=L/R unmovable,2=free)} local TRS={ - [1]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2},{0,1} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2}, {0,-1} }, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-1}, {1,-2} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2}, {0,-1}}, - [12]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2} }, - [21]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2} }, - [32]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2} }, - [23]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2} }, - [02]={{0,0},{1,0}, {-1,0}, {0,-1}, {0,1} }, - [20]={{0,0},{-1,0}, {1,0}, {0,1}, {0,-1} }, - [13]={{0,0},{0,-1}, {0,1}, {-1,0}, {0,-2} }, - [31]={{0,0},{0,1}, {0,-1}, {1,0}, {0,2} }, + { + [01]={{-1, 0},{-1, 1},{ 0,-2},{-1, 2},{ 0, 1}}, + [10]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1,-1},{ 1,-2}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-1},{ 1,-2}}, + [30]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2},{ 0,-1}}, + [12]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1, 2}}, + [21]={{-1, 0},{-1, 1},{ 0,-2},{-1,-2}}, + [32]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2}}, + [23]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-2}}, + [02]={{ 1, 0},{-1, 0},{ 0,-1},{ 0, 1}}, + [20]={{-1, 0},{ 1, 0},{ 0, 1},{ 0,-1}}, + [13]={{ 0,-1},{ 0, 1},{-1, 0},{ 0,-2}}, + [31]={{ 0, 1},{ 0,-1},{ 1, 0},{ 0, 2}}, },--Z - [2]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-1},{-1,-2} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2}, {0,-1}}, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2}, {0,1} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2}, {0,-1} }, - [12]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2} }, - [21]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2} }, - [32]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2} }, - [23]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2} }, - [02]={{0,0},{-1,0}, {1,0}, {0,-1}, {0,1} }, - [20]={{0,0},{1,0}, {-1,0}, {0,1}, {0,-1} }, - [13]={{0,0},{0,1}, {0,-1}, {-1,0}, {0,2} }, - [31]={{0,0},{0,-1}, {0,1}, {1,0}, {0,-2} }, - },--S - [3]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2},{-1,-1},{0,1} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2}, {0,-1}, {1,1} }, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {-1,1} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2} }, - [12]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2}, {1,1} }, - [21]={{0,0},{-1,0}, {-1,-1},{-1,1}, {0,-2}, {-1,-2},{-1,-1} }, - [32]={{0,0},{-1,0}, {-1,-1},{-1,1}, {1,0}, {0,-1}, {0,2}, {-1,2} }, - [23]={{0,0},{1,0}, {1,1}, {-1,0}, {0,-2}, {1,-2} }, - [02]={{0,0},{1,0}, {-1,0}, {0,-1}, {0,1} }, - [20]={{0,0},{-1,0}, {1,0}, {0,1}, {0,-1} }, - [13]={{0,0},{0,1}, {1,0}, {0,-1} }, - [31]={{0,0},{0,-1}, {-1,0}, {0,1} }, - },--L - [4]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {1,1} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2} }, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2}, {1,-1}, {0,1} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2}, {0,-1}, {-1,1} }, - [12]={{0,0},{1,0}, {1,-1}, {1,1}, {-1,0}, {0,-1}, {0,2}, {1,2} }, - [21]={{0,0},{-1,0}, {-1,1}, {1,0}, {0,-2}, {-1,-2} }, - [32]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2}, {-1,1} }, - [23]={{0,0},{1,0}, {1,-1}, {1,1}, {0,-2}, {1,-2}, {1,-1} }, - [02]={{0,0},{-1,0}, {1,0}, {0,-1}, {0,1} }, - [20]={{0,0},{1,0}, {-1,0}, {0,1}, {0,-1} }, - [13]={{0,0},{0,-1}, {1,0}, {0,1} }, - [31]={{0,0},{0,1}, {-1,0}, {0,-1} }, + {},--S + { + [01]={{-1, 0},{-1, 1},{ 0,-2},{ 1, 1}}, + [10]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1, 2}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-2},{ 1,-1},{ 0, 1}}, + [30]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2},{ 0,-1},{-1, 1}}, + [12]={{ 1, 0},{ 1,-1},{ 1, 1},{-1, 0},{ 0,-1},{ 0, 2},{ 1, 2}}, + [21]={{-1, 0},{-1, 1},{ 1, 0},{ 0,-2},{-1,-2}}, + [32]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2},{-1, 1}}, + [23]={{ 1, 0},{ 1,-1},{ 1, 1},{ 0,-2},{ 1,-2},{ 1,-1}}, + [02]={{-1, 0},{ 1, 0},{ 0,-1},{ 0, 1}}, + [20]={{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1}}, + [13]={{ 0,-1},{ 1, 0},{ 0, 1}}, + [31]={{ 0, 1},{-1, 0},{ 0,-1}}, },--J - [5]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2},{-1,-1} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2}, {0,-1}, {1,1}}, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2}, {0,-1} }, - [12]={{0,0},{1,0}, {1,-1}, {0,-1}, {-1,-1},{0,2}, {1,2}}, - [21]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2},{1,1} }, - [32]={{0,0},{-1,0}, {-1,-1},{0,-1}, {1,-1}, {0,2}, {-1,2}}, - [23]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2}, {-1,1} }, - [02]={{0,0},{-1,0}, {1,0}, {0,1} }, - [20]={{0,0},{1,0}, {-1,0}, {0,-1} }, - [13]={{0,0},{0,-1}, {0,1}, {1,0}, {0,-2}, {0,2}}, - [31]={{0,0},{0,-1}, {0,1}, {-1,0}, {0,-2}, {0,2}}, + {},--L + { + [01]={{-1, 0},{-1, 1},{ 0,-2},{-1,-2},{-1,-1}}, + [10]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1, 2},{ 0,-1},{ 1, 1}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-2}}, + [30]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2},{ 0,-1}}, + [12]={{ 1, 0},{ 1,-1},{ 0,-1},{-1,-1},{ 0, 2},{ 1, 2}}, + [21]={{-1, 0},{-1, 1},{ 0,-2},{-1,-2},{ 1, 1}}, + [32]={{-1, 0},{-1,-1},{ 0,-1},{ 1,-1},{ 0, 2},{-1, 2}}, + [23]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-2},{-1, 1}}, + [02]={{-1, 0},{ 1, 0},{ 0, 1}}, + [20]={{ 1, 0},{-1, 0},{ 0,-1}}, + [13]={{ 0,-1},{ 0, 1},{ 1, 0},{ 0,-2},{ 0, 2}}, + [31]={{ 0,-1},{ 0, 1},{-1, 0},{ 0,-2},{ 0, 2}}, },--T - [6]={},--O(special) - [7]={ - [01]={{0,0},{0,1}, {1,0}, {-2,0}, {-2,-1},{1,2} }, - [03]={{0,0},{0,1}, {-1,0}, {2,0}, {2,-1}, {-1,2} }, - [10]={{0,0},{2,0}, {-1,0}, {-1,-2},{2,1}, {0,2} }, - [30]={{0,0},{-2,0}, {1,0}, {1,-2}, {-2,1}, {0,2} }, - [12]={{0,0},{-1,0}, {2,0}, {-1,2}, {2,-1} }, - [32]={{0,0},{1,0}, {-2,0}, {1,-2}, {-2,-1} }, - [21]={{0,0},{-2,0}, {1,0}, {1,-2}, {-2,1} }, - [23]={{0,0},{2,0}, {-1,0}, {-1,-2},{2,1} }, - [02]={{0,0},{-1,0}, {1,0}, {0,-1}, {0,1} }, - [20]={{0,0},{1,0}, {-1,0}, {0,1}, {0,-1} }, - [13]={{0,0},{0,-1}, {-1,0}, {1,0}, {0,1} }, - [31]={{0,0},{0,-1}, {1,0}, {-1,0}, {0,1} }, - }--I -}for i=1,7 do collect(TRS[i])end + function(P,d) + if P.human then SFX.fieldPlay("rotate",nil,P)end + if P.gameEnv.easyFresh then P:freshLockDelay()end + if not P.gameEnv.ospin then return end + local x,y=P.curX,P.curY + if y==P.y_img and((P:solid(x-1,y)or P:solid(x-1,y+1)))and(P:solid(x+2,y)or P:solid(x+2,y+1))then + local D=P.spinSeq%100*10+d + P.spinSeq=D + if D<100 then return end + for i=1,#OspinList do + local L=OspinList[i] + if D==L[1]then + local id,dir=L[2],L[3] + local bk=blocks[id][dir] + local x,y=P.curX+L[4],P.curY+L[5] + if not P:ifoverlap(bk,x,y)and(L[6]>0 or P:ifoverlap(bk,x-1,y)and P:ifoverlap(bk,x+1,y))and(L[6]==2 or P:ifoverlap(bk,x,y-1))and P:ifoverlap(bk,x,y+1)then + local C=P.cur + C.id=id + C.bk=bk + P.curX,P.curY=x,y + P.r,P.c=#bk,#bk[1] + P.dir,P.sc=dir,scs[id][dir] + P.spinLast=2 + P.stat.rotate=P.stat.rotate+1 + P:freshgho() + P.spinSeq=0 + SFX.fieldPlay("rotatekick",nil,P) + return + end + end + end + else + P.spinSeq=0 + end + end,--O + { + [01]={{ 0, 1},{ 1, 0},{-2, 0},{-2,-1},{ 1, 2}}, + [10]={{ 2, 0},{-1, 0},{-1,-2},{ 2, 1},{ 0, 2}}, + [03]={{ 0, 1},{-1, 0},{ 2, 0},{ 2,-1},{-1, 2}}, + [30]={{-2, 0},{ 1, 0},{ 1,-2},{-2, 1},{ 0, 2}}, + [12]={{-1, 0},{ 2, 0},{-1, 2},{ 2,-1}}, + [21]={{-2, 0},{ 1, 0},{ 1,-2},{-2, 1}}, + [32]={{ 1, 0},{-2, 0},{ 1,-2},{-2,-1}}, + [23]={{ 2, 0},{-1, 0},{-1,-2},{ 2, 1}}, + [02]={{-1, 0},{ 1, 0},{ 0,-1},{ 0, 1}}, + [20]={{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1}}, + [13]={{ 0,-1},{-1, 0},{ 1, 0},{ 0, 1}}, + [31]={{ 0,-1},{ 1, 0},{-1, 0},{ 0, 1}}, + },--I + { + [01]={{-1, 0},{ 0, 1},{ 1, 1},{ 0,-3},{ 0, 2},{ 0, 3},{-1, 2}}, + [10]={{ 1, 0},{ 0,-1},{-1,-1},{ 0,-2},{ 0,-3},{ 0, 3},{ 1,-2}}, + [03]={{ 1, 0},{ 0,-3},{ 0, 1},{ 0, 2},{ 0, 3},{ 1, 2}}, + [30]={{-1, 0},{ 0, 1},{ 0,-2},{ 0,-3},{ 0, 3},{-1,-2}}, + },--5Z + {},--5S + { + [01]={{-1, 0},{-1, 1},{ 0,-2},{-1,-2},{-1,-1},{ 0, 1}}, + [10]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1, 2},{ 0,-1},{ 1, 1}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-2},{-1, 1}}, + [30]={{-1, 0},{-1,-1},{ 0, 2},{-1, 2}}, + [12]={{ 1, 0},{ 1,-1},{ 0, 2},{ 1, 2},{ 1, 1}}, + [21]={{-1, 0},{-1,-1},{-1, 1},{ 0,-2},{-1,-2},{-1,-1}}, + [32]={{-1, 0},{-1,-1},{-1, 1},{ 1, 0},{ 0,-1},{ 0, 2},{-1, 2}}, + [23]={{ 1, 0},{ 1, 1},{-1, 0},{ 0,-2},{ 1,-2}}, + [02]={{-1, 0},{ 0,-1},{ 0, 1}}, + [20]={{ 1, 0},{ 0, 1},{ 0,-1}}, + [13]={{ 1, 0},{ 0, 1},{-1, 0}}, + [31]={{-1, 0},{ 0,-1},{ 1, 0}}, + },--Q + {},--P + { + [01]={{-1, 0},{ 1, 0},{-1, 1},{ 0,-2},{ 0,-3}}, + [10]={{ 1, 0},{ 1,-1},{-1, 0},{ 0, 2},{ 0, 3}}, + [03]={{ 1, 0},{ 1,-1}, { 0, 1},{ 0,-2},{ 0,-3}}, + [30]={{-1, 0},{-1, 1},{ 1, 0},{ 0,-1},{ 0, 2},{ 0, 3}}, + [12]={{ 1, 0},{ 0,-1},{-1, 0},{ 0, 2}}, + [21]={{-1, 0},{ 0, 1},{ 1, 0},{ 0,-2}}, + [32]={{-1, 0},{-1, 1},{ 0, 1},{ 0,-1},{ 1, 0},{ 0, 2},{-2, 0}}, + [23]={{ 1, 0},{ 1,-1},{ 0,-1},{ 0, 1},{-1, 0},{ 0,-2},{ 2, 0}}, + [02]={{ 1, 0},{-1, 0},{ 0, 1}}, + [20]={{-1, 0},{ 1, 0},{ 0,-1}}, + [13]={{ 0,-1},{ 1, 0},{ 0, 1}}, + [31]={{ 0,-1},{-1, 0},{ 0, 1}}, + },--F + {},--E + { + [01]={{ 0,-1},{-1,-1},{ 1,-1},{ 1, 0},{ 1,-3},{-1, 0},{ 0, 2},{-1, 2}}, + [10]={{ 1, 0},{ 0,-1},{-1,-1},{ 0,-2},{ 0,-3},{ 1,-2},{ 0, 1}}, + [03]={{ 0,-1},{ 1,-1},{-1,-1},{-1, 0},{-1,-3},{ 1, 0},{ 0, 2},{ 1, 2}}, + [30]={{-1, 0},{ 0,-1},{ 1,-1},{ 0,-2},{ 0,-3},{-1,-2},{ 0, 1}}, + [12]={{ 1, 0},{-1, 0},{ 0,-2},{ 0,-3},{ 0, 1},{-1, 1}}, + [21]={{ 1,-1},{-1, 0},{ 1, 0},{ 0,-1},{ 0, 2},{ 0, 3}}, + [32]={{-1, 0},{ 1, 0},{ 0,-2},{ 0,-3},{ 0, 1},{ 1, 1}}, + [23]={{-1,-1},{ 1, 0},{-1, 0},{ 0,-1},{ 0, 2},{ 0, 3}}, + [02]={{ 0, 1},{ 0,-1},{ 0, 2}}, + [20]={{ 0,-1},{ 0, 1},{ 0,-2}}, + [13]={{ 1, 0},{-1, 1},{-2, 0}}, + [31]={{-1, 0},{ 1, 1},{ 2, 0}}, + },--5T + { + [01]={{-1, 0},{-1, 1},{ 0,-2},{-1,-1},{-1,-2}}, + [10]={{ 1, 0},{ 1,-1}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-2},{ 1,-1},{ 1,-2}}, + [30]={{-1, 0},{-1,-1}}, + [12]={{ 1, 0},{ 1, 1}}, + [21]={{-1,-1},{-1, 1}}, + [32]={{-1, 0},{-1, 1}}, + [23]={{ 1,-1},{ 1, 1}}, + [02]={{ 0, 1}}, + [20]={{ 0,-1}}, + [13]={{ 0,-1},{ 0, 1},{ 1, 0}}, + [31]={{ 0,-1},{ 0, 1},{-1, 0}}, + },--U + { + [01]={{ 0, 1},{-1, 0},{ 0,-2},{-1,-2}}, + [10]={{ 0, 1},{ 1, 0},{ 0,-2},{ 1,-2}}, + [03]={{ 0,-1},{ 0, 1},{ 0, 2}}, + [30]={{ 0,-1},{ 0,-1},{ 0,-2}}, + [12]={{ 0,-1},{ 0, 1}}, + [21]={{ 0,-1},{ 0,-2}}, + [32]={{ 1, 0},{-1, 0}}, + [23]={{-1, 0},{ 1, 0}}, + [02]={{-1, 1},{ 1,-1}}, + [20]={{ 1,-1},{-1, 1}}, + [13]={{ 1, 1},{-1,-1}}, + [31]={{-1,-1},{ 1, 1}}, + },--V + { + [01]={{ 0,-1},{-1, 0},{ 1, 0},{ 1,-1},{ 0, 2}}, + [10]={{ 0,-1},{-1,-1},{ 0, 1},{ 0,-2},{ 1,-2},{ 0, 2}}, + [03]={{ 1, 0},{ 1, 1},{ 0,-1},{ 0,-2},{ 0,-3},{ 1,-1},{ 0, 1},{ 0, 2},{ 0, 3}}, + [30]={{-1, 0},{-1, 1},{ 0,-1},{ 0,-2},{ 0,-3},{-1,-1},{ 0, 1},{ 0, 2},{ 0, 3}}, + [12]={{ 1, 0},{ 0,-1},{ 1, 1},{-1, 0},{ 0, 1},{-1,-1}}, + [21]={{-1, 0},{ 0,-1},{-1, 1},{ 1, 0},{ 0, 1},{ 1,-1}}, + [32]={{ 0,-1},{ 1, 0},{ 0, 1},{-1, 0},{-1,-1},{ 0, 2}}, + [23]={{ 0,-1},{ 1,-1},{ 0, 1},{ 0,-2},{-1,-2},{ 0, 2}}, + [02]={{ 0,-1},{-1, 0}}, + [20]={{ 0, 1},{ 1, 0}}, + [13]={{ 0, 1},{-1, 0}}, + [31]={{ 0,-1},{ 1, 0}}, + },--W + function(P,d) + return + end,--X + { + [01]={{-1, 0},{-1, 1},{ 0,-3},{-1, 1},{-1, 2},{ 0, 1}}, + [10]={{-1, 0},{ 1,-1},{ 0, 3},{ 1,-1},{ 1,-2},{ 0, 1}}, + [03]={{ 0,-1},{ 1,-1},{-1, 0},{ 1, 1},{ 0,-2},{ 1,-2},{ 0,-3},{ 1,-3},{-1, 1}}, + [30]={{ 0, 1},{-1, 1},{ 1, 0},{-1,-1},{ 0, 2},{-1, 2},{ 0, 3},{-1, 3},{ 1,-1}}, + [12]={{ 1, 0},{ 1,-1},{ 0,-1},{ 1,-2},{ 0,-2},{ 1, 1},{-1, 0},{ 0, 2},{ 1, 2}}, + [21]={{-1, 0},{-1, 1},{ 0, 1},{-1, 2},{ 0, 2},{-1,-1},{ 1, 0},{ 0,-2},{-1,-2}}, + [32]={{-1, 0},{-1, 1},{-1,-1},{ 0, 2},{-1, 2},{ 0,-2}}, + [23]={{ 1, 0},{ 1,-1},{ 1, 1},{ 0,-2},{ 1,-2},{ 0, 2}}, + [02]={{ 0,-1},{ 1,-1},{-1, 0},{ 2,-1},{ 0, 1}}, + [20]={{ 0, 1},{-1, 1},{ 1, 0},{-2, 1},{ 0,-1}}, + [13]={{-1, 0},{-1,-1},{ 0, 1},{-1,-2}}, + [31]={{ 1, 0},{ 1, 1},{ 0,-1},{ 1, 2}}, + },--5J + {},--5L + { + [01]={{-1, 0},{-1, 1},{ 1, 0},{-1, 2},{-1,-1},{ 0,-3},{ 0, 1}}, + [10]={{-1, 0},{ 1,-1},{-1, 0},{ 1,-2},{ 1, 1},{ 0, 3},{ 0, 1}}, + [03]={{ 0,-1},{ 1,-1},{-1, 0},{ 1, 1},{ 0,-2},{ 1,-2},{ 0,-3},{ 1,-3},{-1, 1}}, + [30]={{ 0, 1},{-1, 1},{ 1, 0},{-1,-1},{ 0, 2},{-1, 2},{ 0, 3},{-1, 3},{ 1,-1}}, + [12]={{ 1, 0},{ 1,-1},{ 0,-1},{ 1,-2},{ 0,-2},{ 1, 1},{-1, 0},{ 0, 2},{ 1, 2}}, + [21]={{-1, 0},{-1, 1},{ 0, 1},{-1, 2},{ 0, 2},{-1,-1},{ 1, 0},{ 0,-2},{-1,-2}}, + [32]={{-1, 0},{-1, 1},{-1,-1},{ 0, 2},{-1, 2},{ 0,-2}}, + [23]={{ 1, 0},{ 1,-1},{ 1, 1},{ 0,-2},{ 1,-2},{ 0, 2}}, + [02]={{ 0,-1},{ 1,-1},{-1, 0},{ 2,-1},{ 0, 1}}, + [20]={{ 0, 1},{-1, 1},{ 1, 0},{-2, 1},{ 0,-1}}, + [13]={{-1, 0},{-1,-1},{ 0, 1},{-1,-2}}, + [31]={{ 1, 0},{ 1, 1},{ 0,-1},{ 1, 2}}, + },--R + {},--Y + { + [01]={{-1, 0},{-1, 1},{ 0, 1},{ 1, 0},{-1, 2},{-2, 0},{ 0,-2}}, + [10]={{ 1, 0},{-1, 0},{ 0,-1},{ 1,-1},{ 1,-2},{ 2, 0},{ 0, 2}}, + [03]={{-1, 0},{ 1,-1},{ 0,-2},{ 0,-3},{ 1, 0},{ 1,-2},{ 1,-3},{ 0, 1},{-1, 1}}, + [30]={{-1, 0},{ 1,-1},{ 1,-2},{ 1, 0},{ 0,-2},{ 1,-3},{-1, 2},{ 0, 3},{-1, 3}}, + [12]={{-1, 0},{ 1,-1},{-1,-1},{ 1,-2},{ 1, 0},{ 0,-2},{ 1,-3},{-1, 2},{ 0, 3},{-1, 3}}, + [21]={{-1, 0},{ 1,-1},{ 1, 1},{ 0,-2},{ 0,-3},{ 1, 0},{ 1,-2},{ 1,-3},{ 0, 1},{-1, 1}}, + [32]={{-1, 0},{ 0,-1},{-1,-2},{ 1,-1},{ 1, 0},{ 1, 1},{ 0, 2},{ 0, 3}}, + [23]={{ 0,-2},{ 0,-3},{ 1, 2},{ 1, 0},{ 0, 1},{-1, 1},{ 0,-1},{ 0, 2}}, + [02]={{-1, 0},{ 0, 2},{ 0,-1}}, + [20]={{ 1, 0},{ 0,-2},{ 0, 1}}, + [13]={{-1, 0},{-1,-1},{ 0, 1},{ 1, 2}}, + [31]={{ 1, 0},{ 1, 1},{ 0,-1},{-1,-2}}, + },--N + {},--H + { + [01]={{ 1,-1},{ 1, 0},{ 1, 1},{ 0, 1},{-1, 1},{-1, 0},{-1,-1},{ 0,-1},{ 0,-2},{-2,-1},{-2,-2},{ 2, 0},{ 2,-1},{ 2,-2},{ 1, 2},{ 2, 2},{-1, 2},{-2, 2}}, + [10]={{-1, 0},{-1,-1},{ 0,-1},{ 1,-1},{-2,-2},{-2,-1},{-2, 0},{-1,-2},{ 0,-2},{ 1,-2},{ 2,-2},{-1, 1},{-2, 1},{-2, 2},{ 1, 0},{ 2, 0},{ 2,-1},{ 0, 1},{ 1,-1},{ 2,-2}}, + },--5I +} +TRS[25][03]=flipList(TRS[25][01]) +TRS[25][30]=flipList(TRS[25][10]) +sym(TRS[8])sym(TRS[9])sym(TRS[25]) +reflect(TRS[1],TRS[2])--SZ +reflect(TRS[3],TRS[4])--LJ +reflect(TRS[8],TRS[9])--5S5Z +reflect(TRS[10],TRS[11])--PQ +reflect(TRS[12],TRS[13])--FE +reflect(TRS[19],TRS[20])--5L5J +reflect(TRS[21],TRS[22])--RY +reflect(TRS[23],TRS[24])--HN +for i=1,25 do collect(TRS[i])end +pushZero(TRS) + local AIRS={ [1]={ - [01]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2} }, - [10]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2} }, - [03]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2} }, - [30]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2} }, - [12]={{0,0},{1,0}, {1,-1}, {0,2}, {1,2} }, - [21]={{0,0},{-1,0}, {-1,1}, {0,-2}, {-1,-2} }, - [32]={{0,0},{-1,0}, {-1,-1},{0,2}, {-1,2} }, - [23]={{0,0},{1,0}, {1,1}, {0,-2}, {1,-2} }, + [01]={{-1,0},{-1, 1},{ 0,-2},{-1,-2}}, + [10]={{ 1,0},{ 1,-1},{ 0, 2},{ 1, 2}}, + [03]={{ 1,0},{ 1, 1},{ 0,-2},{ 1,-2}}, + [30]={{-1,0},{-1,-1},{ 0, 2},{-1, 2}}, + [12]={{ 1,0},{ 1,-1},{ 0, 2},{ 1, 2}}, + [21]={{-1,0},{-1, 1},{ 0,-2},{-1,-2}}, + [32]={{-1,0},{-1,-1},{ 0, 2},{-1, 2}}, + [23]={{ 1,0},{ 1, 1},{ 0,-2},{ 1,-2}}, }, [7]={ - [01]={{0,0},{-2,0}, {1,0}, {-2,-1},{1,2} }, - [10]={{0,0},{2,0}, {-1,0}, {2,1}, {-1,-2} }, - [12]={{0,0},{-1,0}, {2,0}, {-1,2}, {2,-1} }, - [21]={{0,0},{1,0}, {-2,0}, {1,-2}, {-2,1} }, - [23]={{0,0},{2,0}, {-1,0}, {2,1}, {-1,-2} }, - [32]={{0,0},{-2,0}, {1,0}, {-2,-1},{1,2} }, - [30]={{0,0},{1,0}, {-2,0}, {1,-2}, {-2,1} }, - [03]={{0,0},{-1,0}, {2,0}, {-1,2}, {2,-1} }, + [01]={{-2, 0},{ 1, 0},{-2,-1},{ 1, 2}}, + [10]={{ 2, 0},{-1, 0},{ 2, 1},{-1,-2}}, + [12]={{-1, 0},{ 2, 0},{-1, 2},{ 2,-1}}, + [21]={{ 1, 0},{-2, 0},{ 1,-2},{-2, 1}}, + [23]={{ 2, 0},{-1, 0},{ 2, 1},{-1,-2}}, + [32]={{-2, 0},{ 1, 0},{-2,-1},{ 1, 2}}, + [30]={{ 1, 0},{-2, 0},{ 1,-2},{-2, 1}}, + [03]={{-1, 0},{ 2, 0},{-1, 2},{ 2,-1}}, } } -for i=2,6 do AIRS[i]=AIRS[1]end collect(AIRS[1])collect(AIRS[7]) +for i=2,25 do AIRS[i]=AIRS[1]end +pushZero(AIRS) + +local NONE={} +for i=1,25 do NONE[i]=ZERO end return{ TRS=TRS, AIRS=AIRS, + NONE=NONE, } \ No newline at end of file diff --git a/parts/languages.lua b/parts/languages.lua index e440e797..f0e9face 100644 --- a/parts/languages.lua +++ b/parts/languages.lua @@ -7,10 +7,8 @@ local langList={ atkModeName={"随机","徽章","击杀","反击"}, royale_remain=function(n)return"剩余 "..n.." 名玩家"end, cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!","15 Combo!","16 Combo!","17 Combo!","18 Combo!","19 Combo!","MEGACMB"}, - techrash="Techrash",techrashB2B="B2B Techrash",techrashB3B="B2B2B Techrash", - spin={"Z-spin","S-spin","L-spin","J-spin","T-spin","O-spin","I-spin"}, - block={"Z","S","L","J","T","O","I"}, - clear={" single"," double"," triple"}, + block=nil,spin="-spin ", + clear={"single","double","triple","Techrash","Techrach+"}, mini="Mini",b2b="B2B ",b3b="B2B2B ", PC="Perfect Clear",HPC="Half Clear", hold="暂存",next="下一个", @@ -61,7 +59,7 @@ local langList={ softdroparr="软降ARR:", snapLevelName={"无吸附","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, setting_game="游戏设置", - setting_graphic="画面设置", + setting_video="画面设置", setting_sound="声音设置", setting_control="控制设置", setting_skin="外观设置", @@ -70,6 +68,7 @@ local langList={ ctrlSetHelp="方向键选择/翻页,回车修改,esc返回", musicRoom="音乐室", nowPlaying="正在播放:", + page="页面:", settingSaved="设置已保存", settingSavingError="设置保存失败:", @@ -215,10 +214,10 @@ local langList={ pause="暂停", }, pause={ - resume= "继续(空格)", + resume= "继续(esc)", restart="重新开始(R)", setting="设置(S)", - quit= "退出(esc)", + quit= "退出(Q)", }, setting_game={ graphic="←画面设置", @@ -231,12 +230,11 @@ local langList={ key="键位设置", touch="触屏设置", quickR="快速重新开始", - autoPause="自动暂停", swap="组合键切换攻击模式", fine="极简操作提示音", back="返回", }, - setting_graphic={ + setting_video={ sound="←声音设置", game="游戏设置→", ghost="阴影", @@ -244,14 +242,16 @@ local langList={ center="旋转中心", grid="网格", bagLine="包分界线", - bg="背景", lockFX="锁定特效等级", dropFX="下落特效等级", + clearFX="消除特效等级", shakeFX="晃动特效等级", atkFX="攻击特效等级", + frame="绘制帧率", text="消行文本", fullscreen="全屏", - frame="绘制帧率", + bg="背景", + power="电量显示", back="返回", }, setting_sound={ @@ -317,6 +317,9 @@ local langList={ VKDodge="自动避让", back="返回", }, + setting_lang={ + back="返回", + },--langName added later help={ his="历史", qq="作者QQ", @@ -333,81 +336,79 @@ local langList={ }, }, modes={ - {"竞速","10L","消除10行"}, - {"竞速","20L","消除20行"}, - {"竞速","40L","消除40行"}, - {"竞速","100L","消除100行"}, - {"竞速","400L","消除400行"}, - {"竞速","1000L","消除1000行"}, - {"干旱","100L","你I没了"}, - {"干旱","100L","后 妈 发 牌"}, - {"马拉松","普通","200行加速马拉松"}, - {"马拉松","困难","200行高速马拉松"}, - {"单挑","简单","打败AI"}, - {"单挑","普通","打败AI"}, - {"单挑","困难","打败AI"}, - {"单挑","疯狂","打败AI"}, - {"单挑","极限","打败AI"}, - {"49人混战","简单","49人混战,活到最后"}, - {"49人混战","困难","49人混战,活到最后"}, - {"49人混战","极限","49人混战,活到最后"}, - {"99人混战","简单","99人混战,活到最后"}, - {"99人混战","困难","99人混战,活到最后"}, - {"99人混战","极限","99人混战,活到最后"}, - {"回合制","简单","下棋模式"}, - {"回合制","普通","下棋模式"}, - {"回合制","困难","下棋模式"}, - {"回合制","疯狂","下棋模式"}, - {"回合制","极限","下棋模式"}, - {"大师","疯狂","20G:初心者适用"}, - {"大师","极限","20G:上级者的挑战"}, - {"大师","终点","究极20G:无法触及的终点"}, - {"宗师","GM","成为方块大师"}, - {"隐形","半隐","不强大脑"}, - {"隐形","全隐","挺强大脑"}, - {"隐形","瞬隐","很强大脑"}, - {"隐形","瞬隐+","超强大脑"}, - {"隐形","啥都不剩隐","最强大脑"}, - {"高速经典","CTWC","高速经典"}, - {"生存","简单","你能存活多久?"}, - {"生存","普通","你能存活多久?"}, - {"生存","困难","你能存活多久?"}, - {"生存","疯狂","你能存活多久?"}, - {"生存","极限","你能存活多久?"}, - {"进攻","困难","进攻练习"}, - {"进攻","极限","进攻练习"}, - {"防守","普通","防守练习"}, - {"防守","疯狂","防守练习"}, - {"挖掘","困难","挖掘练习"}, - {"挖掘","极限","挖掘练习"}, - {"大爆炸","简单","All-spin 入门教程\n未制作完成,落块即通"}, - {"C4W练习","普通","无 限 连 击"}, - {"C4W练习","疯狂","无 限 连 击"}, - {"全清训练","普通","简易PC题库,熟悉全清定式的组合"}, - {"全清训练","疯狂","简易PC题库,熟悉全清定式的组合"}, - {"全清挑战","普通","100行内刷PC"}, - {"全清挑战","困难","100行内刷PC"}, - {"全清挑战","疯狂","100行内刷PC"}, - {"科研","普通","禁止断B2B"}, - {"科研","普通+","仅允许spin与PC"}, - {"科研","困难","禁止断B2B"}, - {"科研","困难+","仅允许spin与PC"}, - {"科研","疯狂","禁止普通消除"}, - {"科研","疯狂+","仅允许spin与PC"}, - {"科研","极限","禁止普通消除,强制最简操作"}, - {"科研","极限+","仅允许spin与PC,强制最简操作"}, - {"TSD挑战","简单","你能连续做几个TSD?"}, - {"TSD挑战","困难","你能连续做几个TSD?"}, - {"TSD挑战","极限","你能连续做几个TSD?"}, - {"禅","","不限时200行"}, - {"限时打分","挑战","在两分钟内尽可能拿到最多的分数"}, - {"无尽","","沙盒"}, - {"无尽:挖掘","","挖呀挖呀挖"}, - {"自定义","普通","画点什么然后把它消除!"}, - {"自定义","拼图","画点什么然后把它拼出来吧!"}, - {"本地多人","2P","[非联网]小游戏式联机"}, - {"本地多人","3P","[非联网]小游戏式联机"}, - {"本地多人","4P","[非联网]小游戏式联机"}, + {"竞速", "10L", "消除10行"}, + {"竞速", "20L", "消除20行"}, + {"竞速", "40L", "消除40行"}, + {"竞速", "100L", "消除100行"}, + {"竞速", "400L", "消除400行"}, + {"竞速", "1000L", "消除1000行"}, + {"干旱", "100L", "你I没了"}, + {"干旱", "100L", "后 妈 发 牌"}, + {"马拉松", "普通", "200行加速马拉松"}, + {"马拉松", "困难", "200行高速马拉松"}, + {"单挑", "简单", "打败AI"}, + {"单挑", "普通", "打败AI"}, + {"单挑", "困难", "打败AI"}, + {"单挑", "疯狂", "打败AI"}, + {"单挑", "极限", "打败AI"}, + {"49人混战", "简单", "49人混战,活到最后"}, + {"49人混战", "困难", "49人混战,活到最后"}, + {"49人混战", "极限", "49人混战,活到最后"}, + {"99人混战", "简单", "99人混战,活到最后"}, + {"99人混战", "困难", "99人混战,活到最后"}, + {"99人混战", "极限", "99人混战,活到最后"}, + {"回合制", "简单", "下棋模式"}, + {"回合制", "普通", "下棋模式"}, + {"回合制", "困难", "下棋模式"}, + {"回合制", "疯狂", "下棋模式"}, + {"回合制", "极限", "下棋模式"}, + {"大师", "疯狂", "20G:初心者适用"}, + {"大师", "极限", "20G:上级者的挑战"}, + {"大师", "终点", "究极20G:无法触及的终点"}, + {"宗师", "GM", "成为方块大师"}, + {"隐形", "半隐", "不强大脑"}, + {"隐形", "全隐", "挺强大脑"}, + {"隐形", "瞬隐", "很强大脑"}, + {"隐形", "瞬隐+", "超强大脑"}, + {"隐形", "啥都不剩隐","最强大脑"}, + {"高速经典", "CTWC", "高速经典"}, + {"生存", "简单", "你能存活多久?"}, + {"生存", "普通", "你能存活多久?"}, + {"生存", "困难", "你能存活多久?"}, + {"生存", "疯狂", "你能存活多久?"}, + {"生存", "极限", "你能存活多久?"}, + {"进攻", "困难", "进攻练习"}, + {"进攻", "极限", "进攻练习"}, + {"防守", "普通", "防守练习"}, + {"防守", "疯狂", "防守练习"}, + {"挖掘", "困难", "挖掘练习"}, + {"挖掘", "极限", "挖掘练习"}, + {"大爆炸", "简单", "All-spin 入门教程\n未制作完成,落块即通"}, + {"C4W练习", "普通", "无 限 连 击"}, + {"C4W练习", "疯狂", "无 限 连 击"}, + {"全清训练", "普通", "简易PC题库,熟悉全清定式的组合"}, + {"全清训练", "疯狂", "简易PC题库,熟悉全清定式的组合"}, + {"全清挑战", "普通", "100行内刷PC"}, + {"全清挑战", "困难", "100行内刷PC"}, + {"全清挑战", "疯狂", "100行内刷PC"}, + {"科研", "普通", "禁止断B2B"}, + {"科研", "普通+", "仅允许spin与PC"}, + {"科研", "困难", "禁止断B2B"}, + {"科研", "困难+", "仅允许spin与PC"}, + {"科研", "疯狂", "禁止断B2B"}, + {"科研", "疯狂+", "仅允许spin与PC"}, + {"科研", "极限", "强制最简操作"}, + {"科研", "极限+", "禁止普通消除,强制最简操作"}, + {"TSD挑战", "简单", "你能连续做几个TSD?"}, + {"TSD挑战", "困难", "你能连续做几个TSD?"}, + {"TSD挑战", "极限", "你能连续做几个TSD?"}, + {"禅", "", "不限时200行"}, + {"限时打分", "挑战", "在两分钟内尽可能拿到最多的分数"}, + {"无尽", "", "沙盒"}, + {"无尽:挖掘", "", "挖呀挖呀挖"}, + {"自定义", "普通", "画点什么然后把它消除!"}, + {"自定义", "拼图", "画点什么然后把它拼出来吧!"}, + {"竞速", "五联块", "不可能的任务"}, }, }, { @@ -418,10 +419,8 @@ local langList={ atkModeName={"随机","徽章","击杀","反击"}, royale_remain=function(n)return"剩余 "..n.." 名玩家"end, cmb={nil,"1连击","2连击","3连击","4连击","5连击","6连击","7连击","8连击","9连击","10连击!","11连击!","12连击!","13连击!","14连击!","15连击!","16连击!","17连击!","18连击!","19连击!","巨型连击"}, - techrash="四清",techrashB2B="满贯 四清",techrashB3B="大满贯 四清", - spin={"Z型回旋","S型回旋","L型回旋","J型回旋","T型回旋","O型回旋","I型回旋"}, - block={"Z","S","L","J","T","O","I"}, - clear={"单清","双清","三清"}, + block=nil,spin="型回旋", + clear={"单清","双清","三清","四清","五清"}, mini="迷你",b2b="满贯",b3b="大满贯", PC="场地全清",HPC="场地半清", hold="暂存",next="下一个", @@ -470,7 +469,7 @@ local langList={ }, snapLevelName={"无吸附","10像素吸附","20像素吸附","40像素吸附","60像素吸附","80像素吸附"}, setting_game="游戏设置", - setting_graphic="画面设置", + setting_video="画面设置", setting_sound="声音设置", setting_control="控制设置", setting_skin="外观设置", @@ -479,6 +478,7 @@ local langList={ ctrlSetHelp="方向键选择/翻页,回车修改,esc返回", musicRoom="音乐室", nowPlaying="正在播放:", + page="页面:", settingSaved="设置已保存", settingSavingError="设置保存失败:", @@ -624,10 +624,10 @@ local langList={ pause="暂停", }, pause={ - resume= "继续(空格)", + resume= "继续(esc)", restart="重新开始(R)", setting="设置(S)", - quit= "退出(esc)", + quit= "退出(Q)", }, setting_game={ graphic="←画面设置", @@ -644,7 +644,7 @@ local langList={ fine="极简操作提示音", back="返回", }, - setting_graphic={ + setting_video={ sound="←声音设置", game="游戏设置→", ghost="阴影", @@ -652,14 +652,16 @@ local langList={ center="旋转中心", grid="网格", bagLine="包分界线", - bg="背景", lockFX="锁定特效等级", dropFX="下落特效等级", + clearFX="消除特效等级", shakeFX="晃动特效等级", atkFX="攻击特效等级", + frame="绘制帧率", text="消行文本", fullscreen="全屏", - frame="绘制帧率", + bg="背景", + power="电量显示", back="返回", }, setting_sound={ @@ -725,6 +727,9 @@ local langList={ VKDodge="自动避让", back="返回", }, + setting_lang={ + back="返回", + },--langName added later help={ his="历史", qq="作者QQ", @@ -741,191 +746,188 @@ local langList={ }, }, modes={ - {"竞速","10行","消除10行"}, - {"竞速","20行","消除20行"}, - {"竞速","40行","消除40行"}, - {"竞速","100行","消除100行"}, - {"竞速","400行","消除400行"}, - {"竞速","1000行","消除1000行"}, - {"干旱","100行","你I没了"}, - {"干旱","100行","后 妈 发 牌"}, - {"马拉松","普通","200行加速马拉松"}, - {"马拉松","困难","200行高速马拉松"}, - {"单挑","简单","打败机器人"}, - {"单挑","普通","打败机器人"}, - {"单挑","困难","打败机器人"}, - {"单挑","疯狂","打败机器人"}, - {"单挑","极限","打败机器人"}, - {"49人混战","简单","49人混战,活到最后"}, - {"49人混战","困难","49人混战,活到最后"}, - {"49人混战","极限","49人混战,活到最后"}, - {"99人混战","简单","99人混战,活到最后"}, - {"99人混战","困难","99人混战,活到最后"}, - {"99人混战","极限","99人混战,活到最后"}, - {"回合制","简单","下棋模式"}, - {"回合制","普通","下棋模式"}, - {"回合制","困难","下棋模式"}, - {"回合制","疯狂","下棋模式"}, - {"回合制","极限","下棋模式"}, - {"大师","疯狂","20G:初心者适用"}, - {"大师","极限","20G:上级者的挑战"}, - {"大师","终点","究极20G:无法触及的终点"}, - {"宗师","GM","成为方块大师"}, - {"隐形","半隐","不强大脑"}, - {"隐形","全隐","挺强大脑"}, - {"隐形","瞬隐","很强大脑"}, - {"隐形","瞬隐+","超强大脑"}, - {"隐形","啥都不剩隐","最强大脑"}, - {"高速经典","CTWC","高速经典"}, - {"生存","简单","你能存活多久?"}, - {"生存","普通","你能存活多久?"}, - {"生存","困难","你能存活多久?"}, - {"生存","疯狂","你能存活多久?"}, - {"生存","极限","你能存活多久?"}, - {"进攻","困难","进攻练习"}, - {"进攻","极限","进攻练习"}, - {"防守","普通","防守练习"}, - {"防守","疯狂","防守练习"}, - {"挖掘","困难","挖掘练习"}, - {"挖掘","极限","挖掘练习"}, - {"大爆炸","简单","All-spin 入门教程\n未制作完成,落块即通"}, - {"中四宽练习","普通","无 限 连 击"}, - {"中四宽练习","疯狂","无 限 连 击"}, - {"全清训练","普通","简易全清题库,熟悉全清定式的组合"}, - {"全清训练","疯狂","简易全清题库,熟悉全清定式的组合"}, - {"全清挑战","普通","100行内刷全清"}, - {"全清挑战","困难","100行内刷全清"}, - {"全清挑战","疯狂","100行内刷全清"}, - {"科研","普通","禁止断B2B"}, - {"科研","普通+","仅允许回旋与全清"}, - {"科研","困难","禁止断B2B"}, - {"科研","困难+","仅允许回旋与全清"}, - {"科研","疯狂","禁止普通消除"}, - {"科研","疯狂+","仅允许回旋与全清"}, - {"科研","极限","禁止普通消除,强制最简操作"}, - {"科研","极限+","仅允许回旋与全清,强制最简操作"}, - {"T2挑战","简单","你能连续做几个T旋双清?"}, - {"T2挑战","困难","你能连续做几个T旋双清?"}, - {"T2挑战","极限","你能连续做几个T旋双清?"}, - {"禅","","不限时200行"}, - {"限时打分","挑战","在两分钟内尽可能拿到最多的分数"}, - {"无尽","","沙盒"}, - {"无尽:挖掘","","挖呀挖呀挖"}, - {"自定义","普通","画点什么然后把它消除!"}, - {"自定义","拼图","画点什么然后把它拼出来吧!"}, - {"本地多人","2P","[非联网]小游戏式联机"}, - {"本地多人","3P","[非联网]小游戏式联机"}, - {"本地多人","4P","[非联网]小游戏式联机"}, + {"竞速", "10行", "消除10行"}, + {"竞速", "20行", "消除20行"}, + {"竞速", "40行", "消除40行"}, + {"竞速", "100行", "消除100行"}, + {"竞速", "400行", "消除400行"}, + {"竞速", "1000行", "消除1000行"}, + {"干旱", "100行", "你I没了"}, + {"干旱", "100行", "后 妈 发 牌"}, + {"马拉松", "普通", "200行加速马拉松"}, + {"马拉松", "困难", "200行高速马拉松"}, + {"单挑", "简单", "打败机器人"}, + {"单挑", "普通", "打败机器人"}, + {"单挑", "困难", "打败机器人"}, + {"单挑", "疯狂", "打败机器人"}, + {"单挑", "极限", "打败机器人"}, + {"49人混战", "简单", "49人混战,活到最后"}, + {"49人混战", "困难", "49人混战,活到最后"}, + {"49人混战", "极限", "49人混战,活到最后"}, + {"99人混战", "简单", "99人混战,活到最后"}, + {"99人混战", "困难", "99人混战,活到最后"}, + {"99人混战", "极限", "99人混战,活到最后"}, + {"回合制", "简单", "下棋模式"}, + {"回合制", "普通", "下棋模式"}, + {"回合制", "困难", "下棋模式"}, + {"回合制", "疯狂", "下棋模式"}, + {"回合制", "极限", "下棋模式"}, + {"大师", "疯狂", "20G:初心者适用"}, + {"大师", "极限", "20G:上级者的挑战"}, + {"大师", "终点", "究极20G:无法触及的终点"}, + {"宗师", "GM", "成为方块大师"}, + {"隐形", "半隐", "不强大脑"}, + {"隐形", "全隐", "挺强大脑"}, + {"隐形", "瞬隐", "很强大脑"}, + {"隐形", "瞬隐+", "超强大脑"}, + {"隐形", "啥都不剩隐","最强大脑"}, + {"高速经典", "CTWC", "高速经典"}, + {"生存", "简单", "你能存活多久?"}, + {"生存", "普通", "你能存活多久?"}, + {"生存", "困难", "你能存活多久?"}, + {"生存", "疯狂", "你能存活多久?"}, + {"生存", "极限", "你能存活多久?"}, + {"进攻", "困难", "进攻练习"}, + {"进攻", "极限", "进攻练习"}, + {"防守", "普通", "防守练习"}, + {"防守", "疯狂", "防守练习"}, + {"挖掘", "困难", "挖掘练习"}, + {"挖掘", "极限", "挖掘练习"}, + {"大爆炸", "简单", "All-spin 入门教程\n未制作完成,落块即通"}, + {"中四宽练习", "普通", "无 限 连 击"}, + {"中四宽练习", "疯狂", "无 限 连 击"}, + {"全清训练", "普通", "简易全清题库,熟悉全清定式的组合"}, + {"全清训练", "疯狂", "简易全清题库,熟悉全清定式的组合"}, + {"全清挑战", "普通", "100行内刷全清"}, + {"全清挑战", "困难", "100行内刷全清"}, + {"全清挑战", "疯狂", "100行内刷全清"}, + {"科研", "普通", "禁止断B2B"}, + {"科研", "普通+", "仅允许回旋与全清"}, + {"科研", "困难", "禁止断B2B"}, + {"科研", "困难+", "仅允许回旋与全清"}, + {"科研", "疯狂", "禁止断B2B"}, + {"科研", "疯狂+", "仅允许spin与PC"}, + {"科研", "极限", "强制最简操作"}, + {"科研", "极限+", "禁止普通消除,强制最简操作"}, + {"T2挑战", "简单", "你能连续做几个T旋双清?"}, + {"T2挑战", "困难", "你能连续做几个T旋双清?"}, + {"T2挑战", "极限", "你能连续做几个T旋双清?"}, + {"禅", "", "不限时200行"}, + {"限时打分", "挑战", "在两分钟内尽可能拿到最多的分数"}, + {"无尽", "", "沙盒"}, + {"无尽:挖掘", "", "挖呀挖呀挖"}, + {"自定义", "普通", "画点什么然后把它消除!"}, + {"自定义", "拼图", "画点什么然后把它拼出来吧!"}, + {"竞速", "五联块", "不可能的任务"}, }, }, { - anykey="Any Key to Continue", - newVersion="Updating detected! Saving format may changed", + anykey="Press any button", + newVersion="Updating detected! Save format may have been updated.", marking="Author:MrZ_26\nIllegal recording if u see this", lang="English", - atkModeName={"Random","Badges","K.O.s","Counters"}, - royale_remain=function(n)return n.." Players Remain"end, + atkModeName={"Random","Badges","K.O.s","Attackers"}, + royale_remain=function(n)return n.." Players Remaining"end, cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!","15 Combo!","16 Combo!","17 Combo!","18 Combo!","19 Combo!","MEGACMB"}, - techrash="Techrash",techrashB2B="B2B Techrash",techrashB3B="B2B2B Techrash", - spin={"Z-spin","S-spin","L-spin","J-spin","T-spin","O-spin","I-spin"}, - block={"Z","S","L","J","T","O","I"}, - clear={" single"," double"," triple"}, + block=nil,spin="-spin ", + clear={"single","double"," triple","Techrash","Techrash+"}, mini="Mini",b2b="B2B ",b3b="B2B2B ", PC="Perfect Clear",HPC="Clear", hold="Hold",next="Next", - stage=function(n)return"STAGE "..n end, + stage=function(n)return"Stage "..n end, great="Great!", - awesome="Awesome.", - continue="Continue.", - maxspeed="Max speed", - speedup="Speed up", + awesome="Awesome!", + continue="Keep going!", + maxspeed="Max speed!", + speedup="Speed up!", win="WIN", - finish="FINISH", + finish="Finish", lose="LOSE", - pause="PAUSE", - pauseCount="Pause Count", + pause="Pause", + pauseCount="Pauses:", custom="Custom Game", customOption={ - drop="Drop speed:", - lock="Lock delay:", - wait="Next piece delay:", - fall="Clear row delay:", - next="Next count:", + drop="Drop Speed:", + lock="Lock Delay:", + wait="Entry Delay:", + fall="Line Delay:", + next="Next Length:", hold="Hold:", - sequence="Sequence:", - visible="Visible:", - target="Line limit:", - freshLimit="Lock fresh limit:", - opponent="Opponent speed:", + sequence="Randomizer:", + visible="Visibility:", + target="Line Goal:", + freshLimit="Lock Reset Limit:", + opponent="Opponent Type:", bg="Background:", - bgm="BGM:", + bgm="Music:", }, customVal={ drop={"0G","1/180G","1/60G","1/40G","1/30G","1/25G","1/20G","1/18G","1/16G","1/14G","1/12G","1/10G","1/9G","1/8G","1/7G","1/6G","1/5G","1/4G","1/3G","1/2G","1G","2G","4G","8G","20G"}, - lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"∞"}, + lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"Inf"}, wait=nil, fall=nil, next=nil, - hold={"ON","OFF","FREE"}, + hold={"On","Off","Inf"}, sequence={"bag7","his4","random"}, - visible={"normal","time","invisible","sudden"}, - target={10,20,40,100,200,500,1000,"∞"}, - freshLimit={0,8,15,"∞"}, - opponent={"No CPU","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"}, + visible={"normal","slow fade","fast fade","sudden fade"}, + target={10,20,40,100,200,500,1000,"None"}, + freshLimit={0,8,15,"Inf"}, + opponent={"None","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"}, }, snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"}, - setting_game="Game setting", - setting_graphic="Graphic setting", - setting_sound="Sound setting", - setting_control="Control Setting", - setting_skin="Layout Setting", + setting_game="Game settings", + setting_video="Video settings", + setting_sound="Sound settings", + setting_control="Control Settings", + setting_skin="Layout Settings", preview="Preview", - keyboard="Keyboard",joystick="Joystick", + keyboard="Keyboard",joystick="Controller", ctrlSetHelp="Arrowkey to select/change slot,Enter to change,Esc back", musicRoom="Music Room", nowPlaying="Now Playing:", + page="Page:", - settingSaved="Setting Saved", - settingSavingError="Failed to save setting:", - keyMapSaved="Key setting saved", - keyMapSavingError="Failed to save key setting:", - VKSaved="virtual key saved", + settingSaved="Settings Saved", + settingSavingError="Failed to save settings:", + keyMapSaved="Key settings saved", + keyMapSavingError="Failed to save key settings:", + VKSaved="virtual keys saved", VKSavingError="Failed to save virtual key:", statSavingError="Failed to save stat:", unlockSavingError="Failed to save unlock:", recSavingError="Failed to save record:", needRestart="Effective after restart", - copySuccess="Copy Success", - dataCorrupted="Data Corrupted", - VKTchW="Touch weight", - VKOrgW="Origion weight", - VKCurW="CurPos weight", - noScore="No Score Yet", - highScore="Highscore", - newRecord="New Record", - errorMsg="Techmino ran into a problem and needs to restart.\nWe collected some error info, and you can send them to the author.", + copySuccess="Copied successfully", + dataCorrupted="Data corrupted", + VKTchW="Touch Weight", + VKOrgW="Origion Weight", + VKCurW="Cur. Pos. Weight", + noScore="No Scores Yet", + highScore="Personal Bests", + newRecord="New Record!", + errorMsg="An error has occurred and Techmino needs to restart.\nError info has been created, and you can send it to the author.", acts={ "Move Left:","Move Right:", "Rotate Right:","Rotate Left:","Rotate 180°:", "Hard Drop:","Soft Drop:","Hold:","Function:","Restart:", "Instant Left:","Instant Right:","Ins Down:","Down 1:","Down 4:","Down 10:", - "Left Drop:","Right Drop:","Left INS:","Right INS:", + "Left Drop:","Right Drop:","Left Zangi:","Right Zangi:", }, - load={[0]="Finished","Loading VOICE","Loading BGM","Loading SFX","Loading images","Loading modes","Loading other things"}, + load={[0]="Finished","Loading voice","Loading BGM","Loading SFX","Loading images","Loading modes","Loading other things"}, pauseStat={ "Time:", - "Key/Rotate/Hold:", + "Key/Rot./Hold:", "Piece:", "Row/Dig:", "Attack/DigAtk:", - "Receive:", - "Clear:", - "Spin:", + "Received:", + "Clears:", + "Spins:", "B2B/B3B/PC/HPC:", "Finesse:", }, @@ -939,46 +941,38 @@ local langList={ "DPM", }, stat={ - spin="spin0~3", - clear="clear1~4", - "Game Runned:", - "Game Played:", - "Game Time:", - "Key/Rotate/Hold:", + spin="spins 0-3", + clear="clears 1-4", + "Times Launched:", + "Play Count:", + "Play Time:", + "Key/Rot./Hold:", "Block/Row/Atk.:", "Recv./Res./Asc.:", "Dig/Dig Atk.:", "Eff./Dig Eff.:", - "Finesse Err./Rate:", + "Finesse Errs./Rate:", "B2B/B3B:", "PC/HPC:", }, help={ - "I don't think you need \"help\".", - "THIS IS ONLY A BLOCK GAME,not T****s", - "But just play like playing TO/C2/KOS/TGM3", + "Doesn't this seem to be of \"any help\", right?", + "This is just an ordinary block game, not a certain one.", + "It plays like TO/C2/KOS/TGM3 and others.", "", - "Powered by LOVE2D", - "Author:MrZ E-mail:1046101471@qq.com", - "Program:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:MrZ/Miya", - "Special thanks:Flyz,Farter,196,Teatube,[all test staff] and YOU!", + "Made with LOVE2D", + "Author: MrZ E-mail: 1046101471@qq.com", + "Program: MrZ Art: MrZ Music: MrZ SFX: MrZ Voice: MrZ/Miya", + "Special thanks to Flyz, Farter, 196, Teatube, [all testers] and you!", "", - "Any bugs/suggestions to my E-mail.(may with screenshot)", - "Only released in discord.gg/f9pUvkh for FREE", - "Game downloaded from other way may implanted with virus", - "Only network/vibrating permission applied", - "Author is not responsible for any loss by edited game", + "bug reports/suggestions, sent to the author's testing group or email ~", + "This is a free download available only through discord.gg/f9pUvkh", + "The game downloaded from other sources may contain viruses,", + "and only vibration & networking permissions are needed for mobile versions!", + "The author is not responsible for any losses from modifying the game.", }, - used=[[ - Tool used: - Beepbox - GFIE - Goldwave - Lib used: - Cold_Clear[MinusKelvin] - simple-love-lights[dylhunn] - ]], - support="Support Author", + used="Tool used:\n\tBeepbox\n\tGFIE\n\tGoldwave\nLib used:\n\tCold_Clear[MinusKelvin]\n\tsimple-love-lights[dylhunn]", + support="Support author", group="Official QQ Group(if not hacked):822023725", WidgetText={ main={ @@ -987,13 +981,13 @@ local langList={ music="Music room", stat="Statistics", help="Help", - qplay="qPlay", + qplay="Q. Play", lang="言/A", - quit="Quit", + quit="Exit", }, mode={ - draw="Draw(Q)", - custom="Setting(E)", + draw="Draw (Q)", + custom="Settings (E)", start="Start", back="Back", }, @@ -1009,11 +1003,11 @@ local langList={ down="↓", left="←", right="→", - set1="40L(1)", - set2="1v1(2)", - set3="infinite(3)", - set4="blind(4)", - set5="master(5)", + set1="40L (1)", + set2="1v1 (2)", + set3="Inf. (3)", + set4="Blind (4)", + set5="Master (5)", back="Back", }, draw={ @@ -1029,61 +1023,62 @@ local langList={ pause="Pause", }, pause={ - resume="Resume(space)", - restart="Restart(R)", - setting="Setting(S)", - quit="Quit(esc)", + resume="Resume (esc)", + restart="Retry (R)", + setting="Settings (S)", + quit="Quit (Q)", }, setting_game={ - graphic="←Graphic", + graphic="←Video", sound="Sound→", - ctrl="Control setting", - reTime="Delay before game", - maxNext="Max next count", + ctrl="Control settings", + reTime="Start Delay", + maxNext="Next Queue Length", autoPause="Auto pause", layout="Layout", - key="Key Setting", - touch="Touch Setting", - quickR="Quick restart", - autoPause="Auto pause", - swap="Combo key to change ATK mode", - fine="Finesse error SFX", + key="Key Mappings", + touch="Touch Settings", + quickR="Quick Retry", + swap="Key Combination (Change Atk. Mode)", + fine="Finesse Error Sound", back="Back", }, - setting_graphic={ + setting_video={ sound="←Sound", game="Game→", ghost="Ghost", smooth="Smooth drop", center="Center", grid="Grid", - bagLine="Bag-line", - bg="Background", + bagLine="Bag line", lockFX="Lock FX level", dropFX="Drop FX level", - shakeFX="Shake FX level", - atkFX="ATK FX level", - text="Clear text", - fullscreen="Fullscreen", - frame="draw FPS", + clearFX="Clear FX level", + shakeFX="Field Sway level", + atkFX="ATK. FX level", + frame="Render Frame Rate", + text="Action Text", + fullscreen="Full Screen", + bg="Background", + power="Power Info.", back="Back", }, setting_sound={ game="←Game", - graphic="Graphic→", + graphic="Video→", sfx="SFX", bgm="BGM", vib="Vibration", - voc="Vocal", + voc="Voice", stereo="Stereo", back="Back", }, setting_control={ das="DAS",arr="ARR", - sddas="softdrop DAS",sdarr="softdrop ARR", + sddas="Soft Drop DAS",sdarr="Soft Drop ARR", ihs="Initial Hold", - irs="Initial Rotate", - ims="Initial Move", + irs="Initial Rotation", + ims="Initial Movement", reset="Reset", back="Back", }, @@ -1104,9 +1099,9 @@ local langList={ back="Back", }, setting_touch={ - default="Defaults", + default="Default", snap=function()return text.snapLevelName[sceneTemp.snap]end, - option="Option", + option="Options", back="Back", size="Size", }, @@ -1115,7 +1110,7 @@ local langList={ b5= "Rotate 180°:", b6="Hard Drop:", b7="Soft Drop:", b8="Hold:", b9= "Function:", b10="Restart:", b11="Instant Left:",b12="Instant Right:", b13="Ins Down:", b14="Down 1:", b15="Down 4:", b16="Down 10:", - b17="Left Drop:", b18="Right Drop:", b19="Left INS:", b20="Right INS:", + b17="Left Drop:", b18="Right Drop:", b19="Left Zangi:", b20="Right Zangi:", norm="Normal", pro="Professioanl", hide="Show Virtual Key", @@ -1123,7 +1118,7 @@ local langList={ sfx="SFX", vib="VIB", icon="Icon", - tkset="Track setting", + tkset="Track Settings", alpha="Alpha", back="Back", }, @@ -1131,6 +1126,9 @@ local langList={ VKDodge="Auto Dodge", back="Back", }, + setting_lang={ + back="Back", + },--langName added later help={ his="History", qq="Author's qq", @@ -1147,84 +1145,523 @@ local langList={ }, }, modes={ - {"Sprint", "10L", "Clear 10 lines"}, - {"Sprint", "20L", "Clear 20 lines"}, - {"Sprint", "40L", "Clear 40 lines"}, - {"Sprint", "100L", "Clear 100 lines"}, - {"Sprint", "400L", "Clear 400 lines"}, - {"Sprint", "1000L", "Clear 1000 lines"}, - {"Drought", "100L", "No I piece"}, + {"Sprint", "10L", "Clear 10 lines!"}, + {"Sprint", "20L", "Clear 20 lines!"}, + {"Sprint", "40L", "Clear 40 lines!"}, + {"Sprint", "100L", "Clear 100 lines!"}, + {"Sprint", "400L", "Clear 400 lines!"}, + {"Sprint", "1000L", "Clear 1000 lines!"}, + {"Drought", "100L", "No I piece!"}, {"Drought", "100L", "WTF"}, - {"Marathon", "NORMAL", "200L marathon with acceleration"}, - {"Marathon", "HARD", "200L marathon in high speed"}, - {"Battle", "EASY", "Beat AI"}, - {"Battle", "NORMAL", "Beat AI"}, - {"Battle", "HARD", "Beat AI"}, - {"Battle", "LUNATIC", "Beat AI"}, - {"Battle", "ULTIMATE", "Beat AI"}, - {"Tech 49", "EASY", "49P Melee Fight"}, - {"Tech 49", "HARD", "49P Melee Fight"}, - {"Tech 49", "ULTIMATE", "49P Melee Fight"}, - {"Tech 99", "EASY", "99P Melee Fight"}, - {"Tech 99", "HARD", "99P Melee Fight"}, - {"Tech 99", "ULTIMATE", "99P Melee Fight"}, - {"Turn-Based", "EASY", "Chess?"}, - {"Turn-Based", "NORMAL", "Chess?"}, - {"Turn-Based", "HARD", "Chess?"}, - {"Turn-Based", "LUNATIC", "Chess?"}, - {"Turn-Based", "ULTIMATE", "Chess?"}, - {"Master", "LUNATIC", "20G:Beginner"}, - {"Master", "ULTIMATE", "20G:Pro"}, - {"Master", "FINAL", "20G:Unreachable destination"}, + {"Marathon", "NORMAL", "200-line marathon with accelerating speed."}, + {"Marathon", "HARD", "200-line high-speed marathon."}, + {"Battle", "EASY", "Defeat the AI!"}, + {"Battle", "NORMAL", "Defeat the AI!"}, + {"Battle", "HARD", "Defeat the AI!"}, + {"Battle", "LUNATIC", "Defeat the AI!"}, + {"Battle", "ULTIMATE", "Defeat the AI!"}, + {"Tech 49", "EASY", "49-player battle.\nThe last one standing wins."}, + {"Tech 49", "HARD", "49-player battle.\nThe last one standing wins."}, + {"Tech 49", "ULTIMATE", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "EASY", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "HARD", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "ULTIMATE", "49-player battle.\nThe last one standing wins."}, + {"Turn-Based", "EASY", "Chess mode"}, + {"Turn-Based", "NORMAL", "Chess mode"}, + {"Turn-Based", "HARD", "Chess mode"}, + {"Turn-Based", "LUNATIC", "Chess mode"}, + {"Turn-Based", "ULTIMATE", "Chess mode"}, + {"Master", "LUNATIC", "20G: For beginners."}, + {"Master", "ULTIMATE", "20G: Professional challenge!"}, + {"Master", "FINAL", "20G: Unreachable end point!"}, {"GrandMaster", "GM", "To be Grand Master"}, - {"Blind", "HALF", "Invisible board"}, - {"Blind", "ALL", "Invisible board"}, - {"Blind", "SUDDEN", "Invisible board"}, - {"Blind", "SUDDEN+", "Invisible board"}, - {"Blind", "NOTHING", "Invisible board"}, - {"Classic", "CTWC", "Fast & Slow"}, - {"Survivor", "EASY", "Survive Longer!"}, - {"Survivor", "NORMAL", "Survive Longer!"}, - {"Survivor", "HARD", "Survive Longer!"}, - {"Survivor", "LUNATIC", "Survive Longer!"}, - {"Survivor", "ULTIMATE", "Survive Longer!"}, - {"Attacker", "HARD", "Attacking better then defending"}, - {"Attacker", "ULTIMATE", "Attacking better then defending"}, - {"Defender", "NORMAL", "Hand them!"}, - {"Defender", "LUNATIC", "Hand them!"}, - {"Driller", "HARD", "Downstack!"}, - {"Driller", "ULTIMATE", "Downstack!"}, - {"Big Bang", "EASY", "All-spin Tutorial!\nUnder Construction"}, - {"C4W Train", "NORMAL", "Infinite Combo"}, - {"C4W Train", "LUNATIC", "Infinite Combo"}, - {"PC Training", "NORMAL", "Let's learn some PCs"}, - {"PC Training", "LUNATIC", "Let's learn some PCs"}, - {"PC Challenge", "NORMAL", "More PCs in 100L"}, - {"PC Challenge", "HARD", "More PCs in 100L"}, - {"PC Challenge", "LUNATIC", "More PCs in 100L"}, - {"Tech", "NORMAL", "Keep B2B"}, + {"Blind", "HALF", "For novice players."}, + {"Blind", "ALL", "For intermediate players."}, + {"Blind", "SUDDEN", "For experienced players."}, + {"Blind", "SUDDEN+", "For professionals."}, + {"Blind", "NOTHING", "For masters."}, + {"Classic", "CTWC", "High-speed classic mode."}, + {"Survivor", "EASY", "How long can you survive?"}, + {"Survivor", "NORMAL", "How long can you survive?"}, + {"Survivor", "HARD", "How long can you survive?"}, + {"Survivor", "LUNATIC", "How long can you survive?"}, + {"Survivor", "ULTIMATE", "How long can you survive?"}, + {"Attacker", "HARD", "Offensive practice!"}, + {"Attacker", "ULTIMATE", "Offensive practice!"}, + {"Defender", "NORMAL", "Defensive practice!"}, + {"Defender", "LUNATIC", "Defensive practice!"}, + {"Driller", "HARD", "Digging practice!"}, + {"Driller", "ULTIMATE", "Digging practice!"}, + {"Big Bang", "EASY", "All-spin tutorial!\n[Under construction]"}, + {"C4W Training", "NORMAL", "Infinite combos."}, + {"C4W Training", "LUNATIC", "Infinite combos."}, + {"PC Training", "NORMAL", "Simple Perfect Clear mode."}, + {"PC Training", "LUNATIC", "Simple Perfect Clear mode."}, + {"PC Challenge", "NORMAL", "Get PCs within 100 lines!"}, + {"PC Challenge", "HARD", "Get PCs within 100 lines!"}, + {"PC Challenge", "LUNATIC", "Get PCs within 100 lines!"}, + {"Tech", "NORMAL", "Keep the B2B chain!"}, {"Tech", "NORMAL+", "Spin & PC only"}, - {"Tech", "HARD", "Keep B2B"}, + {"Tech", "HARD", "Keep the B2B chain!"}, {"Tech", "HARD+", "Spin & PC only"}, - {"Tech", "LUNATIC", "No normal clear"}, + {"Tech", "LUNATIC", "Keep the B2B chain!"}, {"Tech", "LUNATIC+", "Spin & PC only"}, - {"Tech", "ULTIMATE", "No normal clear, no finesse fault"}, - {"Tech", "ULTIMATE+", "Spin & PC only, no finesse fault"}, - {"TSD Challenge", "EASY", "T-spin-doubles only"}, - {"TSD Challenge", "HARD", "T-spin-doubles only"}, - {"TSD Challenge", "ULTIMATE", "T-spin-doubles only"}, - {"Zen", "", "200 lines without any limits"}, - {"Ultra", "EXTRA", "Score attack in 120s"}, - {"Infinite", "", "Sandbox"}, - {"Infinite: Dig", "", "Dig to Nether?"}, + {"Tech", "ULTIMATE", "No finesse faults!"}, + {"Tech", "ULTIMATE+", "No normal clears, no finesse faults!"}, + {"TSD Challenge", "EASY", "T-spin-doubles only!"}, + {"TSD Challenge", "HARD", "T-spin-doubles only!"}, + {"TSD Challenge", "ULTIMATE", "T-spin-doubles only!"}, + {"Zen", "", "200 lines without a time limit."}, + {"Ultra", "EXTRA", "Get the highest score within 2 min."}, + {"Infinite", "", "Sandbox mode."}, + {"Infinite: Dig", "", "Dig, dig, dig."}, {"Custom", "NORMAL", "Draw something then clear it!!"}, {"Custom", "PUZZLE", "Draw something then stack it!!"}, - {"Multiplayer", "2P", "Offline Mutiplayer Gaming"}, - {"Multiplayer", "3P", "Offline Mutiplayer Gaming"}, - {"Multiplayer", "4P", "Offline Mutiplayer Gaming"}, + {"Sprint", "Pentomino", "???"}, + }, + }, + { + anykey="↓□↓", + newVersion="!!!!!!!!!!!!!!!!!!!", + marking="Author:MrZ_26\nIllegal recording if u see this", + lang="?????", + atkModeName={"?","( )","!","←→"}, + royale_remain=function(n)return n.."~"end, + cmb={nil,"!","!!","!!!","!!!!","!!!!!","!!!!!!","!!!!!!!","!!!!!!!!","!!!!!!!!!","!!!!!!!!!!","!!!!!!!!!!!","!!!!!!!!!!!!","!!!!!!!!!!!!!","!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!!",}, + block=nil,spin=" ~", + clear={"1","2","3","4","5"}, + mini="v",b2b="^ ",b3b="^^ ", + PC="#<>#",HPC="<>", + hold="[ ]",next="→", + + stage=function(n)return"::"..n.."::"end, + great="!~", + awesome="!!~", + continue="~~", + maxspeed="!!!", + speedup="~!~", + + win=": )", + finish="&", + lose="x", + pause="=", + pauseCount="=:", + + custom="!@#$%^&*", + customOption={ + drop="↓:", + lock="↓_:", + wait="→=:", + fall="↓=:", + next="→:", + hold="[ ]:", + sequence="$=:", + visible="?=:", + target="&=:", + freshLimit="@:", + opponent="^_^:", + bg="{~}:", + bgm="(~):", + }, + customVal={ + drop={"0G","1/180G","1/60G","1/40G","1/30G","1/25G","1/20G","1/18G","1/16G","1/14G","1/12G","1/10G","1/9G","1/8G","1/7G","1/6G","1/5G","1/4G","1/3G","1/2G","1G","2G","4G","8G","20G"}, + lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,"Inf"}, + wait=nil, + fall=nil, + next=nil, + hold={"+","-","~"}, + sequence={"(xxx)","[...]","???"}, + visible={"=","-","_","."}, + target={10,20,40,100,200,500,1000,"x"}, + freshLimit={0,8,15,"~"}, + opponent={"x","9S Lv1","9S Lv2","9S Lv3","9S Lv4","9S Lv5","CC Lv1","CC Lv2","CC Lv3","CC Lv4","CC Lv5","CC Lv6"}, + }, + snapLevelName={"~","10","20","40","60","80"}, + setting_game="%~~%", + setting_video="{~~}", + setting_sound="(~~)", + setting_control="[~~]", + setting_skin="%{~~}", + preview="?:", + keyboard="[##]",joystick="^-^", + ctrlSetHelp="......", + musicRoom="(~~~~)", + nowPlaying="~:", + page=":", + + settingSaved="~~~", + settingSavingError="x!:", + keyMapSaved="~~~", + keyMapSavingError="x!:", + VKSaved="~~~", + VKSavingError="x!:", + statSavingError="x!:", + unlockSavingError="x!:", + recSavingError="x!:", + + needRestart="!!*#R#*!!", + copySuccess="~$~", + dataCorrupted="XXXXX", + VKTchW="Tch↓", + VKOrgW="Org↓", + VKCurW="Cur↓", + noScore="?_____?", + highScore="__&:", + newRecord="^!!!^", + errorMsg="An e??o? h@s occ^__ed @nd Techmino n__ds to r_st@rt.\n&**o* in#o h@$ b==n cre@ted, @nd y0u c@n $&nd it to the @uth0r.", + + acts={ + "←:","→:", + "R→:","←R:","R↑↓:", + "↓↓:","↓:","□←:","F:","R:", + "|←:","→|:","↓_:","↓1:","↓4:","↓10:", + "←↓→↓:","→↓↓:","←↓→↓:","→↓←↓:", + }, + load={[0]="___","_vocie_","_BGM_","_SFX_","_images_","_modes_","_???_"}, + pauseStat={ + "~:", + "=/''/[ ]:", + "□:", + "-/↓:", + "→/↓→:", + "←:", + "□↓:", + "~↓:", + "^^/^^^/#<>#/<>:", + "!#!X:", + }, + radar={"DEF","OFF","ATK","SEND","SPD","DIG"}, + radarData={ + "D'PM", + "OPM", + "APM", + "SPM", + "L'PM", + "DPM", + }, + stat={ + spin="~0-3", + clear="□1-4", + "@:", + "##:", + "~:", + "=/''/[ ]:", + "□/-/→.:", + "←/-↓/↑:", + "↓/↓→.:", + "^%/↓^%:", + "!#!X/%:", + "^/^^:", + "#<>#/<>:", + }, + help={ + "?↓↓↓?? ?", + "□!!~~~,□□□□X", + "□!!==*/*/*/*~", + "", + "Made with LOVE2D", + "Author: MrZ E-mail: 1046101471@qq.com", + "Program: MrZ Art: MrZ Music: MrZ SFX: MrZ Voice: MrZ/Miya", + "Special thanks to Flyz, Farter, 196, Teatube, [all testers] and you!", + "", + "bug reports/suggestions, sent to the author's testing group or email ~", + "This is a free download available only through discord.gg/f9pUvkh", + "The game downloaded from other sources may contain viruses,", + "and only vibration & networking permissions are needed for mobile versions!", + "The author is not responsible for any losses from modifying the game.", + }, + used="Tool used:\n\tBeepbox\n\tGFIE\n\tGoldwave\nLib used:\n\tCold_Clear[MinusKelvin]\n\tsimple-love-lights[dylhunn]", + support="Support author", + group="Official QQ Group(if not hacked):822023725", + WidgetText={ + main={ + play="!!!", + setting="_?_", + music="~~~", + stat="=___", + help="???", + qplay="!", + lang="言/A", + quit="X", + }, + mode={ + draw="ABC (Q)", + custom="_?_ (E)", + start="!!!", + back="X", + }, + music={ + bgm="#~#", + up="↑", + play="!!!", + down="↓", + back="X", + }, + custom={ + up="↑", + down="↓", + left="←", + right="→", + set1="40L (1)", + set2="1v1 (2)", + set3="Inf. (3)", + set4="Blind (4)", + set5="Master (5)", + back="X", + }, + draw={ + any="_", + space="×", + clear="XXX", + demo="X ×", + copy="→__", + paste="__→", + back="X", + }, + play={ + pause="||", + }, + pause={ + resume="!! (esc)", + restart="_→_ (R)", + setting="_?_ (S)", + quit="X (Q)", + }, + setting_game={ + graphic="←Video", + sound="Sound→", + ctrl="=?=", + reTime="3-2-1", + maxNext="=123", + autoPause="A||", + layout="=-=-=", + key="=?", + touch="_?", + quickR="R!", + swap="=+=+=", + fine="!#!X #!#", + back="X", + }, + setting_video={ + sound="←Sound", + game="Game→", + ghost="__↓__", + smooth="~~↓~~", + center="+", + grid="#", + bagLine="123|123", + lockFX="↓_~", + dropFX="↓~", + clearFX="↓↓↓~", + shakeFX="~|~|~", + atkFX="→→~", + frame="|=|", + text="ABC", + fullscreen="|←→|", + bg="__?__", + power="+.", + back="X", + }, + setting_sound={ + game="←Game", + graphic="Video→", + sfx="#!#", + bgm="#~#", + vib="=~=", + voc="~~~", + stereo="←~→", + back="X", + }, + setting_control={ + das="x---x x x",arr="x x-x-x", + sddas="↓---↓ ↓ ↓",sdarr="↓ ↓-↓-↓", + ihs="![ ]", + irs="!''", + ims="!←→", + reset="R", + back="X", + }, + setting_key={ + back="X", + }, + setting_skin={ + prev="←",next="→", + prev1="↑",next1="↓",spin1="R", + prev2="↑",next2="↓",spin2="R", + prev3="↑",next3="↓",spin3="R", + prev4="↑",next4="↓",spin4="R", + prev5="↑",next5="↓",spin5="R", + prev6="↑",next6="↓",spin6="R", + prev7="↑",next7="↓",spin7="R", + skinR="R @%&", + faceR="R ↑↓←→.", + back="X", + }, + setting_touch={ + default="$0", + snap=function()return text.snapLevelName[sceneTemp.snap]end, + option="_?", + back="X", + size="←→", + }, + setting_touchSwitch={ + b1= "←:", b2="→:", b3="R→:", b4="←R:", + b5= "R↑↓:", b6="↓↓:", b7="↓:", b8="□←:", + b9= "F:", b10="R:", b11="←←:", b12="→→:", + b13="↓_:", b14="↓1:", b15="↓4:", b16="↓10:", + b17="←↓→↓:", b18="→↓↓:", b19="←↓→↓:",b20="→↓←↓:", + norm="-", + pro="+", + hide="--?", + track="~=?", + sfx="#!#", + vib="=~=", + icon="@?", + tkset="_~=_", + alpha="+?", + back="X", + }, + setting_trackSetting={ + VKDodge="←_→", + back="X", + }, + setting_lang={ + back="X", + },--langName added later + help={ + his="_&_", + qq="_@_", + back="X", + }, + history={ + prev="↑", + next="↓", + back="X", + }, + stat={ + path="_$_", + back="X", + }, + }, + modes={ + {"Sprint", "10L", "Clear 10 lines!"}, + {"Sprint", "20L", "Clear 20 lines!"}, + {"Sprint", "40L", "Clear 40 lines!"}, + {"Sprint", "100L", "Clear 100 lines!"}, + {"Sprint", "400L", "Clear 400 lines!"}, + {"Sprint", "1000L", "Clear 1000 lines!"}, + {"Drought", "100L", "No I piece!"}, + {"Drought", "100L", "WTF"}, + {"Marathon", "NORMAL", "200-line marathon with accelerating speed."}, + {"Marathon", "HARD", "200-line high-speed marathon."}, + {"Battle", "EASY", "Defeat the AI!"}, + {"Battle", "NORMAL", "Defeat the AI!"}, + {"Battle", "HARD", "Defeat the AI!"}, + {"Battle", "LUNATIC", "Defeat the AI!"}, + {"Battle", "ULTIMATE", "Defeat the AI!"}, + {"Tech 49", "EASY", "49-player battle.\nThe last one standing wins."}, + {"Tech 49", "HARD", "49-player battle.\nThe last one standing wins."}, + {"Tech 49", "ULTIMATE", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "EASY", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "HARD", "49-player battle.\nThe last one standing wins."}, + {"Tech 99", "ULTIMATE", "49-player battle.\nThe last one standing wins."}, + {"Turn-Based", "EASY", "Chess mode"}, + {"Turn-Based", "NORMAL", "Chess mode"}, + {"Turn-Based", "HARD", "Chess mode"}, + {"Turn-Based", "LUNATIC", "Chess mode"}, + {"Turn-Based", "ULTIMATE", "Chess mode"}, + {"Master", "LUNATIC", "20G: For beginners."}, + {"Master", "ULTIMATE", "20G: Professional challenge!"}, + {"Master", "FINAL", "20G: Unreachable end point!"}, + {"GrandMaster", "GM", "To be Grand Master"}, + {"Blind", "HALF", "For novice players."}, + {"Blind", "ALL", "For intermediate players."}, + {"Blind", "SUDDEN", "For experienced players."}, + {"Blind", "SUDDEN+", "For professionals."}, + {"Blind", "NOTHING", "For masters."}, + {"Classic", "CTWC", "High-speed classic mode."}, + {"Survivor", "EASY", "How long can you survive?"}, + {"Survivor", "NORMAL", "How long can you survive?"}, + {"Survivor", "HARD", "How long can you survive?"}, + {"Survivor", "LUNATIC", "How long can you survive?"}, + {"Survivor", "ULTIMATE", "How long can you survive?"}, + {"Attacker", "HARD", "Offensive practice!"}, + {"Attacker", "ULTIMATE", "Offensive practice!"}, + {"Defender", "NORMAL", "Defensive practice!"}, + {"Defender", "LUNATIC", "Defensive practice!"}, + {"Driller", "HARD", "Digging practice!"}, + {"Driller", "ULTIMATE", "Digging practice!"}, + {"Big Bang", "EASY", "All-spin tutorial!\n[Under construction]"}, + {"C4W Training", "NORMAL", "Infinite combos."}, + {"C4W Training", "LUNATIC", "Infinite combos."}, + {"PC Training", "NORMAL", "Simple Perfect Clear mode."}, + {"PC Training", "LUNATIC", "Simple Perfect Clear mode."}, + {"PC Challenge", "NORMAL", "Get PCs within 100 lines!"}, + {"PC Challenge", "HARD", "Get PCs within 100 lines!"}, + {"PC Challenge", "LUNATIC", "Get PCs within 100 lines!"}, + {"Tech", "NORMAL", "Keep the B2B chain!"}, + {"Tech", "NORMAL+", "Spin & PC only"}, + {"Tech", "HARD", "Keep the B2B chain!"}, + {"Tech", "HARD+", "Spin & PC only"}, + {"Tech", "LUNATIC", "Keep the B2B chain!"}, + {"Tech", "LUNATIC+", "Spin & PC only"}, + {"Tech", "ULTIMATE", "No finesse faults!"}, + {"Tech", "ULTIMATE+", "No normal clears, no finesse faults!"}, + {"TSD Challenge", "EASY", "T-spin-doubles only!"}, + {"TSD Challenge", "HARD", "T-spin-doubles only!"}, + {"TSD Challenge", "ULTIMATE", "T-spin-doubles only!"}, + {"Zen", "", "200 lines without a time limit."}, + {"Ultra", "EXTRA", "Get the highest score within 2 min."}, + {"Infinite", "", "Sandbox mode."}, + {"Infinite: Dig", "", "Dig, dig, dig."}, + {"Custom", "NORMAL", "Draw something then clear it!!"}, + {"Custom", "PUZZLE", "Draw something then stack it!!"}, + {"Sprint", "Pentomino", "???"}, }, }, } +local publicText={ + block={ + "Z","S","J","L","T","O","I", + "Z5","S5","Q","P","F","E", + "T5","U","V","W","X", + "J5","L5","R","Y","N","H","I5" + }, +} +for key,list in next,publicText do + for i=1,#langList do + if langList[i][key]then + local L=langList[i][key] + for k,v in next,list do + L[k]=v + end + else + langList[i][key]=list + end + end +end +local publicWidgetText={ + setting_lang={ + chi="中文", + chi2="全中文", + eng="English", + str="?????", + }, +} +for key,list in next,publicWidgetText do + for i=1,#langList do + local WT=langList[i].WidgetText + if WT[key]then + local L=WT[key] + for k,v in next,list do + L[k]=v + end + else + WT[key]=list + end + end +end + local gc=love.graphics local LANG={} local drawableTextLoad={ @@ -1233,7 +1670,7 @@ local drawableTextLoad={ "win","finish","lose","pause", "custom", "setting_game", - "setting_graphic", + "setting_video", "setting_sound", "setting_sound", "setting_control", @@ -1251,24 +1688,11 @@ function LANG.getLen() end function LANG.set(l) text=langList[l] - for S,L in next,Widget do + for S,L in next,widgetList do for N,W in next,L do W.text=text.WidgetText[S][N] end end - gc.push("transform") - gc.origin() - royaleCtrlPad=gc.newCanvas(300,100) - gc.setCanvas(royaleCtrlPad) - gc.setColor(1,1,1) - setFont(20) - gc.setLineWidth(2) - for i=1,4 do - gc.rectangle("line",RCPB[2*i-1],RCPB[2*i],90,35,8,4) - mStr(text.atkModeName[i],RCPB[2*i-1]+45,RCPB[2*i]+3) - end - gc.pop() - gc.setCanvas() for _,s in next,drawableTextLoad do drawableText[s]:set(text[s]) end diff --git a/parts/light.lua b/parts/light.lua index e4c6f739..18393192 100644 --- a/parts/light.lua +++ b/parts/light.lua @@ -1,8 +1,6 @@ -do return end --LIGHT MODULE(Optimized by MrZ,Original on github/love2d community/simple-love-lights) --Heavily based on mattdesl's libGDX implementation: --https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows ---Private-- local gc=love.graphics local C=gc.clear local shadowMapShader=gc.newShader("shader/shadowMap.cs")--Shader for caculating the 1D shadow map. @@ -20,62 +18,72 @@ local function destroy(L) L.renderCanvas:release() end local function draw(L) + --Initialization local r,g,b,a=love.graphics.getColor() gc.setCanvas(L.blackCanvas)C() gc.setCanvas(L.shadowCanvas)C() gc.setCanvas(L.renderCanvas)C() lightRenderShader:send("xresolution",L.size); shadowMapShader:send("yresolution",L.size); - --初始化数据 + + --get up-left of light local X=L.x-L.size*.5 local Y=L.y-L.size*.5 - --整束光的左上角 + + --Render solid gc.translate(-X,-Y) L.blackCanvas:renderTo(L.blackFn) gc.translate(X,Y) - --渲染遮光物 + + --Render shade canvas by solid gc.setShader(shadowMapShader) gc.setCanvas(L.shadowCanvas) gc.draw(L.blackCanvas) - --根据遮光物渲染阴影画布 + + --Render light canvas by shade gc.setShader(lightRenderShader) gc.setCanvas(L.renderCanvas) gc.draw(L.shadowCanvas,0,0,0,1,L.size) - --根据阴影画布渲染光画布 + + --Ready to final render gc.setShader()gc.setCanvas()gc.setBlendMode("add") - --准备渲染 + + --Render to screes gc.setColor(r,g,b,a) gc.draw(L.renderCanvas,X,Y+L.size,0,1,-1) - --渲染到屏幕 + + --Reset gc.setBlendMode("alpha") - --复位 end ---Public-- -function Lights.draw() + +local LIGHT={} +function LIGHT.draw() for i=1,#Lights do Lights[i]:draw() end end -function Lights.clear(L) +function LIGHT.clear(L) for i=#Lights,1,-1 do Lights[i]:destroy() Lights[i]=nil end end -function Lights.add(x,y,R,F) +function LIGHT.add(x,y,R,F) local id=#Lights+1 Lights[id]={ + --Methods id=id, x=x,y=y,size=R, - blackCanvas=gc.newCanvas(R,R),--遮挡物画布 - shadowCanvas=gc.newCanvas(R,1),--1D视深画布 - renderCanvas=gc.newCanvas(R,R),--灯光画布 - blackFn=F,--遮挡物绘图函数 - --方法 + blackCanvas=gc.newCanvas(R,R),--solid canvas + shadowCanvas=gc.newCanvas(R,1),--1D vis-depth canvas + renderCanvas=gc.newCanvas(R,R),--light canvas + blackFn=F,--solid draw funcion + + move=move, setPow=setPow, draw=draw, destroy=destroy, } end -return Lights \ No newline at end of file +return LIGHT \ No newline at end of file diff --git a/parts/list.lua b/parts/list.lua index ec646e74..21b1dbc5 100644 --- a/parts/list.lua +++ b/parts/list.lua @@ -1,31 +1,3 @@ -actName={ - "moveLeft","moveRight", - "rotRight","rotLeft","rot180", - "hardDrop","softDrop", - "hold","func", - "restart", - "insLeft","insRight","insDown","down1","down4","down10", - "dropLeft","dropRight","addLeft","addRight",--Super contorl system -} -musicID={ - "blank", - "way", - "race", - "newera", - "push", - "reason", - "infinite", - "secret7th", - "secret8th", - "shining terminal", - "oxygen", - "distortion", - "rockblock", - "cruelty", - "final", - "8-bit happiness", - "end", -} customID={ "drop","lock", "wait","fall", @@ -51,5 +23,4 @@ customRange={ bg={"none","game1","game2","game3","strap","rgb","glow","matrix"}, bgm={"blank","way","race","newera","push","reason","infinite","secret7th","secret8th","rockblock"}, } -RCPB={10,33,200,33,105,5,105,60} snapLevelValue={1,10,20,40,60,80} \ No newline at end of file diff --git a/parts/mino.lua b/parts/mino.lua index 77e0c865..2832fa4b 100644 --- a/parts/mino.lua +++ b/parts/mino.lua @@ -11,13 +11,34 @@ local function RotCW(B) end local O,_=true,false local L={ + --Tetramino {{_,O,O},{O,O,_}}, --Z {{O,O,_},{_,O,O}}, --S - {{O,O,O},{_,_,O}}, --L {{O,O,O},{O,_,_}}, --J + {{O,O,O},{_,_,O}}, --L {{O,O,O},{_,O,_}}, --T {{O,O},{O,O}}, --O {{O,O,O,O}}, --I + + --Pentomino + {{_,O,O},{_,O,_},{O,O,_}}, --Z + {{O,O,_},{_,O,_},{_,O,O}}, --S + {{O,O,O},{O,O,_}}, --P + {{O,O,O},{_,O,O}}, --Q + {{_,O,_},{O,O,O},{O,_,_}}, --F + {{_,O,_},{O,O,O},{_,_,O}}, --E + {{O,O,O},{_,O,_},{_,O,_}}, --T + {{O,O,O},{O,_,O}}, --U + {{O,O,O},{_,_,O},{_,_,O}}, --V + {{_,O,O},{O,O,_},{O,_,_}}, --W + {{_,O,_},{O,O,O},{_,O,_}}, --X + {{O,O,O,O},{O,_,_,_}}, --J + {{O,O,O,O},{_,_,_,O}}, --L + {{O,O,O,O},{_,O,_,_}}, --R + {{O,O,O,O},{_,_,O,_}}, --Y + {{_,O,O,O},{O,O,_,_}}, --N + {{O,O,O,_},{_,_,O,O}}, --H + {{O,O,O,O,O}}, --I } for i=1,#L do local B=L[i] diff --git a/parts/modes.lua b/parts/modes.lua index c7fee630..0bd79247 100644 --- a/parts/modes.lua +++ b/parts/modes.lua @@ -1,10 +1,10 @@ modes={ - {"sprint_10", id=1, x=0, y=0, size=35,shape=1,icon="timer", unlock={2,3}}, - {"sprint_20", id=2, x=-300, y=0, size=45,shape=1,icon="timer", unlock={73,74,75}}, - {"sprint_40", id=3, x=0, y=-400, size=55,shape=1,icon="timer", unlock={4,9,71,72}}, - {"sprint_100", id=4, x=-200, y=-400, size=45,shape=1,icon="timer", unlock={5,7}}, - {"sprint_400", id=5, x=-400, y=-400, size=35,shape=1,icon="timer", unlock={6}}, - {"sprint_1000", id=6, x=-600, y=-400, size=35,shape=1,icon="timer", unlock={}}, + {"sprint_10", id=1, x=0, y=0, size=35,shape=1,icon="sprint", unlock={2,3}}, + {"sprint_20", id=2, x=-300, y=0, size=45,shape=1,icon="sprint", unlock={}}, + {"sprint_40", id=3, x=0, y=-400, size=55,shape=1,icon="sprint", unlock={4,9,71,72,73}}, + {"sprint_100", id=4, x=-200, y=-400, size=45,shape=1,icon="sprint", unlock={5,7}}, + {"sprint_400", id=5, x=-400, y=-400, size=35,shape=1,icon="sprint", unlock={6}}, + {"sprint_1000", id=6, x=-600, y=-400, size=35,shape=1,icon="sprint", unlock={}}, {"drought_normal", id=7, x=-400, y=-200, size=35,shape=1,icon="noI", unlock={8}}, {"drought_lunatic", id=8, x=-600, y=-200, size=35,shape=1,icon="mess", unlock={}}, {"marathon_normal", id=9, x=0, y=-600, size=55,shape=1,icon="flag", unlock={10,11,22,31,36,37,48,67}}, @@ -39,7 +39,7 @@ modes={ {"blind_ultimate", id=35, x=150, y=-1100, size=35,shape=1,icon="blind", unlock={}}, {"classic_fast", id=36, x=-300, y=-1200, size=40,shape=2,icon="classic", unlock={}}, - + {"survivor_easy", id=37, x=300, y=-600, size=35,shape=1,icon="survivor",unlock={38}}, {"survivor_normal", id=38, x=500, y=-600, size=35,shape=1,icon="survivor",unlock={39,42,44,46}}, {"survivor_hard", id=39, x=700, y=-600, size=35,shape=1,icon="survivor",unlock={40}}, @@ -81,9 +81,7 @@ modes={ {"infinite_dig", id=70, x=-1100, y=-600, size=35,shape=1,icon="infinite_dig",unlock={}}, {"custom_clear", id=71, x=200, y=-350, size=45,shape=3,icon="custom", unlock={}}, {"custom_puzzle", id=72, x=200, y=-200, size=45,shape=3,icon="puzzle", unlock={}}, - {"hotseat_2P", id=73, x=-300, y=200, size=45,shape=3,icon="hotseat", unlock={}}, - {"hotseat_3P", id=74, x=-450, y=200, size=45,shape=3,icon="hotseat", unlock={}}, - {"hotseat_4P", id=75, x=-600, y=200, size=45,shape=3,icon="hotseat", unlock={}}, + {"sprintPenta", id=73, x=-200, y=-200, size=45,shape=3,icon="sprint", unlock={}}, } modeRanks={} for i=1,#modes do diff --git a/parts/sfx.lua b/parts/sfx.lua index 1f78fdef..cc682872 100644 --- a/parts/sfx.lua +++ b/parts/sfx.lua @@ -32,6 +32,9 @@ function SFX.loadAll() SFX.loadOne(i) end end +function SFX.fieldPlay(s,v,P) + SFX.play(s,v,(P.curX+P.sc[2]-6.5)*.15) +end function SFX.play(s,v,pos) if setting.sfx==0 then return end local S=SFX.list[s]--source list diff --git a/parts/spinCenters.lua b/parts/spinCenters.lua index 9d48875b..123cfbf0 100644 --- a/parts/spinCenters.lua +++ b/parts/spinCenters.lua @@ -1,12 +1,40 @@ -local TMP1,TMP2,TMP3,TMP4={1,2},{2,1},{2,2},{1.5,1.5} +local N1,N2={1,2},{2,1} +local N3,N4={2,2},{1.5,1.5} +local I1,I2={0.5,2.5},{2.5,0.5} +local I3,I4={1.5,2.5},{2.5,1.5} +local V4={2.5,2.5} +local L1,L2={1,3},{3,1} local scs={ - {[0]=TMP1,TMP2,TMP3,TMP3}, - {[0]=TMP1,TMP2,TMP3,TMP3}, - {[0]=TMP1,TMP2,TMP3,TMP3}, - {[0]=TMP1,TMP2,TMP3,TMP3}, - {[0]=TMP1,TMP2,TMP3,TMP3}, - {[0]=TMP4,TMP4,TMP4,TMP4}, - {[0]={0.5,2.5},{2.5,0.5},{1.5,2.5},{2.5,1.5}}, + --Tetramino + {[0]=N1,N2,N3,N3},--Z + {[0]=N1,N2,N3,N3},--S + {[0]=N1,N2,N3,N3},--L + {[0]=N1,N2,N3,N3},--J + {[0]=N1,N2,N3,N3},--T + {[0]=N4,N4,N4,N4},--O + {[0]=I1,I2,I3,I4},--I + + --Pentomino + {[0]=N3,N3,N3,N3},--Z + {[0]=N3,N3,N3,N3},--S + {[0]=N1,N2,N3,N3},--P + {[0]=N1,N2,N3,N3},--Q + {[0]=N3,N3,N3,N3},--F + {[0]=N3,N3,N3,N3},--E + {[0]=N3,N3,N3,N3},--T + {[0]=N1,N2,N3,N3},--U + {[0]=I3,N4,I4,V4},--V + {[0]=N3,N3,N3,N3},--W + {[0]=N3,N3,N3,N3},--X + {[0]=I3,I4,I3,I4},--J + {[0]=I3,I4,I3,I4},--L + {[0]=I3,I4,I3,I4},--R + {[0]=I3,I4,I3,I4},--Y + {[0]=I3,I4,I3,I4},--N + {[0]=I3,I4,I3,I4},--H + {[0]=L1,L2,L1,L2},--I } -TMP1,TMP2,TMP3,TMP4=nil +N1,N2,N3,N4=nil +I1,I2,I3,I4=nil +L1,L2=nil return scs \ No newline at end of file diff --git a/parts/voice.lua b/parts/voice.lua index e2b54765..ab8db2b0 100644 --- a/parts/voice.lua +++ b/parts/voice.lua @@ -85,30 +85,30 @@ end function VOC.update() for i=#voiceQueue,1,-1 do local Q=voiceQueue[i] - if Q.s==0 then--闲置轨,自动删除多余 + if Q.s==0 then--Free channel, auto delete when >3 if i>3 then rem(voiceQueue,i) end - elseif Q.s==1 then--等待转换 + elseif Q.s==1 then--Waiting load source Q[1]=getVoice(Q[1]) Q[1]:setVolume(setting.voc*.1) Q[1]:play() Q.s=Q[2]and 2 or 4 - elseif Q.s==2 then--播放1,准备2 + elseif Q.s==2 then--playing 1,ready 2 if Q[1]:getDuration()-Q[1]:tell()<.08 then Q[2]=getVoice(Q[2]) Q[2]:setVolume(setting.voc*.1) Q[2]:play() Q.s=3 end - elseif Q.s==3 then--12同时播放 + elseif Q.s==3 then--playing 12 same time if not Q[1]:isPlaying()then for i=1,#Q do Q[i]=Q[i+1] end Q.s=Q[2]and 2 or 4 end - elseif Q.s==4 then--最后播放 + elseif Q.s==4 then--playing last if not Q[1].isPlaying(Q[1])then Q[1]=nil Q.s=0 @@ -121,12 +121,13 @@ function VOC.play(s,chn) if chn then local L=voiceQueue[chn] local _=VOC.list[s] + if not _ then print("no VOC called:"..s)return end L[#L+1]=_[rnd(#_)] L.s=1 - --添加到queue[chn] + --add to queue[chn] else voiceQueue[VOC.getFreeChannel()]={s=1,VOC.list[s][rnd(#VOC.list[s])]} - --自动创建空轨/播放 + --create new channel & play end end end diff --git a/parts/widget.lua b/parts/widget.lua index f569033b..b95eac3d 100644 --- a/parts/widget.lua +++ b/parts/widget.lua @@ -1,21 +1,14 @@ local gc=love.graphics +local kb=love.keyboard +local int=math.floor local format=string.format +local next=next +local EMPTY={} local button={ type="button", ATV=0,--activating time(0~8) } -function newButton(x,y,w,h,color,font,code,hide,N) - local _={ - x=x-w*.5,y=y-h*.5, - w=w,h=h, - color=color, - font=font, - code=code, - hide=hide, - next=N, - }for k,v in next,button do _[k]=v end return _ -end function button:reset() self.ATV=0 end @@ -26,7 +19,7 @@ function button:FX() sysFX.new("ripple",.16,self.x-self.ATV,self.y-self.ATV,self.w+2*self.ATV,self.h+2*self.ATV) end function button:update() - if widget_sel==self then + if WIDGET.sel==self then if self.ATV<8 then self.ATV=self.ATV+1 end else if self.ATV>0 then self.ATV=self.ATV-1 end @@ -65,15 +58,6 @@ local switch={ ATV=0,--activating time(0~8) CHK=0,--check alpha(0~6) } -function newSwitch(x,y,font,disp,code,hide,N) - local _={ - x=x,y=y,font=font, - disp=disp, - code=code, - hide=hide, - next=N, - }for k,v in next,switch do _[k]=v end return _ -end function switch:reset() self.ATV=0 self.CHK=0 @@ -83,7 +67,7 @@ function switch:isAbove(x,y) end function switch:update() local _=self.ATV - if widget_sel==self then if _<8 then self.ATV=_+1 end + if WIDGET.sel==self then if _<8 then self.ATV=_+1 end else if _>0 then self.ATV=_-1 end end _=self.CHK @@ -123,18 +107,6 @@ local slider={ ATV=0,--activating time(0~8) pos=0,--position shown } -function newSlider(x,y,w,unit,font,change,disp,code,hide,N) - local _={ - x=x,y=y, - w=w,unit=unit, - font=font, - change=change, - disp=disp, - code=code, - hide=hide, - next=N, - }for k,v in next,slider do _[k]=v end return _ -end function slider:reset() self.ATV=0 self.pos=0 @@ -143,7 +115,7 @@ function slider:isAbove(x,y) return x>self.x-10 and xself.y-20 and y0 then self.ATV=self.ATV-1 end @@ -184,4 +156,154 @@ function slider:draw() end function slider:getInfo() print(format("x=%d,y=%d,w=%d",self.x,self.y,self.w)) -end \ No newline at end of file +end + +local WIDGET={} +WIDGET.active=EMPTY--table, contains all active widgets +WIDGET.sel=nil--selected widget +function WIDGET.set(L) + WIDGET.sel=nil + WIDGET.active=L or EMPTY + if L then + for _,W in next,L do + W:reset() + end--Reset all widgets + end +end + +WIDGET.new={} +function WIDGET.new.button(x,y,w,h,color,font,code,hide,N) + local _={ + x=x-w*.5,y=y-h*.5, + w=w,h=h, + color=color, + font=font, + code=code, + hide=hide, + next=N, + }for k,v in next,button do _[k]=v end return _ +end +function WIDGET.new.switch(x,y,font,disp,code,hide,N) + local _={ + x=x,y=y,font=font, + disp=disp, + code=code, + hide=hide, + next=N, + }for k,v in next,switch do _[k]=v end return _ +end +function WIDGET.new.slider(x,y,w,unit,font,change,disp,code,hide,N) + local _={ + x=x,y=y, + w=w,unit=unit, + font=font, + change=change, + disp=disp, + code=code, + hide=hide, + next=N, + }for k,v in next,slider do _[k]=v end return _ +end + +function WIDGET.moveCursor(x,y) + WIDGET.sel=nil + for _,W in next,WIDGET.active do + if not(W.hide and W.hide())and W:isAbove(x,y)then + WIDGET.sel=W + return + end + end +end +function WIDGET.press(x,y) + local W=WIDGET.sel + if not W then return end + if W.type=="button"then + W.code() + W:FX() + SFX.play("button") + VOC.play("nya") + elseif W.type=="switch"then + W.code() + SFX.play("move",.6) + elseif W.type=="slider"then + if not x then return end + local p,P=W.disp(),xW.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5) + if p==P then return end + W.code(P) + if W.change then W.change()end + end + if W.hide and W.hide()then WIDGET.sel=nil end +end +function WIDGET.drag(x,y,dx,dy) + local W=WIDGET.sel + if not W then return end + if W.type=="slider"then + local p,P=W.disp(),xW.x+W.w and W.unit or int((x-W.x)*W.unit/W.w+.5) + if p==P then return end + W.code(P) + if W.change then W.change()end + elseif not W:isAbove(x,y)then + WIDGET.sel=nil + end +end +function WIDGET.keyPressed(i) + if i=="tab"then + if WIDGET.sel then + WIDGET.sel=kb.isDown("lshift")and WIDGET.sel.prev or WIDGET.sel.next or WIDGET.sel + else + WIDGET.sel=select(2,next(WIDGET.active)) + end + elseif i=="space"or i=="return"then + if WIDGET.sel then + WIDGET.press(WIDGET.sel) + end + elseif i=="left"or i=="right"then + local W=WIDGET.sel + if W then + if W.type=="slider"then + local p=W.disp() + local P=i=="left"and(p>0 and p-1)or p0 and p-1)or p------------------------- +---------------------------------------------------- local gameEnv0={ noFly=false, das=10,arr=2, @@ -16,8 +15,8 @@ local gameEnv0={ smooth=false,grid=false, bagLine=false, text=true, - lockFX=3,dropFX=3, - shakeFX=3, + lockFX=2,dropFX=3, + clearFX=2,shakeFX=3, drop=60,lock=60, wait=0,fall=0, @@ -40,9 +39,10 @@ local gameEnv0={ bg="none",bgm="race" } -local comboAtk={0,0,1,1,2,2,3,3,4,4,3,2,3,2,3,2,3}--2 else -local b2bPoint={50,100,180} -local b2bATK={3,5,8} +local WidComboAtk={0,0,1,1,2,2,2,3,3,3,4,4,3}--2 else +local DigComboAtk={0,0,1,1,2,2,3,3,4,4,4}--5 else +local b2bPoint={50,100,180,300} +local b2bATK={3,5,8,10} local clearSCR={80,200,400} local spinSCR={--[blockName][row] {200,750,1600},--Z @@ -52,6 +52,7 @@ local spinSCR={--[blockName][row] {250,800,1500},--T {260,900,1800},--O {300,1200,1700},--I + {220,800,2000,3000},--else } --B2BMUL:1.2/2.0 --Techrash:1K;MUL:1.3/1.8 @@ -59,9 +60,6 @@ local spinSCR={--[blockName][row] local visible_opt={show=1e99,time=300,fast=20,none=0} local reAtk={0,0,1,1,1,2,2,3,3} local reDef={0,1,1,2,3,3,4,4,5} -local initCenterX={6,6,6,6,6,6.5,6.5}--1 added -local initCenterY={22,22,22,22,22,22.5,21.5}--1 added -local CCblockID={4,3,5,6,1,2,0} local scs=require("parts/spinCenters") local kickList=require("parts/kickList") local finesseList={ @@ -83,11 +81,10 @@ local finesseList={ {2,2,2,2,1,1,2,2,2,2}, },--I } -finesseList[1][3],finesseList[1][4],finesseList[7][3],finesseList[7][4]=finesseList[1][1],finesseList[1][2],finesseList[7][1],finesseList[7][2]--SZI逆态视为顺态 -finesseList[2]=finesseList[1]--SZ算法相同 -finesseList[4]=finesseList[3]--JLT算法相同 -finesseList[5]=finesseList[3]--JLT算法相同 -local CCblockID={4,3,5,6,1,2,0} +finesseList[1][3],finesseList[1][4],finesseList[7][3],finesseList[7][4]=finesseList[1][1],finesseList[1][2],finesseList[7][1],finesseList[7][2]--"2-phase" SZI +finesseList[2]=finesseList[1]--S=Z +finesseList[4],finesseList[5]=finesseList[3],finesseList[3]--J=L=T +local CCblockID={4,3,6,5,1,2,0} local freshPrepare={ none=NULL, bag=function(P) @@ -98,7 +95,8 @@ local freshPrepare={ his4=function(P) P.his={rnd(7),rnd(7),rnd(7),rnd(7)} for _=1,6 do - local j,i=0 + local i + local j=0 repeat i=rnd(7) j=j+1 @@ -148,420 +146,14 @@ local freshMethod={ end end, } -local spinName={"zspin","sspin","lspin","jspin","tspin","ospin","ispin"} -local clearName={"single","double","triple"} -local spin_n={[0]="spin_0","spin_1","spin_2","spin_3"} -local clear_n={"clear_1","clear_2","clear_3","clear_4"} +local spinName={"zspin","sspin","jspin","lspin","tspin","ospin","ispin","zspin","sspin","pspin","qspin","fspin","espin","tspin","uspin","vspin","wspin","xspin","jspin","lspin","rspin","yspin","hspin","nspin","ispin"} +local clearName={"single","double","triple","techrash","pentcrash"} +local spin_n={[0]="spin_0","spin_1","spin_2","spin_3","spin_3"} +local clear_n={"clear_1","clear_2","clear_3","clear_4","clear_4"} local ren_n={}for i=1,11 do ren_n[i]="ren_"..i end -------------------------------------------------- +---------------------------------------------------- ---------------------------------------------------- -local frameColor={ - [0]=color.white, - color.lightGreen, - color.lightBlue, - color.lightPurple, - color.lightOrange, -} -local attackColor={ - {color.darkGrey,color.white}, - {color.grey,color.white}, - {color.lightPurple,color.white}, - {color.lightRed,color.white}, - {color.darkGreen,color.cyan}, -} -local function drawPixel(y,x,id) - gc.draw(blockSkin[id],30*x-30,600-30*y) -end -local function drawDial(x,y,speed) - gc.setColor(1,1,1) - mStr(int(speed),x,y-18) - gc.draw(IMG.dialCircle,x,y,nil,nil,nil,32,32) - gc.setColor(1,1,1,.6) - gc.draw(IMG.dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4) -end -local function Pdraw_norm(P) - local curColor=P.cur.color - local _ - gc.push("transform") - gc.translate(P.x,P.y)gc.scale(P.size) - --Camera - gc.setColor(0,0,0,.6)gc.rectangle("fill",0,0,600,690) - gc.setLineWidth(7)gc.setColor(frameColor[P.strength])gc.rectangle("line",0,0,600,690) - --Boarder - gc.translate(150+P.fieldOff.x,70+P.fieldOff.y) - if P.gameEnv.grid then - gc.setLineWidth(1) - gc.setColor(1,1,1,.2) - for x=1,9 do gc.line(30*x,-10,30*x,600)end - for y=0,19 do - y=30*(y-int(P.fieldBeneath/30))+P.fieldBeneath - gc.line(0,y,300,y) - end - end--Grid - gc.translate(0,P.fieldBeneath) - gc.setScissor(scr.x+(P.absFieldX+P.fieldOff.x)*scr.k,scr.y+(P.absFieldY+P.fieldOff.y)*scr.k,300*P.size*scr.k,610*P.size*scr.k) - if P.falling==-1 then - for j=int(P.fieldBeneath/30+1),#P.field do - for i=1,10 do - if P.field[j][i]>0 then - gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) - drawPixel(j,i,P.field[j][i]) - end - end - end - else--field block only - local dy,stepY=0,P.gameEnv.smooth and(P.falling/(P.gameEnv.fall+1))^2.5*30 or 30 - local A=P.falling/P.gameEnv.fall - local h,H=1,#P.field - for j=int(P.fieldBeneath/30+1),H do - while j==P.clearingRow[h]do - h=h+1 - dy=dy+stepY - gc.translate(0,-stepY) - gc.setColor(1,1,1,A) - gc.rectangle("fill",0,630-30*j,300,stepY) - end - for i=1,10 do - if P.field[j][i]>0 then - gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) - drawPixel(j,i,P.field[j][i]) - end - end - end - gc.translate(0,dy) - end--Field with falling animation - - for i=1,#P.lockFX do - _=P.lockFX[i] - if _[3]<.5 then - gc.setColor(1,1,1,2*_[3]) - gc.rectangle("fill",_[1],_[2],60*_[3],30) - else - gc.setColor(1,1,1,2-2*_[3]) - gc.rectangle("fill",_[1]+30,_[2],60*_[3]-60,30) - end - end--lockFX - - for i=1,#P.dropFX do - _=P.dropFX[i] - gc.setColor(1,1,1,_[1]*.12) - for x=_[3],_[5]do - for y=_[6],_[4]do - drawPixel(y,x,_[2]) - end - end - end--dropFX - - if P.waiting==-1 then - if P.gameEnv.ghost then - gc.setColor(1,1,1,.3) - for i=1,P.r do for j=1,P.c do - if P.cur.bk[i][j]then - drawPixel(i+P.y_img-1,j+P.curX-1,curColor) - end - end end - end--Ghost - - local dy=P.gameEnv.smooth and P.y_img~=P.curY and (min(P.dropDelay,1e99)/P.gameEnv.drop-1)*30 or 0 - gc.translate(0,-dy) - local trans=P.lockDelay/P.gameEnv.lock - if P.gameEnv.block then - SHADER.alpha:send("a",trans) - gc.setShader(SHADER.alpha) - _=blockSkin[curColor] - for i=1,P.r do for j=1,P.c do - if P.cur.bk[i][j]then - local x=30*(j+P.curX)-60-3 - local y=630-30*(i+P.curY)-3 - gc.draw(_,x,y)gc.draw(_,x+6,y+6) - gc.draw(_,x+6,y)gc.draw(_,x,y+6) - end - end end - gc.setShader()--White Boarder(indicate lockdelay) - gc.setColor(1,1,1) - for i=1,P.r do for j=1,P.c do - if P.cur.bk[i][j]then - drawPixel(i+P.curY-1,j+P.curX-1,curColor) - end - end end--Block - end - if P.gameEnv.center then - gc.setColor(1,1,1,trans) - local x=30*(P.curX+P.sc[2]-1)-15 - gc.draw(IMG.spinCenter,x,600-30*(P.curY+P.sc[1]-1)+15,nil,nil,nil,4,4) - gc.translate(0,dy) - gc.setColor(1,1,1,.5) - gc.draw(IMG.spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4) - goto E - end--Rotate center - gc.translate(0,dy) - end - ::E:: - gc.setColor(1,1,1) - gc.draw(P.dust) - gc.setScissor()--In-playField things - gc.translate(0,-P.fieldBeneath) - gc.setBlendMode("replace","alphamultiply")--SPEED UPUP(?) - gc.setLineWidth(2) - gc.rectangle("line",-1,-11,302,612)--Draw boarder - gc.rectangle("line",301,0,15,601)--Draw atkBuffer boarder - local h=0 - for i=1,#P.atkBuffer do - local A=P.atkBuffer[i] - local bar=A.amount*30 - if h+bar>600 then bar=600-h end - if not A.sent then - if A.time<20 then - bar=bar*(20*A.time)^.5*.05 - --Appear - end - if A.countdown>0 then - gc.setColor(attackColor[A.lv][1]) - gc.rectangle("fill",303,599-h,11,-bar+3) - gc.setColor(attackColor[A.lv][2]) - gc.rectangle("fill",303,599-h+(-bar+3),11,-(-bar+3)*(1-A.countdown/A.cd0)) - --Timing - else - local t=math.sin((Timer()-i)*30)*.5+.5 - local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2] - gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t)) - gc.rectangle("fill",303,599-h,11,-bar+3) - --Warning - end - else - gc.setColor(attackColor[A.lv][1]) - bar=bar*(20-A.time)*.05 - gc.rectangle("fill",303,599-h,11,-bar+2) - --Disappear - end - h=h+bar - end--Buffer line - local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end - gc.setColor(.8,1,.2) - gc.rectangle("fill",-14,599,11,-b*.5) - gc.setColor(P.b2b<40 and color.white or P.b2b<=1e3 and color.lightRed or color.lightBlue) - gc.rectangle("fill",-14,599,11,-a*.5) - gc.setColor(1,1,1) - if Timer()%.5<.3 then - gc.rectangle("fill",-15,b<40 and 578.5 or 98.5,13,3) - end - gc.rectangle("line",-16,-3,15,604)--Draw b2b bar boarder - --B2B indictator - gc.translate(-P.fieldOff.x,-P.fieldOff.y) - gc.setBlendMode("alpha") - - if P.gameEnv.hold then - mText(drawableText.hold,-81,-15) - if P.holded then gc.setColor(.6,.5,.5)end - local B=P.hd.bk - for i=1,#B do for j=1,#B[1]do - if B[i][j]then - drawPixel(i+17.5-#B*.5,j-2.7-#B[1]*.5,P.hd.color) - end - end end - end--Hold - - gc.setColor(1,1,1) - mText(drawableText.next,381,-15) - local N=1 - while N<=P.gameEnv.next and P.next[N]do - local b,c=P.next[N].bk,P.next[N].color - for i=1,#b do for j=1,#b[1] do - if b[i][j]then - drawPixel(i+20-2.4*N-#b*.5,j+12.7-#b[1]*.5,c) - end - end end - N=N+1 - end - --Next(s) - - if P.gameEnv.bagLine then - local L=P.gameEnv.bagLen - local C=-P.pieceCount%L--phase - gc.setColor(.5,.5,.5) - for i=C,N-1,L do - local y=72*i+36 - gc.line(320,y,442,y) - end - end - --BagLine(s) - - gc.setColor(.8,.8,.8) - gc.draw(drawableText.modeName,-135,-65) - gc.draw(drawableText.levelName,437-drawableText.levelName:getWidth(),-65) - gc.setColor(1,1,1) - if frame<180 then - local count=179-frame - gc.push("transform") - gc.translate(155,220) - setFont(95) - if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end - mStr(int(count/60+1),0,0) - gc.pop() - end--Draw starting counter - TEXT.draw(P.bonus)--Bonus texts - setFont(25) - drawDial(360,520,P.dropSpeed) - drawDial(405,575,P.keySpeed) - gc.setColor(1,1,1) - mStr(format("%.2f",P.stat.time),-81,518)--Time - mStr(P.score1,-81,560)--Score - gc.draw(drawableText.bpm,390,490) - gc.draw(drawableText.kpm,344,583) - --Speed dials - gc.setColor(1,1,1) - curMode.mesDisp(P)--Other messages - if modeEnv.royaleMode then - if P.atkMode then - gc.setColor(1,.8,0,P.swappingAtkMode*.02) - gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4) - end - gc.setColor(1,1,1,P.swappingAtkMode*.025) - gc.draw(royaleCtrlPad) - end - gc.pop() -end -local function Pdraw_small(P) - P.frameWait=P.frameWait-1 - if P.frameWait==0 then - P.frameWait=10 - gc.setCanvas(P.canvas) - gc.clear(0,0,0,.4) - gc.push("transform") - gc.origin() - gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1) - local F=P.field - for j=1,#F do - for i=1,10 do if F[j][i]>0 then - gc.draw(blockSkinMini[F[j][i]],6*i-6,120-6*j) - end end - end--Field - if P.alive then - gc.setLineWidth(2) - gc.setColor(frameColor[P.strength])gc.rectangle("line",1,1,58,118) - end--Draw boarder - if modeEnv.royaleMode then - gc.setColor(1,1,1) - for i=1,P.strength do - gc.draw(IMG.badgeIcon,12*i-7,4,nil,.5) - end - end - if P.result then - gc.setColor(1,1,1,min(P.endCounter,60)*.01) - setFont(17)mStr(P.result,32,47) - setFont(15)mStr(P.modeData.event,30,82) - end - gc.pop() - gc.setCanvas() - --draw content - end - gc.setColor(1,1,1) - gc.draw(P.canvas,P.x,P.y,nil,P.size*10) - --draw Canvas - if P.killMark then - gc.setLineWidth(3) - gc.setColor(1,0,0,min(P.endCounter,25)*.04) - gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size) - end - setFont(30) -end -local function Pdraw_demo(P) - local _ - local curColor=P.cur.color - gc.push("transform") - gc.translate(P.x,P.y)gc.scale(P.size)gc.translate(P.fieldOff.x,P.fieldOff.y) - --Camera - gc.setColor(.1,.1,.1,.8)gc.rectangle("fill",0,0,300,600) - gc.setLineWidth(2)gc.setColor(1,1,1)gc.rectangle("line",-1,-1,302,602) - --Frame - if P.falling==-1 then - for j=int(P.fieldBeneath/30+1),#P.field do - for i=1,10 do - if P.field[j][i]>0 then - gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) - drawPixel(j,i,P.field[j][i]) - end - end - end - else--field block only - local dy,stepY=0,P.gameEnv.smooth and(P.falling/(P.gameEnv.fall+1))^2.5*30 or 30 - local A=P.falling/P.gameEnv.fall - local h,H=1,#P.field - for j=int(P.fieldBeneath/30+1),H do - while j==P.clearingRow[h]do - h=h+1 - dy=dy+stepY - gc.translate(0,-stepY) - gc.setColor(1,1,1,A) - gc.rectangle("fill",0,630-30*j,300,stepY) - end - for i=1,10 do - if P.field[j][i]>0 then - gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) - drawPixel(j,i,P.field[j][i]) - end - end - end - gc.translate(0,dy) - end--Field with falling animation - for i=1,#P.lockFX do - _=P.lockFX[i] - if _[3]<.5 then - gc.setColor(1,1,1,3*_[3]) - gc.rectangle("fill",_[1],_[2],60*_[3],30) - else - gc.setColor(1,1,1,3-3*_[3]) - gc.rectangle("fill",_[1]+30,_[2],60*_[3]-60,30) - end - end--lockFX - for i=1,#P.dropFX do - local S=P.dropFX[i] - gc.setColor(1,1,1,S[1]*.12) - for x=S[3],S[5]do - for y=S[6],S[4]do - drawPixel(y,x,S[2]) - end - end - end--dropFX - if P.waiting==-1 then - gc.setColor(1,1,1,.3) - for i=1,P.r do for j=1,P.c do - if P.cur.bk[i][j]then - drawPixel(i+P.y_img-1,j+P.curX-1,curColor) - end - end end - --Ghost draw - gc.setColor(1,1,1) - for i=1,P.r do for j=1,P.c do - if P.cur.bk[i][j]then - drawPixel(i+P.curY-1,j+P.curX-1,curColor) - end - end end--Block - end - local id=P.hd.id - if id>0 then - _=P.color[id] - gc.setColor(_[1],_[2],_[3],.3) - _=miniBlock[P.hd.id] - gc.draw(_,15,30,nil,16,nil,0,_:getHeight()*.5) - end - local N=1 - while N<=P.gameEnv.next and P.next[N]do - local id=P.next[N].id - _=P.color[id] - gc.setColor(_[1],_[2],_[3],.3) - _=miniBlock[id] - gc.draw(_,285,40*N-10,nil,16,nil,_:getWidth(),_:getHeight()*.5) - N=N+1 - end - --Next - gc.setColor(1,1,1) - gc.draw(P.dust) - gc.translate(-P.fieldOff.x,-P.fieldOff.y) - TEXT.draw(P.bonus) - gc.pop() -end +---------------------------------------------------- local function updateFXs(P,dt) if P.stat.score>P.score1 then if P.stat.score-P.score1<10 then @@ -570,21 +162,31 @@ local function updateFXs(P,dt) P.score1=int(min(P.score1*.9+P.stat.score*.1+1)) end end + for i=#P.lockFX,1,-1 do - local _=P.lockFX[i] - _[3]=_[3]+_[4] - if _[3]>1 then + local S=P.lockFX[i] + S[3]=S[3]+S[4]*dt + if S[3]>1 then rem(P.lockFX,i) end end--lockFX + for i=#P.dropFX,1,-1 do local S=P.dropFX[i] - S[1]=S[1]-1+P.gameEnv.dropFX*.15 - if S[1]<=0 then + S[6]=S[6]+S[7]*dt + if S[6]>1 then rem(P.dropFX,i) end end--dropFX + for i=#P.clearFX,1,-1 do + local S=P.clearFX[i] + S[2]=S[2]+S[3]*dt + if S[2]>1 then + rem(P.clearFX,i) + end + end--clearFX + if P.gameEnv.shakeFX then local O=P.fieldOff O.vx,O.vy=O.vx*.8-abs(O.x)^1.2*(O.x>0 and .1 or -.1),O.vy*.8-abs(O.y)^1.2*(O.y>0 and .1 or -.1) @@ -592,6 +194,7 @@ local function updateFXs(P,dt) if abs(O.x)<.3 then O.x=0 end if abs(O.y)<.3 then O.y=0 end end--field shaking + if P.bonus then TEXT.update(P.bonus) end @@ -600,7 +203,7 @@ local function updateFXs(P,dt) A.time=A.time+1 if not A.sent then if A.countdown>0 then - A.countdown=max(A.countdown-garbageSpeed,0) + A.countdown=max(A.countdown-game.garbageSpeed,0) end else if A.time>20 then @@ -609,9 +212,6 @@ local function updateFXs(P,dt) end end if P.fieldBeneath>0 then P.fieldBeneath=max(P.fieldBeneath-P.gameEnv.pushSpeed,0)end - if not P.small then - P.dust:update(dt) - end end local function Pupdate_alive(P,dt) if P.timing then P.stat.time=P.stat.time+dt end @@ -819,9 +419,425 @@ local function Pupdate_dead(P,dt) if P.b2b1>0 then P.b2b1=max(0,P.b2b1*.92-1)end updateFXs(P,dt) end --------------------------------------------------- +---------------------------------------------------- + +---------------------------------------------------- +local frameColor={ + [0]=color.white, + color.lightGreen, + color.lightBlue, + color.lightPurple, + color.lightOrange, +} +local attackColor={ + {color.darkGrey,color.white}, + {color.grey,color.white}, + {color.lightPurple,color.white}, + {color.lightRed,color.white}, + {color.darkGreen,color.cyan}, +} +local RCPB={10,33,200,33,105,5,105,60} +local function drawPixel(y,x,id) + gc.draw(blockSkin[id],30*x-30,600-30*y) +end +local function drawDial(x,y,speed) + gc.setColor(1,1,1) + mStr(int(speed),x,y-18) + gc.draw(IMG.dialCircle,x,y,nil,nil,nil,32,32) + gc.setColor(1,1,1,.6) + gc.draw(IMG.dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4) +end +local function drawFXs(P) + for i=1,#P.lockFX do + _=P.lockFX[i] + if _[3]<.5 then + gc.setColor(1,1,1,2*_[3]) + gc.rectangle("fill",_[1],_[2],60*_[3],30) + else + gc.setColor(1,1,1,2-2*_[3]) + gc.rectangle("fill",_[1]+30,_[2],60*_[3]-60,30) + end + end--lockFX + + for i=1,#P.dropFX do + _=P.dropFX[i] + gc.setColor(1,1,1,.6-_[6]*.6) + for x=_[2],_[4]do + for y=_[5],_[3]do + drawPixel(y,x,_[1]) + end + end + end--dropFX + + for i=1,#P.clearFX do + local S=P.clearFX[i] + local t=S[2] + local x=t<.3 and 1-(3.3333*t-1)^2 or 1 + local y=t<.2 and 5*t or 1-1.25*(t-.2) + gc.setColor(1,1,1,y) + gc.rectangle("fill",150-x*150,615-S[1]*30-y*15,300*x,y*30) + end--clearFX +end +local function Pdraw_norm(P) + local curColor=P.cur.color + local _ + gc.push("transform") + gc.translate(P.x,P.y)gc.scale(P.size) + --Camera + gc.setColor(0,0,0,.6)gc.rectangle("fill",0,0,600,690) + gc.setLineWidth(7)gc.setColor(frameColor[P.strength])gc.rectangle("line",0,0,600,690) + --Boarder + gc.translate(150+P.fieldOff.x,70+P.fieldOff.y) + if P.gameEnv.grid then + gc.setLineWidth(1) + gc.setColor(1,1,1,.2) + for x=1,9 do gc.line(30*x,-10,30*x,600)end + for y=0,19 do + y=30*(y-int(P.fieldBeneath/30))+P.fieldBeneath + gc.line(0,y,300,y) + end + end--Grid + gc.translate(0,P.fieldBeneath) + gc.setScissor(scr.x+(P.absFieldX+P.fieldOff.x)*scr.k,scr.y+(P.absFieldY+P.fieldOff.y)*scr.k,300*P.size*scr.k,610*P.size*scr.k) + if P.falling==-1 then + for j=int(P.fieldBeneath/30+1),#P.field do + for i=1,10 do + if P.field[j][i]>0 then + gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) + drawPixel(j,i,P.field[j][i]) + end + end + end + else--field block only + local dy,stepY=0,P.gameEnv.smooth and(P.falling/(P.gameEnv.fall+1))^2.5*30 or 30 + local A=P.falling/P.gameEnv.fall + local h,H=1,#P.field + for j=int(P.fieldBeneath/30+1),H do + while j==P.clearingRow[h]do + h=h+1 + dy=dy+stepY + gc.translate(0,-stepY) + gc.setColor(1,1,1,A) + gc.rectangle("fill",0,630-30*j,300,stepY) + end + for i=1,10 do + if P.field[j][i]>0 then + gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) + drawPixel(j,i,P.field[j][i]) + end + end + end + gc.translate(0,dy) + end--Field with falling animation + + drawFXs(P) + + if P.waiting==-1 then + if P.gameEnv.ghost then + gc.setColor(1,1,1,.3) + for i=1,P.r do for j=1,P.c do + if P.cur.bk[i][j]then + drawPixel(i+P.y_img-1,j+P.curX-1,curColor) + end + end end + end--Ghost + + local dy=P.gameEnv.smooth and P.y_img~=P.curY and (min(P.dropDelay,1e99)/P.gameEnv.drop-1)*30 or 0 + gc.translate(0,-dy) + local trans=P.lockDelay/P.gameEnv.lock + if P.gameEnv.block then + SHADER.alpha:send("a",trans) + gc.setShader(SHADER.alpha) + _=blockSkin[curColor] + for i=1,P.r do for j=1,P.c do + if P.cur.bk[i][j]then + local x=30*(j+P.curX)-60-3 + local y=630-30*(i+P.curY)-3 + gc.draw(_,x,y)gc.draw(_,x+6,y+6) + gc.draw(_,x+6,y)gc.draw(_,x,y+6) + end + end end + gc.setShader()--White Boarder(indicate lockdelay) + gc.setColor(1,1,1) + for i=1,P.r do for j=1,P.c do + if P.cur.bk[i][j]then + drawPixel(i+P.curY-1,j+P.curX-1,curColor) + end + end end--Block + end + if P.gameEnv.center then + gc.setColor(1,1,1,trans) + local x=30*(P.curX+P.sc[2]-1)-15 + gc.draw(IMG.spinCenter,x,600-30*(P.curY+P.sc[1]-1)+15,nil,nil,nil,4,4) + gc.translate(0,dy) + gc.setColor(1,1,1,.5) + gc.draw(IMG.spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4) + goto E + end--Rotate center + gc.translate(0,dy) + end + ::E:: + gc.setScissor()--In-playField things + gc.translate(0,-P.fieldBeneath) + gc.setBlendMode("replace","alphamultiply")--SPEED UPUP(?) + gc.setLineWidth(2) + gc.setColor(1,1,1) + gc.rectangle("line",-1,-11,302,612)--Draw boarder + gc.rectangle("line",301,0,15,601)--Draw atkBuffer boarder + local h=0 + for i=1,#P.atkBuffer do + local A=P.atkBuffer[i] + local bar=A.amount*30 + if h+bar>600 then bar=600-h end + if not A.sent then + if A.time<20 then + bar=bar*(20*A.time)^.5*.05 + --Appear + end + if A.countdown>0 then + gc.setColor(attackColor[A.lv][1]) + gc.rectangle("fill",303,599-h,11,-bar+3) + gc.setColor(attackColor[A.lv][2]) + gc.rectangle("fill",303,599-h+(-bar+3),11,-(-bar+3)*(1-A.countdown/A.cd0)) + --Timing + else + local t=math.sin((Timer()-i)*30)*.5+.5 + local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2] + gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t)) + gc.rectangle("fill",303,599-h,11,-bar+3) + --Warning + end + else + gc.setColor(attackColor[A.lv][1]) + bar=bar*(20-A.time)*.05 + gc.rectangle("fill",303,599-h,11,-bar+2) + --Disappear + end + h=h+bar + end--Buffer line + local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end + gc.setColor(.8,1,.2) + gc.rectangle("fill",-14,599,11,-b*.5) + gc.setColor(P.b2b<40 and color.white or P.b2b<=1e3 and color.lightRed or color.lightBlue) + gc.rectangle("fill",-14,599,11,-a*.5) + gc.setColor(1,1,1) + if Timer()%.5<.3 then + gc.rectangle("fill",-15,b<40 and 578.5 or 98.5,13,3) + end + gc.rectangle("line",-16,-3,15,604)--Draw b2b bar boarder + --B2B indictator + gc.translate(-P.fieldOff.x,-P.fieldOff.y) + gc.setBlendMode("alpha") + + if P.gameEnv.hold then + mText(drawableText.hold,-81,-15) + if P.holded then gc.setColor(.6,.5,.5)end + local B=P.hd.bk + for i=1,#B do for j=1,#B[1]do + if B[i][j]then + drawPixel(i+17.5-#B*.5,j-2.7-#B[1]*.5,P.hd.color) + end + end end + end--Hold + + gc.setColor(1,1,1) + mText(drawableText.next,381,-15) + local N=1 + while N<=P.gameEnv.next and P.next[N]do + local b,c=P.next[N].bk,P.next[N].color + for i=1,#b do for j=1,#b[1] do + if b[i][j]then + drawPixel(i+20-2.4*N-#b*.5,j+12.7-#b[1]*.5,c) + end + end end + N=N+1 + end + --Next(s) + + if P.gameEnv.bagLine then + local L=P.gameEnv.bagLen + local C=-P.pieceCount%L--phase + gc.setColor(.5,.5,.5) + for i=C,N-1,L do + local y=72*i+36 + gc.line(320,y,442,y) + end + end + --BagLine(s) + + gc.setColor(.8,.8,.8) + gc.draw(drawableText.modeName,-135,-65) + gc.draw(drawableText.levelName,437-drawableText.levelName:getWidth(),-65) + gc.setColor(1,1,1) + if frame<180 then + local count=179-frame + gc.push("transform") + gc.translate(155,220) + setFont(95) + if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end + mStr(int(count/60+1),0,0) + gc.pop() + end--Draw starting counter + TEXT.draw(P.bonus)--Bonus texts + setFont(25) + drawDial(360,520,P.dropSpeed) + drawDial(405,575,P.keySpeed) + gc.setColor(1,1,1) + mStr(format("%.2f",P.stat.time),-81,518)--Time + mStr(P.score1,-81,560)--Score + gc.draw(drawableText.bpm,390,490) + gc.draw(drawableText.kpm,344,583) + --Speed dials + gc.setColor(1,1,1) + curMode.mesDisp(P)--Other messages + + if modeEnv.royaleMode then + if P.atkMode then + gc.setColor(1,.8,0,P.swappingAtkMode*.02) + gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4) + end + gc.setColor(1,1,1,P.swappingAtkMode*.025) + gc.setLineWidth(2) + setFont(18) + for i=1,4 do + gc.rectangle("line",RCPB[2*i-1],RCPB[2*i],90,35,8,4) + mStr(text.atkModeName[i],RCPB[2*i-1]+45,RCPB[2*i]+3) + end + end + gc.pop() +end +local function Pdraw_small(P) + P.frameWait=P.frameWait-1 + if P.frameWait==0 then + P.frameWait=10 + gc.setCanvas(P.canvas) + gc.clear(0,0,0,.4) + gc.push("transform") + gc.origin() + gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1) + local F=P.field + for j=1,#F do + for i=1,10 do if F[j][i]>0 then + gc.draw(blockSkinMini[F[j][i]],6*i-6,120-6*j) + end end + end--Field + if P.alive then + gc.setLineWidth(2) + gc.setColor(frameColor[P.strength])gc.rectangle("line",1,1,58,118) + end--Draw boarder + if modeEnv.royaleMode then + gc.setColor(1,1,1) + for i=1,P.strength do + gc.draw(IMG.badgeIcon,12*i-7,4,nil,.5) + end + end + if P.result then + gc.setColor(1,1,1,min(P.endCounter,60)*.01) + setFont(17)mStr(P.result,32,47) + setFont(15)mStr(P.modeData.event,30,82) + end + gc.pop() + gc.setCanvas() + --draw content + end + gc.setColor(1,1,1) + gc.draw(P.canvas,P.x,P.y,nil,P.size*10) + --draw Canvas + if P.killMark then + gc.setLineWidth(3) + gc.setColor(1,0,0,min(P.endCounter,25)*.04) + gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size) + end + setFont(30) +end +local function Pdraw_demo(P) + local _ + local curColor=P.cur.color + gc.push("transform") + gc.translate(P.x,P.y)gc.scale(P.size)gc.translate(P.fieldOff.x,P.fieldOff.y) + --Camera + + gc.setColor(.1,.1,.1,.8)gc.rectangle("fill",0,0,300,600) + gc.setLineWidth(2)gc.setColor(1,1,1)gc.rectangle("line",-1,-1,302,602) + --Frame + + if P.falling==-1 then + for j=int(P.fieldBeneath/30+1),#P.field do + for i=1,10 do + if P.field[j][i]>0 then + gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) + drawPixel(j,i,P.field[j][i]) + end + end + end + else--field block only + local dy,stepY=0,P.gameEnv.smooth and(P.falling/(P.gameEnv.fall+1))^2.5*30 or 30 + local A=P.falling/P.gameEnv.fall + local h,H=1,#P.field + for j=int(P.fieldBeneath/30+1),H do + while j==P.clearingRow[h]do + h=h+1 + dy=dy+stepY + gc.translate(0,-stepY) + gc.setColor(1,1,1,A) + gc.rectangle("fill",0,630-30*j,300,stepY) + end + for i=1,10 do + if P.field[j][i]>0 then + gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1)) + drawPixel(j,i,P.field[j][i]) + end + end + end + gc.translate(0,dy) + end--Field with falling animation + + drawFXs(P) + + if P.waiting==-1 then + gc.setColor(1,1,1,.3) + for i=1,P.r do for j=1,P.c do + if P.cur.bk[i][j]then + drawPixel(i+P.y_img-1,j+P.curX-1,curColor) + end + end end + --Ghost draw + gc.setColor(1,1,1) + for i=1,P.r do for j=1,P.c do + if P.cur.bk[i][j]then + drawPixel(i+P.curY-1,j+P.curX-1,curColor) + end + end end--Block + end + + local id=P.hd.id + if id>0 then + _=P.color[id] + gc.setColor(_[1],_[2],_[3],.3) + _=miniBlock[P.hd.id] + gc.draw(_,15,30,nil,16,nil,0,_:getHeight()*.5) + end + --Hold + + local N=1 + while N<=P.gameEnv.next and P.next[N]do + local id=P.next[N].id + _=P.color[id] + gc.setColor(_[1],_[2],_[3],.3) + _=miniBlock[id] + gc.draw(_,285,40*N-10,nil,16,nil,_:getWidth(),_:getHeight()*.5) + N=N+1 + end + --Next + + gc.setColor(1,1,1) + gc.translate(-P.fieldOff.x,-P.fieldOff.y) + TEXT.draw(P.bonus) + gc.pop() +end +---------------------------------------------------- player={}local player=player --------------------------------------------------------- +---------------------------------------------------- local textFX=textFX function player.showText(P,text,dx,dy,font,style,spd,stop) if P.gameEnv.text then @@ -839,13 +855,15 @@ local function without(L,e) end function player.createLockFX(P) local BK=P.cur.bk - local t=.3-P.gameEnv.lockFX*.06 + local t=15-P.gameEnv.lockFX*3 + for i=1,P.r do local y=P.curY+i-1 if without(P.clearedRow,y)then + y=600-30*y for j=1,P.c do if BK[i][j]then - ins(P.lockFX,{30*(P.curX+j-2),600-30*y,0,t}) + ins(P.lockFX,{30*(P.curX+j-2),y,0,t}) end end end @@ -853,7 +871,7 @@ function player.createLockFX(P) end function player.createDropFX(P,x1,y1,x2,y2)--x1y2! if P.gameEnv.block and y1>=y2 then - P.dropFX[#P.dropFX+1]={5,P.cur.color,x1,y1,x2,y2} + P.dropFX[#P.dropFX+1]={P.cur.color,x1,y1,x2,y2,0,12-1.8*P.gameEnv.dropFX} end end function player.createBeam(P,R,send,time,target,color,clear,spin,mini,combo) @@ -919,17 +937,33 @@ function player.createBeam(P,R,send,time,target,color,clear,spin,mini,combo) drag={},--Afterimage coordinate list } end --------------------------------------------------- +---------------------------------------------------- --------------------------------------------------- -local function solid(P,x,y) +---------------------------------------------------- +local function getNewStatTable() + local T={ + time=0,score=0, + key=0,rotate=0,hold=0, + extraPiece=0,extraRate=0, + piece=0,row=0,dig=0, + atk=0,digatk=0,send=0,recv=0,pend=0, + clear={},clear_B={},clear_S={0,0,0,0,0}, + spin={},spin_B={},spin_S={0,0,0,0,0}, + pc=0,hpc=0,b2b=0,b3b=0, + } + for i=1,25 do + T.clear[i]={0,0,0,0,0} + T.spin[i]={0,0,0,0,0} + T.clear_B[i]=0 + T.spin_B[i]=0 + end + return T +end +function player.solid(P,x,y) if x<1 or x>10 or y<1 then return true end if y>#P.field then return false end return P.field[y][x]>0 end -local function getBlockPosition(P)--for stereo sfx - return(P.curX+P.sc[2]-6.5)*.15 -end function player.ifoverlap(P,bk,x,y) local C=#bk[1] if x<1 or x+C>11 or y<1 then return true end @@ -1023,23 +1057,51 @@ function player.garbageRise(P,color,amount,pos) end for i=1,#P.lockFX do _=P.lockFX[i] - _[2]=_[2]-30*amount--calculated pos!Must *=-30 + _[2]=_[2]-30*amount--Shift 30px per line cleared end for i=1,#P.dropFX do _=P.dropFX[i] - _[4],_[6]=_[4]+amount,_[6]+amount + _[3],_[5]=_[3]+amount,_[5]+amount end if #P.field>40 then P:lose()end end + +local invList={2,1,4,3,5,6,7} +function player.pushLine(P,L,mir) + local S=P.gameEnv.skin + for i=1,#L do + local r=freeRow.get(0) + if not mir then + for j=1,10 do + r[j]=S[L[i][j]]or 0 + end + else + for j=1,10 do + r[j]=S[invList[L[i][11-j]]]or 0 + end + end + ins(P.field,1,r) + ins(P.visTime,1,freeRow.get(20)) + end + P.fieldBeneath=P.fieldBeneath+120 + P.curY=P.curY+#L + P:freshgho() +end +function player.pushNext(P,L,mir) + for i=1,#L do + P:getNext(mir and invList[L[i]]or L[i]) + end +end + function player.freshTarget(P) if P.atkMode==1 then if not P.atking or not P.atking.alive or rnd()<.1 then P:changeAtk(randomTarget(P)) end elseif P.atkMode==2 then - P:changeAtk(P~=mostBadge and mostBadge or secBadge or randomTarget(P)) + P:changeAtk(P~=game.mostBadge and game.mostBadge or game.secBadge or randomTarget(P)) elseif P.atkMode==3 then - P:changeAtk(P~=mostDangerous and mostDangerous or secDangerous or randomTarget(P)) + P:changeAtk(P~=game.mostDangerous and game.mostDangerous or game.secDangerous or randomTarget(P)) elseif P.atkMode==4 then for i=1,#P.atker do if not P.atker[i].alive then @@ -1121,90 +1183,44 @@ function player.lock(P) end end end -local OspinList={ - {111,5,2, 0,-1,0},{111,5,2,-1,-1,0},{111,5,0,-1, 0,0},--T - {333,5,2,-1,-1,0},{333,5,2, 0,-1,0},{333,5,0, 0, 0,0},--T - {313,1,2,-1, 0,0},{313,1,2, 0,-1,0},{313,1,2, 0, 0,0},--Z - {131,2,2, 0, 0,0},{131,2,2,-1,-1,0},{131,2,2,-1, 0,0},--S - {113,3,2,-1,-1,0},{331,3,0,-1, 0,0},{331,3,2, 0, 0,0},--L - {331,4,2, 0,-1,0},{113,4,0, 0, 0,0},{113,4,2,-1, 0,0},--J - {222,7,2,-1, 0,1},{222,7,2,-2, 0,1},{222,7,2, 0, 0,1},--I - {121,6,0, 1,-1,1},{112,6,0, 2,-1,2},{122,6,0, 1,-2,2},--O - {323,6,0,-1,-1,2},{332,6,0,-2,-1,2},{322,6,0,-1,-2,2},--O -}--{key,id,dir,dx,dy,freeLv(0=unmovable,1=↔Unmvb,2=free)} function player.spin(P,d,ifpre) - if P.cur.id==6 then - if P.human then - SFX.play("rotate",nil,getBlockPosition(P)) + local iki=P.RS[P.cur.id] + if type(iki)=="table"then + local idir=(P.dir+d)%4 + local icb=blocks[P.cur.id][idir] + local isc=scs[P.cur.id][idir] + local ir,ic=#icb,#icb[1] + local ix,iy=P.curX+P.sc[2]-isc[2],P.curY+P.sc[1]-isc[1] + iki=iki[P.dir*10+idir] + if not iki then + if P.gameEnv.easyFresh then P:freshLockDelay()end + SFX.fieldPlay(ifpre and"prerotate"or "rotate",nil,P) + return end - if P.gameEnv.easyFresh then - P:freshLockDelay() - end - if P.gameEnv.ospin then - local x,y=P.curX,P.curY - if y==P.y_img and((solid(P,x-1,y)or solid(P,x-1,y+1)))and(solid(P,x+2,y)or solid(P,x+2,y+1))then - local D=P.spinSeq%100*10+d - P.spinSeq=D - if D>100 then - for i=1,#OspinList do - local L=OspinList[i] - if D==L[1]then - local id,dir=L[2],L[3] - local bk=blocks[id][dir] - local x,y=P.curX+L[4],P.curY+L[5] - if not P:ifoverlap(bk,x,y)and(L[6]>0 or P:ifoverlap(bk,x-1,y)and P:ifoverlap(bk,x+1,y))and(L[6]==2 or P:ifoverlap(bk,x,y-1))and P:ifoverlap(bk,x,y+1)then - local C=P.cur - C.id=id - C.bk=bk - P.curX,P.curY=x,y - P.r,P.c=#bk,#bk[1] - P.dir,P.sc=dir,scs[id][dir] - P.spinLast=2 - P.stat.rotate=P.stat.rotate+1 - P:freshgho() - P.spinSeq=0 - SFX.play("rotatekick",nil,getBlockPosition(P)) - return - end - end - end + for test=1,P.freshTime<=1.2*P.gameEnv.freshLimit and #iki or 1 do + local x,y=ix+iki[test][1],iy+iki[test][2] + if not P:ifoverlap(icb,x,y)then + ix=x;iy=y + if P.gameEnv.dropFX then + P:createDropFX(P.curX,P.curY+P.r-1,P.curX+P.c-1,P.curY) end - else - P.spinSeq=0 + local y0=P.curY + P.curX,P.curY,P.dir=ix,iy,idir + P.sc,P.cur.bk=scs[P.cur.id][idir],icb + P.r,P.c=ir,ic + P.spinLast=test==2 and 0 or 1 + if not ifpre then P:freshgho()end + if P.gameEnv.easyFresh or y0>P.curY then P:freshLockDelay()end + if P.human then + SFX.fieldPlay(ifpre and"prerotate"or P:ifoverlap(P.cur.bk,P.curX,P.curY+1)and P:ifoverlap(P.cur.bk,P.curX-1,P.curY)and P:ifoverlap(P.cur.bk,P.curX+1,P.curY)and"rotatekick"or"rotate",nil,P) + end + P.stat.rotate=P.stat.rotate+1 + return end end - return + else + iki(P,d) end - local idir=(P.dir+d)%4 - local icb=blocks[P.cur.id][idir] - local isc=scs[P.cur.id][idir] - local ir,ic=#icb,#icb[1] - local ix,iy=P.curX+P.sc[2]-isc[2],P.curY+P.sc[1]-isc[1] - local t--succssful test - local iki=P.RS[P.cur.id][P.dir*10+idir] - for i=1,P.freshTime<=1.2*P.gameEnv.freshLimit and #iki or 1 do - local x,y=ix+iki[i][1],iy+iki[i][2] - if not P:ifoverlap(icb,x,y)then - ix=x;iy=y;t=i - goto spin - end - end - do return end - ::spin:: - if P.gameEnv.dropFX then - P:createDropFX(P.curX,P.curY+P.r-1,P.curX+P.c-1,P.curY) - end - local y0=P.curY - P.curX,P.curY,P.dir=ix,iy,idir - P.sc,P.cur.bk=scs[P.cur.id][idir],icb - P.r,P.c=ir,ic - P.spinLast=t==2 and 0 or 1 - if not ifpre then P:freshgho()end - if P.gameEnv.easyFresh or y0>P.curY then P:freshLockDelay()end - if P.human then - SFX.play(ifpre and"prerotate"or P:ifoverlap(P.cur.bk,P.curX,P.curY+1)and P:ifoverlap(P.cur.bk,P.curX-1,P.curY)and P:ifoverlap(P.cur.bk,P.curX+1,P.curY)and"rotatekick"or"rotate",nil,getBlockPosition(P)) - end - P.stat.rotate=P.stat.rotate+1 end function player.resetBlock(P) local id=P.cur.id @@ -1213,11 +1229,12 @@ function player.resetBlock(P) P.sc=sc --spin center P.dir=face --block direction P.r,P.c=#P.cur.bk,#P.cur.bk[1] --row/column - P.curX=initCenterX[id]-sc[2] - P.curY=initCenterY[id]-sc[1]+ceil(P.fieldBeneath/30) + P.curX=int(6-P.c*.5) + local y=21+ceil(P.fieldBeneath/30) + P.curY=y if P.gameEnv.ims and(P.keyPressing[1]and P.movDir==-1 or P.keyPressing[2]and P.movDir==1)and P.moving>=P.gameEnv.das then local x=P.curX+P.movDir - if not P:ifoverlap(P.cur.bk,x,P.curY)then + if not P:ifoverlap(P.cur.bk,x,y)then P.curX=x end end @@ -1314,46 +1331,48 @@ function player.drop(P)--Place piece local cscore,sendTime=0,0 local dospin=0 local mini - --spin判定 + --spin check if P.spinLast then if P.cur.id<6 then local x,y=P.curX+P.sc[2]-1,P.curY+P.sc[1]-1 local c=0 - if solid(P,x-1,y+1)then c=c+1 end - if solid(P,x+1,y+1)then c=c+1 end + if P:solid(x-1,y+1)then c=c+1 end + if P:solid(x+1,y+1)then c=c+1 end if c==0 then goto NTC end - if solid(P,x-1,y-1)then c=c+1 end - if solid(P,x+1,y-1)then c=c+1 end + if P:solid(x-1,y-1)then c=c+1 end + if P:solid(x+1,y-1)then c=c+1 end if c>2 then dospin=dospin+1 end - end--三角 + end--tri-corner ::NTC:: if P:ifoverlap(P.cur.bk,P.curX-1,P.curY)and P:ifoverlap(P.cur.bk,P.curX+1,P.curY)and P:ifoverlap(P.cur.bk,P.curX,P.curY+1)then dospin=dospin+2 - end--卡块 + end--immovable end - --锁定 + --lock block to field P:lock() - --清空消行列表 + --clear list of cleared-rows if P.clearedRow[1]then P.clearedRow={}end - --消行 + --check rows to be cleared for i=0,P.r-1 do local h=P.curY+i if P:ckfull(h)then cc=cc+1 P.clearingRow[cc]=h-cc+1 P.clearedRow[cc]=h - if not P.small then - local S=P.dust - for _=1,100 do - S:setPosition(rnd(300),600-30*h+rnd(30)) - S:emit(2) - end - end end end - --处理锁定特效 + --create clearing FX + if cc>0 and P.gameEnv.clearFX then + local l=P.clearedRow + local t=8-P.gameEnv.clearFX*2 + for i=1,cc do + ins(P.clearFX,{l[i],0,t}) + end + end + + --create locking FX if P.gameEnv.lockFX then if cc==0 then P:createLockFX() @@ -1362,16 +1381,7 @@ function player.drop(P)--Place piece end end - --处理锁定特效 - if P.gameEnv.lockFX then - if cc==0 then - P:createLockFX() - elseif P.lockFX[1]then - P.lockFX={} - end - end - - --spin结算 + --final spin check if P.spinLast then if cc>0 then if dospin>0 then @@ -1391,9 +1401,11 @@ function player.drop(P)--Place piece dospin=false end - --极简判定:遮挡判断法 + --finesse: roof check local finesse - if P.curY<=18 then + if P.cur.id>7 then + finesse=true + elseif P.curY<=18 then local y0=P.curY local x,c=P.curX,P.c local B=P.cur.bk @@ -1407,10 +1419,10 @@ function player.drop(P)--Place piece if y then x=P.curX+x-1 for y=y0+y,#P.field do - if solid(P,x,y)then + if P:solid(x,y)then finesse=true goto L2 - end--有遮挡视为最简 + end--roof=finesse end end end @@ -1419,7 +1431,7 @@ function player.drop(P)--Place piece end ::L2:: - --移除消去的行 + --remove rows need to be cleared if cc>0 then for i=cc,1,-1 do _=P.clearedRow[i] @@ -1431,7 +1443,8 @@ function player.drop(P)--Place piece end end end - --清除超高特效 + + --cancel no-sense clearing FX _=#P.clearingRow while _>0 and P.clearingRow[_]>#P.field do P.clearingRow[_]=nil @@ -1443,20 +1456,64 @@ function player.drop(P)--Place piece clear=true end - if not finesse then--极简判定:操作判断法 - if dospin then P.ctrlCount=P.ctrlCount-2 end--对无遮挡spin宽松两步 + if not finesse then--finesse: control + if dospin then P.ctrlCount=P.ctrlCount-2 end--allow 2 more step for roof-less spin local id=P.cur.id local dir=P.dir+1 - local d=P.ctrlCount-finesseList[id][dir][P.curX]if d>=2 then P:fineError(2)elseif d>0 then P:fineError(d)end --非最简 - end + local d=P.ctrlCount-finesseList[id][dir][P.curX] + if d>=2 then P:fineError(2) + elseif d>0 then P:fineError(d) + end--not finesse + end if cc>0 then cmb=cmb+1 - if cc==4 then - cscore=1000 + if dospin then + cscore=(spinSCR[P.cur.name]or spinSCR[8])[cc] if P.b2b>1000 then - P:showText(text.techrashB3B,0,-30,50,"fly") - atk=6 + P:showText(text.b3b..text.block[P.cur.name]..text.spin.." "..text.clear[cc],0,-30,35,"stretch") + atk=b2bATK[cc]+cc*.5 + exblock=exblock+1 + cscore=cscore*2 + STAT.b3b=STAT.b3b+1 + if P.human then + VOC.play("b3b",CHN) + end + elseif P.b2b>=50 then + P:showText(text.b2b..text.block[P.cur.name]..text.spin.." "..text.clear[cc],0,-30,35,"spin") + atk=b2bATK[cc] + cscore=cscore*1.2 + STAT.b2b=STAT.b2b+1 + if P.human then + VOC.play("b2b",CHN) + end + else + P:showText(text.block[P.cur.name]..text.spin.." "..text.clear[cc],0,-30,45,"spin") + atk=2*cc + end + sendTime=20+atk*20 + if mini then + P:showText(text.mini,0,-80,35,"appear") + atk=atk*.5 + sendTime=sendTime+60 + cscore=cscore*.6 + P.b2b=P.b2b+b2bPoint[cc]*.4 + if P.human then + VOC.play("mini",CHN) + end + else + P.b2b=P.b2b+b2bPoint[cc] + end + P.lastClear=P.cur.id*10+cc + if P.human then + SFX.play(spin_n[cc]) + VOC.play(spinName[P.cur.name],CHN) + end + elseif cc>=4 then + cscore=cc==4 and 1000 or 1500 + if P.b2b>1000 then + P:showText(text.b3b..text.clear[cc],0,-30,50,"fly") + atk=cc+2 sendTime=100 exblock=exblock+1 cscore=cscore*1.8 @@ -1465,83 +1522,33 @@ function player.drop(P)--Place piece VOC.play("b3b",CHN) end elseif P.b2b>=50 then - P:showText(text.techrashB2B,0,-30,50,"drive") + P:showText(text.b2b..text.clear[cc],0,-30,50,"drive") sendTime=80 - atk=5 + atk=cc+1 cscore=cscore*1.3 STAT.b2b=STAT.b2b+1 if P.human then VOC.play("b2b",CHN) end else - P:showText(text.techrash,0,-30,70,"stretch") + P:showText(text.clear[cc],0,-30,70,"stretch") sendTime=60 - atk=4 + atk=cc end - P.b2b=P.b2b+120 - P.lastClear=74 - if P.human then - VOC.play("techrash",CHN) - end - elseif cc>0 then - if dospin then - cscore=spinSCR[P.cur.name][cc] - if P.b2b>1000 then - P:showText(text.b3b..text.spin[P.cur.name]..text.clear[cc],0,-30,35,"spin") - atk=b2bATK[cc]+cc-1 - exblock=exblock+1 - cscore=cscore*2 - STAT.b3b=STAT.b3b+1 - if P.human then - VOC.play("b3b",CHN) - end - elseif P.b2b>=50 then - P:showText(text.b2b..text.spin[P.cur.name]..text.clear[cc],0,-30,35,"spin") - atk=b2bATK[cc] - cscore=cscore*1.2 - STAT.b2b=STAT.b2b+1 - if P.human then - VOC.play("b2b",CHN) - end - else - P:showText(text.spin[P.cur.name]..text.clear[cc],0,-30,45,"spin") - atk=2*cc - end - sendTime=20+atk*20 - if mini then - P:showText(text.mini,0,-80,35,"appear") - atk=atk*.5 - sendTime=sendTime+60 - cscore=cscore*.6 - P.b2b=P.b2b+b2bPoint[cc]*.4 - if P.human then - VOC.play("mini",CHN) - end - else - P.b2b=P.b2b+b2bPoint[cc] - end - P.lastClear=P.cur.id*10+cc - if P.human then - SFX.play(spin_n[cc]) - VOC.play(spinName[P.cur.name],CHN) - end - elseif not clear then + P.b2b=P.b2b+cc*80-300 + P.lastClear=P.cur.name*10+cc + else + if not clear then P.b2b=max(P.b2b-250,0) P:showText(text.clear[cc],0,-30,27+cc*3,"appear",(8-cc)*.3) atk=cc-.75 sendTime=20+atk*20 cscore=cscore+clearSCR[cc] - P.lastClear=cc - end - if P.human then - VOC.play(clearName[cc],CHN) end + P.lastClear=cc end - sendTime=sendTime+25*cmb - if cmb>1 then - atk=atk+(comboAtk[cmb]or 2) - P:showText(text.cmb[min(cmb,20)],0,25,15+min(cmb,25)*3,cmb<10 and"appear"or"flicker") - cscore=cscore+min(20*cmb,300)*cc + if P.human then + VOC.play(clearName[cc],CHN) end if clear then if #P.field==0 then @@ -1572,7 +1579,13 @@ function player.drop(P)--Place piece SFX.play("clear") end end - P.lastClear=P.cur.id*10+5 + P.lastClear=P.cur.name*10+5 + end + sendTime=sendTime+25*cmb + if cmb>1 then + atk=atk+(gbcc>0 and(DigComboAtk[cmb]or 5)or(WidComboAtk[cmb]or 2)) + P:showText(text.cmb[min(cmb,20)],0,25,15+min(cmb,25)*3,cmb<10 and"appear"or"flicker") + cscore=cscore+min(20*cmb,300)*cc end if P.b2b>1200 then P.b2b=1200 end @@ -1655,7 +1668,7 @@ function player.drop(P)--Place piece cmb=0 local dropScore=10 if dospin then - P:showText(text.spin[P.cur.name],0,-30,45,"appear") + P:showText(text.block[P.cur.name]..text.spin,0,-30,45,"appear") P.b2b=P.b2b+20 if P.human then SFX.play("spin_0") @@ -1701,25 +1714,25 @@ function player.drop(P)--Place piece end local n=P.cur.name if dospin then - _=STAT.spin[n] _[cc+1]=_[cc+1]+1--spin[1/2/3/4/5/6/7][0/1/2/3] - _=STAT.spin_S _[cc+1]=_[cc+1]+1--spin[0/1/2/3] - _=STAT.spin_B _[n]=_[n]+1--spin[1/2/3/4/5/6/7] + _=STAT.spin[n] _[cc+1]=_[cc+1]+1--spin[1~25][0~4] + _=STAT.spin_S _[cc+1]=_[cc+1]+1--spin[0~4] + _=STAT.spin_B _[n]=_[n]+1--spin[1~25] elseif cc>0 then - _=STAT.clear[n] _[cc]=_[cc]+1--clear[1/2/3/4/5/6/7][1/2/3/4] - _=STAT.clear_S _[cc]=_[cc]+1--clear[1/2/3/4] - _=STAT.clear_B _[n]=_[n]+1--clear[1/2/3/4/5/6/7] + _=STAT.clear[n] _[cc]=_[cc]+1--clear[1~25][1~5] + _=STAT.clear_S _[cc]=_[cc]+1--clear[1~5] + _=STAT.clear_B _[n]=_[n]+1--clear[1~25] end --Update stat - + _=P.gameEnv.dropPiece if _ then _(P)end --drop event - if P.human then SFX.play("lock",nil,getBlockPosition(P))end + if P.human then SFX.fieldPlay("lock",nil,P)end --stereo SFX end function player.pressKey(P,i) P.keyPressing[i]=true - P.act[actName[i]](P) + P.act[i](P) if P.control then if P.keyRec then ins(P.keyTime,1,frame) @@ -1735,7 +1748,7 @@ function player.releaseKey(P,i) -- if recording then ins(rec,{-i,frame})end end end --------------------------------------------------- +---------------------------------------------------- ---------------------------------------------------- local function gameOver() @@ -1752,13 +1765,11 @@ local function gameOver() modeRanks[M.id]=R _=true end - if r==0 then - for i=1,#M.unlock do - local m=M.unlock[i] - if not modeRanks[m]then - modeRanks[m]=modes[m].score and 0 or 6 - _=true - end + for i=1,#M.unlock do + local m=M.unlock[i] + if not modeRanks[m]then + modeRanks[m]=modes[m].score and 0 or 6 + _=true end end if _ then @@ -1766,9 +1777,9 @@ local function gameOver() end local D=M.score(P) local L=M.records - local p=#L--排名数-1 + local p=#L--Rank-1 if p>0 then - while M.comp(D,L[p])do--是否靠前 + while M.comp(D,L[p])do--if higher rank p=p-1 if p==0 then break end end @@ -1817,7 +1828,7 @@ function player.win(P,result) P:changeAtk() end if P.human then - gameResult=result or"win" + game.result=result or"win" SFX.play("win") VOC.play("win") if modeEnv.royaleMode then @@ -1890,14 +1901,14 @@ function player.lose(P) players.alive[i]:freshTarget() end end - if #players.alive==royaleData.stage[gameStage]then + if #players.alive==royaleData.stage[game.stage]then royaleLevelup() end end P.gameEnv.keepVisible=P.gameEnv.visible~="show" P:showTextF(text.lose,0,0,90,"appear",.5,.2) if P.human then - gameResult="lose" + game.result="lose" SFX.play("fail") VOC.play("lose") if modeEnv.royaleMode then BGM.play("end")end @@ -1910,9 +1921,9 @@ function player.lose(P) end TASK.new(#players>1 and tickEvent.lose or tickEvent.finish,P) end --------------------------<\Events>-------------------------- +--------------------------<\Events>-------------------------- --------------------------------------------------- +---------------------------------------------------- player.act={} function player.act.moveLeft(P,auto) if not auto then @@ -2004,7 +2015,7 @@ function player.act.hardDrop(P) P.fieldOff.vy=P.gameEnv.shakeFX*.6 end if P.human then - SFX.play("drop",nil,getBlockPosition(P)) + SFX.fieldPlay("drop",nil,P) VIB(1) end end @@ -2147,7 +2158,18 @@ function player.act.addRight(P) P.act.insLeft(P) P.act.hardDrop(P) end --------------------------------------------------- +--give operations a num name +A=player.act +T={ + A.moveLeft ,A.moveRight, A.rotRight, A.rotLeft, + A.rot180 ,A.hardDrop, A.softDrop, A.hold, + A.func ,A.restart, A.insLeft, A.insRight, + A.insDown ,A.down1, A.down4, A.down10, + A.dropLeft ,A.dropRight, A.addLeft, A.addRight +}for i=1,20 do A[i]=T[i]end;A,T=nil +---------------------------------------------------- + +---------------------------------------------------- function newDemoPlayer(id,x,y,size) local P={id=id}players[id]=P P.life=1e99 @@ -2166,18 +2188,7 @@ function newDemoPlayer(id,x,y,size) P.alive=true P.control=true P.timing=false - P.stat={ - time=0,score=0, - key=0,rotate=0,hold=0, - extraPiece=0,extraRate=0, - piece=0,row=0,dig=0, - atk=0,digatk=0,send=0,recv=0,pend=0, - clear_S={0,0,0,0},clear_B={0,0,0,0,0,0,0}, - spin_S={0,0,0,0},spin_B={0,0,0,0,0,0,0}, - clear={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - spin={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - pc=0,hpc=0,b2b=0,b3b=0, - } + P.stat=getNewStatTable() P.modeData={point=0,event=0,counter=0} P.keyTime={}P.keySpeed=0 P.dropTime={}P.dropSpeed=0 @@ -2195,7 +2206,7 @@ function newDemoPlayer(id,x,y,size) smooth=setting.smooth,grid=setting.grid, text=setting.text, lockFX=setting.lockFX,dropFX=setting.dropFX, - shakeFX=setting.shakeFX, + clearFX=setting.clearFX,shakeFX=setting.shakeFX, _20G=false,bone=false, drop=1e99,lock=1e99, @@ -2220,6 +2231,7 @@ function newDemoPlayer(id,x,y,size) local ENV=P.gameEnv if ENV.lockFX==0 then ENV.lockFX=nil end if ENV.dropFX==0 then ENV.dropFX=nil end + if ENV.clearFX==0 then ENV.clearFX=nil end if ENV.shakeFX==0 then ENV.shakeFX=nil end P.color={} for _=1,7 do @@ -2259,9 +2271,8 @@ function newDemoPlayer(id,x,y,size) BOT.setNode(opt,P.AIdata.node) P.AI_bot=BOT.new(opt,wei) BOT.free(opt)BOT.free(wei) - local CCBID={4,3,5,6,1,2,0} for i=1,5 do - BOT.addNext(P.AI_bot,CCBID[P.next[i].id]) + BOT.addNext(P.AI_bot,CCblockID[P.next[i].id]) end elseif P.AI_mode=="9S"then P.RS=kickList.TRS @@ -2276,10 +2287,8 @@ function newDemoPlayer(id,x,y,size) P.garbageBeneath=0 P.fieldBeneath=0 P.score1,P.b2b1=0,0 - P.dropFX,P.lockFX={},{} + P.dropFX,P.lockFX,P.clearFX={},{},{} P.bonus={} - P.dust=clearDust:clone() - P.dust:start() P:popNext() end @@ -2303,8 +2312,6 @@ function newAIPlayer(id,x,y,size,AIdata) P.absFieldX=P.x+150*P.size P.absFieldY=P.y+60*P.size P.draw=Pdraw_norm - P.dust=clearDust:clone() - P.dust:start() P.bonus={}--texts end P.update=Pupdate_alive @@ -2312,18 +2319,7 @@ function newAIPlayer(id,x,y,size,AIdata) P.alive=true P.control=false P.timing=false - P.stat={ - time=0,score=0, - key=0,rotate=0,hold=0, - extraPiece=0,extraRate=0, - piece=0,row=0,dig=0, - atk=0,digatk=0,send=0,recv=0,pend=0, - clear_S={0,0,0,0},clear_B={0,0,0,0,0,0,0}, - spin_S={0,0,0,0},spin_B={0,0,0,0,0,0,0}, - clear={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - spin={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - pc=0,hpc=0,b2b=0,b3b=0, - }--Current gamestat + P.stat=getNewStatTable() P.modeData={point=0,event=0,counter=0}--data use by mode P.keyTime={}for i=1,10 do P.keyTime[i]=-1e5 end P.keySpeed=0 P.dropTime={}for i=1,10 do P.dropTime[i]=-1e5 end P.dropSpeed=0 @@ -2379,7 +2375,7 @@ function newAIPlayer(id,x,y,size,AIdata) end ENV.face={0,0,0,0,0,0,0} - ENV.skin={1,5,2,8,10,3,7} + ENV.skin={1,5,8,2,10,3,7} P.human=false P.AI_mode=AIdata.type P.AI_stage=1 @@ -2411,15 +2407,17 @@ function newAIPlayer(id,x,y,size,AIdata) P.RS=kickList.TRS P.AI_keys={} end - + if P.small then ENV.text=false ENV.lockFX=nil ENV.dropFX=nil + ENV.clearFX=nil ENV.shakeFX=nil else if ENV.lockFX==0 then ENV.lockFX=nil end if ENV.dropFX==0 then ENV.dropFX=nil end + if ENV.clearFX==0 then ENV.clearFX=nil end if ENV.shakeFX==0 then ENV.shakeFX=nil end end @@ -2441,7 +2439,7 @@ function newAIPlayer(id,x,y,size,AIdata) P.fieldBeneath=0 P.score1,P.b2b1=0,0 - P.dropFX,P.lockFX={},{} + P.dropFX,P.lockFX,P.clearFX={},{},{} P.bonus={}--texts P.endCounter=0--used after gameover @@ -2460,26 +2458,13 @@ function newPlayer(id,x,y,size) P.absFieldX=P.x+150*P.size P.absFieldY=P.y+60*P.size P.draw=Pdraw_norm - P.dust=clearDust:clone() - P.dust:start() P.bonus={}--texts P.update=Pupdate_alive P.alive=true P.control=false P.timing=false - P.stat={ - time=0,score=0, - key=0,rotate=0,hold=0, - extraPiece=0,extraRate=0, - piece=0,row=0,dig=0, - atk=0,digatk=0,send=0,recv=0,pend=0, - clear_S={0,0,0,0},clear_B={0,0,0,0,0,0,0}, - spin_S={0,0,0,0},spin_B={0,0,0,0,0,0,0}, - clear={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - spin={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, - pc=0,hpc=0,b2b=0,b3b=0, - }--Current gamestat + P.stat=getNewStatTable() P.modeData={point=0,event=0,counter=0}--data use by mode P.keyTime={}for i=1,10 do P.keyTime[i]=-1e5 end P.keySpeed=0 P.dropTime={}for i=1,10 do P.dropTime[i]=-1e5 end P.dropSpeed=0 @@ -2541,6 +2526,7 @@ function newPlayer(id,x,y,size) if ENV.lockFX==0 then ENV.lockFX=nil end if ENV.dropFX==0 then ENV.dropFX=nil end + if ENV.clearFX==0 then ENV.clearFX=nil end if ENV.shakeFX==0 then ENV.shakeFX=nil end P.color={} @@ -2561,9 +2547,10 @@ function newPlayer(id,x,y,size) P.fieldBeneath=0 P.score1,P.b2b1=0,0 - P.dropFX,P.lockFX={},{} + P.dropFX,P.lockFX,P.clearFX={},{},{} P.bonus={}--texts P.endCounter=0--used after gameover P.result=nil--string:"WIN"/"K.O." -end \ No newline at end of file +end +---------------------------------------------------- \ No newline at end of file diff --git a/scene.lua b/scene.lua index f57b6906..93623feb 100644 --- a/scene.lua +++ b/scene.lua @@ -50,8 +50,8 @@ local sceneInit={ end, music=function() if BGM.nowPlay then - for i=1,#musicID do - if musicID[i]==BGM.nowPlay then + for i=1,BGM.len do + if BGM.list[i]==BGM.nowPlay then sceneTemp=i--music select return end @@ -97,6 +97,13 @@ local sceneInit={ BG.set(modeEnv.bg) end, pause=function(org) + if + org=="setting_game"or + org=="setting_video"or + org=="setting_sound" + then + TEXT.show(text.needRestart,640,440,50,"fly",.6) + end local S=players[1].stat sceneTemp={ timer=org=="play"and 0 or 50, @@ -113,7 +120,7 @@ local sceneInit={ format("%d[%.2f%%]",S.extraPiece,100*max(1-S.extraRate/S.piece,0)), }, - --从上开始,顺时针90° + --from right-down, 60 degree each radar={ (S.recv-S.pend+S.dig)/S.time*60,--DefPM (S.recv-S.pend)/S.time*60, --OffPM @@ -161,11 +168,11 @@ local sceneInit={ setting_game=function() BG.set("space") end, - setting_graphic=function() + setting_video=function() BG.set("space") end, setting_sound=function() - sceneTemp={last=0,jump=0}--last sound time,animation count(10→0) + sceneTemp={last=0,jump=0}--last sound time,animation count(10 to 0) BG.set("space") end, setting_control=function() @@ -263,11 +270,12 @@ local backFunc={ mergeStat(stat,players[1].stat) TASK.clear("play") end, + setting_game= function()FILE.saveSetting()end, + setting_video= function()FILE.saveSetting()end, + setting_sound= function()FILE.saveSetting()end, setting_touch= function()FILE.saveVK()end, setting_key= function()FILE.saveKeyMap()end, - setting_game= function()FILE.saveSetting()end, - setting_graphic=function()FILE.saveSetting()end, - setting_sound= function()FILE.saveSetting()end, + setting_lang= function()FILE.saveSetting()end, } function SCN.swapUpdate() local S=SCN.swap @@ -275,12 +283,9 @@ function SCN.swapUpdate() if S.time==S.mid then SCN.init(S.tar,SCN.cur) SCN.cur=S.tar - for _,W in next,Widget[S.tar]do - W:reset() - end--重置控件 - widget_sel=nil + WIDGET.set(widgetList[S.tar]) collectgarbage() - --此时场景切换 + --Scene swapped this moment end if S.time==0 then SCN.swapping=false @@ -311,7 +316,6 @@ function SCN.swapTo(tar,style) S.time=swap[1] S.mid=swap[2] S.draw=swap[3] - widget_sel=nil end end function SCN.back() diff --git a/shader/lightRender.cs b/shader/lightRender.cs index 5f0d9491..ddbbef3f 100644 --- a/shader/lightRender.cs +++ b/shader/lightRender.cs @@ -1,30 +1,29 @@ #define PI 3.14 extern float xresolution; -//从1D距离map采样 +//sample from 1D vis-depth map float samp(vec2 coord,float r,Image u_texture){ return step(r,Texel(u_texture,coord).r); } vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){ - //直角转极坐标,用于采样1D材质的y总是0 + //cartesian to polar, y of 1D sample is always 0 vec2 norm=texture_coords.st*2.-1.; float r=length(norm); vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.); - //根据离光源距离放大模糊系数,模拟影子淡出 - float blur=(1./xresolution)*smoothstep(0.,1.,r); - //简易高斯模糊 - float sum= - samp(vec2(tc.x-4.*blur,tc.y),r,texture)*.5 - +samp(vec2(tc.x-3.*blur,tc.y),r,texture)*.9 - +samp(vec2(tc.x-2.*blur,tc.y),r,texture)*.12 - +samp(vec2(tc.x-1.*blur,tc.y),r,texture)*.15 + //enlarge blur parameter by distance, light scattering simulation + float blur=(1./xresolution)*smoothstep(.3,1.,r); - +samp(tc,r,texture)*.16//The center tex coord,which gives us hard shadows. - +samp(vec2(tc.x+1.*blur,tc.y),r,texture)*.15 - +samp(vec2(tc.x+2.*blur,tc.y),r,texture)*.12 - +samp(vec2(tc.x+3.*blur,tc.y),r,texture)*.9 - +samp(vec2(tc.x+4.*blur,tc.y),r,texture)*.5; - //sum值为亮度(0~1) - //乘上距离得到逐渐变淡的光线 - return vec4(vec3(1.),sum*smoothstep(1.,.1,r)); + //Simple Gaussian blur + float sum=//brightness(0~1) + samp(vec2(tc.x-3.*blur,tc.y),r,texture)*.1 + +samp(vec2(tc.x-2.*blur,tc.y),r,texture)*.13 + +samp(vec2(tc.x-1.*blur,tc.y),r,texture)*.17 + + +samp(tc,r,texture)*.2//The center tex coord,which gives us hard shadows. + +samp(vec2(tc.x+1.*blur,tc.y),r,texture)*.17 + +samp(vec2(tc.x+2.*blur,tc.y),r,texture)*.13 + +samp(vec2(tc.x+3.*blur,tc.y),r,texture)*.1; + + //Multiply the distance to get a soft fading + return vec4(vec3(1.),sum*smoothstep(1.,0.,r)); } \ No newline at end of file diff --git a/shader/shadowMap.cs b/shader/shadowMap.cs index 1dca3529..302fe480 100644 --- a/shader/shadowMap.cs +++ b/shader/shadowMap.cs @@ -3,14 +3,19 @@ extern float yresolution; vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){ //Iterate through the occluder map's y-axis. for(float y=0.;y.1)return vec4(vec3(y/yresolution),1.);//碰撞检测,像素透明度>.1即透光 + + //sample from solid + if( + Texel(texture,( + vec2(-r*sin(theta),-r*cos(theta))*.5+.5//coord of solid sampling + )) + .a>.1 + )return vec4(vec3(y/yresolution),1.);//collision check, alpha>0.1 means transparent } - return vec4(1,1,1,1);//返回最远距离1 + return vec4(1.,1.,1.,1.);//return max distance 1 } \ No newline at end of file diff --git a/texture.lua b/texture.lua index f63a933a..bef19e9c 100644 --- a/texture.lua +++ b/texture.lua @@ -13,7 +13,7 @@ gc.setDefaultFilter("nearest","nearest") gc.setColor(1,1,1) local VKI=N("/image/virtualkey.png") VKIcon={} -for i=1,#actName do +for i=1,20 do VKIcon[i]=C(36,36) gc.draw(VKI,(i-1)%5*-36,int((i-1)*.2)*-36) end @@ -35,18 +35,7 @@ gc.setLineWidth(4) gc.line(0,20,40,20) gc.line(20,0,20,40) -c=C(6,6) -gc.clear(1,1,1) -clearDust=gc.newParticleSystem(c,1000) -c:release() -clearDust:setParticleLifetime(.2,.3) -clearDust:setEmissionRate(0) -clearDust:setLinearAcceleration(-1500,-200,1500,200) -clearDust:setColors(1,1,1,.5,1,1,1,0) ---Dust particles - gc.setDefaultFilter("linear","linear") -batteryImage=N("/image/mess/power.png") drawableText={ question=T(100,"?"), @@ -65,11 +54,11 @@ drawableText={ mxcmb=T(20,"Max Combo"), pc=T(20,"Perfect Clear"), ko=T(25,"KO"), + D=T(100,"D"), C=T(100,"C"), B=T(100,"B"), A=T(100,"A"), S=T(100,"S"), - SS=T(80,"SS"), modeName=T(30),levelName=T(30), @@ -81,7 +70,7 @@ drawableText={ lose=T(120),pause=T(120), custom=T(80), - setting_game=T(80),setting_graphic=T(80),setting_sound=T(80), + setting_game=T(80),setting_video=T(80),setting_sound=T(80), setting_control=T(70),setting_skin=T(70), preview=T(40), keyboard=T(25),joystick=T(25), @@ -89,7 +78,7 @@ drawableText={ musicRoom=T(80), nowPlaying=T(50), VKTchW=T(30),VKOrgW=T(30),VKCurW=T(30), - noScore=T(50), + noScore=T(45), highScore=T(30), } gc.setCanvas() \ No newline at end of file diff --git a/timer.lua b/timer.lua index 432aa84e..49cb1cd2 100644 --- a/timer.lua +++ b/timer.lua @@ -28,7 +28,7 @@ function Tmr.load() -- M.icon=gc.newImage("image/modeIcon/"..m.icon..".png") -- M.icon=gc.newImage("image/modeIcon/custom.png") elseif S.phase==6 then - --------------------------Loading some other things here? + --------------------------Loading other little things here SKIN.load() stat.run=stat.run+1 -------------------------- @@ -52,7 +52,7 @@ function Tmr.load() S.tar=1 end end - until not S.skip or SCN.swapping + until not S.skip and Timer()-t>.01 end function Tmr.intro() sceneTemp=sceneTemp+1 @@ -239,8 +239,8 @@ function Tmr.play(dt) end end function Tmr.pause(dt) - if not gameResult then - pauseTime=pauseTime+dt + if not game.result then + game.pauseTime=game.pauseTime+dt end if sceneTemp.timer<50 then sceneTemp.timer=sceneTemp.timer+1 diff --git a/toolfunc.lua b/toolfunc.lua index 36fb8500..f6bf6697 100644 --- a/toolfunc.lua +++ b/toolfunc.lua @@ -29,7 +29,6 @@ function destroyPlayers() for i=#players,1,-1 do local P=players[i] if P.canvas then P.canvas:release()end - if P.dust then P.dust:release()end while P.field[1]do freeRow.discard(rem(P.field)) freeRow.discard(rem(P.visTime)) @@ -127,8 +126,8 @@ function pasteBoard() ::ERROR::TEXT.show(text.dataCorrupted,350,360,35,"flicker",.5) end -function mergeStat(stat,Δ) - for k,v in next,Δ do +function mergeStat(stat,delta) + for k,v in next,delta do if type(v)=="table"then mergeStat(stat[k],v) else @@ -146,53 +145,53 @@ function randomTarget(P) end end--return a random opponent for P function freshMostDangerous() - mostDangerous,secDangerous=nil + game.mostDangerous,game.secDangerous=nil local m,m2=0,0 for i=1,#players.alive do local h=#players.alive[i].field if h>=m then - mostDangerous,secDangerous=players.alive[i],mostDangerous + game.mostDangerous,game.secDangerous=players.alive[i],game.mostDangerous m,m2=h,m elseif h>=m2 then - secDangerous=players.alive[i] + game.secDangerous=players.alive[i] m2=h end end end function freshMostBadge() - mostBadge,secBadge=nil + game.mostBadge,game.secBadge=nil local m,m2=0,0 for i=1,#players.alive do local h=players.alive[i].badge if h>=m then - mostBadge,secBadge=players.alive[i],mostBadge + game.mostBadge,game.secBadge=players.alive[i],game.mostBadge m,m2=h,m elseif h>=m2 then - secBadge=players.alive[i] + game.secBadge=players.alive[i] m2=h end end end function royaleLevelup() - gameStage=gameStage+1 + game.stage=game.stage+1 local spd TEXT.show(text.royale_remain(#players.alive),640,200,40,"beat",.3) - if gameStage==2 then + if game.stage==2 then spd=30 - elseif gameStage==3 then + elseif game.stage==3 then spd=15 - garbageSpeed=.6 + game.garbageSpeed=.6 if players[1].alive then BGM.play("cruelty")end - elseif gameStage==4 then + elseif game.stage==4 then spd=10 local _=players.alive for i=1,#_ do _[i].gameEnv.pushSpeed=3 end - elseif gameStage==5 then + elseif game.stage==5 then spd=5 - garbageSpeed=1 - elseif gameStage==6 then + game.garbageSpeed=1 + elseif game.stage==6 then spd=3 if players[1].alive then BGM.play("final")end end @@ -214,8 +213,8 @@ end function pauseGame() if not SCN.swapping then restartCount=0--Avoid strange darkness - if not gameResult then - pauseCount=pauseCount+1 + if not game.result then + game.pauseCount=game.pauseCount+1 end for i=1,#players do local l=players[i].keyPressing @@ -243,18 +242,16 @@ function loadGame(M) SFX.play("enter") end function resetPartGameData() - gameResult=false + game={ + result=false, + pauseTime=0, + pauseCount=0, + garbageSpeed=1, + } frame=150-setting.reTime*15 - pauseTime=0 - pauseCount=0 destroyPlayers() curMode.load() TEXT.clear() - for i=1,#players do - if players.dust then - players.dust:reset() - end - end if modeEnv.task then for i=1,#players do TASK.new(modeEnv.task,players[i]) @@ -271,19 +268,20 @@ function resetPartGameData() for i=1,#players do players[i]:changeAtk(randomTarget(players[i])) end - mostBadge,mostDangerous,secBadge,secDangerous=nil - gameStage=1 - garbageSpeed=.3 + game.stage=1 + game.garbageSpeed=.3 end restoreVirtualKey() collectgarbage() end function resetGameData() - gameResult=false + game={ + result=false, + pauseTime=0,--Time paused + pauseCount=0,--Pausing count + garbageSpeed=1,--garbage timing speed + } frame=150-setting.reTime*15 - garbageSpeed=1 - pauseTime=0--Time paused - pauseCount=0--Pausing count destroyPlayers() modeEnv=curMode.env curMode.load()--bg/bgm need redefine in custom,so up here @@ -302,9 +300,8 @@ function resetGameData() for i=1,#players do players[i]:changeAtk(randomTarget(players[i])) end - mostBadge,mostDangerous,secBadge,secDangerous=nil - gameStage=1 - garbageSpeed=.3 + game.stage=1 + game.garbageSpeed=.3 end restoreVirtualKey() stat.game=stat.game+1 diff --git a/updateLog.lua b/updateLog.lua index d71fcb16..76abc168 100644 --- a/updateLog.lua +++ b/updateLog.lua @@ -1,46 +1,56 @@ local S=[=[ "Patron"(time ordered,may not accurate): [rmb100+]: - 那没事了(T6300) - 弥佑瑶 - Alan + 那没事了(T6300) + 加油啊,钉钉动了的大哥哥(T3228) + 弥佑瑶 + Alan [rmb10+]: - 八零哥 - 蕴空之灵 - gggf127 - dtg - ThTsOd - Fireboos - 金巧 - 10元 - 立斐 - 时雪 - yyangdid - sfqr - 心痕 - Sasoric - 夏小亚 - 加油啊,钉钉动了的大哥哥(T3228) - 仁参 - 乐↗乐↘ - 喜欢c4w的ztcjoin - 面包 - 蠢熏 - 潘一栗 - Lied - 星街书婉 - 込余 - 祝西 - 829 - e m*12 - 我永远爱白银诺艾尔(鹏 - PCX - (D*a) + 八零哥 + 蕴空之灵 + gggf127 + dtg + ThTsOd + Fireboos + 金巧 + 10元 + 立斐 + 时雪 + yyangdid + sfqr + 心痕 + Sasoric + 夏小亚 + 仁参 + 乐↗乐↘ + 喜欢c4w的ztcjoin + 面包 + 蠢熏 + 潘一栗 + Lied + 星街书婉 + 込余 + 祝西 + 829 + e m*12 + 我永远爱白银诺艾尔(鹏 + PCX + kagura77 + 呆喂 + GlowingEmbers + 轩辕辚 + HimuroAki + tech有养成系统了@7065 + HAGE KANOBU + 葡萄味的曼妥思 + (闪电和拐棍) + (D*a) - Thanks! + Thanks!!! Future outlook: New mode: + tutorial game Abbr. test backfire finesse exam(3next, 1pt/mino, drop to score) @@ -48,9 +58,14 @@ Future outlook: bigbang rhythm combo - aquare + square field shifting(left/right) - task-based survival + task survival + dig practice + dig zen + symmetry + hidden mode: sound only + reverb mode (often repeat a piece many times) Other: mod system with: block hidden @@ -60,21 +75,49 @@ Future outlook: next hidden field flip(LR/UD) no fail(∞ lives) - 防沉迷系统 + 简易防沉迷系统 + in-game document lang setting page warning FX(Graphic) game recording - powerinfo switch - new virtualWidgets like joysticks - custom sequence + new widgets (joystick etc.) + custom sequence(TTT!) splashing block cool backgrounds more graphic FXs & 3D features & animations - Encrypt source code(compile to byte code) + Encrypt source code (compile to byte code) new AI: task-Z - smarter CC(think of garbage buffer) -0.8.18:Details Update II +0.8.19/20: Fantastic Global Update II + new: + new clearing FX + pentomino with new rotation system (testing) + new PC training mode with over 1000 quiz + new English translation by @MattMayuga#8789 + new language: ??? + language-setting page + [C B A S SS]→[D C B A S] + powerinfo switch + changed: + resume/quit key changed on pause page (quit with Q, resume with esc) + warning when back to pause page from setting page + some FX based on real time + tiny change (almost nothing) changed for powerInfo + page turing of in-game update log changed + readable update log of 0.8+ ver + some new "tips" + add ENG ver. document(not in game) + code: + swap id of J/L + wall-kick list easier to read + no utf8 char in code/comments + less global variables + light module optimized (but not used) + code optimized + fixed: + impossible to get SS in attacker mode + +0.8.18: Details Update II new: adjustable virtualkey SFX & VIB changed: @@ -87,7 +130,7 @@ Future outlook: delete all removable "goto"s! callback system moduled, main.lua easy to read -0.8.17:Details Update +0.8.17: Details Update new: bag seperating line switch better radar chart & statistics on pause page @@ -114,7 +157,8 @@ Future outlook: moving block when changing target in t49/t99 font error in patron list do not reset pause count when restart -0.8.16:Fantastic Global Update + +0.8.16: Fantastic Global Update new: new statistic page with: Radar chart which shows some important info. of player's performance @@ -147,7 +191,8 @@ Future outlook: error when set to max 0 next AI sequence initializing error when face setting changed DAS error -0.8.15:Bug Fixed + +0.8.15: Bug Fixed new: can switch line-clear text now new attack way "Clear"(half-clear) @@ -163,7 +208,7 @@ Future outlook: error when reach 400 in 20G(Lunatic) error block color in modes with starting field -0.8.14:Cool FX +0.8.14: Cool FX new: click/tap/any-key to skip loading animation lock animation @@ -178,7 +223,7 @@ Future outlook: some times error when touch screen touch/press release with no press, then error -0.8.13:O-spin Update++ +0.8.13: O-spin Update++ new: a independent page to set DAS/ARR, with an animation for preview changed: @@ -190,9 +235,9 @@ Future outlook: wrong behavior in pause scene ospin error in 0.8.12 memory leakage in t49/t99 - new behavior of widgets + unnatural behavior of widgets -0.8.12:Bountful Update +0.8.12: Bountful Update new: layout setting: skin system with customizable block color/direction more information when pause @@ -221,7 +266,7 @@ Future outlook: stage reset problem in t49/t99 wrong info in tech-L/U/U+ mode -0.8.11:Total Update +0.8.11: Total Update changed: better rule of checking invalid game can setting when pause @@ -236,7 +281,7 @@ Future outlook: some O-spin error error line counting when pc(full b2b) -0.8.10:Cool Update +0.8.10: Cool Update new: new BGM:Distortion(master-final) all background darker @@ -245,97 +290,127 @@ Future outlook: error when finish master/ultra mode shakeFX no effect when below 3 -0.8.9:System Detail Update - invalid game when pause too much - quick play re-added - new BGM: Oxygen(c4w&pc training) - space background little changed +0.8.9: System Detail Update + new: + invalid game when pause too much + quick play re-added + new BGM: Oxygen(c4w&pc training) + changed: + space background little changed -0.8.8+:Bug-Fix Update +0.8.8+: Bug-Fix Update fixed many fatal bugs -0.8.8:Space BG Update - background now is cool space with "planets" and "stars", not boring falling tetrominos! - records with date - adjustable waiting time before start - ajustable maxnext count - new error page and a new voice - tiny change in rotate system(JL pistol-spin) - marked the modes with limited das/arr - better board copy/paste - no black side in any screen size - an unlock-all easter egg - cannot press invisible func key - fixed: some mode error - add many fatal bugs +0.8.8: Space BG Update + new: + background now is cool space with "planets" and "stars", instead of boring falling tetrominos + no black side in any screen size + adjustable waiting time before start + ajustable maxnext count + marked the modes with limited das/arr + new error page and a new voice + add many fatal bugs + changed: + simple records with date + tiny change in rotate system(JL pistol-spin) + better board copy/paste + an unlock-all easter egg + fixed: + press invisible func key + some mode error -0.8.7:Game Detail Update - better user experience in mode selecting - support 2^n G falling speed - speed of marathon mode changed - shorter clipboard string(when air above) - attack system/score system little changed - fixed: rank system, some mode error when enter(again!) +0.8.7: Game Detail Update + new: + support 2^n G falling speed + changed: + better user experience in mode selecting + speed of marathon mode changed + code: + shorter clipboard string(when air above) + attack system/score system little changed + fixed: + wrong behaviour of rank system + error when enter some mode(again!) -0.8.6:System Detail Update - gamepad can adjust key - add SFX when enter game - map GUI little adjusted - event system little changed(no ctrl when scene swapping) - fixed:rank system, some mode error when enter +0.8.6: System Detail Update + new: + can adjust gamepad keysetting + add SFX when enter game + changed: + map GUI little adjusted + event system little changed(no control when scene swapping) + fixed: + wrong behaviour of rank system + error when enter some mode -0.8.5-:Exploration Update - mode map!Brandly new GUI for mode selecting - mode unlock system, not that scary for noob - every mode has rank calculating method(may some mistakes/inappropriate number) - save 10 best recoreds for each mode - can save/share custom map now - new mode: Big Bang - button appearance changed - better widget performence - remove Qplay - many bug fixed +0.8.5-: Exploration Update + new: + mode map!Brandly new GUI for mode selecting + mode unlock system, not that scary for noob + every mode has rank calculating method(may some mistakes/inappropriate number) + save 10 best recoreds for each mode + can save/share custom map now + "new mode": Big Bang + changed: + button appearance changed + better widget performence + remove Qplay + fixed: + many bugs -0.8.4:Miya Update+ - vocal more natural(important, may cause new bug) - a bit better performence on mobile devices - fatal bug fixed +0.8.4: Miya Update+ + changed: + vocal more natural(important, may cause new bug) + a bit better performence on mobile devices + fixed: + some fatal bugs -0.8.3:Miya Update - new widget appearence - cuter miya +0.8.3: Miya Update + new: + new widget appearence + cuter miya -0.8.2:Graphics Update - miya figure added - new widget appearence - GUI adjusted - bug fixed +0.8.2: Graphics Update + new: + miya figure added + new widget appearence + changed: + GUI adjusted + fixed: + some bugs -0.8.1:Power Info Update - more FX level - better battery info displaying - 3 next in GMroll - bug fixed +0.8.1: Power Info Update + changed: + more FX level + better battery info displaying + 3 next in GMroll + fixed: + some bugs -0.8.0:Small Update - remade text system - more details - bug fixed +0.8.0: Small Update + new: + better update log from now on(2020.5.2) + changed: + more details + code: + remade text system + fixed: + some bugs -0.7.35:Bug Fixed - bug fixed +0.7.35: Bug Fixed + yeah, only bug fixed -0.7.34:Voice Update+ +0.7.34: Voice Update+ replace most voice shaking FX more natural -0.7.33+:Bot Update +0.7.33+: Bot Update MORE POWERFUL 9-stack AI add stereo-setting slider code optimized bug fixed -0.7.32:Virtualkey Update+ +0.7.32: Virtualkey Update+ Blind-GM now show section directly easier&more standard classic mode can switch Virtualkey's auto dodging @@ -343,11 +418,11 @@ Future outlook: code optimized bug fixed -0.7.31:Stereo Update +0.7.31: Stereo Update stereo system fixed a problem in finesse calculating -0.7.30:Virtualkey Update +0.7.30: Virtualkey Update auto-tracking virtual key, adjustable parameters! can switch on/off virtuakeys add 7 more key @@ -358,26 +433,26 @@ Future outlook: adjusted GUI many bug fixed -0.7.28:Finesse Update +0.7.28: Finesse Update add fineese check(almost useful) code optimized -0.7.27:O-spin Update+ +0.7.27: O-spin Update+ super O transform system - optimized light system(no used) + optimized system(no used) bug fixed -0.7.26:Bug Fixed +0.7.26: Bug Fixed new skin import light lib many bug fixed -0.7.25:Demo Update +0.7.25: Demo Update demo play at main menu ALMOST reconstructed WHOLE PLAYER SYSTEM, NEED TEST many bug fixed -0.7.23/24:Feast of Hearing +0.7.23/24: Feast of Hearing all bgm remade more settings with brand new GUI! new mode: Master-Final @@ -390,7 +465,7 @@ Future outlook: code optimized many bugs fixed -0.7.22:Graphics Update +0.7.22: Graphics Update scoring system smooth dropping can change FX level @@ -406,12 +481,12 @@ Future outlook: support 10% step alpha of virtual key many code optimized&bugs fixed -0.7.21:Title Update +0.7.21: Title Update new title image more GUI details many bugs fixed -0.7.20:Music Room Update +0.7.20: Music Room Update add music room change block/space apperance in draw mode field shake animation @@ -419,7 +494,7 @@ Future outlook: can set BG/BGM in custom mode bug fixed -0.7.19:Voice Update +0.7.19: Voice Update voice system added(voice by Miya) support macOS! new mode: C4W training @@ -430,7 +505,7 @@ Future outlook: new background/sound effect in master mode bug fixed -0.7.18:Skin Update +0.7.18: Skin Update 3 new block skins!(one skin origional by Miya(nya~)) better restarting(to prevent mistakenly touching) switch display of puzzle mode @@ -438,7 +513,7 @@ Future outlook: code optimized default custom options changed to as infinite mode -0.7.17:Pause Update +0.7.17: Pause Update display game stats when pause more options in statistics better pausing @@ -448,7 +523,7 @@ Future outlook: little optimized bugs fixed -0.7.16:Game Detail Update +0.7.16: Game Detail Update change rules of custom puzzle mode change rules of TSD mode better pausing @@ -456,31 +531,31 @@ Future outlook: adjust difficulty of dig mode bugs fixed -0.7.15:Puzzle Update +0.7.15: Puzzle Update can make puzzle by drawing mode can pause game with animation change icon of "Functional key" speed optimized bugs fixed -0.7.14:Creativity Update +0.7.14: Creativity Update drawing mode in custom game adjustable virtual keys with mouse speed optimized rotate also create shade -0.7.13+:Small Update +0.7.13+: Small Update change difficulty of survivor mode little game rule change bugs fixed(AI control error) -0.7.13: +0.7.13: new: Chinese game name: 方块研究所 SUPER COOL instant moving effect new b2b bar style & animation new transition animation - change: + changed: change difficulty of master mode adjust delay algorithm(probably cause controlfeel changing, please reset your DAS setting) code reconstructed @@ -489,7 +564,7 @@ Future outlook: error when seq=his error game area size of custom opponent -0.7.12:Total Update +0.7.12: Total Update AI learned to switch attack mode seperate master mode from marathon mode master mode more interesting @@ -503,7 +578,7 @@ Future outlook: some Chinese translaton editted [reconstruct event system] -0.7.11:Total Update +0.7.11: Total Update some Chinese translaton editted add bone block in 2 hardest marathon(new block-fresh system) play sound when get badges in royale mode @@ -515,13 +590,13 @@ Future outlook: add QR code in help page change some detials -0.7.10:Small Update +0.7.10: Small Update full Chinese translation add Classic mode change O spin's behaviour bugs fixed -0.7.9:O-spin Update +0.7.9: O-spin Update O spin is a lie better attacking pointer language system @@ -530,7 +605,7 @@ Future outlook: code optimized bugs fixed -0.7.8:Performance Update +0.7.8: Performance Update GPU usage decreased much more than before add virtual key animation display player's rank after death in royale mode @@ -539,7 +614,7 @@ Future outlook: code optimized bugs fixed -0.7.7:Mode Update +0.7.7: Mode Update add dig mode add survivor mode combine some modes @@ -547,7 +622,7 @@ Future outlook: more SFXs bugs fixed -0.7.6:Mode Update +0.7.6: Mode Update new font add DIFFICULTY selection virtual keys give visual feedback(PC/phone) @@ -560,7 +635,7 @@ Future outlook: fix all attacking bug of royale mode change sequence of TSD-only mode to bag7 -0.7.5:Total Update +0.7.5: Total Update reduce difficuly of PC training mode, and add more patterns reduce difficuly of death mode add PC challenge mode @@ -575,10 +650,10 @@ Future outlook: change sequence of TSD-only mode royale mode use LESS GPU -0.7.4:Bug Update +0.7.4: Bug Update add a lot of bugs -0.7.3:Game Detail Update +0.7.3: Game Detail Update add infinite target in custom fix TSD-only mode result+1 when finishing with a wrong clear change sequence generator of TSD-only mode @@ -586,7 +661,7 @@ Future outlook: Fix Screen flow smarter AI -0.7.2:Mode Update +0.7.2: Mode Update add PC training mode add TSD-only mode remove non-sense s/z spin double @@ -594,12 +669,19 @@ Future outlook: grid BG changed smarter AI ]=] + local find,sub=string.find,string.sub -local L,n,p={},1,1 +local L,c={},0--list, \n counter, +local p,p1=1,0--cut start/end pos local EOF=#S -repeat - p1=find(S,"\n",p) - L[n]=sub(S,p,p1-1) - n,p=n+1,p1+1 -until p1==EOF -return L \ No newline at end of file + +while true do + p1=find(S,"\n",p1+1) + c=c+1 + if c==23 or p1==EOF then + L[#L+1]=sub(S,p,p1-1) + if p1==EOF then return L end + p=p1+1 + c=0 + end +end \ No newline at end of file diff --git a/widgetList.lua b/widgetList.lua index c640aee7..ec1d4ec7 100644 --- a/widgetList.lua +++ b/widgetList.lua @@ -1,4 +1,4 @@ -local mobile=system=="Android"or system=="iOS" +mobileHide=loadstring("function()return "..tostring(system=="Android"or system=="iOS").." end") local virtualkeySet={ { {1, 80, 720-200, 80},--moveLeft @@ -71,36 +71,23 @@ local virtualkeySet={ {20,1210, 50,30},--addRight },--PC key feedback(top&in a row) } -local customSet={ - {3,20,1,1,7,1,1,1,3,4,1,2,3}, - {5,20,1,1,7,1,1,1,8,3,8,3,3}, - {1,22,1,1,7,3,1,1,8,4,1,7,7}, - {3,20,1,1,7,1,1,3,8,3,1,7,8}, - {25,11,8,11,4,1,2,1,8,3,1,4,9}, -} ---λFuncs for widgets,delete at file end -function defSet(n) - return function() - for i=1,#customSet[n]do - customSel[i]=customSet[n][i] - end - BG.set(customRange.bg[customSel[12]]) - BGM.play(customRange.bgm[customSel[13]]) - end -end -function SETval(k) return function()return setting[k] end end -function SETsto(k) return function(i)setting[k]=i end end -function SETrev(k) return function()setting[k]=not setting[k] end end -function pressKey(k)return function()love.keypressed(k) end end -function setPen(i) return function()sceneTemp.pen=i end end -function prevSkin(n)return function()SKIN.prev(n) end end -function nextSkin(n)return function()SKIN.next(n) end end -function nextDir(n) return function()SKIN.rotate(n) end end -function VKAdisp(n) return function()return VK_org[n].ava end end -function VKAcode(n) return function()VK_org[n].ava=not VK_org[n].ava end end + +--lambda Funcs for widgets,delete at file end +local function SETval(k) return function()return setting[k] end end +local function SETsto(k) return function(i)setting[k]=i end end +local function SETrev(k) return function()setting[k]=not setting[k] end end +local function pressKey(k) return function()love.keypressed(k) end end +local function setPen(i) return function()sceneTemp.pen=i end end +local function prevSkin(n) return function()SKIN.prev(n) end end +local function nextSkin(n) return function()SKIN.next(n) end end +local function nextDir(n) return function()SKIN.rotate(n) end end +local function VKAdisp(n) return function()return VK_org[n].ava end end +local function VKAcode(n) return function()VK_org[n].ava=not VK_org[n].ava end end +local function setLang(n) return function()LANG.set(n)setting.lang=n end end +local newButton,newSwitch,newSlider=WIDGET.new.button,WIDGET.new.switch,WIDGET.new.slider local C=color -local Widget={ +local widgetList={ load={},intro={},quit={}, main={ play= newButton(150,280,200,160,C.lightRed, 55,function()SCN.push()SCN.swapTo("mode")end, nil,"setting"), @@ -109,16 +96,12 @@ local Widget={ help= newButton(150,460,200,160,C.lightYellow, 50,function()SCN.push()SCN.swapTo("help")end, nil,"stat"), stat= newButton(370,460,200,160,C.lightCyan, 43,function()SCN.push()SCN.swapTo("stat")end, nil,"qplay"), qplay= newButton(590,460,200,160,C.lightOrange, 43,function()SCN.push()loadGame(stat.lastPlay)end, nil,"lang"), - lang= newButton(150,610,160,100,C.lightGreen, 45,function() - setting.lang=setting.lang%LANG.getLen()+1 - LANG.set(setting.lang) - TEXT.show(text.lang,370,610,50,"appear",1.6) - end,nil,"quit"), + lang= newButton(150,610,160,100,C.lightGreen, 45,function()SCN.push()SCN.swapTo("setting_lang")end, nil,"quit"), quit= newButton(590,610,160,100,C.lightGrey, 45,function()VOC.play("bye")SCN.swapTo("quit","slowFade")end,nil,"play"), }, mode={ - draw= newButton(1100, 440,220,90,C.lightYellow, 40,function()SCN.push()SCN.swapTo("draw")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), - custom=newButton(1100, 540,220,90,C.lightGreen, 40,function()SCN.push()SCN.swapTo("custom")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), + draw= newButton(1100, 440,240,90,C.lightYellow, 40,function()SCN.push()SCN.swapTo("draw")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), + custom= newButton(1100, 540,240,90,C.lightGreen, 40,function()SCN.push()SCN.swapTo("custom")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), start= newButton(1040, 655,180,80,C.lightGrey, 40,function()if mapCam.sel then SCN.push()loadGame(mapCam.sel)end end,function()return not mapCam.sel end), back= newButton(1200, 655,120,80,C.white, 40,SCN.back), --function()SCN.push()SCN.swapTo("custom")end @@ -135,11 +118,11 @@ local Widget={ down= newButton(1000, 600,100,100,C.white, 45,function()sceneTemp=sceneTemp%#customID+1 end), left= newButton(880, 480,100,100,C.white, 45,pressKey("left")), right= newButton(1120, 480,100,100,C.white, 45,pressKey("right")), - set1= newButton(640, 160,240,75, C.lightYellow, 35,defSet(1)), - set2= newButton(640, 250,240,75, C.lightYellow, 35,defSet(2)), - set3= newButton(640, 340,240,75, C.lightYellow, 35,defSet(3)), - set4= newButton(640, 430,240,75, C.lightYellow, 35,defSet(4)), - set5= newButton(640, 520,240,75, C.lightYellow, 35,defSet(5)), + set1= newButton(640, 160,240,75, C.lightYellow, 35,pressKey("1")), + set2= newButton(640, 250,240,75, C.lightYellow, 35,pressKey("2")), + set3= newButton(640, 340,240,75, C.lightYellow, 35,pressKey("3")), + set4= newButton(640, 430,240,75, C.lightYellow, 35,pressKey("4")), + set5= newButton(640, 520,240,75, C.lightYellow, 35,pressKey("5")), back= newButton(640, 630,180,60, C.white, 35,SCN.back), }, draw={ @@ -181,13 +164,13 @@ local Widget={ resetGameData() SCN.swapTo("play","none") end), - setting=newButton(1130,70,180,90,C.lightBlue,35,function() + setting=newButton(1120,70,240,90,C.lightBlue,35,function() SCN.push()SCN.swapTo("setting_sound") end), quit= newButton(640,600,240,100,C.white,35,SCN.back), }, setting_game={ - graphic=newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_graphic")end, nil,"sound"), + graphic=newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_video")end, nil,"sound"), sound= newButton(1080,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_sound")end, nil,"ctrl"), ctrl= newButton(290,220,320,80,C.lightYellow,35,function()SCN.push()SCN.swapTo("setting_control")end, nil,"key"), key= newButton(640,220,320,80,C.lightGreen,35,function()SCN.push()SCN.swapTo("setting_key")end, nil,"touch"), @@ -204,35 +187,39 @@ local Widget={ fine= newSwitch(1050,540,20, SETval("fine"), SETrev("fine"), nil,"back"), back= newButton(1140,650,200,80,C.white,40,SCN.back, nil,"graphic"), }, - setting_graphic={ + setting_video={ sound= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_sound")end, nil,"game"), game= newButton(1080,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_game")end, nil,"ghost"), - ghost= newSwitch(230,180,35, SETval("ghost"), SETrev("ghost"), nil,"smooth"), - smooth= newSwitch(230,260,25, SETval("smooth"), SETrev("smooth"), nil,"center"), - center= newSwitch(480,180,35, SETval("center"), SETrev("center"), nil,"grid"), - grid= newSwitch(480,260,30, SETval("grid"), SETrev("grid"), nil,"bagLine"), + ghost= newSwitch(250,180,35, SETval("ghost"), SETrev("ghost"), nil,"smooth"), + smooth= newSwitch(250,260,25, SETval("smooth"), SETrev("smooth"), nil,"center"), + center= newSwitch(500,180,35, SETval("center"), SETrev("center"), nil,"grid"), + grid= newSwitch(500,260,30, SETval("grid"), SETrev("grid"), nil,"bagLine"), bagLine=newSwitch(730,180,30, SETval("bagLine"), SETrev("bagLine"), nil,"lockFX"), - lockFX= newSlider(310,340,373,3,35,nil, SETval("lockFX"), SETsto("lockFX"), nil,"dropFX"), - dropFX= newSlider(310,410,373,5,35,nil, SETval("dropFX"), SETsto("dropFX"), nil,"shakeFX"), - shakeFX=newSlider(310,480,373,5,35,nil, SETval("shakeFX"), SETsto("shakeFX"), nil,"atkFX"), - atkFX= newSlider(310,550,373,5,35,nil, SETval("atkFX"), SETsto("atkFX"), nil,"frame"), - frame= newSlider(310,620,373,10,35,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"text"), - text= newSwitch(990,180,35,SETval("text"),SETrev("text"),nil,"fullscreen"), - fullscreen=newSwitch(990,260,35,SETval("fullscreen"),function() + lockFX= newSlider(350,340,373,3,32,nil, SETval("lockFX"), SETsto("lockFX"), nil,"dropFX"), + dropFX= newSlider(350,400,373,5,32,nil, SETval("dropFX"), SETsto("dropFX"), nil,"clearFX"), + clearFX=newSlider(350,460,373,3,32,nil, SETval("clearFX"), SETsto("clearFX"), nil,"shakeFX"), + shakeFX=newSlider(350,520,373,5,32,nil, SETval("shakeFX"), SETsto("shakeFX"), nil,"atkFX"), + atkFX= newSlider(350,580,373,5,32,nil, SETval("atkFX"), SETsto("atkFX"), nil,"frame"), + frame= newSlider(350,640,373,10,30,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"text"), + text= newSwitch(1050,180,35,SETval("text"),SETrev("text"),nil,"fullscreen"), + fullscreen=newSwitch(1050,260,35,SETval("fullscreen"),function() setting.fullscreen=not setting.fullscreen love.window.setFullscreen(setting.fullscreen) love.resize(love.graphics.getWidth(),love.graphics.getHeight()) end,nil,"bg"), - bg= newSwitch(990,330,35,SETval("bg"),function() + bg= newSwitch(1050,340,35,SETval("bg"),function() BG.set("none") setting.bg=not setting.bg BG.set("space") + end,nil,"power"), + power= newSwitch(1050,420,35,SETval("powerInfo"),function() + setting.powerInfo=not setting.powerInfo end,nil,"back"), back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"sound"), }, setting_sound={ game= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_game")end, nil,"graphic"), - graphic=newButton(1080,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_graphic")end, nil,"sfx"), + graphic=newButton(1080,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_video")end, nil,"sfx"), sfx= newSlider(180,250,400,10,35,function()SFX.play("blip_1")end, SETval("sfx"), SETsto("sfx"), nil,"bgm"), bgm= newSlider(750,250,400,10,35,function()BGM.freshVolume()end, SETval("bgm"), SETsto("bgm"), nil,"vib"), vib= newSlider(180,440,400,5 ,28,function()VIB(2)end, SETval("vib"), SETsto("vib"), nil,"voc"), @@ -286,7 +273,7 @@ local Widget={ --spin6=newButton(825,540,90,65,C.white,30,nextDir(6)),--cannot rotate O spin7= newButton(970,540,90,65,C.white,30,nextDir(7)), - skinR= newButton(200,640,220,80,C.lightPurple,35,function()setting.skin={1,5,2,8,10,3,7}SFX.play("rotate")end), + skinR= newButton(200,640,220,80,C.lightPurple,35,function()setting.skin={1,5,8,2,10,3,7}SFX.play("rotate")end), faceR= newButton(480,640,220,80,C.lightRed,35,function()setting.face={0,0,0,0,0,0,0}SFX.play("hold")end), back= newButton(1140,650,200,80,C.white,40,SCN.back), }, @@ -366,27 +353,38 @@ local Widget={ VKCurW= newSlider(140,370,1000,10,35,nil,SETval("VKCurW"),function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end), back= newButton(1080,600,240,80,C.white,45,SCN.back), }, + setting_lang={ + chi= newButton(160,100,200,120,C.white,45,setLang(1),nil,"chi2"), + chi2= newButton(380,100,200,120,C.white,45,setLang(2),nil,"eng"), + eng= newButton(600,100,200,120,C.white,45,setLang(3),nil,"str"), + str= newButton(820,100,200,120,C.white,45,setLang(4),nil,"back"), + back= newButton(640,600,200,80,C.white,40,SCN.back,nil,"chi"), + }, help={ his= newButton(1050,500,250,80,C.white,35,function()SCN.push()SCN.swapTo("history")end,nil,"back"), - qq= newButton(1050,600,250,80,C.white,35,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,function()return mobile end,"his"), - back= newButton(640, 600,200,80,C.white,40,SCN.back,nil,"qq"), + qq= newButton(1050,600,250,80,C.white,35,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,mobileHide,"his"), + back= newButton(640,600,200,80,C.white,40,SCN.back,nil,"qq"), }, history={ prev= newButton(1155,170,180,180,C.white,65,pressKey("up"),function()return sceneTemp[2]==1 end), - next= newButton(1155,400,180,180,C.white,65,pressKey("down"),function()return sceneTemp[2]==#sceneTemp[1]-22 end), + next= newButton(1155,400,180,180,C.white,65,pressKey("down"),function()return sceneTemp[2]==#sceneTemp[1]end), back= newButton(1155,600,180,90,C.white,40,SCN.back), }, stat={ - path= newButton(980,620,250,80,C.white,25,function()love.system.openURL(love.filesystem.getSaveDirectory())end,function()return mobile end,"back"), + path= newButton(980,620,250,80,C.white,25,function()love.system.openURL(love.filesystem.getSaveDirectory())end,mobileHide,"back"), back= newButton(640,620,200,80,C.white,40,SCN.back,nil,"path"), }, } -defSet,SETval,SETsto,SETrev,pressKey,setPen,prevSkin,nextSkin,nextDir,VKAdisp,VKAcode=nil -for _,L in next,Widget do +mobileHide,SETval,SETsto,SETrev=nil +pressKey,setPen,prevSkin,nextSkin=nil +nextDir,VKAdisp,VKAcode,setLang=nil +newButton,newSwitch,newSlider=nil + +for _,L in next,widgetList do for _,W in next,L do if W.next then W.next,L[W.next].prev=L[W.next],W end end end -return Widget \ No newline at end of file +return widgetList \ No newline at end of file