diff --git a/SFX/error.ogg b/SFX/error.ogg index 0943e660..80303398 100644 Binary files a/SFX/error.ogg and b/SFX/error.ogg differ diff --git a/SFX/finesseError.ogg b/SFX/finesseError.ogg new file mode 100644 index 00000000..0943e660 Binary files /dev/null and b/SFX/finesseError.ogg differ diff --git a/SFX/error_long.ogg b/SFX/finesseError_long.ogg similarity index 100% rename from SFX/error_long.ogg rename to SFX/finesseError_long.ogg diff --git a/conf.lua b/conf.lua index 5fad9754..1afbc224 100644 --- a/conf.lua +++ b/conf.lua @@ -1,10 +1,10 @@ -gameVersion="Alpha V0.8.7" +gameVersion="Alpha V0.8.8" function love.conf(t) t.identity="Techmino"--Save directory name t.version="11.1" - t.console=X - t.gammacorrect=X - t.appendidentity=X--Search files in source before save directory + t.console=false + t.gammacorrect=false + t.appendidentity=false--Search files in source before save directory t.accelerometerjoystick=false--ios/android加速度计=摇杆 t.audio.mixwithsystem=true @@ -13,23 +13,23 @@ function love.conf(t) W.icon="/image/icon.png" W.width,W.height=1280,720 W.minwidth,W.minheight=640,360 - W.borderless=X - W.resizable=1 + W.borderless=false + W.resizable=true W.fullscreentype="desktop"--"exclusive" - W.fullscreen=X + W.fullscreen=false W.vsync=0--0:∞fps - W.msaa=X--The number of samples to use with multi-sampled antialiasing (number) + W.msaa=false--The number of samples to use with multi-sampled antialiasing (number) W.depth=0--Bits per sample in the depth buffer W.stencil=1--Bits per sample in the stencil buffer W.display=1--Monitor ID - W.highdpi=X--Enable high-dpi mode for the window on a Retina display (boolean) + W.highdpi=false--Enable high-dpi mode for the window on a Retina display (boolean) W.x,W.y=nil local M=t.modules - M.window,M.system,M.event=1,1,1 - M.audio,M.sound=1,1 - M.math,M.data=1,1 - M.timer,M.graphics,M.font,M.image=1,1,1,1 - M.mouse,M.touch,M.keyboard,M.joystick=1,1,1,1 - M.physics,M.thread,M.video=X + M.window,M.system,M.event=true,true,true + M.audio,M.sound=true,true + M.math,M.data=true,true + M.timer,M.graphics,M.font,M.image=true,true,true,true + M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true + M.physics,M.thread,M.video=false,false,false end \ No newline at end of file diff --git a/dataList.lua b/dataList.lua index 98697d30..2a13dbf1 100644 --- a/dataList.lua +++ b/dataList.lua @@ -36,6 +36,7 @@ local function gameOver() local m=M.unlock[i] modeRanks[m]=modes[m].score and 0 or 6 end + saveUnlock() end end local D=M.score(P) @@ -54,6 +55,7 @@ local function gameOver() if p==0 then P:showText(text.newRecord,0,-100,100,"beat",.5) end + D.date=os.date("%Y/%m/%d %H:%M") ins(L,p+1,D) if L[11]then L[11]=nil end saveRecord(M.saveFileName,L) @@ -88,7 +90,7 @@ function Event.win(P,result) die(P) P.result="WIN" if modeEnv.royaleMode then - P.rank=1 + P.modeData.event=1 P:changeAtk() end if P.human then @@ -130,8 +132,8 @@ function Event.lose(P) P.result="K.O." if modeEnv.royaleMode then P:changeAtk() - P.rank=#players.alive+1 - P:showText(P.rank,0,-120,60,"appear",1,12) + P.modeData.event=#players.alive+1 + P:showText(P.modeData.event,0,-120,60,"appear",1,12) P.strength=0 if P.lastRecv then local A,i=P,0 @@ -142,7 +144,7 @@ function Event.lose(P) if P.id==1 or A.id==1 then P.killMark=A.id==1 end - A.ko,A.badge=A.ko+1,A.badge+P.badge+1 + A.modeData.point,A.badge=A.modeData.point+1,A.badge+P.badge+1 for i=A.strength+1,4 do if A.badge>=royaleData.powerUp[i]then A.strength=i @@ -254,91 +256,91 @@ end -------------------------------------------------- --------------------------------------------------- modes={ - {"sprint_10", id=1, x=0, y=0, shape=1,size=35,unlock={2,3}}, - {"sprint_20", id=2, x=-300, y=0, shape=1,size=45,unlock={73,74,75}}, - {"sprint_40", id=3, x=0, y=-400, shape=1,size=55,unlock={4,9}}, - {"sprint_100", id=4, x=-200, y=-400, shape=1,size=45,unlock={5,7}}, - {"sprint_400", id=5, x=-400, y=-400, shape=1,size=35,unlock={6}}, - {"sprint_1000", id=6, x=-600, y=-400, shape=1,size=35,unlock={}}, - {"drought_normal", id=7, x=-400, y=-200, shape=1,size=35,unlock={8}}, - {"drought_lunatic", id=8, x=-600, y=-200, shape=1,size=35,unlock={}}, - {"marathon_normal", id=9, x=0, y=-600, shape=1,size=55,unlock={10,11,22,31,36,37,48,68,71,72}}, - {"marathon_hard", id=10, x=0, y=-800, shape=1,size=45,unlock={27}}, - {"solo_1", id=11, x=-300, y=-1000, shape=1,size=35,unlock={12}}, - {"solo_2", id=12, x=-500, y=-1000, shape=1,size=35,unlock={13}}, - {"solo_3", id=13, x=-700, y=-1000, shape=1,size=35,unlock={14,16}}, - {"solo_4", id=14, x=-900, y=-1000, shape=1,size=35,unlock={15}}, - {"solo_5", id=15, x=-1100, y=-1000, shape=1,size=35,unlock={}}, - {"techmino49_easy", id=16, x=-900, y=-1200, shape=1,size=35,unlock={17,19}}, - {"techmino49_hard", id=17, x=-900, y=-1400, shape=1,size=35,unlock={18}}, - {"techmino49_ultimate", id=18, x=-900, y=-1600, shape=1,size=35,unlock={}}, + {"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}}, + {"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={}}, + {"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,68,71,72}}, + {"marathon_hard", id=10, x=0, y=-800, size=45,shape=1,icon="flag", unlock={27}}, + {"solo_1", id=11, x=-300, y=-1000, size=35,shape=1,icon="solo", unlock={12}}, + {"solo_2", id=12, x=-500, y=-1000, size=35,shape=1,icon="solo", unlock={13}}, + {"solo_3", id=13, x=-700, y=-1000, size=35,shape=1,icon="solo", unlock={14,16}}, + {"solo_4", id=14, x=-900, y=-1000, size=35,shape=1,icon="solo", unlock={15}}, + {"solo_5", id=15, x=-1100, y=-1000, size=35,shape=1,icon="solo", unlock={}}, + {"techmino49_easy", id=16, x=-900, y=-1200, size=35,shape=1,icon="", unlock={17,19}}, + {"techmino49_hard", id=17, x=-900, y=-1400, size=35,shape=1,icon="", unlock={18}}, + {"techmino49_ultimate", id=18, x=-900, y=-1600, size=35,shape=1,icon="", unlock={}}, - {"techmino99_easy", id=19, x=-1100, y=-1400, shape=1,size=35,unlock={20}}, - {"techmino99_hard", id=20, x=-1100, y=-1600, shape=1,size=35,unlock={21}}, - {"techmino99_ultimate", id=21, x=-1100, y=-1800, shape=1,size=35,unlock={}}, - {"round_1", id=22, x=-300, y=-800, shape=1,size=35,unlock={23}}, - {"round_2", id=23, x=-500, y=-800, shape=1,size=35,unlock={24}}, - {"round_3", id=24, x=-700, y=-800, shape=1,size=35,unlock={25}}, - {"round_4", id=25, x=-900, y=-800, shape=1,size=35,unlock={26}}, - {"round_5", id=26, x=-1100, y=-800, shape=1,size=35,unlock={}}, + {"techmino99_easy", id=19, x=-1100, y=-1400, size=35,shape=1,icon="", unlock={20}}, + {"techmino99_hard", id=20, x=-1100, y=-1600, size=35,shape=1,icon="", unlock={21}}, + {"techmino99_ultimate", id=21, x=-1100, y=-1800, size=35,shape=1,icon="", unlock={}}, + {"round_1", id=22, x=-300, y=-800, size=35,shape=1,icon="round", unlock={23}}, + {"round_2", id=23, x=-500, y=-800, size=35,shape=1,icon="round", unlock={24}}, + {"round_3", id=24, x=-700, y=-800, size=35,shape=1,icon="round", unlock={25}}, + {"round_4", id=25, x=-900, y=-800, size=35,shape=1,icon="round", unlock={26}}, + {"round_5", id=26, x=-1100, y=-800, size=35,shape=1,icon="round", unlock={}}, - {"master_beginner", id=27, x=0, y=-1000, shape=1,size=35,unlock={28}}, - {"master_adavnce", id=28, x=0, y=-1200, shape=1,size=35,unlock={29,30}}, - {"master_final", id=29, x=0, y=-1400, shape=1,size=35,unlock={}}, - {"GM", id=30, x=150, y=-1500, shape=1,size=35,unlock={}}, + {"master_beginner", id=27, x=0, y=-1000, size=35,shape=1,icon="", unlock={28}}, + {"master_adavnce", id=28, x=0, y=-1200, size=35,shape=1,icon="", unlock={29,30}}, + {"master_final", id=29, x=0, y=-1400, size=35,shape=1,icon="", unlock={}}, + {"GM", id=30, x=150, y=-1500, size=35,shape=1,icon="", unlock={}}, - {"blind_easy", id=31, x=150, y=-700, shape=1,size=35,unlock={32}}, - {"blind_normal", id=32, x=150, y=-800, shape=1,size=35,unlock={33}}, - {"blind_hard", id=33, x=150, y=-900, shape=1,size=35,unlock={34}}, - {"blind_lunatic", id=34, x=150, y=-1000, shape=1,size=35,unlock={35}}, - {"blind_ultimate", id=35, x=150, y=-1100, shape=1,size=35,unlock={}}, + {"blind_easy", id=31, x=150, y=-700, size=35,shape=1,icon="", unlock={32}}, + {"blind_normal", id=32, x=150, y=-800, size=35,shape=1,icon="", unlock={33}}, + {"blind_hard", id=33, x=150, y=-900, size=35,shape=1,icon="", unlock={34}}, + {"blind_lunatic", id=34, x=150, y=-1000, size=35,shape=1,icon="", unlock={35}}, + {"blind_ultimate", id=35, x=150, y=-1100, size=35,shape=1,icon="", unlock={}}, - {"classic_fast", id=36, x=-300, y=-1200, shape=1,size=35,unlock={}}, + {"classic_fast", id=36, x=-300, y=-1200, size=35,shape=2,icon="classic", unlock={}}, - {"survivor_easy", id=37, x=300, y=-600, shape=1,size=35,unlock={38}}, - {"survivor_normal", id=38, x=500, y=-600, shape=1,size=35,unlock={39,42,44,46}}, - {"survivor_hard", id=39, x=700, y=-600, shape=1,size=35,unlock={40}}, - {"survivor_lunatic", id=40, x=900, y=-600, shape=1,size=35,unlock={41}}, - {"survivor_ultimate", id=41, x=1100, y=-600, shape=1,size=35,unlock={}}, - {"attacker_hard", id=42, x=300, y=-800, shape=1,size=35,unlock={43}}, - {"attacker_ultimate", id=43, x=300, y=-1000, shape=1,size=35,unlock={}}, + {"survivor_easy", id=37, x=300, y=-600, size=35,shape=1,icon="", unlock={38}}, + {"survivor_normal", id=38, x=500, y=-600, size=35,shape=1,icon="", unlock={39,42,44,46}}, + {"survivor_hard", id=39, x=700, y=-600, size=35,shape=1,icon="", unlock={40}}, + {"survivor_lunatic", id=40, x=900, y=-600, size=35,shape=1,icon="", unlock={41}}, + {"survivor_ultimate", id=41, x=1100, y=-600, size=35,shape=1,icon="", unlock={}}, + {"attacker_hard", id=42, x=300, y=-800, size=35,shape=1,icon="", unlock={43}}, + {"attacker_ultimate", id=43, x=300, y=-1000, size=35,shape=1,icon="", unlock={}}, - {"defender_normal", id=44, x=500, y=-800, shape=1,size=35,unlock={45}}, - {"defender_lunatic", id=45, x=500, y=-1000, shape=1,size=35,unlock={}}, + {"defender_normal", id=44, x=500, y=-800, size=35,shape=1,icon="", unlock={45}}, + {"defender_lunatic", id=45, x=500, y=-1000, size=35,shape=1,icon="", unlock={}}, - {"dig_hard", id=46, x=700, y=-800, shape=1,size=35,unlock={47}}, - {"dig_ultimate", id=47, x=700, y=-1000, shape=1,size=35,unlock={}}, + {"dig_hard", id=46, x=700, y=-800, size=35,shape=1,icon="", unlock={47}}, + {"dig_ultimate", id=47, x=700, y=-1000, size=35,shape=1,icon="", unlock={}}, - {"bigbang", id=48, x=400, y=-400, shape=1,size=55,unlock={49,51,56}}, - {"c4wtrain_normal", id=49, x=700, y=-400, shape=1,size=35,unlock={50}}, - {"c4wtrain_lunatic", id=50, x=900, y=-400, shape=1,size=35,unlock={}}, + {"bigbang", id=48, x=400, y=-400, size=55,shape=1,icon="", unlock={49,51,56}}, + {"c4wtrain_normal", id=49, x=700, y=-400, size=35,shape=1,icon="", unlock={50}}, + {"c4wtrain_lunatic", id=50, x=900, y=-400, size=35,shape=1,icon="", unlock={}}, - {"pctrain_normal", id=51, x=700, y=-200, shape=1,size=35,unlock={52,53}}, - {"pctrain_lunatic", id=52, x=900, y=-200, shape=1,size=35,unlock={}}, - {"pcchallenge_normal", id=53, x=800, y=-100, shape=1,size=35,unlock={54}}, - {"pcchallenge_hard", id=54, x=1000, y=-100, shape=1,size=35,unlock={55}}, - {"pcchallenge_lunatic", id=55, x=1200, y=-100, shape=1,size=35,unlock={}}, - {"tech_normal", id=56, x=400, y=-100, shape=1,size=35,unlock={57,58}}, - {"tech_normal+", id=57, x=650, y=150, shape=1,size=35,unlock={64,67}}, - {"tech_hard", id=58, x=400, y=50, shape=1,size=35,unlock={59,60}}, - {"tech_hard+", id=59, x=250, y=50, shape=1,size=35,unlock={}}, - {"tech_lunatic", id=60, x=400, y=200, shape=1,size=35,unlock={61,62}}, - {"tech_lunatic+", id=61, x=250, y=200, shape=1,size=35,unlock={}}, - {"tech_ultimate", id=62, x=400, y=350, shape=1,size=35,unlock={63}}, - {"tech_ultimate+", id=63, x=250, y=350, shape=1,size=35,unlock={}}, - {"tsd_easy", id=64, x=800, y=200, shape=1,size=35,unlock={65}}, - {"tsd_hard", id=65, x=1000, y=200, shape=1,size=35,unlock={66}}, - {"tsd_ultimate", id=66, x=1200, y=200, shape=1,size=35,unlock={}}, + {"pctrain_normal", id=51, x=700, y=-200, size=35,shape=1,icon="", unlock={52,53}}, + {"pctrain_lunatic", id=52, x=900, y=-200, size=35,shape=1,icon="", unlock={}}, + {"pcchallenge_normal", id=53, x=800, y=-100, size=35,shape=1,icon="", unlock={54}}, + {"pcchallenge_hard", id=54, x=1000, y=-100, size=35,shape=1,icon="", unlock={55}}, + {"pcchallenge_lunatic", id=55, x=1200, y=-100, size=35,shape=1,icon="", unlock={}}, + {"tech_normal", id=56, x=400, y=-100, size=35,shape=1,icon="", unlock={57,58}}, + {"tech_normal+", id=57, x=650, y=150, size=35,shape=1,icon="", unlock={64,67}}, + {"tech_hard", id=58, x=400, y=50, size=35,shape=1,icon="", unlock={59,60}}, + {"tech_hard+", id=59, x=250, y=50, size=35,shape=1,icon="", unlock={}}, + {"tech_lunatic", id=60, x=400, y=200, size=35,shape=1,icon="", unlock={61,62}}, + {"tech_lunatic+", id=61, x=250, y=200, size=35,shape=1,icon="", unlock={}}, + {"tech_ultimate", id=62, x=400, y=350, size=35,shape=1,icon="", unlock={63}}, + {"tech_ultimate+", id=63, x=250, y=350, size=35,shape=1,icon="", unlock={}}, + {"tsd_easy", id=64, x=800, y=200, size=35,shape=1,icon="", unlock={65}}, + {"tsd_hard", id=65, x=1000, y=200, size=35,shape=1,icon="", unlock={66}}, + {"tsd_ultimate", id=66, x=1200, y=200, size=35,shape=1,icon="", unlock={}}, - {"ultra", id=67, x=650, y=400, shape=1,size=35,unlock={}}, - {"zen", id=68, x=-900, y=-600, shape=1,size=35,unlock={69,70}}, - {"infinite", id=69, x=-900, y=-400, shape=1,size=35,unlock={}}, - {"infinite_dig", id=70, x=-1100, y=-600, shape=1,size=35,unlock={}}, - {"custom_clear", id=71, x=200, y=-350, shape=2,size=45,unlock={}}, - {"custom_puzzle", id=72, x=200, y=-200, shape=2,size=45,unlock={}}, - {"hotseat_2P", id=73, x=-300, y=200, shape=2,size=45,unlock={}}, - {"hotseat_3P", id=74, x=-450, y=200, shape=2,size=45,unlock={}}, - {"hotseat_4P", id=75, x=-600, y=200, shape=2,size=45,unlock={}}, + {"ultra", id=67, x=650, y=400, size=35,shape=1,icon="", unlock={}}, + {"zen", id=68, x=-900, y=-600, size=35,shape=1,icon="zen", unlock={69,70}}, + {"infinite", id=69, x=-900, y=-400, size=35,shape=1,icon="", unlock={}}, + {"infinite_dig", id=70, x=-1100, y=-600, size=35,shape=1,icon="", 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="", unlock={}}, + {"hotseat_3P", id=74, x=-450, y=200, size=45,shape=3,icon="", unlock={}}, + {"hotseat_4P", id=75, x=-600, y=200, size=45,shape=3,icon="", unlock={}}, } modeRanks={} for i=1,#modes do diff --git a/default_data.lua b/default_data.lua index 8b7bdfdc..da9b9023 100644 --- a/default_data.lua +++ b/default_data.lua @@ -1,7 +1,10 @@ setting={ das=10,arr=2, sddas=0,sdarr=2, - quickR=true,swap=true, + reTime=10, + maxNext=6, + quickR=true, + swap=true, fine=false, --game @@ -14,13 +17,13 @@ setting={ fullscreen=false, bg=true, - bgblock=true, + bgspace=true, lang=1, skin=1, --graphic sfx=10,bgm=7, - vib=3,voc=0, + vib=0,voc=0, stereo=6, --sound @@ -32,12 +35,12 @@ setting={ {},{},{},{},{},{},{}, --joystick }, - VKSwitch=true, - VKTrack=true,--If tracked - VKDodge=false,--If repel - VKTchW=3,--Touch Weight - VKCurW=4,--CurPos Weight - VKIcon=true, + VKSwitch=false,--if disp + VKTrack=false,--if tracked + VKDodge=false,--if dodge + VKTchW=3,--Touch-Pos Weight + VKCurW=4,--Cur-Pos Weight + VKIcon=true,--if disp icon VKAlpha=3, --control } diff --git a/font.ttf b/font.ttf index 80f34534..5a44a8ba 100644 Binary files a/font.ttf and b/font.ttf differ diff --git a/image/BG/bg1.jpg b/image/BG/bg1.jpg deleted file mode 100644 index 76fa7980..00000000 Binary files a/image/BG/bg1.jpg and /dev/null differ diff --git a/image/BG/bg1.png b/image/BG/bg1.png new file mode 100644 index 00000000..c91cd575 Binary files /dev/null and b/image/BG/bg1.png differ diff --git a/image/BG/bg2.png b/image/BG/bg2.png index 78e711c9..81e9d6dd 100644 Binary files a/image/BG/bg2.png and b/image/BG/bg2.png differ diff --git a/image/mess/ctrlSpeedLimit.png b/image/mess/ctrlSpeedLimit.png new file mode 100644 index 00000000..dbbbe36a Binary files /dev/null and b/image/mess/ctrlSpeedLimit.png differ diff --git a/image/mess/speedLimit.png b/image/mess/speedLimit.png new file mode 100644 index 00000000..ceb602b5 Binary files /dev/null and b/image/mess/speedLimit.png differ diff --git a/image/modeIcon/custom.png b/image/modeIcon/custom.png new file mode 100644 index 00000000..7ee97f62 Binary files /dev/null and b/image/modeIcon/custom.png differ diff --git a/image/modeIcon/ic_pin_drop_black_48dp.png b/image/modeIcon/ic_pin_drop_black_48dp.png new file mode 100644 index 00000000..b1865f7b Binary files /dev/null and b/image/modeIcon/ic_pin_drop_black_48dp.png differ diff --git a/image/modeIcon/puzzle.png b/image/modeIcon/puzzle.png new file mode 100644 index 00000000..55d036f8 Binary files /dev/null and b/image/modeIcon/puzzle.png differ diff --git a/image/modeIcon/solo.png b/image/modeIcon/solo.png new file mode 100644 index 00000000..71441f24 Binary files /dev/null and b/image/modeIcon/solo.png differ diff --git a/image/modeIcon/timer.png b/image/modeIcon/timer.png new file mode 100644 index 00000000..7fcbad90 Binary files /dev/null and b/image/modeIcon/timer.png differ diff --git a/image/modeIcon/zen.png b/image/modeIcon/zen.png new file mode 100644 index 00000000..fdf9b5a8 Binary files /dev/null and b/image/modeIcon/zen.png differ diff --git a/language/chi.lua b/language/chi.lua index 4471279b..e175d925 100644 --- a/language/chi.lua +++ b/language/chi.lua @@ -39,7 +39,7 @@ return{ custom="自定义游戏", customOption={ - drop="下落延迟:", + drop="下落速度:", lock="锁定延迟:", wait="放块延迟:", fall="消行延迟:", @@ -68,7 +68,7 @@ return{ }, softdropdas="软降DAS:", softdroparr="软降ARR:", - snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, + snapLevelName={"无吸附","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, keyboard="键盘",joystick="手柄", space="空格",enter="回车", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回", @@ -81,6 +81,7 @@ return{ settingSaved="设置已保存", settingSavingError="设置保存失败:", statSavingError="数据保存失败:", + unlockSavingError="解锁保存失败", copySuccess="已复制到剪切板", dataCorrupted="数据损坏", VKTchW="触摸点权重", @@ -89,6 +90,7 @@ return{ noScore="暂无成绩", highScore="最佳成绩", newRecord="打破纪录", + errorMsg="Techmino遇到了问题,需要重新启动.\n我们已收集了一些错误信息,你可以向作者进行反馈.", actName=actName, @@ -245,6 +247,8 @@ return{ arrD="-",arrU="+", sddasD="-",sddasU="+", sdarrD="-",sdarrU="+", + reTime="开局等待时间", + maxNext="最大预览数量", quickR="快速重新开始", swap="组合键切换攻击模式", fine="极简操作提示音", @@ -260,7 +264,7 @@ return{ center="旋转中心", skin="皮肤", bg="背景", - bgblock="背景动画", + bgspace="星空背景", smo="平滑下落", dropFX="下落特效等级", shakeFX="晃动特效等级", diff --git a/language/chi_full.lua b/language/chi_full.lua index e1d8e43b..0875910a 100644 --- a/language/chi_full.lua +++ b/language/chi_full.lua @@ -68,7 +68,7 @@ return{ }, softdropdas="软降DAS:", softdroparr="软降ARR:", - snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, + snapLevelName={"无吸附","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, keyboard="键盘",joystick="手柄", space="空格",enter="回车", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回", @@ -81,6 +81,7 @@ return{ settingSaved="设置已保存", settingSavingError="设置保存失败:", statSavingError="数据保存失败:", + unlockSavingError="解锁保存失败", copySuccess="已复制到剪切板", dataCorrupted="数据损坏", VKTchW="触摸点权重", @@ -89,6 +90,7 @@ return{ noScore="暂无成绩", highScore="最佳成绩", newRecord="打破纪录", + errorMsg="Techmino遇到了问题,需要重新启动.\n我们已收集了一些错误信息,你可以向作者进行反馈.", actName=actName, @@ -246,6 +248,8 @@ return{ arrD="-",arrU="+", sddasD="-",sddasU="+", sdarrD="-",sdarrU="+", + reTime="开局等待时间", + maxNext="最大预览数量", quickR="快速重新开始", swap="组合键切换攻击模式", fine="极简操作提示音", @@ -261,7 +265,7 @@ return{ center="旋转中心", skin="皮肤", bg="背景", - bgblock="背景动画", + bgspace="星空背景", smo="平滑下落", dropFX="下落特效等级", shakeFX="晃动特效等级", diff --git a/language/eng.lua b/language/eng.lua index 8bcd6b5b..a9fee3c8 100644 --- a/language/eng.lua +++ b/language/eng.lua @@ -37,7 +37,7 @@ return{ custom="Custom Game", customOption={ - drop="Drop delay:", + drop="Drop speed:", lock="Lock delay:", wait="Next piece delay:", fall="Clear row delay:", @@ -79,6 +79,7 @@ return{ settingSaved="Setting saved", settingSavingError="Failed to save setting:", statSavingError="Failed to save stat:", + unlockSavingError="Failed to save unlock:", copySuccess="Copy Success", dataCorrupted="Data Corrupted", VKTchW="Touch weight", @@ -87,6 +88,7 @@ return{ noScore="No Score Yet", highScore="Highscore", newRecord="New Rocord", + errorMsg="Techmino ran into a problem and needs to restart.\nWe collected some error info,and you can send them to author.", actName=actName, @@ -244,6 +246,8 @@ Lib used: arrD="-",arrU="+", sddasD="-",sddasU="+", sdarrD="-",sdarrU="+", + reTime="Delay before game", + maxNext="Max next count", quickR="Quick restart", swap="Combo key to change ATK mode", fine="Finesse error SFX", @@ -259,7 +263,7 @@ Lib used: center="Center", skin="Skin", bg="Background", - bgblock="BG animation", + bgspace="BG space", smo="Smoooth drop", dropFX="Drop FX level", shakeFX="Shake FX level", diff --git a/list.lua b/list.lua index 853113ee..643689cd 100644 --- a/list.lua +++ b/list.lua @@ -59,7 +59,7 @@ blockColor={ sfx={ "welcome", "click","enter", - "error","error_long", + "finesseError","finesseError_long", --Stereo sfxs(cannot set position) "button","swipe", "ready","start","win","fail","collect", @@ -72,6 +72,8 @@ sfx={ "spin_0","spin_1","spin_2","spin_3", "emit","blip_1","blip_2", "perfectclear", + + "error", --Mono sfxs } bgm={ diff --git a/main.lua b/main.lua index 4a02e878..774859cb 100644 --- a/main.lua +++ b/main.lua @@ -2,11 +2,13 @@ 第一次搞这么大的工程,参考价值不是很大 如果你有时间并且也热爱俄罗斯方块的话,来看代码或者帮助优化的话欢迎! ]] +math.randomseed(os.time()*626) local love=love local ms,kb,tc=love.mouse,love.keyboard,love.touch local gc,sys=love.graphics,love.system local Timer=love.timer.getTime local int,rnd,max,min=math.floor,math.random,math.max,math.min +local abs=math.abs local rem=table.remove package.path="?.lua"--boost @@ -18,10 +20,11 @@ local xOy=love.math.newTransform() local mx,my,mouseShow=-20,-20,false local touching=nil--第一触摸ID local touchDist=nil +joysticks={} local devMode=0 players={alive={},human=0} -scr={x=0,y=0,w=nil,h=nil,k=1} +scr={x=0,y=0,w=0,h=0,rad=0,k=1}--x,y,wid,hei,radius,scale K local scr=scr mapCam={ sel=nil,--selected mode ID @@ -58,6 +61,7 @@ for i=11,20 do preField[i]={0,0,0,0,0,0,0,0,0,0}end freeRow={L=40}for i=1,40 do freeRow[i]={0,0,0,0,0,0,0,0,0,0}end --Game system Vars ------------------------------------------------------------- +space=require("parts/space")local space=space setFont=require("parts/font") blocks=require("parts/mino") -- require("parts/light") @@ -118,19 +122,6 @@ if sys.getPowerInfo()~="unknown"then end end end -local function getNewBlock() - FX_BGblock.ct=FX_BGblock.ct+1 - if FX_BGblock.ct==17 then FX_BGblock.ct=1 end - local t=FX_BGblock.list[FX_BGblock.ct] - t.bn,t.size=FX_BGblock.next,2+3*rnd() - t.b=blocks[t.bn][rnd(0,3)] - t.x=rnd(-#t.b[1]*t.size*30+100,1180) - t.y=0 - t.ty=720+#t.b*30*t.size - t.v=t.size*(1+rnd()) - FX_BGblock.next=FX_BGblock.next%7+1 - return t -end local function onVirtualkey(x,y) local dist,nearest=1e10 for K=1,#virtualkey do @@ -221,6 +212,8 @@ local function onMode(x,y) if M.shape==1 then if x>M.x-s and xM.y-s and y1 then VOICE((t<1.5 or t>15)and"doubt"or rnd()<.8 and"happy"or"egg") sceneTemp.last=Timer() + if rnd()<.26 then + for i=1,#modes do + local M=modes[i] + for i=1,#M.unlock do + local m=M.unlock[i] + modeRanks[m]=modes[m].score and(modeRanks[m]and max(modeRanks[m],0)or 0)or 6 + end + end + saveUnlock() + TEXT("DEVMODE:UNLOCKALL",640,360,50,"stretch",.6) + end end end end @@ -467,7 +471,7 @@ function keyDown.setting_key(key) if key=="escape"then if s.kS then s.kS=false - SFX("error",.5) + SFX("finesseError",.5) else scene.back() end @@ -514,7 +518,7 @@ function gamepadDown.setting_key(key) if key=="back"then if s.jS then s.jS=false - SFX("error",.5) + SFX("finesseError",.5) else scene.back() end @@ -797,10 +801,11 @@ local function widgetControl_gamepad(i) end local lastX,lastY--last clickDown pos function love.mousepressed(x,y,k,t,num) + if t then return end mouseShow=true mx,my=xOy:inverseTransformPoint(x,y) if devMode>0 then print(mx,my)end - if t or scene.swapping then return end + if scene.swapping then return end if mouseDown[scene.cur]then mouseDown[scene.cur](mx,my,k) elseif k==2 then @@ -815,9 +820,10 @@ function love.mousepressed(x,y,k,t,num) lastY=my end function love.mousemoved(x,y,dx,dy,t) + if t then return end mouseShow=true mx,my=xOy:inverseTransformPoint(x,y) - if t or scene.swapping then return end + if scene.swapping then return end dx,dy=dx/scr.k,dy/scr.k if mouseMove[scene.cur]then mouseMove[scene.cur](mx,my,dx,dy) @@ -835,6 +841,7 @@ function love.mousemoved(x,y,dx,dy,t) end end function love.mousereleased(x,y,k,t,num) + if t then return end mx,my=xOy:inverseTransformPoint(x,y) if t or scene.swapping then return end if mouseUp[scene.cur]then @@ -917,6 +924,8 @@ function love.keypressed(i) elseif i=="q"then local W=widget_sel if W then W:getInfo()end + elseif i=="e"then + error("Error Test") elseif widget_sel then local W=widget_sel if i=="left"then W.x=W.x-10 @@ -943,6 +952,17 @@ function love.keyreleased(i) if keyUp[scene.cur]then keyUp[scene.cur](i)end end +function love.joystickadded(JS) + joysticks[#joysticks+1]=JS +end +function love.joystickremoved(JS) + for i=1,#joysticks do + if joysticks[i]==JS then + rem(joysticks,i) + return + end + end +end local keyMirror={ dpup="up", dpdown="down", @@ -966,9 +986,26 @@ function love.gamepadreleased(joystick,i) end end --[[ -function love.joystickpressed(js,k)end -function love.joystickaxis(js,axis,val)end -function love.joystickhat(js,hat,dir)end +function love.joystickpressed(JS,k) + mouseShow=false + if scene.swapping then return end + if gamepadDown[scene.cur]then gamepadDown[scene.cur](i) + elseif keyDown[scene.cur]then keyDown[scene.cur](keyMirror[i]or i) + elseif i=="back"then scene.back() + else widgetControl_gamepad(i) + end +end +function love.joystickreleased(JS,k) + if scene.swapping then return end + if gamepadUp[scene.cur]then gamepadUp[scene.cur](i) + end +end +function love.joystickaxis(JS,axis,val) + +end +function love.joystickhat(JS,hat,dir) + +end function love.sendData(data)end function love.receiveData(id,data)end ]] @@ -978,6 +1015,7 @@ end function love.resize(w,h) love.timer.sleep(.26) scr.w,scr.h,scr.r=w,h,h/w + scr.rad=(w^2+h^2)^.5 if scr.r>=.5625 then scr.k=w/1280 scr.x,scr.y=0,(h-w*9/16)*.5 @@ -985,14 +1023,19 @@ function love.resize(w,h) scr.k=h/720 scr.x,scr.y=(w-h*16/9)*.5,0 end - gc.origin() xOy=xOy:setTransformation(w*.5,h*.5,nil,scr.k,nil,640,360) - gc.replaceTransform(xOy) + if setting.bgspace then + space.resize(w,h) + space.new() + end end function love.focus(f) if system~="Android" and not f and scene.cur=="play"then pauseGame()end end function love.update(dt) + if setting.bgspace then + space.update() + end for i=#sysFX,1,-1 do local S=sysFX[i] S[2]=S[2]+1 @@ -1002,18 +1045,6 @@ function love.update(dt) end end end - for i=#FX_BGblock,1,-1 do - local B=FX_BGblock[i] - B.y=B.y+B.v - if B.y>B.ty then rem(FX_BGblock,i)end - end - if setting.bgblock then - FX_BGblock.tm=FX_BGblock.tm-1 - if FX_BGblock.tm==0 then - FX_BGblock[#FX_BGblock+1]=getNewBlock() - FX_BGblock.tm=rnd(20,30) - end - end for i=#texts,1,-1 do local t=texts[i] t.c=t.c+t.spd @@ -1092,103 +1123,162 @@ function love.update(dt) W:update() end--更新控件 end +function love.errorhandler(msg) + local PUMP,POLL=love.event.pump,love.event.poll + love.mouse.setVisible(true) + love.audio.stop() + local err={"Error:"..msg} + local trace=debug.traceback("",2) + local c=2 + for l in string.gmatch(trace,"(.-)\n")do + if c>2 then + if not string.find(l,"boot")then + err[c]=string.gsub(l,"^\t*","") + c=c+1 + end + else + err[2]="Traceback" + c=3 + end + end + print(table.concat(err,"\n"),1,c-2) + -- err=err:gsub("%[string \"(.-)\"%]","%1") + local CAP + local function _(_)CAP=gc.newImage(_)end + gc.captureScreenshot(_) + local T=0 + return function() + PUMP() + for e,a,b in POLL()do + if e=="quit"or a=="escape"then + destroyPlayers() + return 1 + elseif a=="return"or a=="start"then + destroyPlayers() + return"restart" + elseif e=="resize"then + T=2 + love.resize(a,b) + end + end + T=T+1 + if T==1 then + if sfx.error then + SFX("error",.8) + end + elseif T==2 then + gc.clear(.3,.5,.9) + elseif T==3 then + gc.setColor(1,1,1) + gc.push("transform") + gc.replaceTransform(xOy) + gc.draw(CAP,100,365,nil,512/CAP:getWidth(),288/CAP:getHeight()) + gc.pop() + elseif T==4 then + gc.push("transform") + gc.replaceTransform(xOy) + setFont(120) + gc.print(":(",100,40) + setFont(38) + gc.printf(text.errorMsg,100,200,1280-100) + setFont(20) + gc.print(err[1],626,360) + gc.print("TRACEBACK",626,410) + for i=4,#err-2 do + gc.print(err[i],626,355+20*i) + end + gc.pop() + end + gc.present() + love.timer.sleep(.1) + end +end + local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5} local FPS=love.timer.getFPS function love.draw() gc.discard()--SPEED UPUPUP! Pnt.BG[setting.bg and curBG or"grey"]() - gc.setColor(1,1,1,.2) - for n=1,#FX_BGblock do - local b,img=FX_BGblock[n].b,blockSkin[FX_BGblock[n].bn] - local size=FX_BGblock[n].size - for i=1,#b do for j=1,#b[1]do - if b[i][j]then - gc.draw(img,FX_BGblock[n].x+(j-1)*30*size,FX_BGblock[n].y-i*30*size,nil,size) + if setting.bgspace then + space.draw() + end + gc.push("transform") + gc.replaceTransform(xOy) + if Pnt[scene.cur]then Pnt[scene.cur]()end + for k,W in next,Widget[scene.cur]do + if not(W.hide and W.hide())then + W:draw() end - end end - end--Draw BG falling blocks - if Pnt[scene.cur]then Pnt[scene.cur]()end - for k,W in next,Widget[scene.cur]do - if not(W.hide and W.hide())then - W:draw() - end - end--Draw widgets - if mouseShow then - local r=Timer()*.5 - gc.setColor(1,1,1,min(1-math.abs(1-r%1*2),.3)) - r=int(r)%7+1 - gc.draw(miniBlock[r],mx,my,Timer()%3.1416*4,20,20,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5) - gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5) - gc.setColor(1,1,1)gc.circle("fill",mx,my,3) - end--Awesome mouse! + end--Draw widgets + if mouseShow then + local r=Timer()*.5 + gc.setColor(1,1,1,min(1-math.abs(1-r%1*2),.3)) + r=int(r)%7+1 + gc.draw(miniBlock[r],mx,my,Timer()%3.1416*4,20,20,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5) + gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5) + gc.setColor(1,1,1)gc.circle("fill",mx,my,3) + end--Awesome mouse! + gc.setLineWidth(6) + for i=1,#sysFX do + local S=sysFX[i] + if S[1]==0 then + gc.setColor(1,1,1,1-S[2]/S[3]) + local r=(10*S[2]/S[3])^1.2 + gc.rectangle("line",S[4]-r,S[5]-r,S[6]+2*r,S[7]+2*r) + --按钮波纹 + elseif S[1]==1 then + gc.setColor(S[4],S[5],S[6],1-S[2]/S[3]) + gc.rectangle("fill",S[7],S[8],S[9],S[10],2) + --开关/滑条残影 + end + end--guiFXs + for i=1,#texts do + local t=texts[i] + local p=t.c + gc.setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5) + setFont(t.font) + t:draw() + end--Floating Texts + gc.pop() gc.setColor(1,1,1) if powerInfoCanvas then gc.draw(powerInfoCanvas) end--Power Info - gc.setLineWidth(6) - for i=1,#sysFX do - local S=sysFX[i] - if S[1]==0 then - gc.setColor(1,1,1,1-S[2]/S[3]) - local r=(10*S[2]/S[3])^1.2 - gc.rectangle("line",S[4]-r,S[5]-r,S[6]+2*r,S[7]+2*r) - --按钮波纹 - elseif S[1]==1 then - gc.setColor(S[4],S[5],S[6],1-S[2]/S[3]) - gc.rectangle("fill",S[7],S[8],S[9],S[10],2) - --开关/滑条残影 - end - end--guiFXs - for i=1,#texts do - local t=texts[i] - local p=t.c - gc.setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5) - setFont(t.font) - t:draw() - end--Floating Texts if scene.swapping then - scene.swap.draw(scene.swap.time) - end--Swapping animation - if scr.r~=.5625 then - gc.setColor(0,0,0) - if scr.r>.5625 then - local d=(scr.h-scr.w*9/16)*.5/scr.k - gc.rectangle("fill",0,0,1280,-d) - gc.rectangle("fill",0,720,1280,d) - else--高窗口 - local d=(scr.w-scr.h*16/9)*.5/scr.k - gc.rectangle("fill",0,0,-d,720) - gc.rectangle("fill",1280,0,d,720) - end--扁窗口 - end--Black side + local _=scene.swap + _.draw(_.time) + end--Scene swapping animation setFont(15) gc.setColor(1,1,1) - gc.print(FPS(),5,700) + local _=scr.h-20 + gc.print(FPS(),5,_) if devMode>0 then - gc.setColor(1,devMode==2 and .5 or 1,1) - gc.print("Tasks:"..#Task,5,600) - gc.print("Voices:"..#voiceQueue,5,620) - gc.print("Mouse:"..mx.." "..my,5,640) - gc.print("Free Row:"..#freeRow.."/"..freeRow.L,5,660) - gc.print("Cache used:"..gcinfo(),5,680) - end + gc.setColor(1,1,devMode==2 and .6 or 1) + gc.print("Cache used:"..gcinfo(),5,_-20) + gc.print("Free Row:"..#freeRow.."/"..freeRow.L,5,_-40) + gc.print("Mouse:"..mx.." "..my,5,_-60) + gc.print("Voices:"..#voiceQueue,5,_-80) + gc.print("Tasks:"..#Task,5,_-100) + end--DEV info end function love.run() local T=love.timer - local lastFrame,lastFreshPow=T.getTime(),T.getTime() + local sleep=T.sleep + local lastFrame,lastFreshPow=T.getTime() + local lastFreshPow=lastFrame local readyDrawFrame=0 local mini=love.window.isMinimized local PUMP,POLL=love.event.pump,love.event.poll love.resize(gc.getWidth(),gc.getHeight()) scene.init("load")--Scene Launch - while true do + return function() PUMP() for N,a,b,c,d,e in POLL()do - if N=="quit"then - destroyPlayers() - goto END - elseif love[N]then + if love[N]then love[N](a,b,c,d,e) + elseif N=="quit"then + destroyPlayers() + return 1 end end T.step() @@ -1202,18 +1292,17 @@ function love.run() end end if Timer()-lastFrame<.058 then - T.sleep(.01) + sleep(.01) end while Timer()-lastFrame<.0158 do - T.sleep(.001) - end + sleep(.001) + end--try easily control 60FPS lastFrame=Timer() if Timer()-lastFreshPow>1 then updatePowerInfo() lastFreshPow=Timer() end end - ::END:: end ------------------------------------------------------------- local F=love.filesystem @@ -1237,15 +1326,16 @@ end FILE={ data=F.newFile("data.dat"), setting=F.newFile("setting.dat"), + unlock=F.newFile("unlock.dat"), } +if F.getInfo("unlock.dat")then loadUnlock()end if F.getInfo("data.dat")then loadStat()end if F.getInfo("setting.dat")then loadSetting() elseif system=="Android"or system=="iOS" then setting.swap=false -else - setting.VKSwitch=false + setting.VKSwitch=true + setting.vib=3 end -math.randomseed(os.time()*626) changeLanguage(setting.lang) changeBlockSkin(setting.skin) \ No newline at end of file diff --git a/modes/GM.lua b/modes/GM.lua index e8c0d102..57bb5c38 100644 --- a/modes/GM.lua +++ b/modes/GM.lua @@ -4,6 +4,7 @@ local function score(P) local F=false if P.modeData.point<70 then--if Less then MM local R=#P.cleared + if R==0 then return end if R==4 then R=10 end P.modeData.point=P.modeData.point+R P.modeData.event=sectionName[int(P.modeData.point*.1)+1] @@ -12,14 +13,14 @@ end return{ name={ - "大师", - "大师", - "GM", + "宗师", + "宗师", + "GrandMaster", }, level={ - "", - "", - "", + "GM", + "GM", + "GM", }, info={ "成为方块大师", @@ -47,6 +48,7 @@ return{ }, load=function() newPlayer(1,340,15) + players[1].modeData.event="M7" end, mesDisp=function(P,dx,dy) mDraw(drawableText.line,-82,300) diff --git a/modes/attacker_hard.lua b/modes/attacker_hard.lua index 3de7212d..18822323 100644 --- a/modes/attacker_hard.lua +++ b/modes/attacker_hard.lua @@ -66,7 +66,7 @@ return{ scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, 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 end, } \ No newline at end of file diff --git a/modes/attacker_ultimate.lua b/modes/attacker_ultimate.lua index 0088ba3f..59b26b84 100644 --- a/modes/attacker_ultimate.lua +++ b/modes/attacker_ultimate.lua @@ -79,7 +79,7 @@ return{ scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, 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 end, } \ No newline at end of file diff --git a/modes/bigbang.lua b/modes/bigbang.lua index 7226ab40..d681cbb6 100644 --- a/modes/bigbang.lua +++ b/modes/bigbang.lua @@ -34,8 +34,10 @@ return{ newPlayer(1,340,15) end, mesDisp=function(P,dx,dy) - setFont(50) - mStr("UNFINISHED",150,100) + setFont(60) + for i=1,5 do + mStr("UNFINISHED",120+10*i,100+50*i) + end end, score=function(P)return{P.modeData.event,P.stat.extraRate}end, scoreDisp=function(D)return D[1].."Stage "..format("%.2f",D[2]).."%"end, diff --git a/modes/blind_easy.lua b/modes/blind_easy.lua index e69534cb..c8db1088 100644 --- a/modes/blind_easy.lua +++ b/modes/blind_easy.lua @@ -1,3 +1,4 @@ +local min=math.min return{ name={ "隐形", @@ -33,7 +34,7 @@ return{ mStr(P.stat.row,-82,220) mStr(P.stat.clear_4,-82,340) end, - score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end, + score=function(P)return{min(P.stat.row or 200),P.stat.time}end, scoreDisp=function(D)return D[1].." Lines "..toTime(D[2])end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]=0 and R or 0,-82,280) end, - score=function(P)return{P.stat.row<=100 and P.stat.row or 100,P.stat.time}end, + score=function(P)return{min(P.stat.row,100),P.stat.time}end, scoreDisp=function(D)return D[1].." Lines "..toTime(D[2])end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]=0 and R or 0,-82,280) end, - score=function(P)return{P.stat.row<=100 and P.stat.row or 100,P.stat.time}end, + score=function(P)return{min(P.stat.row,100),P.stat.time}end, scoreDisp=function(D)return D[1].." Lines "..toTime(D[2])end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]b[1]end, getRank=function(P) local L=P.stat.row diff --git a/modes/marathon_hard.lua b/modes/marathon_hard.lua index dc82cd4d..f3636dda 100644 --- a/modes/marathon_hard.lua +++ b/modes/marathon_hard.lua @@ -34,9 +34,10 @@ return{ env={ drop=.5,fall=30, target=50,dropPiece=check, - mindas=7,minarr=1, + mindas=7,minarr=1,minsdarr=1, bg="strap",bgm="race", }, + slowmark=true, load=function() newPlayer(1,340,15) end, diff --git a/modes/marathon_normal.lua b/modes/marathon_normal.lua index 1e39bbcc..7d395b1b 100644 --- a/modes/marathon_normal.lua +++ b/modes/marathon_normal.lua @@ -33,9 +33,11 @@ return{ env={ fall=30, target=10,dropPiece=check_LVup, - mindas=7,minarr=1, + mindas=7,minarr=1,minsdarr=1, + minsdarr=1, bg="strap",bgm="way", }, + slowmark=true, load=function() newPlayer(1,340,15) end, diff --git a/modes/master_adavnce.lua b/modes/master_adavnce.lua index 7e1ab6b4..c6d5bf5f 100644 --- a/modes/master_adavnce.lua +++ b/modes/master_adavnce.lua @@ -59,6 +59,7 @@ return{ freshLimit=15, bg="game2",bgm="secret7th", }, + slowmark=true, load=function() newPlayer(1,340,15) end, @@ -74,12 +75,12 @@ return{ return a[1]>b[1]or(a[1]==b[1]and(a[2]=30 and 5 or + L>=25 and 4 or 3 else return diff --git a/modes/master_beginner.lua b/modes/master_beginner.lua index 91c24f78..d333a703 100644 --- a/modes/master_beginner.lua +++ b/modes/master_beginner.lua @@ -63,6 +63,7 @@ return{ freshLimit=15, bg="strap",bgm="secret8th", }, + slowmark=true, load=function() newPlayer(1,340,15) end, @@ -78,19 +79,19 @@ return{ return a[1]>b[1]or(a[1]==b[1]and(a[2]=30 and 5 or + L>=25 and 4 or 3 else return S>=420 and 3 or S>=250 and 2 or S>=120 and 1 or - L>=30 and 0 + S>=30 and 0 end end, } \ No newline at end of file diff --git a/modes/master_final.lua b/modes/master_final.lua index b4976376..dc6fa6e5 100644 --- a/modes/master_final.lua +++ b/modes/master_final.lua @@ -59,6 +59,7 @@ return{ easyFresh=false,bone=true, bg="none",bgm="shining terminal", }, + slowmark=true, load=function() newPlayer(1,340,15) end, diff --git a/modes/survivor_easy.lua b/modes/survivor_easy.lua index fcd735fa..7d9d7e35 100644 --- a/modes/survivor_easy.lua +++ b/modes/survivor_easy.lua @@ -37,11 +37,9 @@ return{ newPlayer(1,340,15) end, mesDisp=function(P,dx,dy) - mDraw(drawableText.line,-82,300) - mDraw(drawableText.techrash,-82,420) - setFont(75) - mStr(P.stat.row,-82,220) - mStr(P.stat.clear_4,-82,340) + setFont(65) + mStr(P.modeData.event,-82,310) + mDraw(drawableText.wave,-82,375) end, score=function(P)return{P.modeData.event,P.stat.time}end, scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, diff --git a/modes/survivor_hard.lua b/modes/survivor_hard.lua index e603c919..6bce5d38 100644 --- a/modes/survivor_hard.lua +++ b/modes/survivor_hard.lua @@ -42,11 +42,9 @@ return{ newPlayer(1,340,15) end, mesDisp=function(P,dx,dy) - mDraw(drawableText.line,-82,300) - mDraw(drawableText.techrash,-82,420) - setFont(75) - mStr(P.stat.row,-82,220) - mStr(P.stat.clear_4,-82,340) + setFont(65) + mStr(P.modeData.event,-82,310) + mDraw(drawableText.wave,-82,375) end, score=function(P)return{P.modeData.event,P.stat.time}end, scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, diff --git a/modes/survivor_lunatic.lua b/modes/survivor_lunatic.lua index 3ca4fc4e..7788382b 100644 --- a/modes/survivor_lunatic.lua +++ b/modes/survivor_lunatic.lua @@ -38,11 +38,9 @@ return{ newPlayer(1,340,15) end, mesDisp=function(P,dx,dy) - mDraw(drawableText.line,-82,300) - mDraw(drawableText.techrash,-82,420) - setFont(75) - mStr(P.stat.row,-82,220) - mStr(P.stat.clear_4,-82,340) + setFont(65) + mStr(P.modeData.event,-82,310) + mDraw(drawableText.wave,-82,375) end, score=function(P)return{P.modeData.event,P.stat.time}end, scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, diff --git a/modes/survivor_normal.lua b/modes/survivor_normal.lua index c898e45f..0b06b93e 100644 --- a/modes/survivor_normal.lua +++ b/modes/survivor_normal.lua @@ -42,11 +42,9 @@ return{ newPlayer(1,340,15) end, mesDisp=function(P,dx,dy) - mDraw(drawableText.line,-82,300) - mDraw(drawableText.techrash,-82,420) - setFont(75) - mStr(P.stat.row,-82,220) - mStr(P.stat.clear_4,-82,340) + setFont(65) + mStr(P.modeData.event,-82,310) + mDraw(drawableText.wave,-82,375) end, score=function(P)return{P.modeData.event,P.stat.time}end, scoreDisp=function(D)return D[1].." Waves "..toTime(D[2])end, diff --git a/modes/techmino49_easy.lua b/modes/techmino49_easy.lua index 209a0e53..b47e1364 100644 --- a/modes/techmino49_easy.lua +++ b/modes/techmino49_easy.lua @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/49",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R<=3 and 4 or diff --git a/modes/techmino49_hard.lua b/modes/techmino49_hard.lua index c592e671..a6a88ec2 100644 --- a/modes/techmino49_hard.lua +++ b/modes/techmino49_hard.lua @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/49",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R==2 and 4 or diff --git a/modes/techmino49_ultimate.lua b/modes/techmino49_ultimate.lua index fdb2302c..be1b6e02 100644 --- a/modes/techmino49_ultimate.lua +++ b/modes/techmino49_ultimate.lua @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/49",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R==2 and 4 or diff --git a/modes/techmino99_easy.lua b/modes/techmino99_easy.lua index 4ffc5263..65283afe 100644 --- a/modes/techmino99_easy.lua +++ b/modes/techmino99_easy.lua @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/99",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R<=3 and 4 or diff --git a/modes/techmino99_hard.lua b/modes/techmino99_hard.lua index 73a5d3bf..22177c8f 100644 --- a/modes/techmino99_hard.lua +++ b/modes/techmino99_hard.lua @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/99",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R<=3 and 4 or diff --git a/modes/techmino99_ultimate.lua b/modes/techmino99_ultimate.lua index 688d442a..8f69bb08 100644 --- a/modes/techmino99_ultimate.lua +++ b/modes/techmino99_ultimate.lua @@ -58,7 +58,7 @@ return{ if L[n]then newPlayer(n,46*i-36,97*j-72,.068,AITemplate("9S",rnd(4,6))) else - newPlayer(n,46*i-36,97*j-72,.068,AITemplate("CC",rnd(4,6)-1,LV+1,true,LV*10000)) + newPlayer(n,46*i-36,97*j-72,.068,AITemplate("CC",rnd(4,6)-1,4,true,30000)) end n=n+1 end end @@ -66,7 +66,7 @@ return{ if L[n]then newPlayer(n,46*i+264,97*j-72,.068,AITemplate("9S",rnd(4,6))) else - newPlayer(n,46*i+264,97*j-72,.068,AITemplate("CC",rnd(4,6)-1,LV+1,true,LV*10000)) + newPlayer(n,46*i+264,97*j-72,.068,AITemplate("CC",rnd(4,6)-1,4,true,30000)) end n=n+1 end end @@ -74,7 +74,7 @@ return{ mesDisp=function(P,dx,dy) setFont(35) mStr(#players.alive.."/99",-82,175) - mStr(P.ko,-70,215) + mStr(P.modeData.point,-70,215) gc.draw(drawableText.ko,-127,225) setFont(20) gc.setColor(1,.5,0,.6) @@ -86,11 +86,11 @@ return{ gc.draw(badgeIcon,16*i-138,260) end end, - score=function(P)return{P.rank,P.ko}end, + score=function(P)return{P.modeData.event,P.modeData.point}end, scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, comp=function(a,b)return a[1]b[2]end, getRank=function(P) - local R=P.rank + local R=P.modeData.event return R==1 and 5 or R==2 and 4 or diff --git a/modes/tsd_easy.lua b/modes/tsd_easy.lua index 23f484b3..5f3fbbb4 100644 --- a/modes/tsd_easy.lua +++ b/modes/tsd_easy.lua @@ -41,7 +41,7 @@ return{ mDraw(drawableText.tsd,-82,407) end, score=function(P)return{P.modeData.event,P.stat.time}end, - scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end, + scoreDisp=function(D)return D[1].."TSD "..toTime(D[2])end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]or a[1]==b[1]and a[2]b[1]end, getRank=function(P) local T=P.stat.score diff --git a/modes/zen.lua b/modes/zen.lua index 8b5d492d..0d854d3c 100644 --- a/modes/zen.lua +++ b/modes/zen.lua @@ -30,7 +30,7 @@ return{ mStr(R>=0 and R or 0,-82,280) end, score=function(P)return{P.stat.score}end, - scoreDisp=function(D)return D[1]end, + scoreDisp=function(D)return tostring(D[1])end, comp=function(a,b)return a[1]>b[1]end, getRank=function(P) local T=P.stat.score diff --git a/paint.lua b/paint.lua index 2d76b65f..ff58f776 100644 --- a/paint.lua +++ b/paint.lua @@ -1,12 +1,11 @@ local gc=love.graphics local setFont=setFont -local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin +local int,ceil,rnd,max,min,sin=math.floor,math.ceil,math.random,math.max,math.min,math.sin local format=string.format local Timer=love.timer.getTime local scr=scr local modeRankColor={ - [0]=color.darkGrey, --Not pass color.bronze, --Rank1 color.lightGrey, --Rank2 color.lightYellow, --Rank3 @@ -31,8 +30,6 @@ local function stencil_miniTitle() end end -FX_BGblock={tm=150,next=7,ct=0,list={}}--Falling tetrominos on background -for _=1,16 do FX_BGblock.list[_]={v=0}end FX_attack={}--Attack beam FX_badge={}--Badge thrown sysFX={} @@ -61,21 +58,19 @@ end local function drawVirtualkey() local a=setting.VKAlpha*.1 for i=1,#virtualkey do - if i~=9 or modeEnv.Fkey then - local B=virtualkey[i] - if B.ava then - local _=virtualkeyDown[i]and gc.setColor(.7,.7,.7,a)or gc.setColor(1,1,1,a)--Dark magic - gc.setLineWidth(B.r*.07) - local ΔY=virtualkeyPressTime[i] - gc.circle("line",B.x,B.y+ΔY,B.r)--Outline circle - if setting.VKIcon then - gc.draw(VKIcon[i],B.x,B.y+ΔY,nil,B.r*.025,nil,18,18) - end--Icon - if ΔY>0 then - gc.setColor(1,1,1,a*ΔY*.1) - gc.circle("line",B.x,B.y,B.r*(1.4-ΔY*.04)) - end--Ripple - end + local B=virtualkey[i] + if B.ava then + local _=virtualkeyDown[i]and gc.setColor(.7,.7,.7,a)or gc.setColor(1,1,1,a)--Dark magic + gc.setLineWidth(B.r*.07) + local ΔY=virtualkeyPressTime[i] + gc.circle("line",B.x,B.y+ΔY,B.r)--Outline circle + if setting.VKIcon then + gc.draw(VKIcon[i],B.x,B.y+ΔY,nil,B.r*.025,nil,18,18) + end--Icon + if ΔY>0 then + gc.setColor(1,1,1,a*ΔY*.1) + gc.circle("line",B.x,B.y,B.r*(1.4-ΔY*.04)) + end--Ripple end end end @@ -84,6 +79,9 @@ local Pnt={BG={}} function Pnt.BG.none() gc.clear(.15,.15,.15) end +function Pnt.BG.black() + gc.clear() +end function Pnt.BG.grey() gc.clear(.3,.3,.3) end @@ -103,35 +101,37 @@ function Pnt.BG.rgb() end function Pnt.BG.strap() gc.setColor(1,1,1) - local x=Timer()%32*40 - gc.draw(background2,x,0,nil,10) - gc.draw(background2,x-1280,0,nil,10) + local x=Timer()%16*-64 + ::L:: + gc.draw(background2,x,0,nil,8,scr.h) + x=x+1024--image width*8 + if x0 then @@ -449,12 +495,12 @@ end function Pnt.setting_game() gc.setColor(1,1,1) mDraw(drawableText.setting_game,640,15) - setFont(35) - mStr("DAS:"..setting.das,290,205) - mStr("ARR:"..setting.arr,610,205) - setFont(23) - mStr(text.softdropdas..setting.sddas,290,323) - mStr(text.softdroparr..setting.sdarr,610,323) + setFont(33) + mStr("DAS:"..setting.das.."F",290,205) + mStr("ARR:"..setting.arr.."F",610,205) + setFont(22) + mStr(text.softdropdas..setting.sddas.."F",290,323) + mStr(text.softdroparr..setting.sdarr.."F",610,323) end function Pnt.setting_graphic() gc.setColor(1,1,1) diff --git a/parts/space.lua b/parts/space.lua new file mode 100644 index 00000000..89533479 --- /dev/null +++ b/parts/space.lua @@ -0,0 +1,112 @@ +local gc=love.graphics +local sin,cos,rnd,min=math.sin,math.cos,math.random,math.min + +local W,H,R--w,h+=100,r=real Radius +local stars={} +local planet={} + +local function newPlanet() + local a=rnd()*3.142 + local r=(H+W)*(rnd()*2+1)*.06 + planet.r=r + planet.x=W*.5+cos(a)*(R+r) + planet.y=H*.5+sin(a)*(R+r) + planet.vx=-cos(a+rnd()-.5)*.2 + planet.vy=-sin(a+rnd()-.5)*.2 + planet.R=.7+rnd()*.2 + planet.G=.7+rnd()*.1 +end + +local space={}--LIB +function space.resize(w,h) + R=((w*.5)^2+(h*.5)^2)^.5 + W,H=w+100,h+100 +end +function space.new() + newPlanet() + for i=1,2600,5 do + local s=0.75*2^(rnd()*1.5) + stars[i]=s --size + stars[i+1]=rnd(W) --x + stars[i+2]=rnd(H) --y + stars[i+3]=(rnd()-.5)*.05*s --vx + stars[i+4]=(rnd()-.5)*.05*s --vy + end--800 stars +end +function space.translate(dx,dy) + planet.x=planet.x+dx*.26 + planet.y=planet.y+dy*.26 + for i=1,2600,5 do + local s=stars[i] + stars[i+1]=stars[i+1]+dx*s + stars[i+2]=stars[i+2]+dy*s + end +end +function space.scale(k) + planet.r=planet.r*k^.15 + for i=1,2600,5 do + local s=stars[i] + local x=stars[i+1] + local y=stars[i+2] + s=s*k + x=W*.5+(x-W*.5)*k + y=H*.5+(y-H*.5)*k + if k>1 then + if x%W~=x or y%H~=y then + s=.75 + x=W*.5+(rnd()-.5)*W*.5 + y=H*.5+(rnd()-.5)*H*.5 + end + --out,new small one + elseif s<.75 then + local vx,vy + repeat + s=rnd()*.75+2.25 + stars[i]=s --size + x=rnd(W) --x + y=rnd(H) --y + vx=(rnd()-.5)*.15 --vx + vy=(rnd()-.5)*.15 --vy + until x<100 or x>W-100 or y<100 or y>H-100 + stars[i+3]=vx + stars[i+4]=vy + --disappear,new big one + end + stars[i]=s + stars[i+1]=x + stars[i+2]=y + end +end +function space.update(dt) + local x,y=planet.x,planet.y + planet.x=planet.x+planet.vx + planet.y=planet.y+planet.vy + if((planet.x-W*.5)^2+(planet.y-H*.5)^2)^.5>R+planet.r then + newPlanet() + end + for i=1,2600,5 do + stars[i+1]=(stars[i+1]+stars[i+3])%W + stars[i+2]=(stars[i+2]+stars[i+4])%H + end--stars moving +end +function space.draw() + if not stars[1]then return end + gc.translate(-50,-50) + gc.setLineWidth(7) + gc.setColor(planet.R,planet.G,.6,.2) + gc.circle("line",planet.x,planet.y,planet.r+1) + gc.setColor(planet.R,planet.G,.6,.5) + gc.circle("fill",planet.x,planet.y,planet.r) + gc.setColor(1,1,1) + for i=1,2600,5 do + local x,y=stars[i+1],stars[i+2] + gc.circle("fill",x,y,stars[i]) + end + gc.translate(50,50) +end +function space.discard() + stars={} + planet={} + collectgarbage() +end +return space \ No newline at end of file diff --git a/player.lua b/player.lua index 004dfd46..467a9238 100644 --- a/player.lua +++ b/player.lua @@ -4,6 +4,7 @@ local Timer=love.timer.getTime local int,ceil,abs,rnd,max,min=math.floor,math.ceil,math.abs,math.random,math.max,math.min local ins,rem=table.insert,table.remove local format=string.format +local actName=actName--controllings' id local scr=scr--screen camera -------------------------------------------------- @@ -27,7 +28,7 @@ local gameEnv0={ freshLimit=1e99,easyFresh=true, fine=false,fineKill=false, target=1e99,dropPiece=NULL, - mindas=0,minarr=0, + mindas=0,minarr=0,minsdarr=0, bg="none",bgm="race" } local renATK={[0]=0,0,0,1,1,2,2,3,3,4,4}--3 else @@ -102,8 +103,8 @@ local TRS={ [03]={TMP1,{1,0}, {1,1}, {0,-2}, {-1,1} }, [30]={TMP1,{-1,0}, {-1,-1},{0,2}, {-1,2} }, [12]={TMP1,{1,0}, {1,-1}, {0,2}, {1,2}, {1,1} }, - [21]={TMP1,{-1,0}, {-1,1}, {0,-2}, {-1,-2},{-1,-1} }, - [32]={TMP1,{-1,0}, {-1,-1},{1,0}, {0,2}, {-1,2} }, + [21]={TMP1,{-1,0}, {-1,-1},{-1,1}, {0,-2}, {-1,-2},{-1,-1} }, + [32]={TMP1,{-1,0}, {-1,-1},{-1,1}, {1,0}, {0,2}, {-1,2} }, [23]={TMP1,{1,0}, {1,1}, {-1,0}, {0,-2}, {1,-2} }, [02]={TMP1,{1,0}, {-1,0}, {0,-1}, {0,1} }, [20]={TMP1,{-1,0}, {1,0}, {0,1}, {0,-1} }, @@ -115,10 +116,10 @@ local TRS={ [10]={TMP1,{1,0}, {1,-1}, {0,2}, {1,2} }, [03]={TMP1,{1,0}, {1,1}, {0,-2}, {1,-2}, {1,-1}, {0,1} }, [30]={TMP1,{-1,0}, {-1,-1},{0,2}, {-1,2}, {0,-1}, {-1,1} }, - [12]={TMP1,{1,0}, {1,-1}, {-1,0}, {0,2}, {1,2} }, + [12]={TMP1,{1,0}, {1,-1}, {1,1}, {-1,0}, {0,2}, {1,2} }, [21]={TMP1,{-1,0}, {-1,1}, {1,0}, {0,-2}, {-1,-2} }, [32]={TMP1,{-1,0}, {-1,-1},{0,2}, {-1,2}, {-1,1} }, - [23]={TMP1,{1,0}, {1,1}, {0,-2}, {1,-2}, {1,-1} }, + [23]={TMP1,{1,0}, {1,-1}, {1,1}, {0,-2}, {1,-2}, {1,-1} }, [02]={TMP1,{-1,0}, {1,0}, {0,-1}, {0,1} }, [20]={TMP1,{1,0}, {-1,0}, {0,1}, {0,-1} }, [13]={TMP1,{0,-1}, {1,0}, {0,1} }, @@ -517,7 +518,7 @@ function Pdraw_small(P) 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.rank,30,82) + setFont(15)mStr(P.modeData.event,30,82) end gc.pop() gc.setCanvas() @@ -976,10 +977,10 @@ function player.fineError(P,rate) P.stat.extraRate=P.stat.extraRate+rate if P.human then if P.gameEnv.fineKill then - SFX("error_long") + SFX("finesseError_long") Event.lose(P) elseif setting.fine then - SFX("error") + SFX("finesseError") end elseif P.gameEnv.fineKill then Event.lose(P) @@ -2098,10 +2099,9 @@ function newPlayer(id,x,y,size,AIdata) P.field,P.visTime={},{} P.atkBuffer={sum=0} - P.ko,P.badge,P.strength=0,0,0 + P.badge,P.strength=0,0 P.atkMode,P.swappingAtkMode=1,20 P.atker,P.atking,P.lastRecv={} - P.rank=nil --Royale-related P.gameEnv={}--Current game setting environment @@ -2113,9 +2113,11 @@ function newPlayer(id,x,y,size,AIdata) else P.gameEnv[k]=v end - end--reset current game settings + end--load game settings P.gameEnv.das=max(P.gameEnv.das,P.gameEnv.mindas) P.gameEnv.arr=max(P.gameEnv.arr,P.gameEnv.minarr) + P.gameEnv.sdarr=max(P.gameEnv.sdarr,P.gameEnv.minsdarr) + if not AIdata then P.gameEnv.next=min(P.gameEnv.next,setting.maxNext)end--AIdata is not human P.cur={bk={{}},id=0,color=0,name=0}--shape,shapeID,colorID,nameID P.sc,P.dir,P.r,P.c={0,0},0,0,0--spinCenter,direction,row,col diff --git a/scene.lua b/scene.lua index b287d70f..4c17c414 100644 --- a/scene.lua +++ b/scene.lua @@ -47,7 +47,7 @@ local sceneInit={ end end, mode=function() - curBG="glow" + curBG="black" BGM("blank") destroyPlayers() local cam=mapCam @@ -141,7 +141,7 @@ local sceneInit={ sceneTemp={ S.run, S.game, - format("%0.1fHr",S.time*2.78e-4), + format("%.1fHr",S.time*2.78e-4), S.key, S.rotate, S.hold, @@ -155,8 +155,8 @@ local sceneInit={ "["..S.spin_0.."]/"..S.spin_1.."/"..S.spin_2.."/"..S.spin_3, S.b2b.."[+"..S.b3b.."]", S.pc, - format("%0.2f",S.atk/S.row), - S.extraPiece.."["..(int(S.extraRate/S.piece*10000)*.01).."%]", + format("%.2f",S.atk/S.row), + format("%d[%.2f%%]",S.extraPiece,max(100-S.extraRate/S.piece*100,0)), } end, history=function() @@ -168,17 +168,6 @@ local sceneInit={ love.event.quit() end, } -local swapDeck_data={ - {4,0,1,1},{6,0,15,1},{5,0,9,1},{6,0,6,1}, - {1,0,3,1},{3,0,12,1},{1,1,8,1},{2,1,4,2}, - {3,2,13,2},{4,1,12,2},{5,2,1,2},{7,1,11,2}, - {2,1,9,3},{3,0,6,3},{4,2,14,3},{1,0,4,4}, - {7,1,1,4},{6,0,2,4},{5,2,6,4},{6,0,14,5}, - {3,3,15,5},{4,0,7,6},{7,1,10,5},{5,0,2,6}, - {2,1,1,7},{1,0,4,6},{4,1,13,5},{1,1,6,7}, - {5,3,11,5},{3,2,11,7},{6,0,8,7},{4,2,12,8}, - {7,0,8,9},{1,0,2,8},{5,2,4,8},{6,0,15,8}, -}--Block id [ZSLJTOI] ,dir,x,y local gc=love.graphics local swap={ none={1,0,NULL}, @@ -186,37 +175,17 @@ local swap={ fade={30,15,function(t) local t=t>15 and 2-t/15 or t/15 gc.setColor(0,0,0,t) - gc.rectangle("fill",0,0,1280,720) + gc.rectangle("fill",0,0,scr.w,scr.h) end}, fade_togame={120,20,function(t) local t=t>20 and (120-t)/100 or t/20 gc.setColor(0,0,0,t) - gc.rectangle("fill",0,0,1280,720) + gc.rectangle("fill",0,0,scr.w,scr.h) end}, slowFade={180,90,function(t) local t=t>90 and 2-t/90 or t/90 gc.setColor(0,0,0,t) - gc.rectangle("fill",0,0,1280,720) - end}, - deck={50,8,function(t) - gc.setColor(1,1,1) - if t>8 then - local t=t<15 and 15 or t - for i=1,51-t do - local bn=swapDeck_data[i][1] - local b=blocks[bn][swapDeck_data[i][2]] - local cx,cy=swapDeck_data[i][3],swapDeck_data[i][4] - for y=1,#b do for x=1,#b[1]do - if b[y][x]then - gc.draw(blockSkin[bn],80*(cx+x-2),80*(10-cy-y),nil,8/3) - end - end end - end - end - if t<17 then - gc.setColor(1,1,1,1-(t>8 and t-8 or 8-t)*.125) - gc.rectangle("fill",0,0,1280,720) - end + gc.rectangle("fill",0,0,scr.w,scr.h) end}, }--Scene swapping animations local backFunc={ diff --git a/texture.lua b/texture.lua index 18c03d6e..9593a652 100644 --- a/texture.lua +++ b/texture.lua @@ -77,26 +77,8 @@ clearDust:setColors(1,1,1,.5,1,1,1,0) --Dust particles gc.setDefaultFilter("linear","linear") -titleImage=N("/image/mess/title.png") -coloredTitleImage=N("/image/mess/title_colored.png") -dialCircle=N("/image/mess/dialCircle.png") -dialNeedle=N("/image/mess/dialNeedle.png") -badgeIcon=N("/image/mess/badge.png") -spinCenter=N("/image/mess/spinCenter.png") batteryImage=N("/image/mess/power.png") -background1=N("/image/BG/bg1.jpg") -background2=N("/image/BG/bg2.png") -groupCode=N("/image/mess/groupcode.png") -payCode=N("/image/mess/paycode.png") - -miya={ - ch=N("/image/miya/ch.png"), - f1=N("/image/miya/f1.png"), - f2=N("/image/miya/f2.png"), - f3=N("/image/miya/f3.png"), - f4=N("/image/miya/f4.png"), -} drawableText={ question=T(100,"?"), bpm=T(15,"BPM"),kpm=T(15,"KPM"), diff --git a/timer.lua b/timer.lua index 014df1a8..e30026cb 100644 --- a/timer.lua +++ b/timer.lua @@ -1,4 +1,5 @@ local wd=love.window +local gc=love.graphics local kb=love.keyboard local Timer=love.timer.getTime local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin @@ -42,15 +43,40 @@ function Tmr.load() local m=modes[L[2]] modes[L[2]]=require("modes/"..m[1]) local M=modes[L[2]] - M.saveFileName,M.x,M.y,M.shape,M.size,M.id,M.unlock=m[1],m.x,m.y,m.shape,m.size,m.id,m.unlock - M.records=loadRecord(m[1]) + 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 + M.records=loadRecord(m[1])or M.score and{} + -- M.icon=gc.newImage("image/modeIcon/"..m.icon..".png") + -- M.icon=gc.newImage("image/modeIcon/custom.png") L[2]=L[2]+1 if L[2]>L[3]then L[1],L[2],L[3]=5,1,1 end elseif L[1]==5 then --------------------------Loading some other things here? - + local N=gc.newImage + titleImage=N("/image/mess/title.png") + coloredTitleImage=N("/image/mess/title_colored.png") + dialCircle=N("/image/mess/dialCircle.png") + dialNeedle=N("/image/mess/dialNeedle.png") + badgeIcon=N("/image/mess/badge.png") + spinCenter=N("/image/mess/spinCenter.png") + ctrlSpeedLimit=N("/image/mess/ctrlSpeedLimit.png") + speedLimit=N("/image/mess/speedLimit.png") + + background1=N("/image/BG/bg1.png") + background2=N("/image/BG/bg2.png") + groupCode=N("/image/mess/groupcode.png") + payCode=N("/image/mess/paycode.png") + + miya={ + ch=N("/image/miya/ch.png"), + f1=N("/image/miya/f1.png"), + f2=N("/image/miya/f2.png"), + f3=N("/image/miya/f3.png"), + f4=N("/image/miya/f4.png"), + } -------------------------- L[1],L[2],L[3]=0,1,1 SFX("welcome",.2) @@ -74,10 +100,17 @@ function Tmr.mode(dt) local cam=mapCam local F local x,y,k=cam.x,cam.y,cam.k - if kb.isDown("up", "w") then y=y-10*k;F=true end - if kb.isDown("down","s") then y=y+10*k;F=true end - if kb.isDown("left","a") then x=x-10*k;F=true end - if kb.isDown("right","d") then x=x+10*k;F=true end + if kb.isDown("up", "w")then y=y-10*k;F=true end + if kb.isDown("down","s")then y=y+10*k;F=true end + if kb.isDown("left","a")then x=x-10*k;F=true end + if kb.isDown("right","d")then x=x+10*k;F=true end + local js1=joysticks[1] + if js1 then + if js1:isDown("dpup")then y=y-10*k;F=true end + if js1:isDown("dpdown")then y=y+10*k;F=true end + if js1:isDown("dpleft")then x=x-10*k;F=true end + if js1:isDown("dpright")then x=x+10*k;F=true end + end if F or cam.keyCtrl and(x-cam.x1)^2+(y-cam.y1)^2>2.6 then if F then cam.keyCtrl=true @@ -86,12 +119,14 @@ function Tmr.mode(dt) local MM,R=modes,modeRanks for _=1,#MM do if R[_]then + local __ local M=MM[_] local s=M.size - local __ if M.shape==1 then if x>M.x-s and xM.y-s and y7 then s=s-1 end - L=L..char(66+s) + local S="" + local L=preField[y] + for x=1,10,2 do + local H=L[x] + local L=L[x+1] + if H<8 then H=H+1 end + if L<8 then L=L+1 end + S=S..char(H*16+L) end - -- str=str..L.."\n" + str=str..S end - love.system.setClipboardText("Techmino sketchpad:"..str) + love.system.setClipboardText("Techmino sketchpad:"..data.encode("string","base64",data.compress("string","deflate",str))) TEXT(text.copySuccess,350,360,40,"appear",.5) end function pasteBoard() local str=love.system.getClipboardText() - local len=#str - local _ - local p,P=1,10--sum,pStr,pField(r*10+(c-1)) - p=find(str,":") - if p then - p=p+1 - else - p=find(str,"[A-N]") - if not p then - goto E - end - end--int p*//head - ::L:: - _=byte(str,p) - if P==210 then - return - elseif not _ then - if P%10~=0 then - goto E + local fX,fY=1,1--*ptr for Field(r*10+(c-1)) + local _,__ + local p=find(str,":")--ptr* + if p then str=sub(str,p+1)end + str=data.decompress("string","deflate",data.decode("string","base64",str)) + p=1 + ::LOOP:: + _=byte(str,p)--1byte + if not _ then + if fX~=1 then goto ERROR + else goto FINISH + end + end--str end + __=_%16--low4b + _=(_-__)/16--high4b + if _>12 or __>12 then goto ERROR end--illegal blockid + if _<9 then _=_-1 end if __<9 then __=__-1 end + preField[fY][fX]=_;preField[fY][fX+1]=__ + if fX<9 then + fX=fX+2 else - return + if fY==20 then goto FINISH end + fX=1;fY=fY+1 end - end--end check - _=_-66 - if _<-1 or _>12 then p=p+1 - goto L - end--skip illegal char - if _>-2 and _<13 then - if _>7 then _=_+1 end - preField[int(P/10)][P%10+1]=_ - P=P+1 - end - p=p+1 - goto L - ::E:: - TEXT(text.dataCorrupted,350,360,35,"flicker",.5) + goto LOOP + + ::FINISH:: + for y=fY+1,20 do + for x=1,10 do + preField[y][x]=0 + end + end + goto END + ::ERROR:: + TEXT(text.dataCorrupted,350,360,35,"flicker",.5) + ::END:: end function updateStat() @@ -321,7 +328,7 @@ function loadGame(M) end function resetPartGameData() gameResult=false - frame=30 + frame=150-setting.reTime*15 destroyPlayers() curMode.load() texts={} @@ -345,7 +352,7 @@ function resetPartGameData() end function resetGameData() gameResult=false - frame=0 + frame=150-setting.reTime*15 garbageSpeed=1 pauseTime=0--Time paused pauseCount=0--Times paused @@ -403,22 +410,27 @@ function loadRecord(N) setfenv(s,T) T[1]=s() return T[1] - else - return{} end end local function dumpTable(L) local s="{\n" for k,v in next,L do local T + T=type(k) + if T=="number"then k="["..k.."]=" + elseif T=="string"then k=k.."=" + else error("Error data type!") + end T=type(v) if T=="number"then v=tostring(v) elseif T=="string"then v="\""..v.."\"" elseif T=="table"then v=dumpTable(v) else error("Error data type!") end - s=s.."["..k.."]="..v..",\n" + s=s..k..v..",\n" end + print(s) + print("---") return s.."}" end function saveRecord(N,L) @@ -435,6 +447,35 @@ function delRecord(N) fs.remove(N..".dat") end +function saveUnlock() + local t={} + local RR=modeRanks + for i=1,#RR do + t[i]=RR[i]or"X" + end + t=concat(t,",") + local F=FILE.unlock + F:open("w") + local _=F:write(t) + F:flush() + F:close() + if not _ then + TEXT(text.unlockSavingError..mes,640,480,40,"appear",.4) + end +end +function loadUnlock() + local F=FILE.unlock + F:open("r") + local t=F:read() + F:close() + t=splitS(t,",") + for i=1,#modeRanks do + local v=toN(t[i]) + if not v or v<0 or v>6 or v~=int(v)then v=false end + modeRanks[i]=v + end +end + local statOpy={ "run","game","time", "extraPiece","extraRate", @@ -448,27 +489,17 @@ function loadStat() local F=FILE.data F:open("r") local t=F:read() - t=splitS(t,"\r\n") F:close() + t=splitS(t,"\r\n") for i=1,#t do local p=find(t[i],"=") if p then local t,v=sub(t[i],1,p-1),sub(t[i],p+1) - if t=="rank"then - v=splitS(v,",") - for i=1,#modeRanks do - local v=toN(v[i]) - if not v or v<0 or v>6 or v~=int(v)then v=false end - modeRanks[i]=v - end - else - if t=="gametime"then t="time"end - for i=1,#statOpy do - if t==statOpy[i]then - v=toN(v)if not v or v<0 then v=0 end - stat[t]=v - break - end + for i=1,#statOpy do + if t==statOpy[i]then + v=toN(v)if not v or v<0 then v=0 end + stat[t]=v + break end end end @@ -503,17 +534,19 @@ function loadSetting() local F=FILE.setting F:open("r") local t=F:read() - t=splitS(t,"\r\n") F:close() + t=splitS(t,"\r\n") for i=1,#t do local p=find(t[i],"=") if p then local t,v=sub(t[i],1,p-1),sub(t[i],p+1) - if + if--10档的设置 --声音 t=="sfx"or t=="bgm"or t=="voc"or t=="stereo"or --三个触摸设置项 - t=="VKTchW"or t=="VKCurW"or t=="VKAlpha" + t=="VKTchW"or t=="VKCurW"or t=="VKAlpha"or + --重开时间 + t=="reTime" then v=toN(v) if v and v==int(v)and v>=0 and v<=10 then @@ -528,7 +561,7 @@ function loadSetting() --开关设置们 t=="bg"or t=="ghost"or t=="center"or t=="grid"or t=="swap"or - t=="quickR"or t=="fine"or t=="bgblock"or t=="smo"or + t=="quickR"or t=="fine"or t=="bgspace"or t=="smo"or t=="VKSwitch"or t=="VKTrack"or t=="VKDodge"or t=="VKIcon" then setting[t]=v=="true" @@ -569,6 +602,7 @@ end local saveOpt={ "das","arr", "sddas","sdarr", + "reTime", "quickR", "swap", "fine", @@ -582,7 +616,7 @@ local saveOpt={ "fullscreen", "bg", - "bgblock", + "bgspace", "lang", "skin", diff --git a/updateLog.lua b/updateLog.lua index 20efdcea..f8c5ce2f 100644 --- a/updateLog.lua +++ b/updateLog.lua @@ -1,20 +1,20 @@ local S=[=[ -Patron(rmb10+): - Fireboos - gggf - Sasoric +"Patron"(rmb10+): + "Fireboos" + "gggf" + "Sasoric" + sfqr T080 - Ykzl - zxc + "Ykzl" + "zxc" + 10元 ?[D*a] Future outlook: New mode system with: rythem mode combo mode - bigbang mode puzzle mode(ttt) square mode - finesse practice mode infinite 1v1 Other: puzzle import/output(ttt) @@ -22,7 +22,6 @@ Future outlook: (powerinfo switch) virtualWidgets like joysticks splashing block - ajustable next count custom block color/direction custom block sequence CC smarter(think of garbage buffer) @@ -31,6 +30,16 @@ Future outlook: auto GUI position in any screen size more FXs & 3d features & animations Encrypt source code(compile to byte code) +0.8.8: + 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 + an unlock-all easter egg + bugs fixed(some mode error) 0.8.7: better user experience in mode selecting support 2^n G falling speed @@ -200,7 +209,7 @@ Future outlook: bugs fixed 0.7.14: drawing mode in custom game - can adjust virtual keys with mouse + adjustable virtual keys with mouse speed optimized rotate also create shade 0.7.13+: diff --git a/widgetList.lua b/widgetList.lua index c850a36e..d3c0852d 100644 --- a/widgetList.lua +++ b/widgetList.lua @@ -139,19 +139,19 @@ local Widget={ setting=newButton(370,280,200,160,C.lightBlue, 45,function()scene.push()scene.swapTo("setting_game")end, nil,"music"), music= newButton(590,280,200,160,C.lightPurple, 32,function()scene.push()scene.swapTo("music")end, nil,"help"), help= newButton(150,460,200,160,C.lightYellow, 50,function()scene.push()scene.swapTo("help")end, nil,"stat"), - stat= newButton(370,460,200,160,C.lightCyan, 43,function()scene.push()scene.swapTo("stat")end, nil,"lang"), + stat= newButton(370,460,200,160,C.lightCyan, 43,function()scene.push()scene.swapTo("stat")end, nil,"quit"), + quit= newButton(590,460,200,160,C.lightGrey, 55,function()VOICE("bye")scene.swapTo("quit","slowFade")end,nil,"lang"), lang= newButton(150,610,160,100,C.lightGreen, 45,function() setting.lang=setting.lang%#langName+1 changeLanguage(setting.lang) TEXT(text.lang,370,610,50,"appear",1.6) - end,nil,"quit"), - quit= newButton(590,460,200,160,C.lightGrey, 55,function()VOICE("bye")scene.swapTo("quit","slowFade")end,nil,"play"), + end,nil,"play"), }, mode={ draw= newButton(1100, 440,220,90,C.lightYellow, 40,function()scene.push()scene.swapTo("draw")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), setting=newButton(1100, 540,220,90,C.lightGreen, 40,function()scene.push()scene.swapTo("custom")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end), - start= newButton(1100, 640,220,90,C.lightGrey, 40,function()scene.push()loadGame(mapCam.sel)end,function()return not mapCam.sel end), - back= newButton(1205, 50, 130,80, C.white, 40,scene.back), + start= newButton(1040, 655,180,80,C.lightGrey, 40,function()scene.push()loadGame(mapCam.sel)end,function()return not mapCam.sel end), + back= newButton(1200, 655,120,80,C.white, 40,scene.back), --function()scene.push()scene.swapTo("custom")end }, music={ @@ -244,16 +244,18 @@ local Widget={ SFX("blip_1",.4) end end,nil,"sddasD"), - sddasD= newButton(180,340,50,50,C.white,40, function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"), - sddasU= newButton(400,340,50,50,C.white,40, function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"), - sdarrD= newButton(500,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"), - sdarrU= newButton(720,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"quickR"), - quickR= newSwitch(580,430,35,SETdisp("quickR"), SETrev("quickR"), nil,"swap"), - swap= newSwitch(580,510,20,SETdisp("swap"), SETrev("swap"), nil,"fine"), - fine= newSwitch(580,590,20,SETdisp("fine"), SETrev("fine"), nil,"ctrl"), + sddasD= newButton(180,340,50,50,C.white,40, function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"), + sddasU= newButton(400,340,50,50,C.white,40, function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"), + sdarrD= newButton(500,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"), + sdarrU= newButton(720,340,50,50,C.white,40, function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"reTime"), + reTime= newSlider(350,430,300,10,30,nil, SETdisp("reTime"), SETsto("reTime"), nil,"maxNext"), + maxNext=newSlider(350,510,300,6,30,nil, SETdisp("maxNext"), SETsto("maxNext"), nil,"quickR"), + quickR= newSwitch(1000,430,35, SETdisp("quickR"), SETrev("quickR"), nil,"swap"), + swap= newSwitch(1000,510,19, SETdisp("swap"), SETrev("swap"), nil,"fine"), + fine= newSwitch(1000,590,20, SETdisp("fine"), SETrev("fine"), nil,"ctrl"), ctrl= newButton(1020,230,320,80,C.white,35,function()scene.push()scene.swapTo("setting_key")end, nil,"touch"), touch= newButton(1020,340,320,80,C.white,35,function()scene.push()scene.swapTo("setting_touch")end,nil,"back"), - back= newButton(1160,600,160,160,C.white,50,scene.back,nil,"graphic"), + back= newButton(1160,600,160,160,C.white,50,scene.back, nil,"graphic"), }, setting_graphic={ sound= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_sound")end, nil,"game"), @@ -273,8 +275,15 @@ local Widget={ love.resize(love.graphics.getWidth(),love.graphics.getHeight()) end end,nil,"bg"), - bg= newSwitch(990,250,35,SETdisp("bg"),SETrev("bg"),nil,"bgblock"), - bgblock=newSwitch(990,330,35,SETdisp("bgblock"),SETrev("bgblock"),nil,"skin"),--if not setting.bgblock then for i=1,16 do FX_BGblock.list[i].v=3*FX_BGblock.list[i].v end end + bg= newSwitch(990,250,35,SETdisp("bg"),SETrev("bg"),nil,"bgspace"), + bgspace=newSwitch(990,330,35,SETdisp("bgspace"),function() + setting.bgspace=not setting.bgspace + if setting.bgspace then + space.new() + else + space.discard() + end + end,nil,"skin"), skin= newButton(810,420,120,60,C.white,35,function() local _=setting.skin%8+1 setting.skin=_