diff --git a/callback.lua b/callback.lua index c8c93e91..1e4ebb2d 100644 --- a/callback.lua +++ b/callback.lua @@ -5,10 +5,6 @@ local int,rnd,max,min=math.floor,math.random,math.max,math.min local abs=math.abs local rem=table.remove -kb.setKeyRepeat(true) -kb.setTextInput(false) -ms.setVisible(false) - local scr=scr local xOy=love.math.newTransform() local mx,my,mouseShow=-20,-20,false @@ -17,7 +13,6 @@ local touchDist=nil joysticks={} local devMode -players={alive={},human=0} local Tmr=require("timer") local Pnt=require("paint") @@ -153,7 +148,7 @@ local function onMode(x,y) local cam=mapCam x=(cam.x1-640+x)/cam.k1 y=(cam.y1-360+y)/cam.k1 - local MM,R=modes,modeRanks + local MM,R=Modes,modeRanks for _=1,#MM do if R[_]then local M=MM[_] @@ -199,7 +194,7 @@ function mouseClick.mode(x,y,k) if __ then SFX.play("click") cam.moving=true - _=modes[__] + _=Modes[__] cam.x=_.x*cam.k+180 cam.y=_.y*cam.k cam.sel=__ @@ -402,17 +397,17 @@ function mouseDown.setting_sound(x,y,k) VOC.play((t<1.5 or t>15)and"doubt"or rnd()<.8 and"happy"or"egg") sceneTemp.last=Timer() if rnd()<.0626 then - for i=1,#modes do - local M=modes[i] + for i=1,#Modes do + local M=Modes[i] 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 + modeRanks[m]=Modes[m].score and 0 or 6 end end end FILE.saveUnlock() - TEXT.show("DEVMODE:UNLOCKALL",640,360,50,"stretch",.6) + TEXT.show("DEVModes:UNLOCKALL",640,360,50,"stretch",.6) end end end diff --git a/conf.lua b/conf.lua index e0b720f2..db5418f7 100644 --- a/conf.lua +++ b/conf.lua @@ -6,7 +6,7 @@ function love.conf(t) t.gammacorrect=false t.appendidentity=true--search files in source before save directory t.accelerometerjoystick=false--accelerometer=joystick on ios/android - t.audio.mixwithsystem=true + if t.audio then t.audio.mixwithsystem=true end local W=t.window W.title="Techmino "..gameVersion diff --git a/main.lua b/main.lua index 0be8cadb..6df49ba6 100644 --- a/main.lua +++ b/main.lua @@ -2,8 +2,15 @@ Techmino is my first "huge project" optimization is welcomed if you also love tetromino game ]] + +--Global Setting & Vars +package.path="./?.lua;./parts/?.lua;./modules/?.lua" math.randomseed(os.time()*626) ---Global vars +love.keyboard.setKeyRepeat(true) +love.keyboard.setTextInput(false) +love.mouse.setVisible(false) + +function NULL()end system=love.system.getOS() game={} mapCam={ @@ -22,46 +29,49 @@ mapCam={ 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 +players={alive={},human=0} --blockSkin,blockSkinMini={},{}--redefined in SKIN.change --Load modules -setFont=require("parts/setfont") -color=require("parts/color") -blocks=require("parts/mino") -SHADER=require("parts/shader") -AITemplate=require("parts/AITemplate") -freeRow=require("parts/freeRow") -tickEvent=require("parts/tickEvent") +color= require("color") +blocks= require("mino") +AITemplate= require("AITemplate") +freeRow= require("freeRow") -require("parts/list") require("toolfunc") +require("list") +require("gametoolfunc") require("texture") +require("default_data") -SCN=require("scene") -VIB=require("parts/vib") -SFX=require("parts/sfx") -sysFX=require("parts/sysFX") -BGM=require("parts/bgm") -VOC=require("parts/voice") -SKIN=require("parts/skin") -LANG=require("parts/languages") -FILE=require("parts/file") -TEXT=require("parts/text") -TASK=require("parts/task") -BG=require("parts/bg") -IMG=require("parts/img") -WIDGET=require("parts/widget") -LIGHT=require("parts/light") +SKIN= require("skin") +PLY= require("player") +AIfunc= require("ai") +Modes= require("modes") -require("parts/modes") -require("parts/default_data") -require("parts/ai") -PLY=require("player") -widgetList=require("widgetList") +--load Z's Framework +SHADER= require("shader") +VIB= require("vib") +SFX= require("sfx") +sysFX= require("sysFX") +BG= require("bg") +BGM= require("bgm") +VOC= require("voice") +LANG= require("languages") +FILE= require("file") +TEXT= require("text") +TASK= require("task") +IMG= require("img") +WIDGET= require("widget") +Widgets=require("widgetList") +LIGHT= require("light") +SCN= require("scene") require("callback") --load files & settings +modeRanks={}for i=1,#Modes do modeRanks[i]=false assert(i==Modes[i].id,"ModeID error:"..i)end +modeRanks[1]=0 + local fs=love.filesystem if fs.getInfo("keymap.dat")then fs.remove("keymap.dat")end if fs.getInfo("setting.dat")then fs.remove("setting.dat")end diff --git a/modes/infinite.lua b/modes/infinite.lua index b29b5fa9..5cc85e5f 100644 --- a/modes/infinite.lua +++ b/modes/infinite.lua @@ -22,7 +22,7 @@ return{ getRank=function(P) local L=P.stat.row return - L>=2600 and 5 or + L>=2000 and 5 or L>=1500 and 4 or L>=1000 and 3 or L>=500 and 2 or diff --git a/modes/pcchallenge_normal.lua b/modes/pcchallenge_normal.lua index ea1703ce..c8225775 100644 --- a/modes/pcchallenge_normal.lua +++ b/modes/pcchallenge_normal.lua @@ -27,7 +27,7 @@ return{ getRank=function(P) local L=P.stat.pc return - L>=25 and 5 or + L>=24 and 5 or L>=20 and 4 or L>=16 and 3 or L>=13 and 2 or diff --git a/paint.lua b/paint.lua index 1d6ffe75..e07e1ffe 100644 --- a/paint.lua +++ b/paint.lua @@ -152,7 +152,7 @@ function Pnt.mode() gc.scale(cam.zoomK) gc.translate(-cam.x1,-cam.y1) gc.scale(cam.k1) - local MM=modes + local MM=Modes local R=modeRanks local sel=cam.sel setFont(30) diff --git a/parts/ai.lua b/parts/ai.lua index 229d76a5..ffd067df 100644 --- a/parts/ai.lua +++ b/parts/ai.lua @@ -192,7 +192,7 @@ local function getScore(field,cb,cy) return score end ------------------------------------------------- -AI_think={ +return{ ["9S"]={ function(P,ctrl) local Tfield={}--test field diff --git a/parts/bgm.lua b/parts/bgm.lua index b537bbc8..a2a3439b 100644 --- a/parts/bgm.lua +++ b/parts/bgm.lua @@ -1,5 +1,22 @@ +local min=math.min local rem=table.remove +local function fadeOut(_,id) + local src=BGM.list[id] + local v=src:getVolume()-.025*setting.bgm*.1 + src:setVolume(v>0 and v or 0) + if v<=0 then + src:stop() + return true + end +end +local function fadeIn(_,id) + local src=BGM.list[id] + local v=min(src:getVolume()+.025*setting.bgm*.1,setting.bgm*.1) + src:setVolume(v) + if v>=setting.bgm*.1 then return true end +end + local BGM={ --nowPlay=[str:playing ID] --suspend=[str:pausing ID] @@ -36,12 +53,12 @@ function BGM.play(s) return end if BGM.nowPlay~=s then - if BGM.nowPlay then TASK.new(tickEvent.bgmFadeOut,nil,BGM.nowPlay)end - TASK.changeCode(tickEvent.bgmFadeIn,tickEvent.bgmFadeOut) + if BGM.nowPlay then TASK.new(fadeOut,nil,BGM.nowPlay)end + TASK.changeCode(fadeIn,fadeOut) TASK.removeTask_data(s) BGM.nowPlay,BGM.suspend=s - TASK.new(tickEvent.bgmFadeIn,nil,s) + TASK.new(fadeIn,nil,s) BGM.playing=BGM.list[s] BGM.playing:play() end @@ -64,9 +81,9 @@ function BGM.freshVolume() end function BGM.stop() if BGM.nowPlay then - TASK.new(tickEvent.bgmFadeOut,nil,BGM.nowPlay) + TASK.new(fadeOut,nil,BGM.nowPlay) end - TASK.changeCode(tickEvent.bgmFadeIn,tickEvent.bgmFadeOut) + TASK.changeCode(fadeIn,fadeOut) BGM.playing,BGM.nowPlay=nil end return BGM \ No newline at end of file diff --git a/parts/gametoolfunc.lua b/parts/gametoolfunc.lua new file mode 100644 index 00000000..6cd3551e --- /dev/null +++ b/parts/gametoolfunc.lua @@ -0,0 +1,304 @@ +local tm,gc=love.timer,love.graphics +local kb,data=love.keyboard,love.data +local int,abs,rnd=math.floor,math.abs,math.random +local max,min=math.max,math.min +local sub,find=string.sub,string.find +local char,byte=string.char,string.byte +local ins,rem=table.insert,table.remove + +function destroyPlayers() + for i=#players,1,-1 do + local P=players[i] + if P.canvas then P.canvas:release()end + while P.field[1]do + freeRow.discard(rem(P.field)) + freeRow.discard(rem(P.visTime)) + end + if P.AI_mode=="CC"then + BOT.free(P.bot_opt) + BOT.free(P.bot_wei) + BOT.destroy(P.AI_bot) + P.AI_mode=nil + end + players[i]=nil + end + for i=#players.alive,1,-1 do + players.alive[i]=nil + end + players.human=0 + collectgarbage() +end + +function restoreVirtualKey() + for i=1,#VK_org do + local B,O=virtualkey[i],VK_org[i] + B.ava=O.ava + B.x=O.x + B.y=O.y + B.r=O.r + B.isDown=false + B.pressTime=0 + end + if not modeEnv.Fkey then + virtualkey[9].ava=false + end +end +function copyBoard() + local str="" + local H=0 + for y=20,1,-1 do + for x=1,10 do + if preField[y][x]~=0 then + H=y + goto L + end + end + end + ::L:: + for y=1,H do + local S="" + local L=preField[y] + for x=1,10 do + S=S..char(L[x]+1) + end + str=str..S + end + love.system.setClipboardText("Techmino sketchpad:"..data.encode("string","base64",data.compress("string","deflate",str))) + TEXT.show(text.copySuccess,350,360,40,"appear",.5) +end +function pasteBoard() + local str=love.system.getClipboardText() + local fX,fY=1,1--*ptr for Field(r*10+(c-1)) + local _,Bid + local p=find(str,":")--ptr* + if p then str=sub(str,p+1)end + _,str=pcall(data.decode,"string","base64",str) + if not _ then goto ERROR end + _,str=pcall(data.decompress,"string","deflate",str) + if not _ then goto ERROR end + p=1 + while true do + _=byte(str,p)--1byte + if not _ then + if fX~=1 then goto ERROR + else break + end + end--str end + __=_%32-1--block id + if __>17 then goto ERROR end--illegal blockid + _=int(_/32)--mode id + preField[fY][fX]=__ + if fX<10 then + fX=fX+1 + else + if fY==20 then break end + fX=1;fY=fY+1 + end + p=p+1 + end + + for y=fY+1,20 do + for x=1,10 do + preField[y][x]=0 + end + end + do return end + ::ERROR::TEXT.show(text.dataCorrupted,350,360,35,"flicker",.5) +end + +function mergeStat(stat,delta) + for k,v in next,delta do + if type(v)=="table"then + mergeStat(stat[k],v) + else + stat[k]=stat[k]+v + end + end +end +function randomTarget(P) + if #players.alive>1 then + local R + repeat + R=players.alive[rnd(#players.alive)] + until R~=P + return R + end +end--return a random opponent for P +function freshMostDangerous() + 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 + game.mostDangerous,game.secDangerous=players.alive[i],game.mostDangerous + m,m2=h,m + elseif h>=m2 then + game.secDangerous=players.alive[i] + m2=h + end + end +end +function freshMostBadge() + 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 + game.mostBadge,game.secBadge=players.alive[i],game.mostBadge + m,m2=h,m + elseif h>=m2 then + game.secBadge=players.alive[i] + m2=h + end + end +end +function royaleLevelup() + game.stage=game.stage+1 + local spd + TEXT.show(text.royale_remain(#players.alive),640,200,40,"beat",.3) + if game.stage==2 then + spd=30 + elseif game.stage==3 then + spd=15 + game.garbageSpeed=.6 + if players[1].alive then BGM.play("cruelty")end + elseif game.stage==4 then + spd=10 + local _=players.alive + for i=1,#_ do + _[i].gameEnv.pushSpeed=3 + end + elseif game.stage==5 then + spd=5 + game.garbageSpeed=1 + elseif game.stage==6 then + spd=3 + if players[1].alive then BGM.play("final")end + end + for i=1,#players.alive do + players.alive[i].gameEnv.drop=spd + end + if curMode.lv==3 then + for i=1,#players.alive do + local P=players.alive[i] + P.gameEnv.drop=int(P.gameEnv.drop*.3) + if P.gameEnv.drop==0 then + P.curY=P.y_img + P.gameEnv._20G=true + if P.AI_mode=="CC"then CC_switch20G(P)end--little cheating,never mind + end + end + end +end +function pauseGame() + if not SCN.swapping then + restartCount=0--Avoid strange darkness + if not game.result then + game.pauseCount=game.pauseCount+1 + end + for i=1,#players do + local l=players[i].keyPressing + for j=1,#l do + if l[j]then + players[i]:releaseKey(j) + end + end + end + SCN.swapTo("pause","none") + end +end +function resumeGame() + SCN.swapTo("play","none") +end +function loadGame(M) + --rec={} + stat.lastPlay=M + curMode=Modes[M] + local lang=setting.lang + drawableText.modeName:set(text.modes[M][1]) + drawableText.levelName:set(text.modes[M][2]) + needResetGameData=true + SCN.swapTo("play","fade_togame") + SFX.play("enter") +end +function resetPartGameData() + game={ + result=false, + pauseTime=0, + pauseCount=0, + garbageSpeed=1, + warnLVL0=0, + warnLVL=0, + } + frame=150-setting.reTime*15 + destroyPlayers() + curMode.load() + TEXT.clear() + if modeEnv.task then + for i=1,#players do + players[i].newTask(modeEnv.task) + end + end + if modeEnv.royaleMode then + for i=1,#players do + players[i]:changeAtk(randomTarget(players[i])) + end + end + BG.set(modeEnv.bg) + BGM.play(modeEnv.bgm) + if modeEnv.royaleMode then + for i=1,#players do + players[i]:changeAtk(randomTarget(players[i])) + end + game.stage=1 + game.garbageSpeed=.3 + end + restoreVirtualKey() + collectgarbage() +end +function resetGameData() + game={ + result=false, + pauseTime=0,--Time paused + pauseCount=0,--Pausing count + garbageSpeed=1,--garbage timing speed + warnLVL0=0, + warnLVL=0, + } + frame=150-setting.reTime*15 + destroyPlayers() + modeEnv=curMode.env + curMode.load()--bg/bgm need redefine in custom,so up here + if modeEnv.task then + for i=1,#players do + players[i].newTask(modeEnv.task) + end + end + BG.set(modeEnv.bg) + BGM.play(modeEnv.bgm) + + TEXT.clear() + FX_badge={} + FX_attack={} + if modeEnv.royaleMode then + for i=1,#players do + players[i]:changeAtk(randomTarget(players[i])) + end + game.stage=1 + game.garbageSpeed=.3 + end + restoreVirtualKey() + stat.game=stat.game+1 + freeRow.reset(30*#players) + SFX.play("ready") + collectgarbage() +end +function gameStart() + SFX.play("start") + for P=1,#players do + P=players[P] + P:popNext() + P.timing=true + P.control=true + end +end \ No newline at end of file diff --git a/parts/getTip.lua b/parts/getTip.lua index e1d3fcc6..b4d79a81 100644 --- a/parts/getTip.lua +++ b/parts/getTip.lua @@ -44,6 +44,10 @@ if setting.lang==1 then "jstris 也很好玩!", "tetr.io 也很好玩!", "nullpomino 也很好玩!", + "↑↑↓↓←→←→BABA", + "草(日本语)", + "dym,永远的神", + "iced,永远的神", } elseif setting.lang==2 then L={ @@ -90,6 +94,10 @@ elseif setting.lang==2 then "jstris 也很好玩!", "tetr.io 也很好玩!", "nullpomino 也很好玩!", + "↑↑↓↓←→←→BABA", + "草(日本语)", + "dym,永远的神", + "iced,永远的神", } elseif setting.lang==3 then L={ @@ -137,6 +145,11 @@ elseif setting.lang==3 then "Also try jstris!", "Also try tetr.io!", "Also try nullpomino!", + "↑↑↓↓←→←→BABA", + "wwwwww", + "diaoyoumei so bully", + "iced so bully", + "diao so bully", } elseif setting.lang==4 then L={'!','@','#','$','%','^','&','*','(',')','-','=','_','+','[',']','{','}','\\','|',';',':','\'','"',',','<','.','>','/','?'} diff --git a/parts/languages.lua b/parts/languages.lua index 9237cb8c..d08d6930 100644 --- a/parts/languages.lua +++ b/parts/languages.lua @@ -1749,7 +1749,7 @@ function LANG.getLen() end function LANG.set(l) text=langList[l] - for S,L in next,widgetList do + for S,L in next,Widgets do for N,W in next,L do W.text=text.WidgetText[S][N] end diff --git a/parts/modes.lua b/parts/modes.lua index 0bd79247..1c16fd66 100644 --- a/parts/modes.lua +++ b/parts/modes.lua @@ -1,4 +1,4 @@ -modes={ +return{ {"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}}, @@ -82,10 +82,4 @@ modes={ {"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={}}, {"sprintPenta", id=73, x=-200, y=-200, size=45,shape=3,icon="sprint", unlock={}}, -} -modeRanks={} -for i=1,#modes do - modeRanks[i]=false - assert(i==modes[i].id,"ModeID error:"..i) -end -modeRanks[1]=0 \ No newline at end of file +} \ No newline at end of file diff --git a/parts/setfont.lua b/parts/setfont.lua deleted file mode 100644 index 5bfb60cb..00000000 --- a/parts/setfont.lua +++ /dev/null @@ -1,17 +0,0 @@ -local new=love.graphics.setNewFont -local set=love.graphics.setFont -local F,cur={} -return function(s) - local f=F[s] - if s~=cur then - if f then - set(f) - else - f=new("font.ttf",s) - F[s]=f - set(f) - end - cur=s - end - return f -end \ No newline at end of file diff --git a/parts/tickEvent.lua b/parts/tickEvent.lua deleted file mode 100644 index c67fab54..00000000 --- a/parts/tickEvent.lua +++ /dev/null @@ -1,71 +0,0 @@ -local min=math.min -local mini=love.window.isMinimized -local tickEvent={} -function tickEvent.finish(P) - if SCN.cur~="play"then return true end - P.endCounter=P.endCounter+1 - if P.endCounter>120 then pauseGame()end -end -function tickEvent.lose(P) - P.endCounter=P.endCounter+1 - if P.endCounter>80 then - for i=1,#P.field do - for j=1,10 do - if P.visTime[i][j]>0 then - P.visTime[i][j]=P.visTime[i][j]-1 - end - end - end - if P.endCounter==120 then - for _=#P.field,1,-1 do - freeRow.discard(P.field[_]) - freeRow.discard(P.visTime[_]) - P.field[_],P.visTime[_]=nil - end - if #players==1 and SCN.cur=="play"then - pauseGame() - end - return true - end - end -end -function tickEvent.throwBadge(A,data) - data[2]=data[2]-1 - if data[2]%4==0 then - local S,R=data[1],data[1].lastRecv - local x1,y1,x2,y2 - if S.small then - x1,y1=S.centerX,S.centerY - else - x1,y1=S.x+308*S.size,S.y+450*S.size - end - if R.small then - x2,y2=R.centerX,R.centerY - else - x2,y2=R.x+66*R.size,R.y+344*R.size - end - FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0} - --generate badge object - - if not A.ai and data[2]%8==0 then - SFX.play("collect") - end - end - if data[2]<=0 then return true end -end -function tickEvent.bgmFadeOut(_,id) - local src=BGM.list[id] - local v=src:getVolume()-.025*setting.bgm*.1 - src:setVolume(v>0 and v or 0) - if v<=0 then - src:stop() - return true - end -end -function tickEvent.bgmFadeIn(_,id) - local src=BGM.list[id] - local v=min(src:getVolume()+.025*setting.bgm*.1,setting.bgm*.1) - src:setVolume(v) - if v>=setting.bgm*.1 then return true end -end -return tickEvent \ No newline at end of file diff --git a/player.lua b/player.lua index 6995edad..2ecb413d 100644 --- a/player.lua +++ b/player.lua @@ -239,7 +239,7 @@ local function Pupdate_alive(P,dt) local C=P.AI_keys P.AI_delay=P.AI_delay-1 if not C[1]then - P.AI_stage=AI_think[P.AI_mode][P.AI_stage](P,C) + P.AI_stage=AIfunc[P.AI_mode][P.AI_stage](P,C) elseif P.AI_delay<=0 then P:pressKey(C[1])P:releaseKey(C[1]) rem(C,1) @@ -581,10 +581,12 @@ local function Pdraw_norm(P) 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 + if P.gameEnv.ghost then + 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 end--Rotate center gc.translate(0,dy) end @@ -1770,6 +1772,60 @@ end ---------------------------------------------------- ---------------------------------------------------- +local tick={} +function tick.finish(P) + if SCN.cur~="play"then return true end + P.endCounter=P.endCounter+1 + if P.endCounter>120 then pauseGame()end +end +function tick.lose(P) + P.endCounter=P.endCounter+1 + if P.endCounter>80 then + for i=1,#P.field do + for j=1,10 do + if P.visTime[i][j]>0 then + P.visTime[i][j]=P.visTime[i][j]-1 + end + end + end + if P.endCounter==120 then + for _=#P.field,1,-1 do + freeRow.discard(P.field[_]) + freeRow.discard(P.visTime[_]) + P.field[_],P.visTime[_]=nil + end + if #players==1 and SCN.cur=="play"then + pauseGame() + end + return true + end + end +end +function tick.throwBadge(A,data) + data[2]=data[2]-1 + if data[2]%4==0 then + local S,R=data[1],data[1].lastRecv + local x1,y1,x2,y2 + if S.small then + x1,y1=S.centerX,S.centerY + else + x1,y1=S.x+308*S.size,S.y+450*S.size + end + if R.small then + x2,y2=R.centerX,R.centerY + else + x2,y2=R.x+66*R.size,R.y+344*R.size + end + FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0} + --generate badge object + + if not A.ai and data[2]%8==0 then + SFX.play("collect") + end + end + if data[2]<=0 then return true end +end + local function gameOver() FILE.saveData() local M=curMode @@ -1787,7 +1843,7 @@ local function gameOver() 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 + modeRanks[m]=Modes[m].score and 0 or 6 _=true end end @@ -1857,7 +1913,7 @@ function player.win(P,result) if P.human then gameOver() end - TASK.new(tickEvent.finish,P) + TASK.new(tick.finish,P) end function player.lose(P) if P.life>0 then @@ -1901,7 +1957,7 @@ function player.lose(P) end P.lastRecv=A if P.id==1 or A.id==1 then - TASK.new(tickEvent.throwBadge,A,{P,max(3,P.badge)*4}) + TASK.new(tick.throwBadge,A,{P,max(3,P.badge)*4}) end freshMostBadge() end @@ -1934,7 +1990,9 @@ function player.lose(P) end end gameOver() - TASK.new(#players>1 and tickEvent.lose or tickEvent.finish,P) + TASK.new(#players>1 and tick.lose or tick.finish,P) + else + TASK.new(tick.lose,P) end if #players.alive==1 then players.alive[1]:win() @@ -2090,6 +2148,7 @@ function player.act.insLeft(P,auto) end if x0~=P.curX then if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end + P.spinLast=false end if P.gameEnv.shakeFX then P.fieldOff.vx=-P.gameEnv.shakeFX*.5 @@ -2112,6 +2171,7 @@ function player.act.insRight(P,auto) end if x0~=P.curX then if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end + P.spinLast=false end if P.gameEnv.shakeFX then P.fieldOff.vx=P.gameEnv.shakeFX*.5 diff --git a/scene.lua b/scene.lua index 719e5f0b..b9c0bf6b 100644 --- a/scene.lua +++ b/scene.lua @@ -29,7 +29,7 @@ function sceneInit.load() #BGM.list, #SFX.list, IMG.getCount(), - #modes, + #Modes, 1, }, skip=false,--if skipping @@ -68,7 +68,7 @@ function sceneInit.mode(org) local cam=mapCam cam.zoomK=org=="main"and 5 or 1 if cam.sel then - local M=modes[cam.sel] + local M=Modes[cam.sel] cam.x,cam.y=M.x*cam.k+180,M.y*cam.k cam.x1,cam.y1=cam.x,cam.y end @@ -246,7 +246,7 @@ function sceneInit.stat() end function sceneInit.history() BG.set("strap") - sceneTemp={require("updateLog"),1}--scroll pos + sceneTemp={require("parts/updateLog"),1}--scroll pos end function sceneInit.quit() love.timer.sleep(.3) @@ -293,7 +293,7 @@ function SCN.swapUpdate() if S.time==S.mid then SCN.init(S.tar,SCN.cur) SCN.cur=S.tar - WIDGET.set(widgetList[S.tar]) + WIDGET.set(Widgets[S.tar]) collectgarbage() --Scene swapped this moment end diff --git a/timer.lua b/timer.lua index 8ed68870..df92f926 100644 --- a/timer.lua +++ b/timer.lua @@ -18,9 +18,9 @@ function Tmr.load() elseif S.phase==4 then IMG.loadOne(S.cur) elseif S.phase==5 then - local m=modes[S.cur] - modes[S.cur]=require("modes/"..m[1]) - local M=modes[S.cur] + local m=Modes[S.cur] + Modes[S.cur]=require("modes/"..m[1]) + local M=Modes[S.cur] M.saveFileName,M.id=m[1],m.id M.x,M.y,M.size,M.shape=m.x,m.y,m.size,m.shape M.unlock=m.unlock @@ -105,7 +105,7 @@ function Tmr.mode(dt) cam.keyCtrl=true end local x,y=(cam.x1-180)/cam.k1,cam.y1/cam.k1 - local MM,R=modes,modeRanks + local MM,R=Modes,modeRanks for _=1,#MM do if R[_]then local __ @@ -142,7 +142,7 @@ function Tmr.mode(dt) cam.zoomMethod=_=="play"and 1 or _=="mode"and 2 if cam.zoomMethod==1 then if cam.sel then - local M=modes[cam.sel] + local M=Modes[cam.sel] cam.x=cam.x*.8+M.x*cam.k*.2 cam.y=cam.y*.8+M.y*cam.k*.2 end diff --git a/toolfunc.lua b/toolfunc.lua index 4488e0a6..94616aa4 100644 --- a/toolfunc.lua +++ b/toolfunc.lua @@ -1,11 +1,26 @@ -local tm,gc=love.timer,love.graphics -local kb,data=love.keyboard,love.data -local int,abs,rnd=math.floor,math.abs,math.random -local max,min=math.max,math.min -local sub,find=string.sub,string.find -local format,char,byte=string.format,string.char,string.byte -local ins,rem=table.insert,table.remove +local gc=love.graphics +local fontData=love.filesystem.newFile("font.ttf") +local newFont=gc.setNewFont +local setNewFont=gc.setFont +local fontCache,currentFontSize={} +function setFont(s) + local f=fontCache[s] + if s~=currentFontSize then + if f then + setNewFont(f) + else + f=newFont(fontData,s) + fontCache[s]=f + setNewFont(f) + end + currentFontSize=s + end + return f +end + +local int=math.floor +local format=string.format function toTime(s) if s<60 then return format("%.3fs",s) @@ -24,301 +39,4 @@ function mText(s,x,y) end function mDraw(s,x,y,a,k) gc.draw(s,x,y,a,k,nil,s:getWidth()*.5,s:getHeight()*.5) -end -function destroyPlayers() - for i=#players,1,-1 do - local P=players[i] - if P.canvas then P.canvas:release()end - while P.field[1]do - freeRow.discard(rem(P.field)) - freeRow.discard(rem(P.visTime)) - end - if P.AI_mode=="CC"then - BOT.free(P.bot_opt) - BOT.free(P.bot_wei) - BOT.destroy(P.AI_bot) - P.AI_mode=nil - end - players[i]=nil - end - for i=#players.alive,1,-1 do - players.alive[i]=nil - end - players.human=0 - collectgarbage() -end ---Single-usage funcs - -function restoreVirtualKey() - for i=1,#VK_org do - local B,O=virtualkey[i],VK_org[i] - B.ava=O.ava - B.x=O.x - B.y=O.y - B.r=O.r - B.isDown=false - B.pressTime=0 - end - if not modeEnv.Fkey then - virtualkey[9].ava=false - end -end -function copyBoard() - local str="" - local H=0 - for y=20,1,-1 do - for x=1,10 do - if preField[y][x]~=0 then - H=y - goto L - end - end - end - ::L:: - for y=1,H do - local S="" - local L=preField[y] - for x=1,10 do - S=S..char(L[x]+1) - end - str=str..S - end - love.system.setClipboardText("Techmino sketchpad:"..data.encode("string","base64",data.compress("string","deflate",str))) - TEXT.show(text.copySuccess,350,360,40,"appear",.5) -end -function pasteBoard() - local str=love.system.getClipboardText() - local fX,fY=1,1--*ptr for Field(r*10+(c-1)) - local _,Bid - local p=find(str,":")--ptr* - if p then str=sub(str,p+1)end - _,str=pcall(data.decode,"string","base64",str) - if not _ then goto ERROR end - _,str=pcall(data.decompress,"string","deflate",str) - if not _ then goto ERROR end - p=1 - while true do - _=byte(str,p)--1byte - if not _ then - if fX~=1 then goto ERROR - else break - end - end--str end - __=_%32-1--block id - if __>17 then goto ERROR end--illegal blockid - _=int(_/32)--mode id - preField[fY][fX]=__ - if fX<10 then - fX=fX+1 - else - if fY==20 then break end - fX=1;fY=fY+1 - end - p=p+1 - end - - for y=fY+1,20 do - for x=1,10 do - preField[y][x]=0 - end - end - do return end - ::ERROR::TEXT.show(text.dataCorrupted,350,360,35,"flicker",.5) -end - -function mergeStat(stat,delta) - for k,v in next,delta do - if type(v)=="table"then - mergeStat(stat[k],v) - else - stat[k]=stat[k]+v - end - end -end -function randomTarget(P) - if #players.alive>1 then - local R - repeat - R=players.alive[rnd(#players.alive)] - until R~=P - return R - end -end--return a random opponent for P -function freshMostDangerous() - 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 - game.mostDangerous,game.secDangerous=players.alive[i],game.mostDangerous - m,m2=h,m - elseif h>=m2 then - game.secDangerous=players.alive[i] - m2=h - end - end -end -function freshMostBadge() - 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 - game.mostBadge,game.secBadge=players.alive[i],game.mostBadge - m,m2=h,m - elseif h>=m2 then - game.secBadge=players.alive[i] - m2=h - end - end -end -function royaleLevelup() - game.stage=game.stage+1 - local spd - TEXT.show(text.royale_remain(#players.alive),640,200,40,"beat",.3) - if game.stage==2 then - spd=30 - elseif game.stage==3 then - spd=15 - game.garbageSpeed=.6 - if players[1].alive then BGM.play("cruelty")end - elseif game.stage==4 then - spd=10 - local _=players.alive - for i=1,#_ do - _[i].gameEnv.pushSpeed=3 - end - elseif game.stage==5 then - spd=5 - game.garbageSpeed=1 - elseif game.stage==6 then - spd=3 - if players[1].alive then BGM.play("final")end - end - for i=1,#players.alive do - players.alive[i].gameEnv.drop=spd - end - if curMode.lv==3 then - for i=1,#players.alive do - local P=players.alive[i] - P.gameEnv.drop=int(P.gameEnv.drop*.3) - if P.gameEnv.drop==0 then - P.curY=P.y_img - P.gameEnv._20G=true - if P.AI_mode=="CC"then CC_switch20G(P)end--little cheating,never mind - end - end - end -end -function pauseGame() - if not SCN.swapping then - restartCount=0--Avoid strange darkness - if not game.result then - game.pauseCount=game.pauseCount+1 - end - for i=1,#players do - local l=players[i].keyPressing - for j=1,#l do - if l[j]then - players[i]:releaseKey(j) - end - end - end - SCN.swapTo("pause","none") - end -end -function resumeGame() - SCN.swapTo("play","none") -end -function loadGame(M) - --rec={} - stat.lastPlay=M - curMode=modes[M] - local lang=setting.lang - drawableText.modeName:set(text.modes[M][1]) - drawableText.levelName:set(text.modes[M][2]) - needResetGameData=true - SCN.swapTo("play","fade_togame") - SFX.play("enter") -end -function resetPartGameData() - game={ - result=false, - pauseTime=0, - pauseCount=0, - garbageSpeed=1, - warnLVL0=0, - warnLVL=0, - } - frame=150-setting.reTime*15 - destroyPlayers() - curMode.load() - TEXT.clear() - if modeEnv.task then - for i=1,#players do - TASK.new(modeEnv.task,players[i]) - end - end - if modeEnv.royaleMode then - for i=1,#players do - players[i]:changeAtk(randomTarget(players[i])) - end - end - BG.set(modeEnv.bg) - BGM.play(modeEnv.bgm) - if modeEnv.royaleMode then - for i=1,#players do - players[i]:changeAtk(randomTarget(players[i])) - end - game.stage=1 - game.garbageSpeed=.3 - end - restoreVirtualKey() - collectgarbage() -end -function resetGameData() - game={ - result=false, - pauseTime=0,--Time paused - pauseCount=0,--Pausing count - garbageSpeed=1,--garbage timing speed - warnLVL0=0, - warnLVL=0, - } - frame=150-setting.reTime*15 - destroyPlayers() - modeEnv=curMode.env - curMode.load()--bg/bgm need redefine in custom,so up here - if modeEnv.task then - for i=1,#players do - TASK.new(modeEnv.task,players[i]) - end - end - BG.set(modeEnv.bg) - BGM.play(modeEnv.bgm) - - TEXT.clear() - FX_badge={} - FX_attack={} - if modeEnv.royaleMode then - for i=1,#players do - players[i]:changeAtk(randomTarget(players[i])) - end - game.stage=1 - game.garbageSpeed=.3 - end - restoreVirtualKey() - stat.game=stat.game+1 - freeRow.reset(30*#players) - SFX.play("ready") - collectgarbage() -end -function gameStart() - SFX.play("start") - for P=1,#players do - P=players[P] - P:popNext() - P.timing=true - P.control=true - end end \ No newline at end of file diff --git a/updateLog.lua b/updateLog.lua index b24e5a81..87984537 100644 --- a/updateLog.lua +++ b/updateLog.lua @@ -7,54 +7,25 @@ local S=[=[ Alan 幽灵3383 靏鸖龘龘 + 込余 [rmb10+]: - 八零哥 - 蕴空之灵 - gggf127 - dtg - ThTsOd - Fireboos - 金巧 - 10元 - 立斐 - Deep_Sea - 时雪 - yyangdid - sfqr - 心痕 - Sasoric - 夏小亚 - 仁参 - 乐↗乐↘ - 喜欢c4w的ztcjoin - 面包 - 蠢熏 - 潘一栗 - Lied - 星街书婉 - 込余 - 祝西 - 829 - e m*12 - 我永远爱白银诺艾尔(鹏 - PCX - kagura77 - 呆喂 - GlowingEmbers - 轩辕辚 - HimuroAki - TCV100 - tech有养成系统了@7065 - HAGE KANOBU - 闪电和拐棍 - 葡萄味的曼妥思 - 世界沃德 - 蓝绿 + 八零哥 蕴空之灵 gggf127 dtg + ThTsOd Fireboos 金巧 10元 + 立斐 Deep_Sea 时雪 yyangdid + sfqr 心痕 Sasoric 夏小亚 + 仁参 乐↗乐↘ 喜欢c4w的ztcjoin 面包 + 蠢熏 潘一栗 Lied 星街书婉 + 祝西 829 e m*12 我永远爱白银诺艾尔(鹏 + PCX kagura77 呆喂 GlowingEmbers + 轩辕辚 HimuroAki TCV100 tech有养成系统了@7065 + HAGE KANOBU 闪电和拐棍 葡萄味的曼妥思 世界沃德 + 蓝绿 天生的魔法师 saki 琳雨空 Thanks!!! Future outlook: New mode: + PUYO game tutorial finesse tutorial game Abbr. test @@ -71,8 +42,9 @@ Future outlook: dig zen sprint_symmetry hidden: sound only - reverb mode (often repeat a piece many times) - KPP-locked mode + reverb (often repeat a piece many times) + KPP-locked + parkour Other: mod system with: block hidden @@ -86,13 +58,17 @@ Future outlook: 15 puzzle mine sweeper 2048 + tank battle + time-based-rank for master advanced mode(1:58/2:28/3:03/300P/100P) 简易防沉迷系统 - next SFX + full-key control + dragging control + "next" SFX + new layout of player (rectangle so stupid) better drop FX 60+ fps supporting in-game document lang setting page - dragging control game recording new widgets (joystick etc.) custom sequence(TTT!) @@ -103,14 +79,28 @@ Future outlook: network game new AI: task-Z +0.8.25: Custom Sequence Update + new: + --TODO: custom sequence + changed: + little easier to get S in PC challenge (easy mode) + easier to get S in infinite mode + code: + file sorted + fixed: + hard move won't deactive "spin" + do not clear dead enemies' field + show ghost's center when ghost is off + 0.8.24: Bug Fixed new: ready to refuse auto-formating stats. if update from versions too old changed: - little changing of pentomini wallkicks + little changing of pentomino wallkick list fixed: incorrect color of P/Q rank of petomino may be [custom] + 0.8.23: Details Update new: new hidden BGM: Hay what kind of feeling diff --git a/widgetList.lua b/widgetList.lua index ae1e11f6..f038c61e 100644 --- a/widgetList.lua +++ b/widgetList.lua @@ -1,4 +1,5 @@ -mobileHide=(system=="Android"or system=="iOS")and function()return true end +local mobileHide=(system=="Android"or system=="iOS")and function()return true end +local function BACK()SCN.back()end local virtualkeySet={ { {1, 80, 720-200, 80},--moveLeft @@ -87,7 +88,7 @@ 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 widgetList={ +local Widgets={ load={},intro={},quit={}, main={ play= newButton(150,280,200,160,C.lightRed, 55,function()SCN.push()SCN.swapTo("mode")end, nil,"setting"), @@ -103,7 +104,7 @@ local widgetList={ 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), + back= newButton(1200, 655,120,80,C.white, 40,BACK), --function()SCN.push()SCN.swapTo("custom")end }, music={ @@ -111,7 +112,7 @@ local widgetList={ up= newButton(1100, 200,120,120,C.white,55,pressKey("up")), play= newButton(1100, 340,120,120,C.white,35,pressKey("space"),function()return setting.bgm==0 end), down= newButton(1100, 480,120,120,C.white,55,pressKey("down")), - back= newButton(640, 630,230,90, C.white,40,SCN.back), + back= newButton(640, 630,230,90, C.white,40,BACK), }, custom={ up= newButton(1000, 360,100,100,C.white, 45,function()sceneTemp=(sceneTemp-2)%#customID+1 end), @@ -123,7 +124,7 @@ local widgetList={ 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), + back= newButton(640, 630,180,60, C.white, 35,BACK), }, draw={ b1= newButton(500+65*1, 150,58,58,C.red, 30,setPen(1)),--B1 @@ -151,7 +152,7 @@ local widgetList={ demo= newSwitch(755, 640,30,function()return sceneTemp.demo end,function()sceneTemp.demo=not sceneTemp.demo end), copy= newButton(920, 640,120,120,C.lightRed, 35,copyBoard), paste= newButton(1060, 640,120,120,C.lightBlue, 35,pasteBoard), - back= newButton(1200, 640,120,120,C.white, 35,SCN.back), + back= newButton(1200, 640,120,120,C.white, 35,BACK), }, play={ pause= newButton(1235,45,80,80,C.white,25,pauseGame), @@ -167,7 +168,7 @@ local widgetList={ 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), + quit= newButton(640,600,240,100,C.white,35,BACK), }, setting_game={ graphic=newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_video")end, nil,"sound"), @@ -185,7 +186,7 @@ local widgetList={ quickR= newSwitch(1050,340,35, SETval("quickR"), SETrev("quickR"), nil,"swap"), swap= newSwitch(1050,440,19, SETval("swap"), SETrev("swap"), nil,"fine"), fine= newSwitch(1050,540,20, SETval("fine"), SETrev("fine"), nil,"back"), - back= newButton(1140,650,200,80,C.white,40,SCN.back, nil,"graphic"), + back= newButton(1140,650,200,80,C.white,40,BACK, nil,"graphic"), }, setting_video={ sound= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_sound")end, nil,"game"), @@ -216,7 +217,7 @@ local widgetList={ power= newSwitch(1050,500,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"), + back= newButton(1140,650,200,80,C.white,40,BACK,nil,"sound"), }, setting_sound={ game= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_game")end, nil,"graphic"), @@ -226,7 +227,7 @@ local widgetList={ vib= newSlider(180,440,400,5 ,28,function()VIB(2)end, SETval("vib"), SETsto("vib"), nil,"voc"), voc= newSlider(750,440,400,10,32,function()VOC.play("nya")end, SETval("voc"), SETsto("voc"), nil,"stereo"), stereo= newSlider(180,630,400,10,35,function()SFX.play("move",1,-1)SFX.play("lock",1,1)end, SETval("stereo"), SETsto("stereo"),function()return setting.sfx==0 end,"back"), - back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"game"), + back= newButton(1140,650,200,80,C.white,40,BACK,nil,"game"), }, setting_control={ das= newSlider(226,200,910, 26, 30,nil,SETval("das"), SETsto("das"), nil,"arr"), @@ -242,10 +243,10 @@ local widgetList={ _.sddas,_.sdarr=0,2 _.ihs,_.irs,_.ims=false,false,false end,nil,"back"), - back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"das"), + back= newButton(1140,650,200,80,C.white,40,BACK,nil,"das"), }, setting_key={ - back=newButton(1140,650,200,80,C.white,45,SCN.back), + back=newButton(1140,650,200,80,C.white,45,BACK), }, setting_skin={ prev= newButton(700,100,140,100,C.white,50,function()SKIN.prevSet()end), @@ -284,7 +285,7 @@ local widgetList={ end SFX.play("hold") end), - back= newButton(1140,650,200,80,C.white,40,SCN.back), + back= newButton(1140,650,200,80,C.white,40,BACK), }, setting_touch={ default=newButton(520,80,170,80,C.white,35,function() @@ -310,7 +311,7 @@ local widgetList={ SCN.push() SCN.swapTo("setting_touchSwitch") end), - back= newButton(760,180,170,80,C.white,40,SCN.back), + back= newButton(760,180,170,80,C.white,40,BACK), size= newSlider(450,265,460,14,40,nil,function() return VK_org[sceneTemp.sel].r/10-1 end, @@ -354,38 +355,38 @@ local widgetList={ SCN.swapTo("setting_trackSetting") end,function()return not setting.VKTrack end), alpha= newSlider(840,540,400,10,40,nil,SETval("VKAlpha"),SETsto("VKAlpha")), - back= newButton(1120,620,200,80,C.white,45,SCN.back), + back= newButton(1120,620,200,80,C.white,45,BACK), }, setting_trackSetting={ VKDodge=newSwitch(400,200, 35,SETval("VKDodge"),SETrev("VKDodge")), VKTchW= newSlider(140,310,1000,10,35,nil,SETval("VKTchW"),function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end), 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), + back= newButton(1080,600,240,80,C.white,45,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"), + back= newButton(640,600,200,80,C.white,40,BACK,nil,"chi"), }, help={ staff= newButton(980,500,150,80,C.white,32,function()SCN.push()SCN.swapTo("staff")end,nil,"his"), his= newButton(1160,500,150,80,C.white,32,function()SCN.push()SCN.swapTo("history")end,nil,"qq"), qq= newButton(980,600,150,80,C.white,32,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,mobileHide,"back"), - back= newButton(640,600,200,80,C.white,40,SCN.back,nil,"staff"), + back= newButton(640,600,200,80,C.white,40,BACK,nil,"staff"), }, staff={ - back= newButton(1160,630,150,80,C.white,40,SCN.back), + back= newButton(1160,630,150,80,C.white,40,BACK), }, 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]end), - back= newButton(1155,600,180,90,C.white,40,SCN.back), + back= newButton(1155,600,180,90,C.white,40,BACK), }, stat={ 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"), + back= newButton(640,620,200,80,C.white,40,BACK,nil,"path"), }, } mobileHide,SETval,SETsto,SETrev=nil @@ -393,11 +394,11 @@ pressKey,setPen,prevSkin,nextSkin=nil nextDir,VKAdisp,VKAcode,setLang=nil newButton,newSwitch,newSlider=nil -for _,L in next,widgetList do +for _,L in next,Widgets 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 widgetList \ No newline at end of file +return Widgets \ No newline at end of file