425 lines
11 KiB
Lua
425 lines
11 KiB
Lua
--[[
|
|
______ __ _
|
|
/_ __/___ _____ / /_ ____ ___ (_)____ ____
|
|
/ / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \
|
|
/ / / __// /__ / / / // / / / / // // / / // /_/ /
|
|
/_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/
|
|
Techmino is my first "huge project"
|
|
optimization is welcomed if you also love tetromino game
|
|
]]--
|
|
|
|
local fs=love.filesystem
|
|
|
|
--?
|
|
NONE={}function NULL()end
|
|
DBP=print--Use this in permanent code
|
|
TIME=love.timer.getTime
|
|
YIELD=coroutine.yield
|
|
SYSTEM=love.system.getOS()
|
|
MOBILE=SYSTEM=="Android"or SYSTEM=="iOS"
|
|
SAVEDIR=fs.getSaveDirectory()
|
|
|
|
--Global Vars & Settings
|
|
LOADED=false
|
|
DAILYLAUNCH=false
|
|
NOGAME=false
|
|
LOGIN=false
|
|
EDITING=""
|
|
WSCONN=false
|
|
LATEST_VERSION=false
|
|
|
|
--Festival check within one statement
|
|
THEME=(
|
|
--Christmas
|
|
os.date"%m"=="12"and math.abs(os.date"%d"-25)<4 and
|
|
"Xmas"or
|
|
|
|
--Spring festival
|
|
os.date"%m"<"03"and math.abs((({
|
|
--Festival days. Jan 26=26, Feb 1=32, etc.
|
|
24,43,32,22,40,29,49,38,26,45,
|
|
34,23,41,31,50,39,28,47,36,25,
|
|
43,32,22,41,29,48,37,26,44,34,
|
|
23,42,31,50,39,28,46,35,24,43,
|
|
32,22,41,30,48,37,26,45,33,23,
|
|
42,32,50,39,28,46,35,24,43,33,
|
|
21,40,
|
|
})[os.date"%Y"-2000]or -26)-((os.date"%m"-1)*31+os.date"%d"))<6 and
|
|
"sprFes"or
|
|
|
|
--Z day (Feb./Mar./Apr./May./June 26)
|
|
math.abs(os.date"%m"-4)<=2 and os.date"%d"+0==26 and
|
|
"zDay"or
|
|
|
|
false
|
|
)
|
|
|
|
--System setting
|
|
math.randomseed(os.time()*626)
|
|
love.keyboard.setKeyRepeat(true)
|
|
love.keyboard.setTextInput(false)
|
|
love.mouse.setVisible(false)
|
|
|
|
--Create directories
|
|
for _,v in next,{"conf","record","replay"}do
|
|
local info=fs.getInfo(v)
|
|
if info then
|
|
if info.type=="directory"then goto NEXT end
|
|
fs.remove(v)
|
|
end
|
|
fs.createDirectory(v)
|
|
::NEXT::
|
|
end
|
|
|
|
--Delete some useless files
|
|
for _,v in next,{
|
|
"client.so",
|
|
"cold_clear.dll",
|
|
"CCloader.dll",
|
|
"tech_u.dat",
|
|
"tech_u+.dat",
|
|
"sprintFix.dat",
|
|
"sprintLock.dat",
|
|
"marathon_u.dat",
|
|
"infinite.dat",
|
|
"infinite_dig.dat",
|
|
"conf/account",
|
|
}do
|
|
if fs.getInfo(v)then fs.remove(v)end
|
|
end
|
|
|
|
--Collect files of old version
|
|
if fs.getInfo("data.dat")or fs.getInfo("key.dat")or fs.getInfo("settings.dat")then
|
|
for k,v in next,{
|
|
["settings.dat"]="conf/settings",
|
|
["unlock.dat"]="conf/unlock",
|
|
["data.dat"]="conf/data",
|
|
["key.dat"]="conf/key",
|
|
["virtualkey.dat"]="conf/virtualkey",
|
|
["account.dat"]="conf/user",
|
|
}do
|
|
if fs.getInfo(k)then
|
|
fs.write(v,fs.read(k))
|
|
fs.remove(k)
|
|
end
|
|
end
|
|
for _,name in next,fs.getDirectoryItems("")do
|
|
if name:sub(-4)==".dat"then
|
|
fs.write("record/"..name:sub(1,-4).."rec",fs.read(name))
|
|
fs.remove(name)
|
|
end
|
|
end
|
|
end
|
|
|
|
--Force delete all useless files
|
|
for _,name in next,fs.getDirectoryItems("")do
|
|
if fs.getRealDirectory(name)==SAVEDIR and fs.getInfo(name).type=="file"then
|
|
fs.remove(name)
|
|
end
|
|
end
|
|
|
|
--Load modules
|
|
require"Zframework"
|
|
|
|
require"parts.list"
|
|
require"parts.globalTables"
|
|
require"parts.gametoolfunc"
|
|
SCR.setSize(1280,720)--Initialize Screen size
|
|
FIELD[1]=newBoard()--Initialize field[1]
|
|
|
|
AIBUILDER= require"parts.AITemplate"
|
|
FREEROW= require"parts.freeRow"
|
|
|
|
TEXTURE= require"parts.texture"
|
|
SKIN= require"parts.skin"
|
|
PLY= require"parts.player"
|
|
AIFUNC= require"parts.ai"
|
|
MODES= require"parts.modes"
|
|
|
|
--First start for phones
|
|
if not fs.getInfo("conf/settings")and MOBILE then
|
|
SETTING.VKSwitch=true
|
|
SETTING.swap=false
|
|
SETTING.powerInfo=true
|
|
SETTING.fullscreen=true
|
|
end
|
|
if SETTING.fullscreen then love.window.setFullscreen(true)end
|
|
|
|
--Initialize image libs
|
|
IMG.init{
|
|
batteryImage="mess/power.png",
|
|
lock="mess/lock.png",
|
|
dialCircle="mess/dialCircle.png",
|
|
dialNeedle="mess/dialNeedle.png",
|
|
lifeIcon="mess/life.png",
|
|
badgeIcon="mess/badge.png",
|
|
spinCenter="mess/spinCenter.png",
|
|
ctrlSpeedLimit="mess/ctrlSpeedLimit.png",
|
|
speedLimit="mess/speedLimit.png",
|
|
pay1="mess/pay1.png",
|
|
pay2="mess/pay2.png",
|
|
|
|
miyaCH="miya/ch.png",
|
|
miyaF1="miya/f1.png",
|
|
miyaF2="miya/f2.png",
|
|
miyaF3="miya/f3.png",
|
|
miyaF4="miya/f4.png",
|
|
|
|
electric="mess/electric.png",
|
|
hbm="mess/hbm.png",
|
|
|
|
lanterns={
|
|
"lanterns/1.png",
|
|
"lanterns/2.png",
|
|
"lanterns/3.png",
|
|
"lanterns/4.png",
|
|
"lanterns/5.png",
|
|
"lanterns/6.png",
|
|
},
|
|
}
|
|
SKIN.init{
|
|
"crystal_scf",
|
|
"contrast_mrz",
|
|
"polkadots_scf",
|
|
"toy_scf",
|
|
"smooth_mrz",
|
|
"simple_scf",
|
|
"glass_scf",
|
|
"penta_scf",
|
|
"bubble_scf",
|
|
"minoes_scf",
|
|
"pure_mrz",
|
|
"bright_scf",
|
|
"glow_mrz",
|
|
"plastic_mrz",
|
|
"paper_mrz",
|
|
"yinyang_scf",
|
|
"cartooncup_earety",
|
|
"jelly_miya",
|
|
"brick_notypey",
|
|
"gem_notypey",
|
|
"classic",
|
|
"ball_shaw",
|
|
"retro_notypey",
|
|
"textbone_mrz",
|
|
"coloredbone_mrz",
|
|
"wtf",
|
|
}
|
|
|
|
--Initialize sound libs
|
|
SFX.init((function()
|
|
local L={}
|
|
for _,v in next,fs.getDirectoryItems("media/SFX")do
|
|
if fs.getRealDirectory("media/SFX/"..v)~=SAVEDIR then
|
|
L[#L+1]=v:sub(1,-5)
|
|
else
|
|
LOG.print("Dangerous file : %SAVE%/media/SFX/"..v)
|
|
end
|
|
end
|
|
return L
|
|
end)())
|
|
BGM.init((function()
|
|
local L={}
|
|
for _,v in next,fs.getDirectoryItems("media/BGM")do
|
|
if fs.getRealDirectory("media/BGM/"..v)~=SAVEDIR then
|
|
L[#L+1]=v:sub(1,-5)
|
|
else
|
|
LOG.print("Dangerous file : %SAVE%/media/BGM/"..v)
|
|
end
|
|
end
|
|
return L
|
|
end)())
|
|
VOC.init{
|
|
"zspin","sspin","lspin","jspin","tspin","ospin","ispin",
|
|
"single","double","triple","techrash",
|
|
"mini","b2b","b3b",
|
|
"perfect_clear","half_clear",
|
|
"win","lose","bye",
|
|
"test","happy","doubt","sad","egg",
|
|
"welcome_voc",
|
|
}
|
|
|
|
--Initialize language lib
|
|
LANG.init(
|
|
{
|
|
require"parts.language.lang_zh",
|
|
require"parts.language.lang_zh2",
|
|
require"parts.language.lang_yygq",
|
|
require"parts.language.lang_en",
|
|
require"parts.language.lang_fr",
|
|
require"parts.language.lang_sp",
|
|
require"parts.language.lang_pt",
|
|
require"parts.language.lang_symbol",
|
|
--1. Add language file to LANG folder;
|
|
--2. Require it;
|
|
--3. Add a button in parts/scenes/setting_lang.lua;
|
|
},
|
|
{
|
|
block={
|
|
"Z","S","J","L","T","O","I",
|
|
"Z5","S5","Q","P","F","E",
|
|
"T5","U","V","W","X",
|
|
"J5","L5","R","Y","N","H","I5",
|
|
"I3","C","I2","O1"
|
|
},
|
|
}
|
|
)
|
|
|
|
--Load shader files from SOURCE ONLY
|
|
SHADER={}
|
|
for _,v in next,fs.getDirectoryItems("parts/shaders")do
|
|
if fs.getRealDirectory("parts/shaders/"..v)~=SAVEDIR then
|
|
local name=v:sub(1,-6)
|
|
SHADER[name]=love.graphics.newShader("parts/shaders/"..name..".glsl")
|
|
else
|
|
LOG.print("Dangerous file : %SAVE%/parts/shaders/"..v)
|
|
end
|
|
end
|
|
|
|
--Load background files from SOURCE ONLY
|
|
for _,v in next,fs.getDirectoryItems("parts/backgrounds")do
|
|
if fs.getRealDirectory("parts/backgrounds/"..v)~=SAVEDIR then
|
|
if v:sub(-3)=="lua"then
|
|
local name=v:sub(1,-5)
|
|
BG.add(name,require("parts.backgrounds."..name))
|
|
end
|
|
else
|
|
LOG.print("Dangerous file : %SAVE%/parts/backgrounds/"..v)
|
|
end
|
|
end
|
|
|
|
--Load scene files from SOURCE ONLY
|
|
for _,v in next,fs.getDirectoryItems("parts/scenes")do
|
|
if fs.getRealDirectory("parts/scenes/"..v)~=SAVEDIR then
|
|
local sceneName=v:sub(1,-5)
|
|
SCN.add(sceneName,require("parts.scenes."..sceneName))
|
|
LANG.addScene(sceneName)
|
|
else
|
|
LOG.print("Dangerous file : %SAVE%/parts/scenes/"..v)
|
|
end
|
|
end
|
|
LANG.set(SETTING.lang)
|
|
|
|
--Update data
|
|
do
|
|
--Check setting file
|
|
if
|
|
type(STAT.version)~="number"or
|
|
type(SETTING.block)~="boolean"or
|
|
type(SETTING.sfx_spawn)~="number"or
|
|
type(SETTING.ghost)~="number"or
|
|
type(SETTING.center)~="number"or
|
|
type(SETTING.grid)~="number"or
|
|
#SETTING.skin<29 or
|
|
SETTING.bgm>1 or SETTING.sfx>1 or SETTING.voc>1 or
|
|
SETTING.stereo>1 or SETTING.VKSFX>1 or SETTING.VKAlpha>1 or
|
|
SETTING.VKCurW>1 or SETTING.VKCurW>1
|
|
then
|
|
NOGAME=true
|
|
fs.remove("conf/settings")
|
|
end
|
|
|
|
if STAT.extraRate then
|
|
STAT.finesseRate=5*(STAT.piece-STAT.extraRate)
|
|
end
|
|
if type(STAT.version)~="number"then
|
|
STAT.version=0
|
|
end
|
|
if STAT.version<1204 then
|
|
STAT.frame=math.floor(STAT.time*60)
|
|
STAT.lastPlay="sprint_10l"
|
|
RANKS.sprintFix=nil
|
|
RANKS.sprintLock=nil
|
|
end
|
|
if STAT.version<1208 then
|
|
SETTING.skinSet=1
|
|
end
|
|
|
|
if STAT.version<1300 then
|
|
for _,name in next,fs.getDirectoryItems("replay")do
|
|
fs.remove("replay/"..name)
|
|
end
|
|
end
|
|
|
|
if STAT.version<1302 then
|
|
if RANKS.pctrain_n then RANKS.pctrain_n=0 end
|
|
if RANKS.pctrain_l then RANKS.pctrain_l=0 end
|
|
fs.remove("conf/user")
|
|
NOGAME=true
|
|
end
|
|
|
|
if STAT.version<1303 then
|
|
SETTING.appLock=false
|
|
end
|
|
|
|
for _,v in next,VK_org do
|
|
if not v.color then
|
|
NOGAME=true
|
|
fs.remove("conf/virtualkey")
|
|
break
|
|
end
|
|
end
|
|
|
|
if RANKS.infinite then RANKS.infinite=6 end
|
|
if RANKS.infinite_dig then RANKS.infinite_dig=6 end
|
|
|
|
local needSaveRank
|
|
for k in next,RANKS do
|
|
if type(k)=="number"then
|
|
RANKS[k]=nil
|
|
needSaveRank=true
|
|
end
|
|
end
|
|
local modeTable={attacker_h="attacker_hard",attacker_u="attacker_ultimate",blind_e="blind_easy",blind_h="blind_hard",blind_l="blind_lunatic",blind_n="blind_normal",blind_u="blind_ultimate",c4wtrain_l="c4wtrain_lunatic",c4wtrain_n="c4wtrain_normal",defender_l="defender_lunatic",defender_n="defender_normal",dig_100l="dig_10",dig_10l="dig_100",dig_400l="dig_40",dig_40l="dig_400",dig_h="dig_hard",dig_u="dig_ultimate",drought_l="drought_lunatic",drought_n="drought_normal",marathon_h="marathon_hard",marathon_n="marathon_normal",pc_h="pcchallenge_hard",pc_l="pcchallenge_lunatic",pc_n="pcchallenge_normal",pctrain_l="pctrain_lunatic",pctrain_n="pctrain_normal",round_e="round_1",round_h="round_2",round_l="round_3",round_n="round_4",round_u="round_5",solo_e="solo_1",solo_h="solo_2",solo_l="solo_3",solo_n="solo_4",solo_u="solo_5",sprint_10l="sprint_10",sprint_20l="sprint_20",sprint_40l="sprint_40",sprint_400l="sprint_400",sprint_100l="sprint_100",sprint_1000l="sprint_1000",survivor_e="survivor_easy",survivor_h="survivor_hard",survivor_l="survivor_lunatic",survivor_n="survivor_normal",survivor_u="survivor_ultimate",tech_finesse_f="tech_finesse2",tech_h_plus="tech_hard2",tech_h="tech_hard",tech_l_plus="tech_lunatic2",tech_l="tech_lunatic",tech_n_plus="tech_normal2",tech_n="tech_normal",techmino49_e="techmino49_easy",techmino49_h="techmino49_hard",techmino49_u="techmino49_ultimate",techmino99_e="techmino99_easy",techmino99_h="techmino99_hard",techmino99_u="techmino99_ultimate",tsd_e="tsd_easy",tsd_h="tsd_hard",tsd_u="tsd_ultimate"}
|
|
for k,v in next,modeTable do
|
|
v="record/"..v
|
|
if fs.getInfo(v.."dat")then
|
|
fs.write("record/"..k.."rec",fs.read(v.."dat"))
|
|
fs.remove(v.."dat")
|
|
end
|
|
if fs.getInfo(v.."rec")then
|
|
fs.write("record/"..k.."rec",fs.read(v.."rec"))
|
|
fs.remove(v.."rec")
|
|
end
|
|
end
|
|
if RANKS.blind_easy then
|
|
for k,v in next,modeTable do
|
|
RANKS[k]=RANKS[v]
|
|
RANKS[v]=nil
|
|
end
|
|
needSaveRank=true
|
|
end
|
|
if not RANKS.sprint_10l then
|
|
RANKS.sprint_10l=0
|
|
needSaveRank=true
|
|
end
|
|
if needSaveRank then
|
|
FILE.save(RANKS,"conf/unlock")
|
|
end
|
|
|
|
if keyMap[1]then
|
|
NOGAME=true
|
|
fs.remove("conf/key")
|
|
end
|
|
USER.username=nil
|
|
|
|
if STAT.version~=VERSION_CODE then
|
|
newVersionLaunch=true
|
|
STAT.version=VERSION_CODE
|
|
FILE.save(STAT,"conf/data")
|
|
end
|
|
end
|
|
|
|
if THEME=="Xmas"then
|
|
BG.setDefault("snow")
|
|
BGM.setDefault("mXmas")
|
|
elseif THEME=="sprFes"then
|
|
BG.setDefault("firework")
|
|
BGM.setDefault("spring festival")
|
|
elseif THEME=="zDay"then
|
|
BG.setDefault("lanterns")
|
|
BGM.setDefault("overzero")
|
|
else
|
|
BG.setDefault("space")
|
|
BGM.setDefault("blank")
|
|
end |