local gc,sys=love.graphics,love.system local kb=love.keyboard local max,min,floor=math.max,math.min,math.floor local ins,rem=table.insert,table.remove local FIELD=CUSTOMGAME_LOCAL.field local scene={} local curPen local pens={-2,0,-1,[false]=false}-- Color (air/smart) local penMode local penPath={} local penX,penY local demo-- If show x local page local function isEmpty(L) for i=1,#L do if L[i]~=0 then return end end return true end local penKey={ ['1']=1,['2']=2,['3']=3,['4']=4,['5']=5,['6']=6,['7']=7,['8']=8, q=9,w=10,e=11,r=12,t=13,y=14,u=15,i=16, a=17,s=18,d=19,f=20,g=21,h=22,j=23,k=24, z=0,x=-1,c=-2, } local minoPosCode={ [102]=1,[1121]=1,-- Z [195]=2,[610]=2,-- S [39]=3,[1569]=3,[228]=3,[1091]=3,-- J [135]=4,[547]=4,[225]=4,[1602]=4,-- L [71]=5,[609]=5,[226]=5,[1122]=5,-- T [99]=6,-- O [15]=7,[4641]=7,-- I [1606]=8,[2273]=8,-- Z5 [3139]=9,[740]=9,-- S5 [103]=10,[1633]=10,[230]=10,[1123]=10,-- P [199]=11,[611]=11,[227]=11,[1634]=11,-- Q [738]=12,[3170]=12,[1252]=12,[1219]=12,-- F [2274]=13,[1126]=13,[1249]=13,[1730]=13,-- E [1095]=14,[737]=14,[3650]=14,[2276]=14,-- T5 [167]=15,[1571]=15,[229]=15,[1603]=15,-- U [2183]=16,[551]=16,[3617]=16,[3716]=16,-- V [614]=17,[3169]=17,[1732]=17,[2243]=17,-- W [1250]=18,-- X [47]=19,[12833]=19,[488]=19,[9283]=19,-- J5 [271]=20,[4643]=20,[481]=20,[13378]=20,-- L5 [79]=21,[5665]=21,[484]=21,[9314]=21,-- R [143]=22,[4705]=22,[482]=22,[9794]=22,-- Y [110]=23,[9761]=23,[236]=23,[9313]=23,-- N [391]=24,[4706]=24,[451]=24,[5698]=24,-- H [31]=25,[21025]=25,-- I5 [7]=26,[545]=26,-- I3 [67]=27,[35]=27,[97]=27,[98]=27,-- C [3]=28,[33]=28,-- I2 [1]=29,-- O1 } local function _pTouch(x,y) if not curPen then return end for i=1,#penPath do if x==penPath[i][1] and y==penPath[i][2] then return end end if #penPath==0 then penMode= pens[curPen]>0 and (FIELD[page][y][x]~=pens[curPen] and 0 or 1) or pens[curPen]==0 and 1 or pens[curPen]==-1 and 0 or pens[curPen]==-2 and (FIELD[page][y][x]<=0 and 0 or 1) end ins(penPath,{x,y}) end local function _pDraw() local l=#penPath if l==0 then return end local C-- Color if penMode==0 then if pens[curPen]==-2 then if l<=5 then local sum=0 local x,y={},{} for i=1,l do ins(x,penPath[i][1]) ins(y,penPath[i][2]) end local minY,minX=min(unpack(y)),min(unpack(x)) for i=1,#y do sum=sum+2^((11-(y[i]-minY))*(y[i]-minY)/2+(x[i]-minX)) end if minoPosCode[sum] then C=SETTING.skin[minoPosCode[sum]] end else C=20 end else C=pens[curPen] end else C=0 end local F=FIELD[page] if C then for i=1,l do F[penPath[i][2]][penPath[i][1]]=C end end penPath={} penMode=0 while #F>0 and isEmpty(F[#F]) do rem(F) end end function scene.enter() curPen=false penMode=0 penX,penY=1,1 demo=false page=1 end function scene.leave() saveFile(DATA.copyBoards(FIELD),'conf/customBoards') end function scene.mouseMove(x,y) local sx,sy=floor((x-200)/30)+1,20-floor((y-60)/30) if sx>=1 and sx<=10 and sy>=1 and sy<=20 then penX,penY=sx,sy if curPen then _pTouch(sx,sy) end else penX,penY=nil end end function scene.mouseDown(x,y,k) if k>3 then return end if not curPen then curPen=k elseif curPen~=k then curPen=false penPath={} end scene.mouseMove(x,y) end function scene.mouseUp(_,_,k) if k>3 then return end if curPen==k then _pDraw() curPen=false end end function scene.touchDown(x,y) scene.mouseDown(x,y,1) end function scene.touchUp(x,y) scene.mouseUp(x,y,1) end scene.touchMove=scene.mouseMove function scene.keyDown(key) if key=='up' or key=='down' or key=='left' or key=='right' then if not penX or not penY then penX,penY=1,1 end if key=='up' then if penY<20 then penY=penY+1 end elseif key=='down' then if penY>1 then penY=penY-1 end elseif key=='left' then if penX>1 then penX=penX-1 end elseif key=='right' then if penX<10 then penX=penX+1 end end if kb.isDown('space') then scene.keyDown('space') end elseif key=='space' then if penX and penY then curPen=1 _pTouch(penX,penY) end elseif key=='delete' then if tryReset() then FIELD[page]=DATA.newBoard() SFX.play('finesseError',.7) end elseif key=='j' then demo=not demo elseif key=='k' then ins(FIELD[page],1,{21,21,21,21,21,21,21,21,21,21}) SFX.play('blip') elseif key=='l' then local F=FIELD[page] local cleared=false for i=#F,1,-1 do local full=true for j=1,10 do if F[i][j]<=0 then full=false break end-- goto CONTINUE_notFull end if full then cleared=true SYSFX.newShade(3,200,660-30*i,300,30) SYSFX.newRectRipple(3,200,660-30*i,300,30) rem(F,i) end -- ::CONTINUE_notFull:: end if cleared then SFX.play('clear_3',.8) SFX.play('fall',.8) end elseif key=='n' then ins(FIELD,page+1,DATA.newBoard(FIELD[page])) page=page+1 SFX.play('warn_1',.8) SYSFX.newShade(3,200,60,300,600,.5,1,.5) elseif key=='m' then rem(FIELD,page) page=max(page-1,1) if not FIELD[1] then ins(FIELD,DATA.newBoard()) end SYSFX.newShade(3,200,60,300,600,1,.5,.5) SFX.play('clear_4',.8) SFX.play('fall',.8) elseif key=='c' and kb.isDown('lctrl','rctrl') or key=='cC' then CLIPBOARD.set("Techmino Field:"..DATA.copyBoard(FIELD[page])) MES.new('check',text.exportSuccess) elseif key=='v' and kb.isDown('lctrl','rctrl') or key=='cV' then local str=CLIPBOARD.get() local p=str:find(":")-- ptr* if p then if not str:sub(1,p-1):find("Field") then MES.new('error',text.pasteWrongPlace) end str=str:sub(p+1) end local success,F,hitHeightLimit=DATA.pasteBoard(str) if success then FIELD[page]=F if hitHeightLimit then MES.new('warn',text.tooHighField) end MES.new('check',text.importSuccess) else MES.new('error',text.dataCorrupted) end elseif key=='pageup' then page=max(page-1,1) elseif key=='pagedown' then page=min(page+1,#FIELD) elseif key=='escape' then if curPen then curPen=false penPath={} else SCN.back() end elseif penKey[key] then pens[1]=penKey[key] end end function scene.keyUp(key) if key=='space' then _pDraw() curPen=false end end function scene.draw() gc.translate(200,60) -- Draw grid gc.setColor(1,1,1,.2) gc.setLineWidth(1) for x=1,9 do gc.line(30*x,0,30*x,600) end for y=0,19 do gc.line(0,30*y,300,30*y) end -- Draw field gc.setColor(COLOR.Z) gc.setLineWidth(2) gc.rectangle('line',-2,-2,304,604,5) local cross=TEXTURE.puzzleMark[-1] local invis=TEXTURE.puzzleMark[-2] local F=FIELD[page] local texture=SKIN.lib[SETTING.skinSet] for y=1,#F do for x=1,10 do local B=F[y][x] if B>0 then if B~=18 then -- Normal block gc.draw(texture[B],30*x-30,600-30*y) elseif not demo then -- Invisible block gc.draw(invis,30*x-30,600-30*y) end elseif B==-1 and not demo then -- Cross gc.draw(cross,30*x-30,600-30*y) end end end -- Draw pen if penX and penY then local x,y=30*penX,600-30*penY if curPen==1 or curPen==2 then gc.setLineWidth(5) gc.rectangle('line',x-30,y,30,30,4) elseif curPen==3 then gc.setLineWidth(3) gc.line(x-15,y,x-30,y+15) gc.line(x,y,x-30,y+30) gc.line(x,y+15,x-15,y+30) end gc.setLineWidth(2) gc.rectangle('line',x-30,y,30,30,3) gc.setColor(1,1,1,.2) gc.rectangle('fill',x-30,y,30,30,3) end -- Draw smart pen path if #penPath>0 then gc.setLineWidth(4) if penMode==0 then if pens[curPen]==-2 then if #penPath<=5 then gc.setColor(COLOR.rainbow_light(TIME()*6.2)) else gc.setColor(.9,.9,.9,.7+.2*math.sin(TIME()*12.6)) end for i=1,#penPath do gc.rectangle('line',30*penPath[i][1]-30+2,600-30*penPath[i][2]+2,30-4,30-4,3) end elseif pens[curPen]==-1 then gc.setColor(1,1,0,.7+.3*math.sin(TIME()*12.6)) for i=1,#penPath do gc.draw(cross,30*penPath[i][1]-30,600-30*penPath[i][2]) end elseif pens[curPen]==0 then gc.setColor(1,0,0) for i=1,#penPath do gc.draw(cross,30*penPath[i][1]-30+math.random(-1,1),600-30*penPath[i][2]+math.random(-1,1)) end else local c=BLOCK_COLORS[pens[curPen]] gc.setColor(c[1],c[2],c[3],.7+.2*math.sin(TIME()*12.6)) for i=1,#penPath do gc.rectangle('line',30*penPath[i][1]-30+2,600-30*penPath[i][2]+2,30-4,30-4,3) end end else gc.setColor(1,0,0) for i=1,#penPath do gc.draw(cross,30*penPath[i][1]-30+math.random(-1,1),600-30*penPath[i][2]+math.random(-1,1)) end end end gc.translate(-200,-60) -- Draw page setFont(55) gc.setColor(COLOR.Z) GC.mStr(page,100,530) GC.mStr(#FIELD,100,600) gc.rectangle('fill',50,600,100,6) -- Draw mouse & pen color gc.translate(560,475) -- Mouse gc.setLineWidth(2) gc.rectangle('line',0,0,80,110,5) gc.line(0,40,80,40) gc.line(33,0,33,25,47,25,47,0) gc.line(40,25,40,40) -- Left button if pens[1]>0 then gc.setColor(BLOCK_COLORS[pens[1]]) gc.rectangle('fill',5,5,23,30,3) elseif pens[1]==-1 then gc.setColor(COLOR.Z) gc.line(5,5,28,35) gc.line(28,5,5,35) elseif pens[1]==-2 then if penMode==0 then gc.setLineWidth(13) gc.setColor(COLOR.rainbow(TIME()*12.6)) gc.rectangle('fill',5,5,23,30,3) else gc.setLineWidth(3) gc.setColor(1,0,0) gc.line(5,5,28,35) gc.line(28,5,5,35) end end -- Right button if pens[2]>0 then gc.setColor(BLOCK_COLORS[pens[2]]) gc.rectangle('fill',52,5,23,30,3) elseif pens[2]==-1 then gc.setColor(COLOR.Z) gc.setLineWidth(3) gc.line(52,5,75,35) gc.line(75,5,52,35) elseif pens[2]==-2 then if penMode==0 then gc.setLineWidth(13) gc.setColor(COLOR.rainbow(TIME()*12.6)) gc.rectangle('fill',52,5,23,30,3) else gc.setLineWidth(3) gc.setColor(1,0,0) gc.line(52,5,75,35) gc.line(75,5,52,35) end end -- Middle button if pens[3]>0 then gc.setColor(BLOCK_COLORS[pens[3]]) gc.rectangle('fill',35,2,10,21,3) elseif pens[3]==-1 then gc.setColor(COLOR.Z) gc.setLineWidth(2) gc.line(35,2,45,23) gc.line(45,2,35,23) elseif pens[3]==-2 then if penMode==0 then gc.setLineWidth(13) gc.setColor(COLOR.rainbow(TIME()*12.6)) gc.rectangle('fill',35,2,10,21,3) else gc.setLineWidth(3) gc.setColor(1,0,0) gc.line(35,2,45,23) gc.line(45,2,35,23) end end gc.translate(-560,-475) -- Block name setFont(55) gc.setColor(1,1,1) for i=1,7 do local skin=SETTING.skin[i]-1 GC.mStr(text.block[i],580+(skin%8)*80,90+80*floor(skin/8)) end end local function _setPen(i) return function(k) pens[k]=i end end scene.widgetList={ WIDGET.newText{name='title', x=1020,y=5,lim=480,font=70,align='R'}, WIDGET.newText{name='subTitle', x=1030,y=50,lim=170,font=35,align='L',color='H'}, WIDGET.newButton{name='b1', x=580, y=130,w=73,fText="",color='R',code=_setPen(1)},-- B1 WIDGET.newButton{name='b2', x=660, y=130,w=73,fText="",color='F',code=_setPen(2)},-- B2 WIDGET.newButton{name='b3', x=740, y=130,w=73,fText="",color='O',code=_setPen(3)},-- B3 WIDGET.newButton{name='b4', x=820, y=130,w=73,fText="",color='Y',code=_setPen(4)},-- B4 WIDGET.newButton{name='b5', x=900, y=130,w=73,fText="",color='L',code=_setPen(5)},-- B5 WIDGET.newButton{name='b6', x=980, y=130,w=73,fText="",color='J',code=_setPen(6)},-- B6 WIDGET.newButton{name='b7', x=1060,y=130,w=73,fText="",color='G',code=_setPen(7)},-- B7 WIDGET.newButton{name='b8', x=1140,y=130,w=73,fText="",color='A',code=_setPen(8)},-- B8 WIDGET.newButton{name='b9', x=580, y=210,w=73,fText="",color='C',code=_setPen(9)},-- B9 WIDGET.newButton{name='b10', x=660, y=210,w=73,fText="",color='N',code=_setPen(10)},-- B10 WIDGET.newButton{name='b11', x=740, y=210,w=73,fText="",color='S',code=_setPen(11)},-- B11 WIDGET.newButton{name='b12', x=820, y=210,w=73,fText="",color='B',code=_setPen(12)},-- B12 WIDGET.newButton{name='b13', x=900, y=210,w=73,fText="",color='V',code=_setPen(13)},-- B13 WIDGET.newButton{name='b14', x=980, y=210,w=73,fText="",color='P',code=_setPen(14)},-- B14 WIDGET.newButton{name='b15', x=1060,y=210,w=73,fText="",color='M',code=_setPen(15)},-- B15 WIDGET.newButton{name='b16', x=1140,y=210,w=73,fText="",color='W',code=_setPen(16)},-- B16 WIDGET.newButton{name='b17', x=580, y=290,w=73,font=40,fText=CHAR.icon.bone, color='dH',code=_setPen(17)},-- BONE WIDGET.newButton{name='b18', x=660, y=290,w=73,font=40,fText=CHAR.icon.invis, color='D', code=_setPen(18)},-- HIDE WIDGET.newButton{name='b19', x=740, y=290,w=73,font=40,fText=CHAR.icon.bomb, color='lY',code=_setPen(19)},-- BOMB WIDGET.newButton{name='b20', x=820, y=290,w=73,font=40,fText=CHAR.icon.garbage,color='H', code=_setPen(20)},-- GB1 WIDGET.newButton{name='b21', x=900, y=290,w=73,font=40,fText=CHAR.icon.garbage,color='lH',code=_setPen(21)},-- GB2 WIDGET.newButton{name='b22', x=980, y=290,w=73,font=40,fText=CHAR.icon.garbage,color='dV',code=_setPen(22)},-- GB3 WIDGET.newButton{name='b23', x=1060,y=290,w=73,font=40,fText=CHAR.icon.garbage,color='dR',code=_setPen(23)},-- GB4 WIDGET.newButton{name='b24', x=1140,y=290,w=73,font=40,fText=CHAR.icon.garbage,color='dG',code=_setPen(24)},-- GB5 WIDGET.newButton{name='any', x=600, y=400,w=120,color='lH', font=40,code=_setPen(0)}, WIDGET.newButton{name='space', x=730, y=400,w=120,color='H', font=55,code=_setPen(-1),fText=CHAR.icon.cross_thick}, WIDGET.newButton{name='smart', x=860, y=400,w=120,color='lG', font=30,code=_setPen(-2)}, WIDGET.newButton{name='push', x=990, y=400,w=120,h=120,color='lY',font=20,code=pressKey'k'}, WIDGET.newButton{name='del', x=1120,y=400,w=120,h=120,color='lY',font=20,code=pressKey'l'}, WIDGET.newButton{name='copy', x=730, y=530,w=120,color='lR',font=60,fText=CHAR.icon.export,code=pressKey'cC'}, WIDGET.newButton{name='paste', x=860, y=530,w=120,color='lB',font=60,fText=CHAR.icon.import,code=pressKey'cV'}, WIDGET.newButton{name='clear', x=990, y=530,w=120,color='Z', font=70,fText=CHAR.icon.trash,code=pressKey'delete'}, WIDGET.newSwitch{name='demo', x=755, y=640,lim=220,disp=function() return demo end,code=function() demo=not demo end}, WIDGET.newButton{name='newPg', x=100, y=110,w=160,h=110,color='N', font=20,code=pressKey'n'}, WIDGET.newButton{name='delPg', x=100, y=230,w=160,h=110,color='lR',font=20,code=pressKey'm'}, WIDGET.newButton{name='prevPg', x=100, y=350,w=160,h=110,color='lG',font=20,code=pressKey'pageup',hideF=function() return page==1 end}, WIDGET.newButton{name='nextPg', x=100, y=470,w=160,h=110,color='lG',font=20,code=pressKey'pagedown',hideF=function() return page==#FIELD end}, WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene}, } return scene