This commit is contained in:
MrZ_26
2020-02-12 23:49:24 +08:00
parent 3155bc48ef
commit f6835c2118
105 changed files with 6602 additions and 3009 deletions

BIN
SFX/click.ogg Normal file

Binary file not shown.

View File

@@ -46,6 +46,9 @@ function newButton(x,y,w,h,color,font,code,hide,N)
next=N,
}for k,v in next,button do _[k]=v end return _
end
function button:reset()
self.ATV=0
end
function button:isAbove(x,y)
return x>self.x-self.ATV and x<self.x+self.w+2*self.ATV and y>self.y-self.ATV and y<self.y+self.h+2*self.ATV
end
@@ -64,11 +67,7 @@ function button:draw()
local x,y,w,h=self.x,self.y,self.w,self.h
local r,g,b=unpack(self.color)
gc.setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
local sd=shader_glow
sd:send("X",x)sd:send("Y",y)sd:send("W",w)sd:send("H",h)
gc.setShader(sd)
gc.rectangle("fill",x-self.ATV,y-self.ATV,w+2*self.ATV,h+2*self.ATV)
gc.setShader()
if self.ATV>0 then
gc.setLineWidth(4)
gc.setColor(1,1,1,self.ATV*.125)
@@ -95,6 +94,7 @@ end
local switch={
type="switch",
ATV=0,--activating time(0~8)
CHK=0,--check alpha(0~6)
}
function newSwitch(x,y,font,disp,code,hide,N)
local _={
@@ -105,35 +105,37 @@ function newSwitch(x,y,font,disp,code,hide,N)
next=N,
}for k,v in next,switch do _[k]=v end return _
end
function switch:reset()
self.ATV=0
self.CHK=0
end
function switch:isAbove(x,y)
return x>self.x and x<self.x+50 and y>self.y-25 and y<self.y+25
end
function switch:update()
if widget_sel==self then
if self.ATV<8 then self.ATV=self.ATV+1 end
else
if self.ATV>0 then self.ATV=self.ATV-1 end
local _=self.ATV
if widget_sel==self then if _<8 then self.ATV=_+1 end
else if _>0 then self.ATV=_-1 end
end
_=self.CHK
if self:disp()then if _<6 then self.CHK=_+1 end
else if _>0 then self.CHK=_-1 end
end
end
function switch:draw()
local x,y=self.x,self.y-25
if self.disp()then
if self.ATV>0 then
gc.setColor(1,.3,.3,self.ATV*.06)
gc.rectangle("fill",x,y,50,50)
end
gc.setColor(.9,1,.9)
if self.ATV>0 then
gc.setColor(1,1,1,self.ATV*.08)
gc.rectangle("fill",x,y,50,50)
end
if self.CHK>0 then
gc.setColor(.9,1,.9,self.CHK/6)
gc.setLineWidth(6)
gc.line(x+5,y+25,x+18,y+38,x+45,y+11)
else
if self.ATV>0 then
gc.setColor(.3,1,.3,self.ATV*.06)
gc.rectangle("fill",x,y,50,50)
end
end
--checked
gc.setLineWidth(4)
gc.setColor(1,1,1)
gc.setColor(1,1,1,.6+self.ATV*.05)
gc.rectangle("line",x,y,50,50)
--frame
local t=self.text
@@ -164,6 +166,10 @@ function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
next=N,
}for k,v in next,slider do _[k]=v end return _
end
function slider:reset()
self.ATV=0
self.pos=0
end
function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end
@@ -174,7 +180,7 @@ function slider:update()
if self.ATV>0 then self.ATV=self.ATV-1 end
end
if not(self.hide and self.hide())then
self.pos=self.pos*.8+self.disp()*.2
self.pos=self.pos*.7+self.disp()*.3
end
end
function slider:draw()
@@ -197,7 +203,7 @@ function slider:draw()
gc.printf(t,x-312,y-self.font*.7,300,"right")
end
--text
local x,y,w,h=x1+(x2-x1)*self.pos/self.unit-10-self.ATV,y-16-self.ATV,20+2*self.ATV,32+2*self.ATV
local x,y,w,h=x1+(x2-x1)*self.pos/self.unit-10-self.ATV*.5,y-16-self.ATV,20+self.ATV,32+2*self.ATV
gc.setColor(.8,.8,.8)
gc.rectangle("fill",x,y,w,h)
if self.ATV>0 then

View File

@@ -1,4 +1,4 @@
gameVersion="Alpha V0.8.4"
gameVersion="Alpha V0.8.5-"
function love.conf(t)
t.identity="Techmino"--Save directory name
t.version="11.1"
@@ -17,9 +17,9 @@ function love.conf(t)
W.resizable=1
W.fullscreentype="desktop"--"exclusive"
W.fullscreen=X
W.vsync=0--0∞fps
W.vsync=0--0:∞fps
W.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
W.depth=X--Bits per sample in the depth buffer
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)

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,31 @@
游戏方法:
控制系统提供的一个个方块,每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
完成当前游戏模式中的目标或者是活到最后即算胜利.
控制系统提供的一个个四联方块(左右移动和旋转90,180,270度),每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
活到最后或者完成目标即胜利.
旋转系统:
使用Techmino专属旋转系统,细节不赘述
使用Techmino专属旋转系统
细节不赘述
spin判定:
结合了不可移动判定和三角判定,是否为mini也与这二者有关,细节不赘述
结合了不可移动判定和三角判定,是否为mini也与判定过程数据有关
细节不赘述
攻击系统:
消1/2/3/4攻击0/1/2/4
spin1/2/3攻击2/4/6,若mini则减半
B2B:增加1~2(techrash)/1~3(spin)攻击
B3B:满B2B效果+1额外抵挡
PC:其它攻击与6~8(本局内递增)取高+2额外抵挡
PC:其它的伤害之和开根号后向上取整,再+6~10(本局内递增)+2额外抵挡
连击:0,0,1,1,2,2,3,3,4,4,3……
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
back to back(B2B)点数说明:
B2B点数的范围在0~1200
在40及以上特殊消除时B2B,在1000以上特殊消除时B3B,1200封顶
@@ -25,65 +35,15 @@ back to back(B2B)点数说明:
普通消除-250
1000以上空放一块-40(不减到低于1000)
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
混战模式说明:
许多玩家同时进行一局游戏对手都是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家攻击AOE,若未被任何人锁定则伏击随机玩家
坚持到最后的玩家就是胜利者.
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
模式说明:
竞速:
用你最快的速度消除40行(据难度而定)吧!
马拉松:
根据总消行数,速度会逐渐加快,消除两百行吧!(easy和hard就是normal开始和结束的速度,消除200行不加速)
大师:
马拉松进化版,如果觉得马拉松太简单了久玩这个吧,每一个难度都是一层境界,L难度和U难度攒到500点数通关,final难度为上级者专属游戏模式,不建议游玩.
经典:
使用低速控制设置在高速下落时尽可能消除更多的行,没有通关目标.(到90有"彩蛋")
禅:
闲得无聊,只是想单纯地打打块地时候可以玩此模式,无重力消除200行.
无尽:
无尽模式,边上会显示玩家的消行数和攻击效率,适合科研(术语).
单挑:
和一个电脑玩家单挑,带加号的和最后一个模式是超强机器人(仅限Windows平台),试试你能稳定打败多难的对手吧!
回合制:
玩法同单挑模式,只不过只有当一个人放下一个方块后另一个人才能放下一块.
仅TSD:
这个模式中,玩家必须用TSD(T spin double)的方式消除,否则直接判负,你能连续打出多少个TSD呢?
隐形:
根据不同难度,场地内(甚至当前方块)会隐形,看看你能活多久吧!(GM难度为类似TGM3的GM Roll,用于上级者练习)
挖掘:
每隔一定时间,系统会向场地的低端添加一行垃圾行,间隔会随着波数增加而越来越短,你能顶住几波呢?
生存:
每隔一定时间,系统会向玩家的垃圾缓冲槽中添加垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家可以将其抵消也可以让其释放,尽可能活更久的时间.
防守:
系统会向玩家的垃圾缓冲槽中添加难消除的垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家要尽量抵消他们来让自己存活更久.
进攻:
当玩家的攻击缓冲槽空时,系统会向玩家的垃圾缓冲槽中添加大量的垃圾行(高难度下后期甚至会远超过20),释放速度和间隔都会随着波数增加而越来越短,垃圾上涨速度也会提升.赶紧在其释放之前将攻击抵消到不会一下致命的量!
科研:
玩家只被允许做特殊消除(spin/全消/消四),在带+的难度中不允许消四,U难度下玩家甚至只被允许每一个方块都使用最简操作控制,任何违反规则的行为都会判负.
C4W练习:(或者说是4w练习)
系统直接提供给玩家"留4列"的场地,玩家可以自由练习4w消除,该技巧在某些时候实战很有用.(需要学会spin,否则意义不是很大)
全清训练:
系统会连续给玩家提供"标准开局PC套路"的场地和四个方块(不允许使用hold),玩家需要一直完成PC,否则判负.
全清挑战:
在消除一百行的限制内,你能全清几次?
49人混战:
许多玩家同时进行一局游戏其它的是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家AOE,若无则伏击随机玩家
坚持到最后的玩家就是胜利者.
99人混战:
同49人混战,只是增加到了99名玩家,难度系数也有调整,对设备的要求也较高.
干旱:
系统提供的方块序列变得奇怪了!你能消除100行不死吗,或者,多快?
多人:
使用键盘或者多个手柄(也许?)
自定义:
玩家可以自由调整下落速度等等几乎大多数设置(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来玩方块拼图.在拼图模式下,按功能键切换是否显示提示模板.其中打"X"的格子不允许有方块,空的格子可以是任何状态,玩家能获得的七种普通方块必须完全符合,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.
自定义模式说明:
玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来进行拼图模式.
在拼图模式下,按功能键切换是否展示提示.其中打"X"的格子不允许有方块,空的格子可以是任何状态,普通的七种彩色方块必须颜色对应,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.

BIN
font.ttf

Binary file not shown.

View File

@@ -77,43 +77,22 @@ return{
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
recSavingError="纪录保存失败:",
settingSaved="设置已保存",
settingSavingError="设置保存失败:",
statSavingError="数据保存失败:",
copySuccess="已复制到剪切板",
dataCorrupted="数据损坏",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
noScore="暂无成绩",
highScore="最佳成绩",
newRecord="打破纪录",
actName=actName,
modeName={
[0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
"挖掘","生存","防守","进攻","科研",
"C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人",
},
modeInfo={
sprint="挑战世界纪录",
marathon="尝试坚持到最后",
master="成为方块大师",
classic="高速经典",
zen="无重力消除200行",
infinite="科研沙盒",
solo="打败AI",
round="下棋",
tsd="尽可能做TSD",
blind="最强大脑",
dig="核能挖掘机",
survivor="你能存活多久?",
defender="防守练习",
attacker="进攻练习",
tech="尽可能不要普通消除",
c4wtrain="无 限 连 击",
pctrain="熟悉全清定式的组合",
pcchallenge="100行内尽可能多PC",
techmino49="49人混战",
techmino99="99人混战",
drought="异常序列",
hotseat="友尽模式",
},
load={[0]="加载完成","加载语音ing","加载音乐ing","加载音效ing",},
load={[0]="加载完成","加载语音ing","加载音乐ing","加载音效ing","加载模式ing","加载乱七八糟的东西ing"},
tips={
"不是动画,真的在加载!",
"大满贯10连击消四全清!",
@@ -133,7 +112,7 @@ return{
"20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备",
"方块可以不是休闲游戏",
"本游戏可不是休闲游戏",
"调到特殊的日期也不会发生什么的",
"3.1415926535897932384",
"2.7182818284590452353",
@@ -171,7 +150,7 @@ return{
},
help={
"好像也没啥好帮助的吧?就当是关于了",
"这只是一个方块游戏,请勿过度解读和随意联想",
"这只是一个普通的方块游戏,请勿称此游戏为某某某方块",
"不过就当成TOP/C2/KOS/TGM3/JS玩好了",
"游戏还在测试阶段,请 勿 外 传",
"",
@@ -196,7 +175,6 @@ return{
WidgetText={
main={
lang="言/A",
qplay="快速开始",
play="开始",
setting="设置",
music="音乐室",
@@ -205,12 +183,9 @@ return{
quit="退出",
},
mode={
up="",
down="",
left="",
right="",
draw="画图(Q)",
setting="参数(E)",
start="开始",
custom="自定义(C)",
back=BK,
},
music={
@@ -225,9 +200,6 @@ return{
down="",
left="",
right="",
start1="消除开始",
start2="拼图开始",
draw="画图(D)",
set1="40行(1)",
set2="1v1(2)",
set3="无尽(3)",
@@ -251,6 +223,9 @@ return{
gb5="",
space="×",
clear="清除",
demo="演示模式",
copy="复制",
paste="粘贴",
back=BK,
},
play={

View File

@@ -77,43 +77,22 @@ return{
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
recSavingError="纪录保存失败:",
settingSaved="设置已保存",
settingSavingError="设置保存失败:",
statSavingError="数据保存失败:",
copySuccess="已复制到剪切板",
dataCorrupted="数据损坏",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
noScore="暂无成绩",
highScore="最佳成绩",
newRecord="打破纪录",
actName=actName,
modeName={
[0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
"挖掘","生存","防守","进攻","科研",
"C4W练习","全清训练","全清挑战","49人混战","99人混战","干旱","多人",
},
modeInfo={
sprint="挑战世界纪录",
marathon="尝试坚持到最后",
master="成为方块大师",
classic="高速经典",
zen="无重力消除200行",
infinite="科研沙盒",
solo="打败AI",
round="下棋",
tsd="尽可能做T旋双清",
blind="最强大脑",
dig="核能挖掘机",
survivor="你能存活多久?",
defender="防守练习",
attacker="进攻练习",
tech="尽可能不要普通消除!",
c4wtrain="无 限 连 击",
pctrain="熟悉全清定式的组合",
pcchallenge="100行内尽可能多全清",
techmino49="49人混战",
techmino99="99人混战",
drought="异常序列",
hotseat="友尽模式",
},
load={[0]="加载完成","加载语音ing","加载音乐ing","加载音效ing",},
load={[0]="加载完成","加载语音ing","加载音乐ing","加载音效ing","加载模式ing","加载乱七八糟的东西ing"},
tips={
"不是动画,真的在加载!",
"大满贯10连击消四全清!",
@@ -133,7 +112,7 @@ return{
"20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备",
"方块可以不是休闲游戏",
"本游戏可不是休闲游戏",
"调到特殊的日期也不会发生什么的",
"3.1415926535897932384",
"2.7182818284590452353",
@@ -171,7 +150,7 @@ return{
},
help={
"好像也没啥好帮助的吧?就当是关于了",
"这只是一个方块游戏,请勿过度解读和随意联想",
"这只是一个普通的方块游戏,请勿称此游戏为某某某方块",
"不过就当成TOP/C2/KOS/TGM3/JS玩好了",
"游戏还在测试阶段,请 勿 外 传",
"",
@@ -196,7 +175,6 @@ return{
WidgetText={
main={
lang="言/A",
qplay="快速开始",
play="开始",
setting="设置",
music="音乐室",
@@ -205,12 +183,9 @@ return{
quit="退出",
},
mode={
up="",
down="",
left="",
right="",
draw="画图(Q)",
setting="参数(E)",
start="开始",
custom="自定义(C)",
back=BK,
},
music={
@@ -225,9 +200,6 @@ return{
down="",
left="",
right="",
start1="消除开始",
start2="拼图开始",
draw="画图(D)",
set1="40行(1)",
set2="1v1(2)",
set3="无尽(3)",
@@ -251,6 +223,9 @@ return{
gb5="",
space="×",
clear="清除",
demo="演示模式",
copy="复制",
paste="粘贴",
back=BK,
},
play={

View File

@@ -75,43 +75,22 @@ return{
setting_sound="Sound setting",
musicRoom="Music Room",
nowPlaying="Now Playing:",
recSavingError="Failed to save record:",
settingSaved="Setting saved",
settingSavingError="Failed to save setting:",
statSavingError="Failed to save stat:",
copySuccess="Copy Success",
dataCorrupted="Data Corrupted",
VKTchW="Touch weight",
VKOrgW="Origion weight",
VKCurW="CurPos weight",
noScore="No Score Yet",
highScore="Highscore",
newRecord="New Rocord",
actName=actName,
modeName={
[0]="Custom",
"Sprint","Marathon","Master","Classic","Zen","Infinite","1v1","Round","TSD-only","Blind",
"Dig","Survivor","Defender","Attacker","Tech",
"C4W Train","PC Train","PC Challenge","Techmino49","Techmino99","Drought","Hotseat",
},
modeInfo={
sprint="Speed run",
marathon="Survive and reach target",
master="To be Grand Master",
classic="Vintage car drag racing",
zen="Clear 200 Lines without gravity",
infinite="Infinite game,infinite happiness",
solo="Beat AI",
round="Chess?",
tsd="Make more T-spin-doubles",
blind="Invisible board",
dig="Downstack!",
survivor="Survive Longer!",
defender="Hand them!",
attacker="Attacking better then defending",
tech="Don't do normal clear",
c4wtrain="Infinite combo",
pctrain="Let's learn some PCs",
pcchallenge="Make PCs in 100 Lines",
techmino49="Melee fight with 48 AIs",
techmino99="Melee fight with 98 AIs",
drought="ERRSEQ flood attack",
hotseat="",
},
load={[0]="Finished","Loading VOICE","Loading BGM","Loading SFX",},
load={[0]="Finished","Loading VOICE","Loading BGM","Loading SFX","Loading modes","Loading other things"},
tips={
"Not animation,real loading!",
"Back to Back 10 combo Techrash PC!",
@@ -170,7 +149,7 @@ return{
},
help={
"I don't think you need \"help\".",
"THIS IS ONLY A BLOCK GAME",
"THIS IS ONLY A BLOCK GAME,not T****s",
"But just play like playing TOP/C2/KOS/TGM3",
"Game is not public now,so DO NOT DISTIRBUTE",
"",
@@ -195,7 +174,6 @@ Lib used:
WidgetText={
main={
lang="言/A",
qplay="Qplay",
play="Play",
setting="Settings",
music="Music room",
@@ -204,12 +182,9 @@ Lib used:
quit="Quit",
},
mode={
up="",
down="",
left="",
right="",
draw="Draw(Q)",
setting="Setting(E)",
start="Start",
custom="Custom(C)",
back=BK,
},
music={
@@ -224,9 +199,6 @@ Lib used:
down="",
left="",
right="",
start1="Clear Start",
start2="Puzzle Start",
draw="Draw(D)",
set1="40L(1)",
set2="1v1(2)",
set3="infinite(3)",
@@ -250,6 +222,9 @@ Lib used:
gb5="",
space="×",
clear="Clear",
demo="Demo",
copy="Copy",
paste="Paste",
back=BK,
},
play={

426
list.lua
View File

@@ -1,4 +1,3 @@
local mobile=system=="Android"or system=="iOS"
actName={
"moveLeft","moveRight",
"rotRight","rotLeft","rotFlip",
@@ -34,8 +33,10 @@ color={
darkGrey={.3,.3,.3},
white={1,1,1},
bronze={.7,.4,0},
orange={1,.6,0},
lightOrange={1,.7,.3},
darkOrange={.6,.4,0},
purple={.5,0,1},
lightPurple={.8,.4,1},
darkPurple={.3,0,.6},
@@ -57,6 +58,7 @@ blockColor={
}
sfx={
"welcome",
"click",
"error","error_long",
--Stereo sfxs(cannot set position)
"button","swipe",
@@ -89,7 +91,7 @@ bgm={
"shining terminal",
"end",
}
voiceBank={}
voiceBank={}--{{srcs1},{srcs2},...}
voiceName={
"zspin","sspin","lspin","jspin","tspin","ospin","ispin",
"single","double","triple","techrash",
@@ -174,422 +176,4 @@ customRange={
}
RCPB={10,33,200,33,105,5,105,60}
snapLevelValue={1,10,20,40,60,80}
modeID={
[0]="custom",
"sprint","marathon","master","classic","zen","infinite","solo","round","tsd","blind",
"dig","survivor","defender","attacker","tech",
"c4wtrain","pctrain","pcchallenge","techmino49","techmino99","drought","hotseat",
}
local O,_=true,false
blocks={
{[0]={{_,O,O},{O,O,_}},{{O,_},{O,O},{_,O}}},
{[0]={{O,O,_},{_,O,O}},{{_,O},{O,O},{O,_}}},
{[0]={{O,O,O},{_,_,O}},{{O,O},{O,_},{O,_}},{{O,_,_},{O,O,O}},{{_,O},{_,O},{O,O}}},
{[0]={{O,O,O},{O,_,_}},{{O,_},{O,_},{O,O}},{{_,_,O},{O,O,O}},{{O,O},{_,O},{_,O}}},
{[0]={{O,O,O},{_,O,_}},{{O,_},{O,O},{O,_}},{{_,O,_},{O,O,O}},{{_,O},{O,O},{_,O}}},
{[0]={{O,O},{O,O}},{{O,O},{O,O}}},
{[0]={{O,O,O,O}},{{O},{O},{O},{O}}},
}
local l={1,2,6,7}for i=1,4 do blocks[l[i]][2],blocks[l[i]][3]=blocks[l[i]][0],blocks[l[i]][1]end
for i=1,7 do blocks[i+7]=blocks[i]end
local virtualkeySet={
{
{1, 80, 720-200, 80},--moveLeft
{2, 320, 720-200, 80},--moveRight
{3, 1280-80, 720-200, 80},--rotRight
{4, 1280-200, 720-80, 80},--rotLeft
{5, 1280-200, 720-320, 80},--rotFlip
{6, 200, 720-320, 80},--hardDrop
{7, 200, 720-80, 80},--softDrop
{8, 1280-320, 720-200, 80},--hold
{9, 1280-80, 280, 80},--func
{10,80, 280, 80},--restart
},--Farter's set,thanks
{
{1, 1280-320, 720-200, 80},--moveLeft
{2, 1280-80, 720-200, 80},--moveRight
{3, 200, 720-80, 80},--rotRight
{4, 80, 720-200, 80},--rotLeft
{5, 200, 720-320, 80},--rotFlip
{6, 1280-200, 720-320, 80},--hardDrop
{7, 1280-200, 720-80, 80},--softDrop
{8, 320, 720-200, 80},--hold
{9, 80, 280, 80},--func
{10,1280-80, 280, 80},--restart
},--Mirrored farter's set,sknaht
{
{1, 80, 720-80, 80},--moveLeft
{2, 240, 720-80, 80},--moveRight
{3, 1280-240, 720-80, 80},--rotRight
{4, 1280-400, 720-80, 80},--rotLeft
{5, 1280-240, 720-240, 80},--rotFlip
{6, 1280-80, 720-80, 80},--hardDrop
{7, 1280-80, 720-240, 80},--softDrop
{8, 1280-80, 720-400, 80},--hold
{9, 80, 360, 80},--func
{10,80, 80, 80},--restart
},--Author's set,not recommend
{
{1, 1280-400, 720-80, 80},--moveLeft
{2, 1280-80, 720-80, 80},--moveRight
{3, 240, 720-80, 80},--rotRight
{4, 80, 720-80, 80},--rotLeft
{5, 240, 720-240, 80},--rotFlip
{6, 1280-240, 720-240, 80},--hardDrop
{7, 1280-240, 720-80, 80},--softDrop
{8, 1280-80, 720-240, 80},--hold
{9, 80, 720-240, 80},--func
{10,80, 320, 80},--restart
},--Keyboard set
{
{10,70, 50,30},--restart
{9, 130, 50,30},--func
{4, 190, 50,30},--rotLeft
{3, 250, 50,30},--rotRight
{5, 310, 50,30},--rotFlip
{1, 370, 50,30},--moveLeft
{2, 430, 50,30},--moveRight
{8, 490, 50,30},--hold
{7, 550, 50,30},--softDrop1
{6, 610, 50,30},--hardDrop
{11,670, 50,30},--insLeft
{12,730, 50,30},--insRight
{13,790, 50,30},--insDown
{14,850, 50,30},--down1
{15,910, 50,30},--down4
{16,970, 50,30},--down10
{17,1030, 50,30},--dropLeft
{18,1090, 50,30},--dropRight
{19,1150, 50,30},--addLeft
{20,1210, 50,30},--addRight
},--PC key feedback(top&in a row)
}
local customSet={
{20,20,1,1,7,1,1,1,3,4,1,2,3},
{18,20,1,1,7,1,1,1,8,3,8,3,3},
{22,22,1,1,7,3,1,1,8,4,1,7,7},
{20,20,1,1,7,1,1,3,8,3,1,7,8},
{1,11,8,11,4,1,2,1,8,3,1,4,9},
}
local function useDefaultSet(n)
for i=1,#customSet[n]do
customSel[i]=customSet[n][i]
end
curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]])
end
--λFuncs for widgets
local function SETdisp(k)
return function()
return setting[k]
end
end
local function SETsto(k)
return function(i)setting[k]=i end
end
local function SETrev(k)
return function()
setting[k]=not setting[k]
end
end
local function pressKey(k)
return function()
love.keypressed(k)
end
end
local function setPen(i)
return function()
sceneTemp.pen=i
end
end
local function VKAdisp(n)
return function()
return VK_org[n].ava
end
end
local function VKAcode(n)
return function()
VK_org[n].ava=not VK_org[n].ava
end
end
local C=color
local skinName={
"Normal(MrZ)",
"Jelly(Miya)",
"Plastic(MrZ)",
"Glow(MrZ)",
"Pure(MrZ)",
"Text Bone(MrZ)",
"Colored Bone(MrZ)",
"white Bone(MrZ)",
}
-- T1,T2=0,0
Widget={
load={},intro={},quit={},
main={
play= newButton(150,280,200,160,C.lightRed, 55,function()scene.push()scene.swapTo("mode")end, nil,"setting"),
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,"qplay"),
qplay= newButton(540,415,100,70,C.lightOrange, 23,function()scene.push()loadGame(modeSel,levelSel)end, nil,"lang"),
lang= newButton(590,505,200,70,C.lightRed, 45,function()
setting.lang=setting.lang%#langName+1
swapLanguage(setting.lang)
TEXT(text.lang,795,500,50,"appear",1.6)
end,nil,"quit"),
-- S1= newSlider(520,550,380,10,10,nil,function()return T1 end,function(i)T1=i end),
-- S2= newSlider(520,590,380,10,10,nil,function()return T2 end,function(i)T2=i end),
quit= newButton(370,620,280,100,C.lightGrey, 55,function()VOICE("bye")scene.swapTo("quit","slowFade")end,nil,"play"),
},
mode={
up= newButton(1000, 210,200,140,C.white, 75,pressKey("up"), function()return modeSel==1 end),
down= newButton(1000, 430,200,140,C.white, 75,pressKey("down"), function()return modeSel==#modeID end),
left= newButton(190, 150,100,80, C.white, 35,pressKey("left"), function()return levelSel==1 end),
right= newButton(350, 150,100,80, C.white, 35,pressKey("right"), function()return levelSel==#modes[modeID[modeSel]].level end),
start= newButton(1000, 600,250,100,C.lightGreen, 45,function()scene.push()loadGame(modeSel,levelSel)end),
custom= newButton(275, 460,200,90, C.lightYellow, 35,function()scene.push()scene.swapTo("custom")end),
back= newButton(640, 630,230,90, C.white, 40,scene.back),
},
music={
bgm= newSlider(760, 80,400,10,35,nil,SETdisp("bgm"),function(i)setting.bgm=i;BGM(bgmPlaying)end),
up= newButton(1100, 200,120,120,C.white,55,pressKey("up")),
play= newButton(1100, 340,120,120,C.white,35,pressKey("space"),function()return setting.bgm==0 end),
down= newButton(1100, 480,120,120,C.white,55,pressKey("down")),
back= newButton(640, 630,230,90, C.white,40,scene.back),
},
custom={
up= newButton(1000, 220,100,100,C.white, 45,function()sceneTemp=(sceneTemp-2)%#customID+1 end),
down= newButton(1000, 460,100,100,C.white, 45,function()sceneTemp=sceneTemp%#customID+1 end),
left= newButton(880, 340,100,100,C.white, 45,pressKey("left")),
right= newButton(1120, 340,100,100,C.white, 45,pressKey("right")),
start1= newButton(880, 580,220,70, C.lightGreen, 35,function()scene.push()loadGame(0,1)end),
start2= newButton(1120, 580,220,70, C.lightPurple, 35,function()scene.push()loadGame(0,2)end),
draw= newButton(1000, 90, 190,85, C.lightCyan, 35,function()scene.push()scene.swapTo("draw")end),
set1= newButton(640, 160,240,75, C.lightYellow, 35,function()useDefaultSet(1)end),
set2= newButton(640, 250,240,75, C.lightYellow, 35,function()useDefaultSet(2)end),
set3= newButton(640, 340,240,75, C.lightYellow, 35,function()useDefaultSet(3)end),
set4= newButton(640, 430,240,75, C.lightYellow, 35,function()useDefaultSet(4)end),
set5= newButton(640, 520,240,75, C.lightYellow, 35,function()useDefaultSet(5)end),
back= newButton(640, 630,180,60, C.white, 35,scene.back),
},
draw={
block1= newButton(920, 80, 120,120,C.red, 60,setPen(1)),
block2= newButton(1060, 80, 120,120,C.green, 60,setPen(2)),
block3= newButton(1200, 80, 120,120,C.orange, 60,setPen(3)),
block4= newButton(920, 220,120,120,C.blue, 60,setPen(4)),
block5= newButton(1060, 220,120,120,C.magenta, 60,setPen(5)),
block6= newButton(1200, 220,120,120,C.yellow, 60,setPen(6)),
block7= newButton(920, 360,120,120,C.cyan, 60,setPen(7)),
gb1= newButton(1060, 360,120,120,C.darkGrey, 60,setPen(9)),
gb2= newButton(1200, 360,120,120,C.grey, 60,setPen(10)),
gb3= newButton(920, 500,120,120,C.darkPurple, 60,setPen(11)),
gb4= newButton(1060, 500,120,120,C.darkRed, 60,setPen(12)),
gb5= newButton(1200, 500,120,120,C.darkGreen, 60,setPen(13)),
clear= newButton(780, 80, 120,120,C.white, 40,pressKey("delete")),
any= newButton(780, 220,120,120,C.lightGrey, 40,setPen(0)),
space= newButton(780, 360,120,120,C.grey, 65,setPen(-1)),
back= newButton(1200, 640,120,120,C.white, 35,scene.back),
},
play={
pause= newButton(1235,45,80,80,C.white,25,pauseGame),
},
pause={
resume= newButton(640,290,240,100,C.white,45,resumeGame),
restart=newButton(640,445,240,100,C.white,45,function()
clearTask("play")
updateStat()
resetGameData()
scene.swapTo("play","none")
end),
sfx= newSlider(950,60,280,10,35,function()SFX("blip_1")end, SETdisp("sfx"),SETsto("sfx")),
bgm= newSlider(950,120,280,10,35,function()BGM(bgmPlaying or"blank")end, SETdisp("bgm"),SETsto("bgm")),
quit= newButton(640,600,240,100,C.white,45,scene.back),
},
setting_game={
graphic=newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_graphic")end,nil,"sound"),
sound= newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_sound")end, nil,"dasD"),
dasD= newButton(180,230,50,50,C.white,40,function()
setting.das=(setting.das-1)%31
if setting.arr>setting.das then
setting.arr=setting.das
Widget.setting_game.arrD:FX()
SFX("blip_1",.4)
end
end,nil,"dasU"),
dasU= newButton(400,230,50,50,C.white,40,function()
setting.das=(setting.das+1)%31
if setting.arr>setting.das then
setting.das=setting.arr
Widget.setting_game.arrD:FX()
SFX("blip_1",.4)
end
end,nil,"arrD"),
arrD= newButton(500,230,50,50,C.white,40,function()
setting.arr=(setting.arr-1)%16
if setting.arr>setting.das then
setting.das=setting.arr
Widget.setting_game.dasU:FX()
SFX("blip_1",.4)
end
end,nil,"arrU"),
arrU= newButton(720,230,50,50,C.white,40,function()
setting.arr=(setting.arr+1)%16
if setting.arr>setting.das then
setting.das=setting.arr
Widget.setting_game.dasU:FX()
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"),
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"),
},
setting_graphic={
sound= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_sound")end, nil,"game"),
game= newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"ghost"),
ghost= newSwitch(310,180,35,SETdisp("ghost"), SETrev("ghost"), nil,"center"),
center= newSwitch(580,180,35,SETdisp("center"), SETrev("center"), nil,"smo"),
smo= newSwitch(310,260,25,SETdisp("smo"), SETrev("smo"), nil,"grid"),
grid= newSwitch(580,260,30,SETdisp("grid"), SETrev("grid"), nil,"dropFX"),
dropFX= newSlider(310,350,373,5,35,nil,SETdisp("dropFX"), SETsto("dropFX"), nil,"shakeFX"),
shakeFX=newSlider(310,430,373,5,35,nil,SETdisp("shakeFX"), SETsto("shakeFX"), nil,"atkFX"),
atkFX= newSlider(310,510,373,5,35,nil,SETdisp("atkFX"), SETsto("atkFX"), nil,"frame"),
frame= newSlider(310,590,373,10,35,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"fullscreen"),
fullscreen=newSwitch(990,180,40,SETdisp("fullscreen"),function()
setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen)
if not setting.fullscreen then
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
skin= newButton(810,420,120,60,C.white,35,function()
local _=setting.skin%8+1
setting.skin=_
changeBlockSkin(_)
TEXT(skinName[_],850,475,28,"appear")
end,nil,"back"),
back= newButton(1160,600,160,160,C.white,50,scene.back,nil,"sound"),
},
setting_sound={
game= newButton(200,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_game")end, nil,"graphic"),
graphic=newButton(1080,80,240,80,C.lightCyan,35,function()scene.swapTo("setting_graphic")end, nil,"sfx"),
sfx= newSlider(180,250,400,10,35,function()SFX("blip_1")end, SETdisp("sfx"), SETsto("sfx"), nil,"bgm"),
bgm= newSlider(750,250,400,10,35,function()BGM(bgmPlaying or"blank")end, SETdisp("bgm"), SETsto("bgm"), nil,"vib"),
vib= newSlider(180,440,400,5 ,35,function()VIB(1)end, SETdisp("vib"), SETsto("vib"), nil,"voc"),
voc= newSlider(750,440,400,10,35,function()VOICE("nya")end, SETdisp("voc"), SETsto("voc"), nil,"stereo"),
stereo= newSlider(180,630,400,10,35,function()SFX("move",1,-1)SFX("lock",1,1)end, SETdisp("stereo"), SETsto("stereo"),function()return setting.sfx==0 end,"back"),
back=newButton(1160,600,160,160,C.white,50,scene.back,nil,"game"),
},
setting_key={
back=newButton(1140,650,200,80,C.white,45,scene.back),
},
setting_touch={
default=newButton(520,80,170,80,C.white,35,function()
local D=virtualkeySet[sceneTemp.default]
for i=1,#VK_org do
VK_org[i].ava=false
end
for n=1,#D do
local T=D[n]
if T[1]then
local B=VK_org[n]
B.ava=true
B.x,B.y,B.r=T[2],T[3],T[4]
end
end--Replace keys
sceneTemp.default=sceneTemp.default%5+1
sceneTemp.sel=nil
end),
snap= newButton(760,80,170,80,C.white,35,function()
sceneTemp.snap=sceneTemp.snap%6+1
end),
option= newButton(520,180,170,80,C.white,40,function()
scene.push()
scene.swapTo("setting_touchSwitch")
end),
back= newButton(760,180,170,80,C.white,40,scene.back),
size= newSlider(450,265,460,14,40,nil,function()
return VK_org[sceneTemp.sel].r/10-1
end,
function(v)
if sceneTemp.sel then
VK_org[sceneTemp.sel].r=10+v*10
end
end,
function()return not sceneTemp.sel end),
},
setting_touchSwitch={
b1= newSwitch(280,80, 35,VKAdisp(1),VKAcode(1)),
b2= newSwitch(280,140, 35,VKAdisp(2),VKAcode(2)),
b3= newSwitch(280,200, 35,VKAdisp(3),VKAcode(3)),
b4= newSwitch(280,260, 35,VKAdisp(4),VKAcode(4)),
b5= newSwitch(280,320, 35,VKAdisp(5),VKAcode(5)),
b6= newSwitch(280,380, 35,VKAdisp(6),VKAcode(6)),
b7= newSwitch(280,440, 35,VKAdisp(7),VKAcode(7)),
b8= newSwitch(280,500, 35,VKAdisp(8),VKAcode(8)),
b9= newSwitch(280,560, 35,VKAdisp(9),VKAcode(9)),
b10= newSwitch(280,620, 35,VKAdisp(10),VKAcode(10)),
b11= newSwitch(620,80, 35,VKAdisp(11),VKAcode(11)),
b12= newSwitch(620,140, 35,VKAdisp(12),VKAcode(12)),
b13= newSwitch(620,200, 35,VKAdisp(13),VKAcode(13)),
b14= newSwitch(620,260, 35,VKAdisp(14),VKAcode(14)),
b15= newSwitch(620,320, 35,VKAdisp(15),VKAcode(15)),
b16= newSwitch(620,380, 35,VKAdisp(16),VKAcode(16)),
b17= newSwitch(620,440, 35,VKAdisp(17),VKAcode(17)),
b18= newSwitch(620,500, 35,VKAdisp(18),VKAcode(18)),
b19= newSwitch(620,560, 35,VKAdisp(19),VKAcode(19)),
b20= newSwitch(620,620, 35,VKAdisp(20),VKAcode(20)),
norm= newButton(840,100,240,80,C.white,45,function()for i=1,20 do VK_org[i].ava=i<11 end end),
pro= newButton(1120,100,240,80,C.white,35,function()for i=1,20 do VK_org[i].ava=true end end),
hide= newSwitch(1170,200,40,SETdisp("VKSwitch"),SETrev("VKSwitch")),
track= newSwitch(1170,300,35,SETdisp("VKTrack"),SETrev("VKTrack")),
icon= newSwitch(850,300,40,SETdisp("VKIcon"),SETrev("VKIcon")),
tkset= newButton(1120,400,240,80,C.white,32,function()
scene.push()
scene.swapTo("setting_trackSetting")
end,function()return not setting.VKTrack end),
alpha= newSlider(840,490,400,10,40,nil,SETdisp("VKAlpha"),SETsto("VKAlpha")),
back= newButton(1100,600,240,80,C.white,45,scene.back),
},
setting_trackSetting={
VKDodge=newSwitch(400,200, 35,SETdisp("VKDodge"),SETrev("VKDodge")),
VKTchW= newSlider(140,310,1000,10,35,nil,SETdisp("VKTchW"),function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end),
VKCurW= newSlider(140,370,1000,10,35,nil,SETdisp("VKCurW"),function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end),
back= newButton(1080,600,240,80,C.white,45,scene.back),
},
help={
his= newButton(1050,520,230,60,C.white,35,function()scene.push()scene.swapTo("history")end,nil,"back"),
qq= newButton(1050,600,230,60,C.white,35,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end, function()return mobile end,"his"),
back= newButton(640, 600,180,60,C.white,35,scene.back,nil,"qq"),
},
history={
prev= newButton(1155,170,180,180,C.white,65,pressKey("up"),function()return sceneTemp==1 end),
next= newButton(1155,400,180,180,C.white,65,pressKey("down"),function()return sceneTemp==#updateLog-22 end),
back= newButton(1155,600,180,90,C.white,35,scene.back),
},
stat={
path= newButton(980,620,250,60,C.white,25,function()love.system.openURL(love.filesystem.getSaveDirectory())end,function()return mobile end,"back"),
back= newButton(640,620,180,60,C.white,35,scene.back,nil,"path"),
},
}
for _,L in next,Widget do
for _,W in next,L do
if W.next then
W.next,L[W.next].prev=L[W.next],W
end
end
end
widget_sel=nil--selected widget object
snapLevelValue={1,10,20,40,60,80}

269
main.lua
View File

@@ -8,22 +8,38 @@ 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 rem=table.remove
package.path="?.lua"
NULL=function()end
--Libs
-------------------------------------------------------------
system=sys.getOS()
local xOy=love.math.newTransform()
local mx,my,mouseShow=-20,-20,false
local touching--第一触摸ID
local touching=nil--第一触摸ID
local touchDist=nil
local devMode=0
modeSel,levelSel=1,3--初始模式选择(saved in setting)
players={alive={},human=0}
scr={x=0,y=0,w=gc.getWidth(),h=gc.getHeight(),k=1}
scr={x=0,y=0,w=nil,h=nil,k=1}
local scr=scr
mapCam={
sel=nil,--selected mode ID
x=0,y=0,k=1,--camera pos/k
x1=0,y1=0,k1=1,--camera pos/k shown
--basic paras
keyCtrl=false,--if controlling with key
zoomMethod=nil,
zoomK=nil,
--for auto zooming when enter/leave scene
}
curBG="none"
bgmPlaying=nil
voiceQueue={free=0}
texts={}
widget_sel=nil--selected widget object
virtualkeyDown,virtualkeyPressTime={},{}
for i=1,20 do
virtualkeyDown[i]=X
@@ -35,20 +51,6 @@ kb.setTextInput(false)
ms.setVisible(false)
--Application Vars
-------------------------------------------------------------
local Fonts={}
function setFont(s)
if s~=currentFont then
if Fonts[s]then
gc.setFont(Fonts[s])
else
local t=gc.setNewFont("font.ttf",s)
Fonts[s]=t
gc.setFont(t)
end
currentFont=s
end
return Fonts[s]
end
customSel={22,22,1,1,7,3,1,1,8,4,1,1,1}
preField={h=20}
for i=1,10 do preField[i]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}end
@@ -56,6 +58,10 @@ 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
-------------------------------------------------------------
setFont=require("parts/font")
blocks=require("parts/mino")
-- require("parts/light")
-- require("parts/shader")
scene=require("scene")
require("default_data")
require("class")
@@ -64,13 +70,12 @@ require("toolfunc")
require("sound")
require("text")
require("list")
require("player")
Widget=require("widgetList")
require("dataList")
require("texture")
require("light")
local Tmr=require("timer")
local Pnt=require("paint")
require("player")
require("shader")
--Modules
-------------------------------------------------------------
local powerInfoCanvas,updatePowerInfo
@@ -175,10 +180,12 @@ local function wheelScroll(y)
floatWheel=floatWheel+1
end
end
local mouseDown,mouseMove,mouseUp,wheelmoved={},{},{},{}
local mouseClick,touchClick={},{}
local mouseDown,mouseMove,mouseUp,wheelMoved={},{},{},{}
local touchDown,touchUp,touchMove={},{},{}
local keyDown,keyUp={},{}
local gamepadDown,gamepadUp={},{}
function mouseDown.intro(x,y,k)
if k==2 then
VOICE("bye")
@@ -202,42 +209,103 @@ function keyDown.intro(key)
end
end
function wheelmoved.mode(x,y)
wheelScroll(y)
local function onMode(x,y)
local cam=mapCam
x=(cam.x1-640+x)/cam.k1
y=(cam.y1-360+y)/cam.k1
local MM,R=modes,modeRanks
for _=1,#MM do
if R[_]then
local M=MM[_]
local s=M.size
if M.shape==1 then
if x>M.x-s and x<M.x+s and y>M.y-s and y<M.y+s then return _ end
elseif M.shape==2 then
if(x-M.x)^2+(y-M.y)^2<s^2 then return _ end
end
end
end
end
function wheelMoved.mode(x,y)
local cam=mapCam
local t=cam.k
local k=t+y*.1
if k>1.5 then k=1.5
elseif k<.3 then k=.3
end
t=k/t
if cam.sel then
cam.x=(cam.x-180)*t+180;cam.y=cam.y*t
else
cam.x=cam.x*t;cam.y=cam.y*t
end
cam.k=k
cam.keyCtrl=false
end
function mouseMove.mode(x,y,dx,dy)
if ms.isDown(1)then
mapCam.x,mapCam.y=mapCam.x-dx,mapCam.y-dy
end
mapCam.keyCtrl=false
end
function mouseClick.mode(x,y,k)
local cam=mapCam
local _=cam.sel
if not cam.sel or x<920 then
local __=onMode(x,y)
if __ and _~=__ then
SFX("click")
cam.moving=true
_=modes[__]
cam.x,cam.y=_.x*cam.k+180,_.y*cam.k
end
cam.sel=__
end
cam.keyCtrl=false
end
function touchMove.mode(id,x,y,dx,dy)
local L=tc.getTouches()
if not L[2]then
mapCam.x,mapCam.y=mapCam.x-dx,mapCam.y-dy
elseif not L[3]then
x,y=xOy:inverseTransformPoint(tc.getPosition(L[1]))
dx,dy=xOy:inverseTransformPoint(tc.getPosition(L[2]))--dx,dy not Δ!
local d=(x-dx)^2+(y-dy)^2
if d>100 then
d=d^.5
if touchDist then
wheelMoved.mode(nil,(d-touchDist)*.02)
end
touchDist=d
end
end
mapCam.keyCtrl=false
end
function touchClick.mode(x,y,id)
mouseClick.mode(x,y,1)
end
function keyDown.mode(key)
if key=="down"then
if modeSel<#modeID then
modeSel=modeSel+1
levelSel=1
SFX("move",.4)
if key=="return"then
if mapCam.sel then
mapCam.keyCtrl=false
scene.push()loadGame(mapCam.sel)
end
elseif key=="up"then
if modeSel>1 then
modeSel=modeSel-1
levelSel=1
SFX("move",.4)
end
elseif key=="left"then
if levelSel>1 then
levelSel=levelSel-1
end
elseif key=="right"then
if levelSel<#modes[modeID[modeSel]].level then
levelSel=levelSel+1
end
elseif key=="return"then
scene.push()loadGame(modeSel,levelSel)
elseif key=="c"then
scene.push()
scene.swapTo("custom")
elseif key=="escape"then
scene.back()
if mapCam.sel then
mapCam.sel=nil
else
scene.back()
end
elseif mapCam.sel==71 or mapCam.sel==72 then
if key=="q"then
scene.push()scene.swapTo("draw")
elseif key=="e"then
scene.push()scene.swapTo("custom")
end
end
end
function wheelmoved.music(x,y)
function wheelMoved.music(x,y)
if y>0 then
keyDown.music("up")
elseif y<0 then
@@ -280,13 +348,6 @@ function keyDown.custom(key)
sceneTemp=sel%#customID+1
elseif key=="up"then
sceneTemp=(sel-2)%#customID+1
elseif key=="d"then
scene.push()
scene.swapTo("draw")
elseif key=="return"then
scene.push()loadGame(0,1)
elseif key=="space"then
scene.push()loadGame(0,2)
elseif key=="1"then
Widget.custom.set1.code()
elseif key=="2"then
@@ -314,7 +375,7 @@ function mouseMove.draw(x,y,dx,dy)
preField[sy][sx]=ms.isDown(1)and sceneTemp.pen or ms.isDown(2)and -1 or 0
end
end
function wheelmoved.draw(x,y)
function wheelMoved.draw(x,y)
local pen=sceneTemp.pen
if y<0 then
pen=pen+1
@@ -371,6 +432,10 @@ function keyDown.draw(key)
end
elseif key=="escape"then
scene.back()
elseif key=="c"then
if kb.isDown("lctrl","rctrl")then copyBoard()end
elseif key=="v"then
if kb.isDown("lctrl","rctrl")then pasteBoard()end
else
pen=penKey[key]or pen
end
@@ -631,14 +696,14 @@ function gamepadUp.play(key)
end
end
function wheelmoved.history(x,y)
function wheelMoved.history(x,y)
wheelScroll(y)
end
function keyDown.history(key)
if key=="up"then
sceneTemp=max(sceneTemp-10,1)
sceneTemp[2]=max(sceneTemp[2]-10,1)
elseif key=="down"then
sceneTemp=min(sceneTemp+10,#updateLog-22)
sceneTemp[2]=min(sceneTemp[2]+10,#sceneTemp[1]-22)
elseif key=="escape"then
scene.back()
end
@@ -722,6 +787,7 @@ local function widgetControl_gamepad(i)
end
end
end
local lastX,lastY--last clickDown pos
function love.mousepressed(x,y,k,t,num)
if devMode>0 then print(x,y)end
if t then return end
@@ -736,6 +802,8 @@ function love.mousepressed(x,y,k,t,num)
widgetPress(widget_sel,mx,my)
end
end
lastX=mx
lastY=my
mouseShow=true
end
function love.mousemoved(x,y,dx,dy,t)
@@ -764,9 +832,12 @@ function love.mousereleased(x,y,k,t,num)
if mouseUp[scene.cur]then
mouseUp[scene.cur](mx,my,k)
end
if(mx-lastX)^2+(my-lastY)^2<26 and mouseClick[scene.cur]then
mouseClick[scene.cur](mx,my,k)
end
end
function love.wheelmoved(x,y)
if wheelmoved[scene.cur]then wheelmoved[scene.cur](x,y)end
if wheelMoved[scene.cur]then wheelMoved[scene.cur](x,y)end
end
function love.touchpressed(id,x,y)
@@ -775,8 +846,10 @@ function love.touchpressed(id,x,y)
touching=id
love.touchmoved(id,x,y,0,0)
end
touchDist=nil--reset distance
lastX,lastY=xOy:inverseTransformPoint(x,y)
if touchDown[scene.cur]then
touchDown[scene.cur](id,xOy:inverseTransformPoint(x,y))
touchDown[scene.cur](id,lastX,lastY)
end
end
function love.touchmoved(id,x,y,dx,dy)
@@ -811,6 +884,9 @@ function love.touchreleased(id,x,y)
if touchUp[scene.cur]then
touchUp[scene.cur](id,x,y)
end
if(x-lastX)^2+(y-lastY)^2<26 and touchClick[scene.cur]then
touchClick[scene.cur](x,y,k)
end
end
function love.keypressed(i)
mouseShow=false
@@ -901,9 +977,6 @@ function love.focus(f)
if system~="Android" and not f and scene.cur=="play"then pauseGame()end
end
function love.update(dt)
-- if players then for k,v in pairs(players[1])do
-- if rawget(_G,k)and k~="next"and k~="hold"and k~="stat"then print(k,_G[v])end
-- end end--check player data flew
for i=#sysFX,1,-1 do
local S=sysFX[i]
S[2]=S[2]+1
@@ -943,8 +1016,10 @@ function love.update(dt)
if S.time==S.mid then
scene.cur=S.tar
scene.init(S.tar)
for _,W in next,Widget[S.tar]do
W:reset()
end--重置控件
widget_sel=nil
texts={}
collectgarbage()
--此时场景切换
end
@@ -967,18 +1042,18 @@ function love.update(dt)
if Q.s==0 then--闲置轨,自动删除多余
if i>3 then
local _=voiceQueue
for i=i,#_ do
::L::
_[i]=_[i+1]
end
if _[i]then i=i+1 goto L end
end
elseif Q.s==1 then--等待转换
Q[1]=getVoice(Q[1])
Q[1]:setVolume(setting.voc*.1)
Q[1]:play()
Q.s=Q[2]and 2 or 4
elseif Q.s==2 then--播放1,等待2
elseif Q.s==2 then--播放1,准备2
if Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=getVoice(Q[2])
Q[2]=getVoice(Q[2])--Bug:no voice called Q[2](may fixed)
Q[2]:setVolume(setting.voc*.1)
Q[2]:play()
Q.s=3
@@ -991,27 +1066,13 @@ function love.update(dt)
Q.s=Q[2]and 2 or 4
end
elseif Q.s==4 then--最后播放
if not Q[1]:isPlaying()then
if not Q[1].isPlaying(Q[1])then--Bug:Q[1] is nil
Q[1]=nil
Q.s=0
end
end
if #Q>0 then
if Q[1]:isPlaying()then
if Q[2]and type(Q[2])=="string"and Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=getVoice(Q[2])
end
--快放完了,播放下一个
else
for i=1,#Q do
Q[i]=Q[i+1]
end
--放完了,移除
end
else
end
end
for k,W in next,Widget[scene.cur]do
for _,W in next,Widget[scene.cur]do
W:update()
end--更新控件
end
@@ -1036,7 +1097,7 @@ function love.draw()
W:draw()
end
end--Draw widgets
if mouseShow and not touching then
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
@@ -1109,7 +1170,7 @@ function love.run()
for N,a,b,c,d,e in POLL()do
if N=="quit"then
destroyPlayers()
saveData()
saveStat()
saveSetting()
goto END
elseif love[N]then
@@ -1140,12 +1201,32 @@ function love.run()
end
::END::
end
userData,userSetting=love.filesystem.newFile("userdata"),love.filesystem.newFile("usersetting")
if love.filesystem.getInfo("userdata")then
loadData()
-------------------------------------------------------------
local F=love.filesystem
if F.getInfo("data")then
F.write("data.dat",F.read("data"))
F.remove("data")
end
if love.filesystem.getInfo("usersetting")then
if F.getInfo("userdata")then
F.write("data.dat",F.read("userdata"))
F.remove("userdata")
end
if F.getInfo("setting")then
F.write("setting.dat",F.read("setting"))
F.remove("setting")
end
if F.getInfo("usersetting")then
F.write("setting.dat",F.read("usersetting"))
F.remove("usersetting")
end
--NEW FILENAME!!!
FILE={
data=F.newFile("data.dat"),
setting=F.newFile("setting.dat"),
vk=F.newFile("vk"),
}
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

68
modes/GM.lua Normal file
View File

@@ -0,0 +1,68 @@
local int,max,min=math.floor,math.max,math.min
local sectionName={"M7","M8","M9","M","MK","MV","MO","MM","GM"}
local function score(P)
local F=false
if P.modeData.point<70 then--if Less then MM
local R=#P.cleared
if R==4 then R=10 end
P.modeData.point=P.modeData.point+R
P.modeData.event=sectionName[int(P.modeData.point*.1)+1]
end
end
return{
name={
"大师",
"大师",
"GM",
},
level={
"",
"",
"",
},
info={
"成为方块大师",
"成为方块大师",
"To be Grand Master",
},
color=color.lightBlue,
env={
_20G=true,
drop=0,lock=15,
wait=10,fall=15,
next=3,
visible="fast",
freshLimit=15,
dropPiece=score,
task=function(P)
if P.stat.time>=53.5 then
P.modeData.point=min(P.modeData.point+16,80)
P.modeData.event=sectionName[int(P.modeData.point*.1)+1]
Event.win(P,"finish")
end
end,
arr=1,
bg="game3",bgm="shining terminal",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
mDraw(drawableText.line,-82,300)
mDraw(drawableText.techrash,-82,420)
mDraw(drawableText.grade,-82,170)
setFont(55)
mStr(P.modeData.event,-82,110)
setFont(75)
mStr(P.stat.row,-82,220)
mStr(P.stat.clear_4,-82,340)
end,
score=function(P)return{P.modeData.point,P.stat.score}end,
scoreDisp=function(D)return sectionName[int(D[1]*.1)+1].." "..D[2]end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local P=P.modeData.point
return P==80 and 5 or P>=70 and 4 or P>=60 and 3 or P>=40 and 2 or P>=20 and 1
end,
}

72
modes/attacker_hard.lua Normal file
View File

@@ -0,0 +1,72 @@
local int,rnd=math.floor,math.random
return{
name={
"进攻",
"进攻",
"Attacker",
},
level={
"困难",
"困难",
"HARD",
},
info={
"进攻练习",
"进攻练习",
"Attacking better then defending",
},
color=color.magenta,
env={
drop=30,lock=60,
fall=12,
freshLimit=15,
pushSpeed=2,
task=function(P)
if not P.control then return end
if P.atkBuffer.sum==0 then
local p=#P.atkBuffer+1
local B,D=P.atkBuffer,P.modeData
local t
if D.event<20 then
t=1500-30*D.event--1500~900
B[p]= {pos=rnd(4,7),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=3}
B[p+1]= {pos=rnd(3,8),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=4}
else
t=900-10*(D.event-20)--900~600
B[p]= {pos=rnd(10),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=4}
B[p+1]= {pos=rnd(4,7),amount=8,countdown=t,cd0=t,time=0,sent=false,lv=5}
end
B.sum=B.sum+22
P.stat.recv=P.stat.recv+22
if D.event<50 then
D.event=D.event+1
D.point=int(72e4/t)*.1
if D.event==20 then
P:showText(text.great,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=3
elseif D.event==50 then
P:showText(text.maxspeed,0,-140,100,"appear",.6)
end
end
end
end,
bg="game3",bgm="push",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(55)
mStr(P.modeData.event,-82,200)
mStr("24",-82,320)
mDraw(drawableText.wave,-82,260)
mDraw(drawableText.nextWave,-82,380)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modedata.event
return W>100 and 4 or W>=80 and 3 or W>=50 and 2 or W>=20 and 1
end,
}

View File

@@ -0,0 +1,85 @@
local int,rnd=math.floor,math.random
return{
name={
"进攻",
"进攻",
"Attacker",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"进攻练习",
"进攻练习",
"Attacking better then defending",
},
color=color.lightYellow,
env={
drop=5,lock=60,
fall=8,
freshLimit=15,
task=function(P)
if not P.control then return end
if P.atkBuffer.sum<2 then
local p=#P.atkBuffer+1
local B,D=P.atkBuffer,P.modeData
local s,t
if D.event<10 then
t=1000-20*D.event--1000~800
B[p]= {pos=rnd(5,6),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=3}
B[p+1]= {pos=rnd(4,7),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=4}
s=22
elseif D.event<20 then
t=800-20*(D.event-15)--800~600
B[p]= {pos=rnd(3,8),amount=11,countdown=t,cd0=t,time=0,sent=false,lv=4}
B[p+1]= {pos=rnd(4,7),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=5}
s=25
else
t=600-15*(D.event-30)--600~450
B[p]= {pos=rnd(2)*9-8,amount=12,countdown=t,cd0=t,time=0,sent=false,lv=5}
B[p+1]= {pos=rnd(3,8),amount=16,countdown=t,cd0=t,time=0,sent=false,lv=5}
s=28
end
B.sum=B.sum+s
P.stat.recv=P.stat.recv+s
if D.event<45 then
D.event=D.event+1
D.point=int(s*36e3/t)*.1
if D.event==10 then
P:showText(text.great,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=4
elseif D.event==20 then
P:showText(text.awesome,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=5
elseif D.event==30 then
P:showText(text.maxspeed,0,-140,100,"appear",.6)
end
end
end
end,
bg="game4",bgm="shining terminal",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(55)
mStr(P.modeData.event,-82,200)
mStr(
P.modeData.event<10 and 22
or P.modeData.event<20 and 25
or 28
,-82,320)
mDraw(drawableText.wave,-82,260)
mDraw(drawableText.nextWave,-82,380)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modedata.event
return W>40 and 4 or W>=30 and 3 or W>=20 and 2 or W>=10 and 1
end,
}

53
modes/bigbang.lua Normal file
View File

@@ -0,0 +1,53 @@
local format=string.format
local function getField()
local F={}
return F
end
local function newField(P)
end
return{
name={
"大爆炸",
"大爆炸",
"Big Bang",
},
level={
"简单",
"简单",
"EASY",
},
info={
"All-spin 入门教程",
"All-spin 入门教程",
"All-spin Tutorial!",
},
color=color.grey,
env={
drop=1e99,lock=1e99,
hold=false,
dropPiece=Event.lose,
task=nil,
bg="game1",bgm="newera",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(50)
mStr("UNFINISHED",150,100)
end,
score=function(P)return{P.modeData.event,P.stat.extraRate}end,
scoreDisp=function(D)return D[1].."Stage "..format("%.2f",D[2]).."%"end,
comp=function(a,b)return a[1]>b[1]end,
getRank=function(P)
local W=P.modeData.event
return
W>=150 and 5 or
W>=100 and 4 or
W>=70 and 3 or
W>=40 and 2 or
W>=20 and 1 or
1
end,
}

54
modes/blind_easy.lua Normal file
View File

@@ -0,0 +1,54 @@
return{
name={
"隐形",
"隐形",
"Blind",
},
level={
"半隐",
"半隐",
"HALF",
},
info={
"最强大脑",
"最强大脑",
"Invisible board",
},
color=color.cyan,
env={
drop=30,lock=45,
visible="time",
dropPiece=Event.reach_winCheck,
freshLimit=10,
target=200,
bg="glow",bgm="newera",
},
load=function()
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)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=140 and 5 or
T<=200 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1
end
end,
}

56
modes/blind_hard.lua Normal file
View File

@@ -0,0 +1,56 @@
return{
name={
"隐形",
"隐形",
"Blind",
},
level={
"瞬隐",
"瞬隐",
"SUDDEN",
},
info={
"最强大脑",
"最强大脑",
"Invisible board",
},
color=color.magenta,
env={
drop=15,lock=45,
fall=10,lock=60,
center=false,
visible="none",
dropPiece=Event.reach_winCheck,
freshLimit=15,
target=200,
bg="rgb",bgm="secret7th",
},
load=function()
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)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=150 and 5 or
T<=210 and 4 or
3
else
return
L>=150 and 3 or
L>=90 and 2 or
L>=40 and 1
end
end,
}

56
modes/blind_lunatic.lua Normal file
View File

@@ -0,0 +1,56 @@
return{
name={
"隐形",
"隐形",
"Blind",
},
level={
"瞬隐+",
"瞬隐+",
"SUDDEN+",
},
info={
"最强大脑",
"最强大脑",
"Invisible board",
},
color=color.red,
env={
drop=10,lock=60,
fall=5,
center=false,ghost=false,
visible="none",
dropPiece=Event.reach_winCheck,
freshLimit=15,
target=200,
bg="rgb",bgm="secret8th",
},
load=function()
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)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=240 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1
end
end,
}

55
modes/blind_normal.lua Normal file
View File

@@ -0,0 +1,55 @@
return{
name={
"隐形",
"隐形",
"Blind",
},
level={
"全隐",
"全隐",
"ALL",
},
info={
"最强大脑",
"最强大脑",
"Invisible board",
},
color=color.green,
env={
drop=15,lock=45,
freshLimit=10,
visible="fast",
dropPiece=Event.reach_winCheck,
freshLimit=10,
target=200,
bg="glow",bgm="reason",
},
load=function()
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)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=150 and 5 or
T<=210 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1
end
end,
}

51
modes/blind_ultimate.lua Normal file
View File

@@ -0,0 +1,51 @@
return{
name={
"隐形",
"隐形",
"Blind",
},
level={
"啥都不剩隐",
"啥都不剩隐",
"NOTHING",
},
info={
"最强大脑",
"最强大脑",
"Invisible board",
},
color=color.red,
env={
drop=30,lock=60,
fall=5,
block=false,
center=false,ghost=false,
visible="none",
dropPiece=Event.reach_winCheck,
freshLimit=15,
target=200,
bg="rgb",bgm="secret7th",
},
load=function()
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)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L>=100 and 4 or
L>=50 and 3 or
L>=26 and 2 or
L>=10 and 1
end,
}

View File

@@ -0,0 +1,86 @@
local rnd=math.random
local function check_c4w(P)
for i=1,#P.cleared do
P.field[#P.field+1]=getNewRow(10)
P.visTime[#P.visTime+1]=getNewRow(20)
for i=4,7 do P.field[#P.field][i]=0 end
end
if #P.cleared==0 then
Event.lose(P)
else
if P.combo>P.modeData.point then
P.modeData.point=P.combo
end
if P.stat.row>=100 then
Event.win(P,"finish")
end
end
end
return{
name={
"C4W练习",
"中四宽练习",
"C4W Train",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"无 限 连 击",
"无 限 连 击",
"Infinite combo",
},
color=color.red,
env={
drop=5,lock=30,
dropPiece=check_c4w,
freshLimit=15,ospin=false,
bg="rgb",bgm="newera",
},
load=function()
newPlayer(1,340,15)
local P=players[1]
local F=P.field
for i=1,24 do
F[i]=getNewRow(10)
P.visTime[i]=getNewRow(20)
for x=4,7 do F[i][x]=0 end
end
local r=rnd(6)
if r==1 then F[1][5],F[1][4],F[2][4]=10,10,10
elseif r==2 then F[1][6],F[1][7],F[2][7]=10,10,10
elseif r==3 then F[1][4],F[2][4],F[2][5]=10,10,10
elseif r==4 then F[1][7],F[2][7],F[2][6]=10,10,10
elseif r==5 then F[1][4],F[1][5],F[1][6]=10,10,10
elseif r==6 then F[1][7],F[1][6],F[1][5]=10,10,10
end
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.combo,-82,310)
mStr(P.modeData.point,-82,400)
mDraw(drawableText.combo,-82,358)
mDraw(drawableText.mxcmb,-82,450)
end,
score=function(P)return{P.combo<=100 and P.combo or 100,P.stat.time}end,
scoreDisp=function(D)return D[1].." Combo "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.modeData.point
if L==100 then
local T=P.stat.time
return
T<=40 and 5 or
T<=60 and 4 or
3
else
return
L>=70 and 3 or
L>=40 and 2 or
L>=20 and 1
end
end,
}

84
modes/c4wtrain_normal.lua Normal file
View File

@@ -0,0 +1,84 @@
local rnd=math.random
local function check_c4w(P)
for i=1,#P.cleared do
P.field[#P.field+1]=getNewRow(10)
P.visTime[#P.visTime+1]=getNewRow(20)
for i=4,7 do P.field[#P.field][i]=0 end
end
if #P.cleared>0 then
if P.combo>P.modeData.point then
P.modeData.point=P.combo
end
if P.stat.row>=100 then
Event.win(P,"finish")
end
end
end
return{
name={
"C4W练习",
"中四宽练习",
"C4W Train",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"无 限 连 击",
"无 限 连 击",
"Infinite combo",
},
color=color.green,
env={
drop=30,lock=60,oncehold=false,
dropPiece=check_c4w,
freshLimit=15,ospin=false,
bg="rgb",bgm="newera",
},
load=function()
newPlayer(1,340,15)
local P=players[1]
local F=P.field
for i=1,24 do
F[i]=getNewRow(10)
P.visTime[i]=getNewRow(20)
for x=4,7 do F[i][x]=0 end
end
local r=rnd(6)
if r==1 then F[1][5],F[1][4],F[2][4]=10,10,10
elseif r==2 then F[1][6],F[1][7],F[2][7]=10,10,10
elseif r==3 then F[1][4],F[2][4],F[2][5]=10,10,10
elseif r==4 then F[1][7],F[2][7],F[2][6]=10,10,10
elseif r==5 then F[1][4],F[1][5],F[1][6]=10,10,10
elseif r==6 then F[1][7],F[1][6],F[1][5]=10,10,10
end
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.combo,-82,310)
mStr(P.modeData.point,-82,400)
mDraw(drawableText.combo,-82,358)
mDraw(drawableText.mxcmb,-82,450)
end,
score=function(P)return{P.modeData.point<=100 and P.modeData.point or 100,P.stat.time}end,
scoreDisp=function(D)return D[1].." Combo "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==100 then
local T=P.stat.time
return
T<=30 and 5 or
T<=50 and 4 or
T<=80 and 3 or
2
else
return
L>=60 and 2 or
L>=30 and 1
end
end,
}

68
modes/classic_fast.lua Normal file
View File

@@ -0,0 +1,68 @@
local gc=love.graphics
local function check_LVup(P)
if P.stat.row>=P.gameEnv.target then
P.gameEnv.target=P.gameEnv.target+10
if P.gameEnv.target==110 then
P.gameEnv.drop,P.gameEnv.lock=2,2
elseif P.gameEnv.target==200 then
P.gameEnv.drop,P.gameEnv.lock=1,1
end
if P.gameEnv.target>100 then
SFX("reach")
end
end
end
return{
name={
"高速经典",
"高速经典",
"Classic",
},
level={
"CTWC",
"锦标赛",
"CTWC",
},
info={
"高速经典",
"高速经典",
"Vintage car drag racing",
},
color=color.lightBlue,
env={
das=16,arr=6,sddas=2,sdarr=2,
ghost=false,center=false,
drop=3,lock=3,wait=10,fall=25,
next=1,hold=false,
sequence="rnd",
freshLimit=0,
target=10,dropPiece=check_LVup,
bg="rgb",bgm="rockblock",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(75)
local r=P.gameEnv.target*.1
mStr(r<11 and 18 or r<22 and r+8 or r==22 and"00"or r==23 and"0a"or format("%x",r*10-220),-82,210)
mDraw(drawableText.speedLV,-82,290)
setFont(45)
mStr(P.stat.row,-82,320)
mStr(P.gameEnv.target,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.stat.row,P.stat.score}end,
scoreDisp=function(D)return D[1].." Rows "..D[2]end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local L=P.stat.row
return
L>=200 and 5 or
L>=191 and 4 or
L>=110 and 3 or
L>=50 and 2 or
L>=2 and 1
end,
}

80
modes/custom_clear.lua Normal file
View File

@@ -0,0 +1,80 @@
local gc=love.graphics
local int=math.floor
return{
name={
"自定义",
"自定义",
"Custom",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"画点什么然后把它消除!",
"画点什么然后把它消除!",
"Draw something then clear it!",
},
color=color.white,
env={
dropPiece=Event.reach_winCheck,
},
load=function()
for i=1,#customID do
local k=customID[i]
modeEnv[k]=customRange[k][customSel[i]]
end
modeEnv._20G=modeEnv.drop==0
modeEnv.oncehold=customSel[6]==1
newPlayer(1,340,15)
local L=modeEnv.opponent
if L~=0 then
modeEnv.target=nil
if L<10 then
newPlayer(2,965,360,.5,AITemplate("9S",2*L))
else
newPlayer(2,965,360,.5,AITemplate("CC",L-6,2+int((L-11)*.5),modeEnv.hold,15000+5000*(L-10)))
end
end
preField.h=20
repeat
for i=1,10 do
if preField[preField.h][i]>0 then
goto L
end
end
preField.h=preField.h-1
until preField.h==0
::L::
for _,P in next,players.alive do
local t=P.showTime*3
for y=1,preField.h do
P.field[y]=getNewRow(0)
P.visTime[y]=getNewRow(t)
for x=1,10 do P.field[y][x]=preField[y][x]end
end
end
modeEnv.bg=customRange.bg[customSel[12]]
modeEnv.bgm=customRange.bgm[customSel[13]]
end,
mesDisp=function(P,dx,dy)
setFont(55)
if P.gameEnv.puzzle or P.gameEnv.target>1e10 then
mStr(P.stat.row,-82,225)
mDraw(drawableText.line,-82,290)
else
local R=P.gameEnv.target-P.stat.row
mStr(R>=0 and R or 0,-82,240)
end
if P.gameEnv.puzzle and P.modeData.event==0 then
local m=puzzleMark
for y=1,preField.h do for x=1,10 do
local T=preField[y][x]
if T~=0 then
gc.draw(m[T],30*x-30+dx,600-30*y+dy)
end
end end
end
end,
}

88
modes/custom_puzzle.lua Normal file
View File

@@ -0,0 +1,88 @@
local gc=love.graphics
local int=math.floor
local function puzzleCheck(P)
for y=1,20 do
local L=P.field[y]
for x=1,10 do
local a,b=preField[y][x],L and L[x]or 0
if a~=0 then
if a==-1 then if b>0 then return end
elseif a<8 then if a~=b then return end
elseif a>7 then if b==0 then return end
end
end
end
end
P.modeData.event=1
Event.win(P,"finish")
end
return{
name={
"自定义",
"自定义",
"Custom",
},
level={
"拼图",
"拼图",
"PUZZLE",
},
info={
"画点什么然后把它拼出来吧!",
"画点什么然后把它拼出来吧!",
"Draw something then stack it!",
},
color=color.white,
env={
puzzle=true,
Fkey=function(P)P.modeData.event=1-P.modeData.event end,
dropPiece=puzzleCheck,
},
load=function()
for i=1,#customID do
local k=customID[i]
modeEnv[k]=customRange[k][customSel[i]]
end
modeEnv._20G=modeEnv.drop==0
modeEnv.oncehold=customSel[6]==1
modeEnv.target=0
newPlayer(1,340,15)
local L=modeEnv.opponent
if L~=0 then
modeEnv.target=nil
if L<10 then
newPlayer(2,965,360,.5,AITemplate("9S",2*L))
else
newPlayer(2,965,360,.5,AITemplate("CC",L-6,2+int((L-11)*.5),modeEnv.hold,15000+5000*(L-10)))
end
end
preField.h=20
repeat
for i=1,10 do
if preField[preField.h][i]~=0 then
goto L
end
end
preField.h=preField.h-1
until preField.h==0
::L::
modeEnv.bg=customRange.bg[customSel[12]]
modeEnv.bgm=customRange.bgm[customSel[13]]
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
mStr(P.stat.row,-82,225)
mDraw(drawableText.line,-82,290)
if P.gameEnv.puzzle and P.modeData.event==0 then
local m=puzzleMark
for y=1,preField.h do for x=1,10 do
local T=preField[y][x]
if T~=0 then
gc.draw(m[T],30*x-30+dx,600-30*y+dy)
end
end end
end
end,
}

View File

@@ -0,0 +1,78 @@
local int,rnd=math.floor,math.random
return{
name={
"防守",
"防守",
"Defender",
},
level={
"疯狂",
"疯狂",
"Lunatic",
},
info={
"防守练习",
"防守练习",
"Hand them!",
},
color=color.red,
env={
drop=5,lock=60,
fall=6,
freshLimit=15,
pushSpeed=2,
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
local t=240-2*P.modeData.event
if P.modeData.counter>=t then
P.modeData.counter=0
for _=1,4 do
P.atkBuffer[#P.atkBuffer+1]={pos=rnd(10),amount=1,countdown=5*t,cd0=5*t,time=0,sent=false,lv=2}
end
P.atkBuffer.sum=P.atkBuffer.sum+4
P.stat.recv=P.stat.recv+4
local D=P.modeData
if D.event<75 then
D.event=D.event+1
D.point=int(144e3/(240-2*D.event))*.1
if D.event==25 then
P:showText(text.great,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=3
P.dropDelay,P.gameEnv.drop=4,4
elseif D.event==50 then
P:showText(text.awesome,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=4
P.dropDelay,P.gameEnv.drop=3,3
elseif D.event==75 then
P:showText(text.maxspeed,0,-140,100,"appear",.6)
P.dropDelay,P.gameEnv.drop=2,2
end
end
end
end,
bg="game4",bgm="way",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(55)
mStr(P.modeData.event,-82,200)
mStr(P.modeData.point,-82,320)
mDraw(drawableText.wave,-82,260)
mDraw(drawableText.rpm,-82,380)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=100 and 5 or
W>=80 and 4 or
W>=55 and 3 or
W>=30 and 2 or
W>=20 and 1
end,
}

78
modes/defender_normal.lua Normal file
View File

@@ -0,0 +1,78 @@
local int,rnd=math.floor,math.random
return{
name={
"防守",
"防守",
"Defender",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"防守练习",
"防守练习",
"Hand them!",
},
color=color.green,
env={
drop=30,lock=60,
fall=10,
freshLimit=15,
pushSpeed=1,
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
local t=360-P.modeData.event*2
if P.modeData.counter>=t then
P.modeData.counter=0
for _=1,3 do
P.atkBuffer[#P.atkBuffer+1]={pos=rnd(2,9),amount=1,countdown=2*t,cd0=2*t,time=0,sent=false,lv=1}
end
P.atkBuffer.sum=P.atkBuffer.sum+3
P.stat.recv=P.stat.recv+3
local D=P.modeData
if D.event<90 then
D.event=D.event+1
D.point=int(108e3/(360-D.event*2))*.1
if D.event==25 then
P:showText(text.great,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=2
P.dropDelay,P.gameEnv.drop=20,20
elseif D.event==50 then
P:showText(text.awesome,0,-140,100,"appear",.6)
P.gameEnv.pushSpeed=3
P.dropDelay,P.gameEnv.drop=10,10
elseif D.event==90 then
P.dropDelay,P.gameEnv.drop=5,5
P:showText(text.maxspeed,0,-140,100,"appear",.6)
end
end
end
end,
bg="game3",bgm="way",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(55)
mStr(P.modeData.event,-82,200)
mStr(P.modeData.point,-82,320)
mDraw(drawableText.wave,-82,260)
mDraw(drawableText.rpm,-82,380)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=120 and 5 or
W>=100 and 4 or
W>=70 and 3 or
W>=40 and 2 or
W>=10 and 1
end,
}

54
modes/dig_hard.lua Normal file
View File

@@ -0,0 +1,54 @@
local max,rnd=math.max,math.random
return{
name={
"挖掘",
"挖掘",
"Dig",
},
level={
"困难",
"困难",
"HARD",
},
info={
"挖掘练习",
"挖掘练习",
"Downstack!",
},
color=color.magenta,
env={
drop=60,lock=120,
fall=20,
freshLimit=15,
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(90,180-P.modeData.event)then
P.modeData.counter=0
P:garbageRise(10,1,rnd(10))
P.modeData.event=P.modeData.event+1
end
end,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(65)
mStr(P.modeData.event,-82,310)
mDraw(drawableText.wave,-82,375)
end,
score=function(P)return{P.modeData.event,P.stat.row}end,
scoreDisp=function(D)return D[1].." Waves "..D[2].." Rows"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=150 and 5 or
W>=110 and 4 or
W>=80 and 3 or
W>=50 and 2 or
W>=20 and 1
end,
}

53
modes/dig_ultimate.lua Normal file
View File

@@ -0,0 +1,53 @@
local max,rnd=math.max,math.random
return{
name={
"挖掘",
"挖掘",
"Dig",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"挖掘练习",
"挖掘练习",
"Downstack!",
},
color=color.lightYellow,
env={
drop=10,lock=30,
freshLimit=15,
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(45,80-.3*P.modeData.event)then
P.modeData.counter=0
P:garbageRise(11+P.modeData.event%3,1,rnd(10))
P.modeData.event=P.modeData.event+1
end
end,
bg="game2",bgm="secret7th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(65)
mStr(P.modeData.event,-82,310)
mDraw(drawableText.wave,-82,375)
end,
score=function(P)return{P.modeData.event,P.stat.row}end,
scoreDisp=function(D)return D[1].." Waves "..D[2].." Rows"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=120 and 5 or
W>=100 and 4 or
W>=80 and 3 or
W>=50 and 2 or
W>=20 and 1
end,
}

47
modes/drought_lunatic.lua Normal file
View File

@@ -0,0 +1,47 @@
return{
name={
"干旱",
"干旱",
"Drought",
},
level={
"100L",
"100行",
"100L",
},
info={
"后 妈 发 牌",
"后 妈 发 牌",
"ERRSEQ flood attack",
},
color=color.red,
env={
drop=20,lock=60,
sequence="drought2",
target=100,dropPiece=Event.reach_winCheck,
ospin=false,
freshLimit=15,
bg="glow",bgm="reason",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(70)
local R=100-P.stat.row
mStr(R>=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,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<100 then return end
local T=P.stat.time
return
T<=70 and 5 or
T<=110 and 4 or
T<=160 and 3 or
T<=240 and 2 or
1
end,
}

47
modes/drought_normal.lua Normal file
View File

@@ -0,0 +1,47 @@
return{
name={
"干旱",
"干旱",
"Drought",
},
level={
"100L",
"100行",
"100L",
},
info={
"你I没了",
"你I没了",
"B a g 6",
},
color=color.green,
env={
drop=20,lock=60,
sequence="drought1",
target=100,dropPiece=Event.reach_winCheck,
ospin=false,
freshLimit=15,
bg="glow",bgm="reason",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(70)
local R=100-P.stat.row
mStr(R>=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,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<100 then return end
local T=P.stat.time
return
T<=65 and 5 or
T<=100 and 4 or
T<=145 and 3 or
T<=220 and 2 or
1
end,
}

29
modes/hotseat_2P.lua Normal file
View File

@@ -0,0 +1,29 @@
return{
name={
"本地多人",
"本地多人",
"Hotseat",
},
level={
"2P",
"2P",
"2P",
},
info={
"友尽模式",
"友尽模式",
"End of friendship",
},
color=color.white,
env={
drop=60,lock=60,
freshLimit=15,
bg="none",bgm="way",
},
load=function()
newPlayer(1,20,15)
newPlayer(2,650,15)
end,
mesDisp=function(P,dx,dy)
end,
}

30
modes/hotseat_3P.lua Normal file
View File

@@ -0,0 +1,30 @@
return{
name={
"本地多人",
"本地多人",
"Hotseat",
},
level={
"3P",
"3P",
"3P",
},
info={
"友尽模式",
"友尽模式",
"End of friendship",
},
color=color.white,
env={
drop=60,lock=60,
freshLimit=15,
bg="none",bgm="way",
},
load=function()
newPlayer(1,20,100,.65)
newPlayer(2,435,100,.65)
newPlayer(3,850,100,.65)
end,
mesDisp=function(P,dx,dy)
end,
}

31
modes/hotseat_4P.lua Normal file
View File

@@ -0,0 +1,31 @@
return{
name={
"本地多人",
"本地多人",
"Hotseat",
},
level={
"4P",
"4P",
"4P",
},
info={
"友尽模式",
"友尽模式",
"End of friendship",
},
color=color.white,
env={
drop=60,lock=60,
freshLimit=15,
bg="none",bgm="way",
},
load=function()
newPlayer(1,25,160,.5)
newPlayer(2,335,160,.5)
newPlayer(3,645,160,.5)
newPlayer(4,955,160,.5)
end,
mesDisp=function(P,dx,dy)
end,
}

46
modes/infinite.lua Normal file
View File

@@ -0,0 +1,46 @@
local format=string.format
return{
name={
"无尽",
"无尽",
"Infinite",
},
level={
"时间杀手 II",
"时间杀手 II",
"Time Killer II",
},
info={
"沙盒",
"沙盒",
"Sandbox",
},
color=color.lightGrey,
env={
drop=1e99,lock=1e99,
oncehold=false,
bg="glow",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,260)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,370)
mDraw(drawableText.atk,-82,313)
mDraw(drawableText.eff,-82,425)
end,
score=function(P)return{P.stat.score}end,
scoreDisp=function(D)return D[1]end,
comp=function(a,b)return a[1]>b[1]end,
getRank=function(P)
local L=P.stat.row
return
L>=2600 and 5 or
L>=1500 and 4 or
L>=1000 and 3 or
L>=500 and 2 or
L>=100 and 1
end,
}

63
modes/infinite_dig.lua Normal file
View File

@@ -0,0 +1,63 @@
local format,rnd=string.format,math.random
local function check_rise(P)
local L=P.cleared
for i=1,#L do
if L[i]<6 then
P:garbageRise(10,1,rnd(10))
P.modeData.point=P.modeData.point+1
end
end
end
return{
name={
"无尽:挖掘",
"无尽:挖掘",
"Infinite:dig",
},
level={
"时间杀手 III",
"时间杀手 III",
"Time Killer III",
},
info={
"挖呀挖呀挖",
"挖呀挖呀挖",
"Dig to Nether?",
},
color=color.white,
env={
drop=1e99,lock=1e99,
oncehold=false,
dropPiece=check_rise,
pushSpeed=1,
bg="glow",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
for _=1,5 do
players[1]:garbageRise(10,1,rnd(10))
end
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.modeData.point,-82,190)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.line,-82,243)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.modeData.point}end,
scoreDisp=function(D)return D[1].." Rows"end,
comp=function(a,b)return a[1]>b[1]end,
getRank=function(P)
local L=P.modeData.point
return
L>=626 and 5 or
L>=400 and 4 or
L>=200 and 3 or
L>=100 and 2 or
L>=10 and 1
end,
}

56
modes/marathon_hard.lua Normal file
View File

@@ -0,0 +1,56 @@
local gc=love.graphics
local function check(P)
if P.stat.row>=200 then
Event.win(P,"finish")
end
end
return{
name={
"马拉松",
"马拉松",
"Marathon",
},
level={
"困难",
"困难",
"HARD",
},
info={
"200行20G马拉松",
"200行20G马拉松",
"200L marathon in 20G",
},
color=color.magenta,
env={
_20G=true,fall=15,
dropPiece=check,
bg="strap",bgm="race",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.row,-82,320)
mStr(200,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=200 and 5 or
T<=260 and 4 or
3
else
return
L>=100 and 2 or
L>=50 and 1
end
end,
}

65
modes/marathon_normal.lua Normal file
View File

@@ -0,0 +1,65 @@
local gc=love.graphics
local marathon_drop={[0]=60,48,40,30,24,18,15,12,10,8,7,6,5,4,3,2,1,1,0,0}
local function check_LVup(P)
local T=P.modeData.point+10
if P.stat.row>=T then
if T==200 then
Event.win(P,"finish")
else
P.gameEnv.drop=marathon_drop[T/10]
if T==180 then P.gameEnv._20G=true end
SFX("reach")
P.modeData.point=T
end
end
end
return{
name={
"马拉松",
"马拉松",
"Marathon",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"200行变速马拉松",
"200行变速马拉松",
"200L marathon with acceleration",
},
color=color.green,
env={
drop=60,fall=20,
target=10,dropPiece=check_LVup,
bg="strap",bgm="way",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.row,-82,320)
mStr(P.modeData.point+10,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L==200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=240 and 4 or
3
else
return
L>=150 and 2 or
L>=100 and 1
end
end,
}

91
modes/master_adavnce.lua Normal file
View File

@@ -0,0 +1,91 @@
local gc=love.graphics
local int=math.floor
local death_lock={12,11,10,9,8}
local death_wait={10,9,8,7,6}
local death_fall={10,9,8,7,6}
local function score(P)
local c=#P.cleared
if c==0 and P.modeData.point%100==99 then return end
local s=c<3 and c+1 or c==3 and 5 or 7
if P.combo>7 then s=s+2
elseif P.combo>3 then s=s+1
end
P.modeData.point=P.modeData.point+s
if P.modeData.point%100==99 then
SFX("blip_1")
elseif P.modeData.point>=100*(P.modeData.event+1)then
local s=P.modeData.event+1;P.modeData.event=s--level up!
local E=P.gameEnv
curBG=s==1 and"game3"or s==2 and"game4"or s==3 and"game5"or s==4 and"game6"or"game5"
E.lock=death_lock[s]
E.wait=death_wait[s]
E.fall=death_fall[s]
E.das=int(6.9-s*.4)
if s==3 then P.gameEnv.bone=true end
if s==5 then
P.modeData.point,P.modeData.event=500,4
Event.win(P,"finish")
else
P:showText(text.stage(s),0,-120,80,"fly")
end
SFX("reach")
end
end
return{
name={
"大师",
"大师",
"Master",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"进阶20G",
"进阶20G",
"Advanced 20G",
},
color=color.red,
env={
_20G=true,
lock=death_lock[1],
wait=death_wait[1],
fall=death_fall[1],
dropPiece=score,
das=6,arr=1,
freshLimit=15,
bg="game2",bgm="secret7th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.modeData.point,-82,320)
mStr((P.modeData.event+1)*100,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.modeData.point,P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..D[2].."L "..toTime(D[3])end,
comp=function(a,b)
return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3]))
end,
getRank=function(P)
local L=P.stat.row
local S=P.modeData.point
if S==500 then
return
L<=260 and 5 or
L<=320 and 4 or
3
else
return
S>=426 and 3 or
S>=326 and 2 or
S>=226 and 1
end
end,
}

95
modes/master_beginner.lua Normal file
View File

@@ -0,0 +1,95 @@
local gc=love.graphics
local rush_lock={20,18,16,15,14}
local rush_wait={12,10,9,8,7}
local rush_fall={18,16,14,13,12}
local function score(P)
local c=#P.cleared
if c==0 and P.modeData.point%100==99 then return end
local s=c<3 and c+1 or c==3 and 5 or 7
if P.combo>7 then s=s+2
elseif P.combo>3 then s=s+1
end
P.modeData.point=P.modeData.point+s
if P.modeData.point%100==99 then
SFX("blip_1")
elseif P.modeData.point>=100*(P.modeData.event+1)then
local s=P.modeData.event+1;P.modeData.event=s--level up!
local E=P.gameEnv
curBG=s==1 and"game1"or s==2 and"game2"or s==3 and"game3"or "game4"
E.lock=rush_lock[s]
E.wait=rush_wait[s]
E.fall=rush_fall[s]
E.das=10-s
if s==2 then
P.gameEnv.arr=2
elseif s==4 then
P.gameEnv.bone=true
end
if s==5 then
P.modeData.point,P.modeData.event=500,4
Event.win(P,"finish")
else
P:showText(text.stage(s),0,-120,80,"fly")
end
SFX("reach")
end
end
return{
name={
"大师",
"大师",
"Master",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"初心20G",
"初心20G",
"Beginner 20G",
},
color=color.red,
env={
_20G=true,
lock=rush_lock[1],
wait=rush_wait[1],
fall=rush_fall[1],
dropPiece=score,
das=9,arr=3,
freshLimit=15,
bg="strap",bgm="secret8th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.modeData.point,-82,320)
mStr((P.modeData.event+1)*100,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.modeData.point,P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..D[2].."L "..toTime(D[3])end,
comp=function(a,b)
return a[1]>b[1]or(a[1]==b[1]and(a[2]<b[2]or a[2]==b[2]and a[3]<b[3]))
end,
getRank=function(P)
local L=P.stat.row
local S=P.modeData.point
if S==500 then
return
L<=250 and 5 or
L<=300 and 4 or
3
else
return
S>=420 and 3 or
S>=250 and 2 or
S>=120 and 1
end
end,
}

84
modes/master_final.lua Normal file
View File

@@ -0,0 +1,84 @@
local gc=love.graphics
local int=math.floor
local function score(P)
local c=#P.cleared
if c==0 and P.modeData.point%100==99 then return end
local s=c<3 and c+1 or c==3 and 5 or 7
if P.combo>7 then s=s+2
elseif P.combo>3 then s=s+1
end
local MD=P.modeData
MD.point=MD.point+s
if MD.point%100==99 then SFX("blip_1")end
if int(MD.point*.01)>MD.event then
local s=MD.event+1;MD.event=s--level up!
P:showText(text.stage(s),0,-120,80,"fly")
local E=P.gameEnv
if s<4 then--first 300
if s~=1 then E.lock=E.lock-1 end
if s~=2 then E.wait=E.wait-1 end
if s~=3 then E.fall=E.fall-1 end
elseif s<10 then
if s==4 or s==7 then E.das=E.das-1 end
s=s%3
if s==0 then E.lock=E.lock-1
elseif s==1 then E.wait=E.wait-1
elseif s==2 then E.fall=E.fall-1
end
else
MD.point,MD.event=1000,9
Event.win(P,"finish")
end
SFX("reach")
end
end
return{
name={
"大师",
"大师",
"Master",
},
level={
"终点",
"终点",
"FINAL",
},
info={
"究极20G:无法到达的终点",
"究极20G:无法到达的终点",
"Extreme 20G:Unreachable destination",
},
color=color.lightGrey,
env={
_20G=true,lock=12,
wait=10,fall=10,
dropPiece=score,
das=5,arr=1,
freshLimit=15,
easyFresh=false,bone=true,
bg="none",bgm="shining terminal",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
local MD=P.modeData
mStr(MD.point,-82,320)
mStr((MD.event+1)*100,-82,370)
gc.rectangle("fill",-125,375,90,4)
end,
score=function(P)return{P.modeData.point,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local S=P.modeData.point
return
S>=1000 and 5 or
S>=800 and 4 or
S>=600 and 3 or
S>=400 and 2 or
S>=200 and 1
end,
}

View File

@@ -0,0 +1,57 @@
local gc=love.graphics
return{
name={
"全清挑战",
"全清挑战",
"PC Challenge",
},
level={
"困难",
"困难",
"HARD",
},
info={
"100行内刷PC",
"100行内刷全清",
"More PCs in 100L",
},
color=color.magenta,
env={
drop=60,lock=120,
fall=10,
target=100,dropPiece=Event.reach_winCheck,
freshLimit=15,
ospin=false,
bg="rgb",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
local R=100-P.stat.row
mStr(R>=0 and R or 0,-82,250)
setFont(75)
mStr(P.stat.pc,-82,350)
mDraw(drawableText.pc,-82,432)
gc.setColor(.5,.5,.5)
if frame>179 then
local y=72*(7-(P.stat.piece+(P.hd.id>0 and 2 or 1))%7)-36
gc.line(320,y,442,y)
end
end,
score=function(P)return{P.stat.pc,P.stat.time}end,
scoreDisp=function(D)return D[1].." PCs "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.pc
return
L>=16 and 5 or
L>=13 and 4 or
L>=10 and 3 or
L>=7 and 2 or
L>=4 and 1
end,
}

View File

@@ -0,0 +1,57 @@
local gc=love.graphics
return{
name={
"全清挑战",
"全清挑战",
"PC Challenge",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"100行内刷PC",
"100行内刷全清",
"More PCs in 100L",
},
color=color.red,
env={
drop=20,lock=60,
fall=20,
target=100,dropPiece=Event.reach_winCheck,
freshLimit=15,
ospin=false,
bg="rgb",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
local R=100-P.stat.row
mStr(R>=0 and R or 0,-82,250)
setFont(75)
mStr(P.stat.pc,-82,350)
mDraw(drawableText.pc,-82,432)
gc.setColor(.5,.5,.5)
if frame>179 then
local y=72*(7-(P.stat.piece+(P.hd.id>0 and 2 or 1))%7)-36
gc.line(320,y,442,y)
end
end,
score=function(P)return{P.stat.pc,P.stat.time}end,
scoreDisp=function(D)return D[1].." PCs "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.pc
return
L>=15 and 5 or
L>=12 and 4 or
L>=9 and 3 or
L>=6 and 2 or
L>=3 and 1
end,
}

View File

@@ -0,0 +1,56 @@
local gc=love.graphics
return{
name={
"全清挑战",
"全清挑战",
"PC Challenge",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"100行内刷PC",
"100行内刷全清",
"More PCs in 100L",
},
color=color.green,
env={
oncehold=false,
drop=300,lock=1e99,
target=100,dropPiece=Event.reach_winCheck,
ospin=false,
bg="rgb",bgm="newera",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
local R=100-P.stat.row
mStr(R>=0 and R or 0,-82,250)
setFont(75)
mStr(P.stat.pc,-82,350)
mDraw(drawableText.pc,-82,432)
gc.setColor(.5,.5,.5)
if frame>179 then
local y=72*(7-(P.stat.piece+(P.hd.id>0 and 2 or 1))%7)-36
gc.line(320,y,442,y)
end
end,
score=function(P)return{P.stat.pc,P.stat.time}end,
scoreDisp=function(D)return D[1].." PCs "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.pc
return
L>=25 and 5 or
L>=20 and 4 or
L>=16 and 3 or
L>=13 and 2 or
L>=10 and 1
end,
}

114
modes/pctrain_lunatic.lua Normal file
View File

@@ -0,0 +1,114 @@
local int,rnd=math.floor,math.random
local ins=table.insert
local pc_drop={50,45,40,35,30,26,22,18,15,12}
local pc_lock={55,50,45,40,36,32,30}
local pc_fall={18,16,14,12,10,9,8,7,6}
local PCbase=require("parts/PCbase")
local PClist=require("parts/PClist")
local function task_PC(P)
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter==21 then
local t=P.stat.pc%2
for i=1,4 do
local r=getNewRow(0)
for j=1,10 do
r[j]=PCbase[4*t+i][j]
end
ins(P.field,1,r)
ins(P.visTime,1,getNewRow(20))
end
P.fieldBeneath=P.fieldBeneath+120
P.curY=P.curY+4
P:freshgho()
return true
end
end
local function newPC(P)
local r=P.field;r=r[#r]
if r then
local c=0
for i=1,10 do if r[i]>0 then c=c+1 end end
if c<5 then
Event.lose(P)
end
end
if P.stat.piece%4==0 and #P.field==0 then
P.modeData.event=P.modeData.event==0 and 1 or 0
local r=rnd(#PClist)
local f=P.modeData.event==0
for i=1,4 do
local b=PClist[r][i]
if f then
if b<3 then b=3-b
elseif b<5 then b=7-b
end
end
P.next[#P.next+1]={bk=blocks[b][0],id=b,color=b,name=b}--P:newNext(b)'s simple version!
end
P.modeData.counter=P.stat.piece==0 and 20 or 0
newTask(task_PC,P)
local s=P.stat.pc*.5
if int(s)==s and s>0 then
P.gameEnv.drop=pc_drop[s]or 10
P.gameEnv.lock=pc_lock[s]or 20
P.gameEnv.fall=pc_fall[s]or 5
if s==10 then
P:showText(text.maxspeed,0,-140,100,"appear",.6)
else
P:showText(text.speedup,0,-140,40,"appear",.8)
end
end
end
end
return{
name={
"全清训练",
"全清训练",
"PC Train",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"简易PC题库,熟悉全清定式的组合",
"简易全清题库,熟悉全清定式的组合",
"Let's learn some PCs",
},
color=color.red,
env={
next=4,
hold=false,
drop=60,lock=60,
fall=20,
sequence="none",
freshLimit=15,
dropPiece=newPC,
ospin=false,
bg="rgb",bgm="newera",
},
load=function()
newPlayer(1,340,15)
newPC(players[1])
end,
mesDisp=function(P,dx,dy)
setFont(75)
mStr(P.stat.pc,-82,330)
mDraw(drawableText.pc,-82,412)
end,
score=function(P)return{P.stat.pc,P.stat.time}end,
scoreDisp=function(D)return D[1].." PCs "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.pc
return
L>=50 and 5 or
L>=40 and 4 or
L>=30 and 3 or
L>=20 and 2 or
L>=10 and 1
end,
}

97
modes/pctrain_normal.lua Normal file
View File

@@ -0,0 +1,97 @@
local rnd=math.random
local ins=table.insert
local PCbase=require("parts/PCbase")
local PClist=require("parts/PClist")
local function task_PC(P)
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter==21 then
local t=P.stat.pc%2
for i=1,4 do
local r=getNewRow(0)
for j=1,10 do
r[j]=PCbase[4*t+i][j]
end
ins(P.field,1,r)
ins(P.visTime,1,getNewRow(20))
end
P.fieldBeneath=P.fieldBeneath+120
P.curY=P.curY+4
P:freshgho()
return true
end
end
local function newPC(P)
local r=P.field;r=r[#r]
if r then
local c=0
for i=1,10 do if r[i]>0 then c=c+1 end end
if c<5 then
Event.lose(P)
end
end
if P.stat.piece%4==0 and #P.field==0 then
P.modeData.event=P.modeData.event==0 and 1 or 0
local r=rnd(#PClist)
local f=P.modeData.event==0
for i=1,4 do
local b=PClist[r][i]
if f then
if b<3 then b=3-b
elseif b<5 then b=7-b
end
end
P.next[#P.next+1]={bk=blocks[b][0],id=b,color=b,name=b}--P:newNext(b)'s simple version!
end
P.modeData.counter=P.stat.piece==0 and 20 or 0
newTask(task_PC,P)
end
end
return{
name={
"全清训练",
"全清训练",
"PC Train",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"简易PC题库,熟悉全清定式的组合",
"简易全清题库,熟悉全清定式的组合",
"Let's learn some PCs",
},
color=color.green,
env={
next=4,
hold=false,
drop=150,lock=150,
fall=20,
sequence="none",
dropPiece=newPC,
ospin=false,
bg="rgb",bgm="newera",
},
load=function()
newPlayer(1,340,15)
newPC(players[1])
end,
mesDisp=function(P,dx,dy)
setFont(75)
mStr(P.stat.pc,-82,330)
mDraw(drawableText.pc,-82,412)
end,
score=function(P)return{P.stat.pc,P.stat.time}end,
scoreDisp=function(D)return D[1].." PCs "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.pc
return
L>=100 and 5 or
L>=60 and 4 or
L>=40 and 3 or
L>=25 and 2 or
L>=15 and 1
end,
}

56
modes/round_1.lua Normal file
View File

@@ -0,0 +1,56 @@
local function update_round(P)
if #players.alive>1 then
P.control=false
local ID=P.id
repeat
ID=ID+1
if not players[ID]then ID=1 end
until players[ID].alive or ID==P.id
players[ID].control=true
end
end
return{
name={
"回合制",
"回合制",
"Turn-Base",
},
level={
"简单",
"简单",
"EASY",
},
info={
"下棋模式",
"下棋模式",
"Chess?",
},
color=color.cyan,
env={
drop=60,lock=60,
oncehold=false,
dropPiece=update_round,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",10))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.piece,P.stat.time}end,
scoreDisp=function(D)return D[1].." Pieces "..toTime(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.piece
return
T<=20 and 5 or
T<=26 and 4 or
T<=40 and 3 or
T<=60 and 2 or
1
end
end,
}

56
modes/round_2.lua Normal file
View File

@@ -0,0 +1,56 @@
local function update_round(P)
if #players.alive>1 then
P.control=false
local ID=P.id
repeat
ID=ID+1
if not players[ID]then ID=1 end
until players[ID].alive or ID==P.id
players[ID].control=true
end
end
return{
name={
"回合制",
"回合制",
"Turn-Base",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"下棋模式",
"下棋模式",
"Chess?",
},
color=color.green,
env={
drop=60,lock=60,
oncehold=false,
dropPiece=update_round,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",10))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.piece,P.stat.time}end,
scoreDisp=function(D)return D[1].." Pieces "..toTime(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.piece
return
T<=30 and 5 or
T<=40 and 4 or
T<=55 and 3 or
T<=70 and 2 or
1
end
end,
}

56
modes/round_3.lua Normal file
View File

@@ -0,0 +1,56 @@
local function update_round(P)
if #players.alive>1 then
P.control=false
local ID=P.id
repeat
ID=ID+1
if not players[ID]then ID=1 end
until players[ID].alive or ID==P.id
players[ID].control=true
end
end
return{
name={
"回合制",
"回合制",
"Turn-Base",
},
level={
"困难",
"困难",
"HARD",
},
info={
"下棋模式",
"下棋模式",
"Chess?",
},
color=color.magenta,
env={
drop=60,lock=60,
oncehold=false,
dropPiece=update_round,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",10))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.piece,P.stat.time}end,
scoreDisp=function(D)return D[1].." Pieces "..toTime(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.piece
return
T<=35 and 5 or
T<=45 and 4 or
T<=65 and 3 or
T<=85 and 2 or
1
end
end,
}

56
modes/round_4.lua Normal file
View File

@@ -0,0 +1,56 @@
local function update_round(P)
if #players.alive>1 then
P.control=false
local ID=P.id
repeat
ID=ID+1
if not players[ID]then ID=1 end
until players[ID].alive or ID==P.id
players[ID].control=true
end
end
return{
name={
"回合制",
"回合制",
"Turn-Base",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"下棋模式",
"下棋模式",
"Chess?",
},
color=color.red,
env={
drop=60,lock=60,
oncehold=false,
dropPiece=update_round,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",10))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.piece,P.stat.time}end,
scoreDisp=function(D)return D[1].." Pieces "..toTime(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.piece
return
T<=40 and 5 or
T<=50 and 4 or
T<=75 and 3 or
T<=100 and 2 or
1
end
end,
}

56
modes/round_5.lua Normal file
View File

@@ -0,0 +1,56 @@
local function update_round(P)
if #players.alive>1 then
P.control=false
local ID=P.id
repeat
ID=ID+1
if not players[ID]then ID=1 end
until players[ID].alive or ID==P.id
players[ID].control=true
end
end
return{
name={
"回合制",
"回合制",
"Turn-Base",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"下棋模式",
"下棋模式",
"Chess?",
},
color=color.lightYellow,
env={
drop=60,lock=60,
oncehold=false,
dropPiece=update_round,
bg="game2",bgm="push",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",10))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.piece,P.stat.time}end,
scoreDisp=function(D)return D[1].." Pieces "..toTime(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.piece
return
T<=50 and 5 or
T<=60 and 4 or
T<=80 and 3 or
T<=100 and 2 or
1
end
end,
}

43
modes/solo_1.lua Normal file
View File

@@ -0,0 +1,43 @@
return{
name={
"单挑",
"单挑",
"Battle",
},
level={
"简单",
"简单",
"EASY",
},
info={
"打败AI",
"打败电脑",
"Beat AI",
},
color=color.cyan,
env={
drop=60,lock=60,
freshLimit=15,
bg="game2",bgm="race",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",3))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.time}end,
scoreDisp=function(D)return toTime(D[1])end,
comp=function(a,b)return a[1]<b[1]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.time
return
T<=15 and 5 or
T<=25 and 4 or
T<=40 and 3 or
T<=80 and 2 or
1
end
end,
}

43
modes/solo_2.lua Normal file
View File

@@ -0,0 +1,43 @@
return{
name={
"单挑",
"单挑",
"Battle",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"打败AI",
"打败AI",
"Beat AI",
},
color=color.green,
env={
drop=60,lock=60,
freshLimit=15,
bg="game2",bgm="race",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",5))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.time}end,
scoreDisp=function(D)return toTime(D[1])end,
comp=function(a,b)return a[1]<b[1]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.time
return
T<=16 and 5 or
T<=28 and 4 or
T<=45 and 3 or
T<=90 and 2 or
1
end
end,
}

43
modes/solo_3.lua Normal file
View File

@@ -0,0 +1,43 @@
return{
name={
"单挑",
"单挑",
"Battle",
},
level={
"困难",
"困难",
"HARD",
},
info={
"打败AI",
"打败AI",
"Beat AI",
},
color=color.magenta,
env={
drop=60,lock=60,
freshLimit=15,
bg="game2",bgm="race",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",7))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.time}end,
scoreDisp=function(D)return toTime(D[1])end,
comp=function(a,b)return a[1]<b[1]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.time
return
T<=17 and 5 or
T<=26 and 4 or
T<=45 and 3 or
T<=60 and 2 or
1
end
end,
}

43
modes/solo_4.lua Normal file
View File

@@ -0,0 +1,43 @@
return{
name={
"单挑",
"单挑",
"Battle",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"打败AI",
"打败AI",
"Beat AI",
},
color=color.red,
env={
drop=60,lock=60,
freshLimit=15,
bg="game2",bgm="race",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",8))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.time}end,
scoreDisp=function(D)return toTime(D[1])end,
comp=function(a,b)return a[1]<b[1]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.time
return
T<=18 and 5 or
T<=30 and 4 or
T<=50 and 3 or
T<=70 and 2 or
1
end
end,
}

43
modes/solo_5.lua Normal file
View File

@@ -0,0 +1,43 @@
return{
name={
"单挑",
"单挑",
"Battle",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"打败AI",
"打败AI",
"Beat AI",
},
color=color.lightYellow,
env={
drop=60,lock=60,
freshLimit=15,
bg="game2",bgm="race",
},
load=function()
newPlayer(1,340,15)
newPlayer(2,965,360,.5,AITemplate("9S",9))
end,
mesDisp=function(P,dx,dy)
end,
score=function(P)return{P.stat.time}end,
scoreDisp=function(D)return toTime(D[1])end,
comp=function(a,b)return a[1]<b[1]end,
getRank=function(P)
if P.result=="WIN"then
local T=P.stat.time
return
T<=20 and 5 or
T<=30 and 4 or
T<=45 and 3 or
T<=60 and 2 or
1
end
end,
}

53
modes/sprint_10.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"10L",
"10行",
"10L",
},
info={
"消除10行",
"消除10行",
"Clear 10 lines",
},
color=color.cyan,
env={
drop=60,lock=60,
target=10,dropPiece=Event.reach_winCheck,
bg="strap",bgm="race",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=10-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<10 then return end
local T=P.stat.time
return
T<=7 and 5 or
T<=10 and 4 or
T<=25 and 3 or
T<=40 and 2 or
T<=60 and 1
end,
}

53
modes/sprint_100.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"100L",
"100行",
"100L",
},
info={
"消除100行",
"消除100行",
"Clear 100 lines",
},
color=color.orange,
env={
drop=60,lock=60,
target=100,dropPiece=Event.reach_winCheck,
bg="strap",bgm="race",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=100-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<100 then return end
local T=P.stat.time
return
T<=60 and 5 or
T<=90 and 4 or
T<=130 and 3 or
T<=200 and 2 or
T<=270 and 1
end,
}

53
modes/sprint_1000.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"1000L",
"1000行",
"1000L",
},
info={
"消除1000行",
"消除1000行",
"Clear 1000 lines",
},
color=color.lightGrey,
env={
drop=60,lock=60,
target=1000,dropPiece=Event.reach_winCheck,
bg="strap",bgm="push",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=1000-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<1000 then return end
local T=P.stat.time
return
T<=626 and 5 or
T<=1000 and 4 or
T<=1400 and 3 or
T<=2200 and 2 or
T<=3000 and 1
end,
}

53
modes/sprint_20.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"20L",
"20行",
"20L",
},
info={
"消除20行",
"消除20行",
"Clear 20 lines",
},
color=color.lightBlue,
env={
drop=60,lock=60,
target=20,dropPiece=Event.reach_winCheck,
bg="strap",bgm="race",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=20-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<20 then return end
local T=P.stat.time
return
T<=13 and 5 or
T<=18 and 4 or
T<=45 and 3 or
T<=70 and 2 or
T<=100 and 1
end,
}

53
modes/sprint_40.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"40L",
"40行",
"40L",
},
info={
"消除40行",
"消除40行",
"Clear 40 lines",
},
color=color.green,
env={
drop=60,lock=60,
target=40,dropPiece=Event.reach_winCheck,
bg="strap",bgm="race",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=40-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<40 then return end
local T=P.stat.time
return
T<=25 and 5 or
T<=32 and 4 or
T<=40 and 3 or
T<=60 and 2 or
T<=100 and 1
end,
}

53
modes/sprint_400.lua Normal file
View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local rnd=math.random
return{
name={
"竞速",
"竞速",
"Sprint",
},
level={
"400L",
"400行",
"400L",
},
info={
"消除400行",
"消除400行",
"Clear 400 lines",
},
color=color.red,
env={
drop=60,lock=60,
target=400,dropPiece=Event.reach_winCheck,
bg="strap",bgm="push",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P)
local dx,dy=P.fieldOff.x,P.fieldOff.y
setFont(55)
local r=400-P.stat.row
if r<0 then r=0 end
mStr(r,-82,265)
if r<21 and r>0 then
gc.setLineWidth(4)
gc.setColor(1,r>10 and 0 or rnd(),.5)
gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
end
end,
score=function(P)return{P.stat.time,P.stat.piece}end,
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
if P.stat.row<400 then return end
local T=P.stat.time
return
T<=255 and 5 or
T<=330 and 4 or
T<=420 and 3 or
T<=626 and 2 or
T<=1000 and 1
end,
}

59
modes/survivor_easy.lua Normal file
View File

@@ -0,0 +1,59 @@
local max,rnd=math.max,math.random
return{
name={
"生存",
"生存",
"Survivor",
},
level={
"简单",
"简单",
"EASY",
},
info={
"你能存活多久?",
"你能存活多久?",
"Survive Longer!",
},
color=color.cyan,
env={
drop=30,lock=45,
freshLimit=10,
visible="time",
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,150-2*P.modeData.event)and P.atkBuffer.sum<4 then
P.atkBuffer[#P.atkBuffer+1]={pos=rnd(10),amount=1,countdown=30,cd0=30,time=0,sent=false,lv=1}
P.atkBuffer.sum=P.atkBuffer.sum+1
P.stat.recv=P.stat.recv+1
if P.modeData.event==45 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end,
bg="glow",bgm="newera",
},
load=function()
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)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=100 and 5 or
W>=60 and 4 or
W>=45 and 3 or
W>=30 and 2 or
W>=15 and 1
end,
}

64
modes/survivor_hard.lua Normal file
View File

@@ -0,0 +1,64 @@
local max,rnd=math.max,math.random
return{
name={
"生存",
"生存",
"Survivor",
},
level={
"困难",
"困难",
"HARD",
},
info={
"你能存活多久?",
"你能存活多久?",
"Survive Longer!",
},
color=color.magenta,
env={
drop=30,lock=45,
freshLimit=10,
visible="time",
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,180-2*P.modeData.event)and P.atkBuffer.sum<15 then
P.atkBuffer[#P.atkBuffer+1]=
P.modeData.event%3<2 and
{pos=rnd(10),amount=1,countdown=0,cd0=0,time=0,sent=false,lv=1}
or
{pos=rnd(10),amount=3,countdown=60,cd0=60,time=0,sent=false,lv=2}
local R=(P.modeData.event%3<2 and 1 or 3)
P.atkBuffer.sum=P.atkBuffer.sum+R
P.stat.recv=P.stat.recv+R
if P.modeData.event==60 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end,
bg="glow",bgm="newera",
},
load=function()
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)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=90 and 5 or
W>=60 and 4 or
W>=45 and 3 or
W>=30 and 2 or
W>=15 and 1
end,
}

View File

@@ -0,0 +1,60 @@
local max,rnd=math.max,math.random
return{
name={
"生存",
"生存",
"Survivor",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"你能存活多久?",
"你能存活多久?",
"Survive Longer!",
},
color=color.red,
env={
drop=30,lock=45,
freshLimit=10,
visible="time",
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(60,150-P.modeData.event)and P.atkBuffer.sum<20 then
local t=max(60,90-P.modeData.event)
P.atkBuffer[#P.atkBuffer+1]={pos=rnd(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3}
P.atkBuffer.sum=P.atkBuffer.sum+4
P.stat.recv=P.stat.recv+4
if P.modeData.event==60 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end,
bg="glow",bgm="newera",
},
load=function()
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)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=110 and 5 or
W>=80 and 4 or
W>=55 and 3 or
W>=30 and 2 or
W>=15 and 1
end,
}

64
modes/survivor_normal.lua Normal file
View File

@@ -0,0 +1,64 @@
local max,rnd=math.max,math.random
return{
name={
"生存",
"生存",
"Survivor",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"你能存活多久?",
"你能存活多久?",
"Survive Longer!",
},
color=color.green,
env={
drop=30,lock=45,
freshLimit=10,
visible="time",
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(90,180-2*P.modeData.event)and P.atkBuffer.sum<8 then
local d=P.modeData.event+1
P.atkBuffer[#P.atkBuffer+1]=
d%4==0 and{pos=rnd(10),amount=1,countdown=60,cd0=60,time=0,sent=false,lv=1}or
d%4==1 and{pos=rnd(10),amount=2,countdown=70,cd0=70,time=0,sent=false,lv=1}or
d%4==2 and{pos=rnd(10),amount=3,countdown=80,cd0=80,time=0,sent=false,lv=2}or
d%4==3 and{pos=rnd(10),amount=4,countdown=90,cd0=90,time=0,sent=false,lv=3}
P.atkBuffer.sum=P.atkBuffer.sum+d%4+1
P.stat.recv=P.stat.recv+d%4+1
if P.modeData.event==45 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=d
end
end,
bg="glow",bgm="newera",
},
load=function()
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)
end,
score=function(P)return{P.modeData.event,P.stat.time}end,
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]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=80 and 5 or
W>=55 and 4 or
W>=45 and 3 or
W>=30 and 2 or
W>=15 and 1
end,
}

View File

@@ -0,0 +1,63 @@
local max,rnd=math.max,math.random
return{
name={
"生存",
"生存",
"Survivor",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"你能存活多久?",
"你能存活多久?",
"Survive Longer!",
},
color=color.lightYellow,
env={
drop=5,lock=60,
fall=10,
freshLimit=15,
pushSpeed=2,
task=function(P)
if not P.control then return end
P.modeData.counter=P.modeData.counter+1
if P.modeData.counter>=max(300,600-10*P.modeData.event)and P.atkBuffer.sum<20 then
local t=max(300,480-12*P.modeData.event)
local p=#P.atkBuffer+1
P.atkBuffer[p] ={pos=rnd(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=2}
P.atkBuffer[p+1]={pos=rnd(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3}
P.atkBuffer[p+2]={pos=rnd(10),amount=6,countdown=1.2*t,cd0=1.2*t,time=0,sent=false,lv=4}
P.atkBuffer[p+3]={pos=rnd(10),amount=6,countdown=1.5*t,cd0=1.5*t,time=0,sent=false,lv=5}
P.atkBuffer.sum=P.atkBuffer.sum+20
P.stat.recv=P.stat.recv+20
P.modeData.counter=0
if P.modeData.event==31 then P:showText(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.event=P.modeData.event+1
end
end,
bg="rgb",bgm="secret7th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
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,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.event
return
W>=35 and 5 or
W>=26 and 4 or
W>=20 and 3 or
W>=10 and 2 or
W>=5 and 1
end,
}

53
modes/tech_hard+.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_ultimate(P)
if #P.cleared>0 and P.lastClear<10 or P.lastClear==74 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"困难+",
"困难+",
"HARD+",
},
info={
"仅允许spin与PC",
"仅允许spin与全清",
"Spin&PC only",
},
color=color.darkMagenta,
env={
drop=30,lock=60,
freshLimit=15,
target=200,
dropPiece=tech_reach_ultimate,
bg="matrix",bgm="secret8th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==126 and 4 or
L==90 and 3 or
L==60 and 2 or
L==30 and 1
end,
}

53
modes/tech_hard.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_easy(P)
if #P.cleared>0 and P.b2b<40 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"困难",
"困难",
"HARD",
},
info={
"禁止断B2B",
"禁止断满贯",
"Keep B2B",
},
color=color.magenta,
env={
drop=20,lock=60,
freshLimit=15,
target=200,
dropPiece=tech_reach_easy,
bg="matrix",bgm="secret8th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==126 and 4 or
L==90 and 3 or
L==60 and 2 or
L==30 and 1
end,
}

53
modes/tech_lunatic+.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_ultimate(P)
if #P.cleared>0 and P.lastClear<10 or P.lastClear==74 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"疯狂+",
"疯狂+",
"LUNATIC+",
},
info={
"仅允许spin与PC",
"仅允许spin与全清",
"Spin&PC only",
},
color=color.darkRed,
env={
_20G=true,lock=60,
freshLimit=15,
target=200,
dropPiece=tech_reach_ultimate,
bg="matrix",bgm="secret7th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==140 and 4 or
L==90 and 3 or
L==60 and 2 or
L==30 and 1
end,
}

53
modes/tech_lunatic.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_hard(P)
if #P.cleared>0 and P.lastClear<10 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"疯狂",
"疯狂",
"LUNATIC",
},
info={
"禁止断B2B",
"禁止断满贯",
"Keep B2B",
},
color=color.red,
env={
_20G=true,lock=60,
freshLimit=15,
target=200,
dropPiece=tech_reach_hard,
bg="matrix",bgm="secret7th",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==140 and 4 or
L==90 and 3 or
L==60 and 2 or
L==30 and 1
end,
}

53
modes/tech_normal+.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_ultimate(P)
if #P.cleared>0 and P.lastClear<10 or P.lastClear==74 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"普通+",
"普通+",
"NORMAL+",
},
info={
"仅允许spin与PC",
"仅允许spin与全清",
"Spin&PC only",
},
color=color.darkGreen,
env={
oncehold=false,
drop=1e99,lock=1e99,
target=200,
dropPiece=tech_reach_ultimate,
bg="matrix",bgm="newera",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==126 and 4 or
L==80 and 3 or
L==50 and 2 or
L==20 and 1
end,
}

53
modes/tech_normal.lua Normal file
View File

@@ -0,0 +1,53 @@
local function tech_check_easy(P)
if #P.cleared>0 and P.b2b<40 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"普通",
"普通",
"NORMAL",
},
info={
"禁止断B2B",
"禁止断B2B",
"Keep B2B",
},
color=color.green,
env={
oncehold=false,
drop=1e99,lock=1e99,
target=200,
dropPiece=tech_check_easy,
bg="matrix",bgm="newera",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==126 and 4 or
L==80 and 3 or
L==50 and 2 or
L==20 and 1
end,
}

54
modes/tech_ultimate+.lua Normal file
View File

@@ -0,0 +1,54 @@
local function tech_check_ultimate(P)
if #P.cleared>0 and P.lastClear<10 or P.lastClear==74 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"极限+",
"极限+",
"ULTIMATE+",
},
info={
"禁止普通消除,强制最简操作",
"禁止普通消除,强制最简操作",
"Don't do normal clear,no finesse error",
},
color=color.grey,
env={
drop=1e99,lock=60,
freshLimit=15,
target=200,
fineKill=true,
dropPiece=tech_reach_ultimate,
bg="flink",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==150 and 4 or
L==100 and 3 or
L==70 and 2 or
L==40 and 1
end,
}

54
modes/tech_ultimate.lua Normal file
View File

@@ -0,0 +1,54 @@
local function tech_check_hard(P)
if #P.cleared>0 and P.lastClear<10 then
Event.lose(P)
end
end
return{
name={
"科研",
"科研",
"Tech",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"仅允许spin与PC,强制最简操作",
"仅允许spin与全清,强制最简操作",
"Don't do normal clear,no finesse error",
},
color=color.lightYellow,
env={
drop=1e99,lock=60,
freshLimit=15,
target=200,
fineKill=true,
dropPiece=tech_reach_hard,
bg="flink",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(45)
mStr(P.stat.atk,-82,310)
mStr(format("%.2f",P.stat.atk/P.stat.row),-82,420)
mDraw(drawableText.atk,-82,363)
mDraw(drawableText.eff,-82,475)
end,
score=function(P)return{P.stat.row<=200 and P.stat.row or 200,P.stat.time}end,
scoreDisp=function(D)return D[1].." Rows "..toTime(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
return
L==200 and 5 or
L==150 and 4 or
L==100 and 3 or
L==70 and 2 or
L==40 and 1
end,
}

101
modes/techmino49_easy.lua Normal file
View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"49人混战",
"49人混战",
"Techmino49",
},
level={
"简单",
"简单",
"EASY",
},
info={
"49人混战,活到最后",
"49人混战,活到最后",
"49P melee fight",
},
color=color.cyan,
env={
drop=60,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
newPlayer(1,340,15)
local L={}for i=1,49 do L[i]=true end
local t=system~="Windows"and 0 or 2
while t>0 do
local r=rnd(2,49)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,4 do for j=1,6 do
if L[n]then
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("9S",rnd(4,6)))
else
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("CC",rnd(4,6)-1,2,true,10000))
end
n=n+1
end end
for i=9,12 do for j=1,6 do
if L[n]then
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("9S",rnd(4,6)))
else
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("CC",rnd(4,6)-1,2,true,10000))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/49",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R<=3 and 4 or
R<=5 and 3 or
R<=10 and 2 or
R<=15 and 1
end,
}

101
modes/techmino49_hard.lua Normal file
View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"49人混战",
"49人混战",
"Techmino49",
},
level={
"困难",
"困难",
"HARD",
},
info={
"49人混战,活到最后",
"49人混战,活到最后",
"49P melee fight",
},
color=color.magenta,
env={
drop=60,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
newPlayer(1,340,15)
local L={}for i=1,49 do L[i]=true end
local t=system~="Windows"and 0 or 4
while t>0 do
local r=rnd(2,49)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,4 do for j=1,6 do
if L[n]then
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("9S",rnd(4,8)))
else
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("CC",rnd(4,8)-1,3,true,20000))
end
n=n+1
end end
for i=9,12 do for j=1,6 do
if L[n]then
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("9S",rnd(4,8)))
else
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("CC",rnd(4,8)-1,3,true,20000))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/49",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R==2 and 4 or
R<=4 and 3 or
R<=6 and 2 or
R<=8 and 1
end,
}

View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"49人混战",
"49人混战",
"Techmino49",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"49人混战,活到最后",
"49人混战,活到最后",
"49P melee fight",
},
color=color.lightYellow,
env={
drop=15,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
newPlayer(1,340,15)
local L={}for i=1,49 do L[i]=true end
local t=system~="Windows"and 0 or 6
while t>0 do
local r=rnd(2,49)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,4 do for j=1,6 do
if L[n]then
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("9S",rnd(8,10)))
else
newPlayer(n,78*i-54,115*j-98,.09,AITemplate("CC",rnd(8,10)-1,4,true,30000))
end
n=n+1
end end
for i=9,12 do for j=1,6 do
if L[n]then
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("9S",rnd(8,10)))
else
newPlayer(n,78*i+267,115*j-98,.09,AITemplate("CC",rnd(8,10)-1,4,true,30000))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/49",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R==2 and 4 or
R==3 and 3 or
R==4 and 2 or
R<=6 and 1
end,
}

101
modes/techmino99_easy.lua Normal file
View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"99人混战",
"99人混战",
"Techmino99",
},
level={
"简单",
"简单",
"EASY",
},
info={
"99人混战,活到最后",
"99人混战,活到最后",
"99P melee fight",
},
color=color.cyan,
env={
drop=60,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
newPlayer(1,340,15)
local L={}for i=1,100 do L[i]=true end
local t=system~="Windows"and 0 or 4
while t>0 do
local r=rnd(2,99)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,7 do for j=1,7 do
if L[n]then
newPlayer(n,46*i-36,97*j-72,.068,AITemplate("9S",rnd(4,8)))
else
newPlayer(n,46*i-36,97*j-72,.068,AITemplate("CC",rnd(4,8)-1,2,true,10000))
end
n=n+1
end end
for i=15,21 do for j=1,7 do
if L[n]then
newPlayer(n,46*i+264,97*j-72,.068,AITemplate("9S",rnd(4,8)))
else
newPlayer(n,46*i+264,97*j-72,.068,AITemplate("CC",rnd(4,8)-1,2,true,10000))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/99",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R<=3 and 4 or
R<=6 and 3 or
R<=10 and 2 or
R<=20 and 1
end,
}

101
modes/techmino99_hard.lua Normal file
View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"99人混战",
"99人混战",
"Techmino99",
},
level={
"困难",
"困难",
"HARD",
},
info={
"99人混战,活到最后",
"99人混战,活到最后",
"99P melee fight",
},
color=color.magenta,
env={
drop=60,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
newPlayer(1,340,15)
local L={}for i=1,100 do L[i]=true end
local t=system~="Windows"and 0 or 4
while t>0 do
local r=rnd(2,99)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,7 do for j=1,7 do
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,3,true,20000))
end
n=n+1
end end
for i=15,21 do for j=1,7 do
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,3,true,20000))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/99",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R<=3 and 4 or
R<=6 and 3 or
R<=8 and 2 or
R<=10 and 1
end,
}

View File

@@ -0,0 +1,101 @@
local gc=love.graphics
local int,rnd=math.floor,math.random
local powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
local function selectTarget(P)
if setting.swap then
for i=1,#P.keyPressing do
if P.keyPressing[i]then
P.keyPressing[i]=false
end
end
P.keyPressing[9]=true
else
P:changeAtkMode(P.atkMode<3 and P.atkMode+2 or 5-P.atkMode)
P.swappingAtkMode=30
end
end
return{
name={
"99人混战",
"99人混战",
"Techmino99",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"99人混战,活到最后",
"99人混战,活到最后",
"99P melee fight",
},
color=color.lightYellow,
env={
drop=15,lock=60,
fall=20,
royaleMode=true,
Fkey=selectTarget,
pushSpeed=2,
freshLimit=15,
bg="game3",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
newPlayer(1,340,15)
local L={}for i=1,100 do L[i]=true end
local t=system~="Windows"and 0 or 4
while t>0 do
local r=rnd(2,99)
if L[r]then L[r],t=false,t-1 end
end
local n=2
for i=1,7 do for j=1,7 do
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))
end
n=n+1
end end
for i=15,21 do for j=1,7 do
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))
end
n=n+1
end end
end,
mesDisp=function(P,dx,dy)
setFont(35)
mStr(#players.alive.."/99",-82,175)
mStr(P.ko,-70,215)
gc.draw(drawableText.ko,-127,225)
setFont(20)
gc.setColor(1,.5,0,.6)
gc.print(P.badge,-47,227)
gc.setColor(1,1,1)
setFont(25)
gc.print(powerUp[P.strength],-132,290)
for i=1,P.strength do
gc.draw(badgeIcon,16*i-138,260)
end
end,
score=function(P)return{P.rank,P.ko}end,
scoreDisp=function(D)return"NO."..D[1].." KO:"..D[2]end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function(P)
local R=P.rank
return
R==1 and 5 or
R==2 and 4 or
R==3 and 3 or
R<=5 and 2 or
R<=7 and 1
end,
}

55
modes/tsd_easy.lua Normal file
View File

@@ -0,0 +1,55 @@
local function check_tsd(P)
if #P.cleared>0 then
if P.lastClear~=52 then
Event.lose(P)
elseif #P.cleared>0 then
P.modeData.event=P.modeData.event+1
end
end
end
return{
name={
"TSD挑战",
"T旋双清挑战",
"TSD Challenge",
},
level={
"简单",
"简单",
"EASY",
},
info={
"你能连续做几个TSD?",
"你能连续做几个T旋双清?",
"T-spin-doubles only",
},
color=color.green,
env={
drop=1e99,lock=1e99,
oncehold=false,
dropPiece=check_tsd,
ospin=false,
bg="matrix",bgm="reason",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(75)
mStr(P.modeData.event,-82,330)
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,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local T=P.modeData.event
return
T>=23 and 5 or
T>=20 and 4 or
T>=15 and 3 or
T>=10 and 2 or
T>=6 and 1
end,
}

55
modes/tsd_hard.lua Normal file
View File

@@ -0,0 +1,55 @@
local function check_tsd(P)
if #P.cleared>0 then
if P.lastClear~=52 then
Event.lose(P)
elseif #P.cleared>0 then
P.modeData.event=P.modeData.event+1
end
end
end
return{
name={
"TSD挑战",
"T旋双清挑战",
"TSD Challenge",
},
level={
"困难",
"困难",
"HARD",
},
info={
"你能连续做几个TSD?",
"你能连续做几个T旋双清?",
"T-spin-doubles only",
},
color=color.magenta,
env={
drop=60,lock=60,
freshLimit=15,
dropPiece=check_tsd,
ospin=false,
bg="matrix",bgm="reason",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(75)
mStr(P.modeData.event,-82,330)
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,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local T=P.modeData.event
return
T>=21 and 5 or
T>=19 and 4 or
T>=16 and 3 or
T>=13 and 2 or
T>=10 and 1
end,
}

55
modes/tsd_ultimate.lua Normal file
View File

@@ -0,0 +1,55 @@
local function check_tsd(P)
if #P.cleared>0 then
if P.lastClear~=52 then
Event.lose(P)
elseif #P.cleared>0 then
P.modeData.event=P.modeData.event+1
end
end
end
return{
name={
"TSD挑战",
"T旋双清挑战",
"TSD Challenge",
},
level={
"极限",
"极限",
"ULTIMATE",
},
info={
"你能连续做几个TSD?",
"你能连续做几个T旋双清?",
"T-spin-doubles only",
},
color=color.lightYellow,
env={
drop=60,lock=60,
freshLimit=15,
dropPiece=check_tsd,
ospin=false,
bg="matrix",bgm="reason",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(75)
mStr(P.modeData.event,-82,330)
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,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local T=P.modeData.event
return
T>=20 and 5 or
T>=18 and 4 or
T>=16 and 3 or
T>=14 and 2 or
T>=12 and 1
end,
}

42
modes/ultra.lua Normal file
View File

@@ -0,0 +1,42 @@
return{
name={
"限时打分",
"限时打分",
"Ultra",
},
level={
"挑战",
"挑战",
"EXTRA",
},
info={
"在两分钟内尽可能拿到最多的分数",
"在两分钟内尽可能拿到最多的分数",
"Score attack in 120s",
},
color=color.grey,
env={
drop=1e99,lock=1e99,
task=function(P)
if P.stat.time>=120 then
Event.win(P,"finish")
end
end,
bg="matrix",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
gc.circle("line",-30,100,40)
gc.setColor(1,0,0)
gc.arc("fill",-40,100,50,0,1)
end,
score=function(P)return{P.score}end,
scoreDisp=function(D)return D[1]end,
comp=function(a,b)return a[1]>b[1]end,
getRank=function(P)
local T=P.stat.score
return 1
end,
}

44
modes/zen.lua Normal file
View File

@@ -0,0 +1,44 @@
return{
name={
"",
"",
"Zen",
},
level={
"时间杀手 I",
"时间杀手 I",
"Time Killer I",
},
info={
"不限时200行",
"不限时200行",
"200 lines without any limits",
},
color=color.lightGrey,
env={
drop=1e99,lock=1e99,
oncehold=false,target=200,
dropPiece=Event.reach_winCheck,
bg="strap",bgm="infinite",
},
load=function()
newPlayer(1,340,15)
end,
mesDisp=function(P,dx,dy)
setFont(70)
local R=200-P.stat.row
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,
comp=function(a,b)return a[1]>b[1]end,
getRank=function(P)
local T=P.stat.score
return
T>=1e5 and 5 or
T>=8e4 and 4 or
T>=5e4 and 3 or
T>=2e4 and 2 or
T>=1e4 and 1
end,
}

202
paint.lua
View File

@@ -5,82 +5,15 @@ local format=string.format
local Timer=love.timer.getTime
local scr=scr
local modeLevelColor={
EASY=color.cyan,
NORMAL=color.green,
HARD=color.magenta,
LUNATIC=color.red,
EXTRA=color.lightMagenta,
ULTIMATE=color.lightYellow,
FINAL=color.lightGrey,
["EASY+"]=color.darkCyan,
["NORMAL+"]=color.darkGreen,
["HARD+"]=color.darkMagenta,
["LUNATIC+"]=color.darkRed,
["ULTIMATE+"]=color.grey,
MESS=color.lightGrey,
GM=color.blue,
DEATH=color.lightRed,
CTWC=color.lightBlue,
["10L"]=color.cyan,
["20L"]=color.lightBlue,
["40L"]=color.green,
["100L"]=color.orange,
["400L"]=color.red,
["1000L"]=color.lightGrey,
local modeRankColor={
[0]=color.darkGrey, --Not pass
color.bronze, --Rank1
color.lightGrey, --Rank2
color.lightYellow, --Rank3
color.lightMagenta, --Rank4
color.lightCyan, --Rank5
color.purple, --Special
}
local dataOptL={"key","rotate","hold",nil,nil,nil,"send","recv","pend"}
local function dataOpt(i)
local stat=players[1].stat
if i==4 then
return stat.piece.." "..(int(stat.piece/stat.time*100)*.01).."PPS"
elseif i==5 then
return stat.row.." "..(int(stat.row/stat.time*600)*.1).."LPM"
elseif i==6 then
return stat.atk.." "..(int(stat.atk/stat.time*600)*.1).."APM"
elseif i<10 then
return stat[dataOptL[i]]
elseif i==10 then
return stat.clear_1.."/"..stat.clear_2.."/"..stat.clear_3.."/"..stat.clear_4
elseif i==11 then
return "["..stat.spin_0.."]/"..stat.spin_1.."/"..stat.spin_2.."/"..stat.spin_3
elseif i==12 then
return stat.b2b.."[+"..stat.b3b.."]"
elseif i==13 then
return stat.pc
elseif i==14 then
return format("%0.2f",stat.atk/stat.row)
elseif i==15 then
return stat.extraPiece
elseif i==16 then
return max(100-int(stat.extraRate/stat.piece*10000)*.01,0).."%"
end
end
local statOptL={
"run","game",nil,
"key","rotate","hold","piece","row",
"atk","send","recv","pend",
}
local function statOpt(i)
if i<13 and i~=3 then
return stat[statOptL[i]]
elseif i==3 then
return format("%0.1fHr",stat.time*2.78e-4)
elseif i==13 then
return stat.clear_1.."/"..stat.clear_2.."/"..stat.clear_3.."/"..stat.clear_4
elseif i==14 then
return "["..stat.spin_0.."]/"..stat.spin_1.."/"..stat.spin_2.."/"..stat.spin_3
elseif i==15 then
return stat.b2b.."[+"..stat.b3b.."]"
elseif i==16 then
return stat.pc
elseif i==17 then
return format("%0.2f",stat.atk/stat.row)
elseif i==18 then
return stat.extraPiece.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end
end
local miniTitle_rect={
{2,0,5,1},{4,1,1,6},
{9,0,4,1},{9,3,4,1},{9,6,4,1},{8,0,1,7},
@@ -98,7 +31,8 @@ local function stencil_miniTitle()
end
end
FX_BGblock={tm=150,next=7,ct=0,list={{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},}}--Falling tetrominos on background
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={}
@@ -265,33 +199,82 @@ function Pnt.main()
setFont(30)
gc.print(gameVersion,70,125)
gc.print(system,610,100)
gc.print(modes[modeID[modeSel]].level[levelSel],600,373)
setFont(25)
gc.print(text.modeName[modeSel],600,414)
players[1]:draw()
end
function Pnt.mode()
gc.setColor(1,1,1)
gc.draw(titleImage,830,30)
setFont(35)
local lv=modes[modeID[modeSel]].level[levelSel]
gc.setColor(modeLevelColor[lv]or color.white)
mStr(lv,270,200)
setFont(25)
gc.setColor(color.white)
mStr(text.modeInfo[modeID[modeSel]],270,240)
setFont(75)
gc.setColor(color.grey)
mStr(text.modeName[modeSel],643,273)
for i=modeSel-2,modeSel+2 do
if i>=1 and i<=#modeID then
local f=75-abs(i-modeSel)*20
gc.setColor(i==modeSel and color.white or abs(i-modeSel)==1 and color.grey or color.darkGrey)
setFont(f)
mStr(text.modeName[i],640,310+70*(i-modeSel)-f*.5)
local cam=mapCam
gc.push("transform")
gc.translate(640,360)
gc.scale(cam.zoomK)
gc.translate(-cam.x1,-cam.y1)
gc.scale(cam.k1)
local MM,R=modes,modeRanks
for _=1,#MM do
local M=MM[_]
if R[_]then
gc.setLineWidth(8)
gc.setColor(1,1,1,.15)
for _=1,#M.unlock do
local m=M.unlock[_]
if R[m]then
m=MM[m]
gc.line(M.x,M.y,m.x,m.y)
end
end
local S=M.size
local d=((M.x-(cam.x1-180)/cam.k1)^2+(M.y-cam.y1/cam.k1)^2)^.5
if d<600 then S=S*(1.3-d*0.0005) end
gc.setColor(modeRankColor[modeRanks[M.id]])
if M.shape==1 then--Rectangle
gc.rectangle("fill",M.x-S,M.y-S,2*S,2*S)
if cam.sel==_ then
gc.setColor(1,1,1)
gc.setLineWidth(10)
gc.rectangle("line",M.x-S+5,M.y-S+5,2*S-10,2*S-10)
end
elseif M.shape==2 then--Octagon
gc.circle("fill",M.x,M.y,S,8)
if cam.sel==_ then
gc.setColor(1,1,1)
gc.setLineWidth(10)
gc.circle("line",M.x,M.y,S-5,8)
end
end
end
end
gc.pop()
if cam.sel then
local M=MM[cam.sel]
local lang=setting.lang
gc.setColor(.6,.6,.6,.5)
gc.rectangle("fill",920,0,360,720)--Info board
gc.setColor(M.color)
setFont(40)
mStr(M.name[lang],1030,5)
setFont(30)
mStr(M.level[lang],1030,50)
gc.setColor(1,1,1)
setFont(30)
gc.printf(M.info[lang],1100-180,130,360,"center")
local L=M.records
if L[1]then
mDraw(drawableText.highScore,1100,240)
gc.setColor(.3,.3,.3,.8)
gc.rectangle("fill",940,290,320,280)--Highscore board
gc.setColor(1,1,1)
setFont(23)
for i=1,#L do
gc.print(M.scoreDisp(L[i]),955,275+25*i)
end
elseif M.score then
mDraw(drawableText.noScore,1100,370)
end
end
if cam.keyCtrl then
gc.setColor(1,1,1)
gc.draw(mapCross,460-20,360-20)
end
end
function Pnt.music()
gc.setColor(1,1,1,.3+sin(Timer()*5)*.2)
@@ -350,7 +333,7 @@ function Pnt.draw()
local B=preField[y][x]
if B>0 then
gc.draw(blockSkin[B],30*x-30,600-30*y)
elseif B==-1 then
elseif B==-1 and not sceneTemp.demo then
gc.draw(cross,30*x-30,600-30*y)
end
end end
@@ -449,11 +432,11 @@ function Pnt.pause()
end
for i=1,8 do
gc.print(text.stat[i+3],110,30*i+270)
gc.print(dataOpt(i),305,30*i+270)
gc.print(sceneTemp[i],305,30*i+270)
end
for i=9,16 do
gc.print(text.stat[i+3],860,30*i+30)
gc.print(dataOpt(i),1050,30*i+30)
gc.print(sceneTemp[i],1050,30*i+30)
end
setFont(35)
if system~="Android"then
@@ -485,12 +468,12 @@ function Pnt.setting_sound()
local _=sceneTemp.jump
local x,y=800,340+10*sin(t*.5)+(_-10)*_*.3
gc.translate(x,y)
gc.draw(miya_ch,0,0)
gc.draw(miya.ch,0,0)
gc.setColor(1,1,1,.7)
gc.draw(miya_f1,4,47+4*sin(t*.9))
gc.draw(miya_f2,42,107+5*sin(t))
gc.draw(miya_f3,93,126+3*sin(t*.7))
gc.draw(miya_f4,129,98+3*sin(t*.7))
gc.draw(miya.f1,4,47+4*sin(t*.9))
gc.draw(miya.f2,42,107+5*sin(t))
gc.draw(miya.f3,93,126+3*sin(t*.7))
gc.draw(miya.f4,129,98+3*sin(t*.7))
gc.translate(-x,-y)
end
function Pnt.setting_key()
@@ -592,7 +575,7 @@ function Pnt.stat()
gc.setColor(1,1,1)
for i=1,18 do
gc.print(text.stat[i],400,30*i-5)
gc.print(statOpt(i),720,30*i-5)
gc.print(sceneTemp[i],720,30*i-5)
end
gc.draw(titleImage,260,600,.2+.07*sin(Timer()*3),nil,nil,206,35)
end
@@ -603,8 +586,9 @@ function Pnt.history()
gc.setLineWidth(4)
gc.rectangle("line",30,45,1000,632)
setFont(20)
for i=0,min(22,#updateLog-sceneTemp)do
gc.print(updateLog[sceneTemp+i],40,50+27*(i))
local _=sceneTemp
for i=0,min(22,#_[1]-_[2])do
gc.print(_[1][_[2]+i],40,50+27*(i))
end
end
return Pnt

10
parts/PCbase.lua Normal file
View File

@@ -0,0 +1,10 @@
return{
{3,3,3,0,0,0,0,0,2,2},
{3,6,6,0,0,0,0,2,2,5},
{4,6,6,0,0,0,1,1,5,5},
{4,4,4,0,0,0,0,1,1,5},
{1,1,0,0,0,0,0,4,4,4},
{5,1,1,0,0,0,0,6,6,4},
{5,5,2,2,0,0,0,6,6,3},
{5,2,2,0,0,0,0,3,3,3},
}

11
parts/PClist.lua Normal file
View File

@@ -0,0 +1,11 @@
return{
{7,7,4,5},{7,7,6,4},{7,7,2,4},{7,7,1,3},{7,7,5,6},{7,7,5,2},{7,7,5,4},{7,7,5,3},
{7,4,1,2},{7,3,5,7},{7,5,4,3},{7,5,1,2},{7,1,4,2},{7,4,2,5},{7,6,4,5},{7,5,4,2},
{7,5,6,4},{7,5,3,6},{7,2,5,6},{7,2,6,4},{7,2,1,3},{7,5,2,7},{7,5,7,2},{7,5,2,3},
{7,5,3,2},{7,6,5,4},{7,3,1,5},{7,3,2,5},{7,4,1,5},{7,4,5,2},{7,7,3,6},{7,3,7,6},
{7,3,6,2},{7,3,7,1},{7,6,4,2},{3,2,7,6},{3,2,6,7},{7,7,4,5},{7,5,3,4},{7,3,6,5},
{7,3,2,5},{7,4,6,5},{7,5,2,3},{7,3,5,7},{7,3,2,5},{7,3,5,1},{7,5,2,3},{3,6,2,5},
{3,1,2,5},{3,1,1,5},{3,1,5,2},{3,1,5,1},{3,5,1,2},{4,5,3,2},{4,2,6,5},{6,5,3,2},
{1,4,2,5},{1,5,3,6},{5,2,6,3},{5,2,1,3},{5,2,7,4},{2,4,1,5},{2,4,5,1},{2,1,4,5},
{2,5,4,3},{2,5,6,7},{7,5,4,2},{4,5,3,5},
}

17
parts/font.lua Normal file
View File

@@ -0,0 +1,17 @@
local new=love.graphics.setNewFont
local set=love.graphics.setFont
local F,cur={}
return function(s)
local f=F[s]
if s~=cur then
if f then
set(f)
else
f=new("font.ttf",s)
F[s]=f
set(f)
end
cur=s
end
return f
end

View File

@@ -3,8 +3,8 @@
--https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
local gc=love.graphics
local C=gc.clear
local shadowMapShader=gc.newShader("shadowMapShader.cs")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("lightRenderShader.cs")--Shader for rendering blurred lights and shadows.
local shadowMapShader=gc.newShader("parts/shader/shadowMap.cs")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("parts/shader/lightRender.cs")--Shader for rendering blurred lights and shadows.
Lights={}--Lightsource objects
local Lights=Lights
--Private--

37
parts/mino.lua Normal file
View File

@@ -0,0 +1,37 @@
local O,_=true,false
local L={
{{_,O,O},{O,O,_}}, --Z
{{O,O,_},{_,O,O}}, --S
{{O,O,O},{_,_,O}}, --L
{{O,O,O},{O,_,_}}, --J
{{O,O,O},{_,O,_}}, --T
{{O,O},{O,O}}, --O
{{O,O,O,O}}, --I
}
local function RotCW(B)
local N={}
local r,c=#B,#B[1]--row,col
for x=1,c do
N[x]={}
for y=1,r do
N[x][y]=B[y][c-x+1]
end
end
return N
end
-- [1,1,1]
-- [0,0,1]--r=2,c=3
-- ↓ (Y inv)
-- [1,1]
-- [1,0]
-- [1,0]
for i=1,#L do
local B=L[i]
L[i]={[0]=B}
B=RotCW(B)L[i][1]=B
B=RotCW(B)L[i][2]=B
B=RotCW(B)L[i][3]=B
end
return L

2
parts/shader.lua Normal file
View File

@@ -0,0 +1,2 @@
gc=love.graphics
shader_glow=gc.newShader("parts/shader/glow.cs")

View File

@@ -10,7 +10,7 @@ vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
float r=length(norm);
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
//根据离光源距离放大模糊系数,模拟影子淡出
float blur=(1./xresolution)*smoothstep(0.,1.,r);
float blur=(1./xresolution)*smoothstep(0.,1.,r);
//简易高斯模糊
float sum=

View File

@@ -5,7 +5,7 @@ vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
for(float y=0.;y<yresolution;y++){
//直角转极坐标
vec2 norm=vec2(texture_coords.s,y/yresolution)*2.-1.;
float theta=PI*1.5+norm.x*PI;
float theta=PI*1.5+norm.x*PI;
float r=(1.+norm.y)*.5;
//y/yresolution为到光源的距离(0~1)
//遮光物采样

1019
player.lua

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
local int,max,format=math.floor,math.max,string.format
local scene={
cur="load",--Current scene
swapping=false,--ifSwapping
@@ -9,7 +10,7 @@ local scene={
draw=nil, --Swap draw
},
seq={"quit","slowFade"},--Back sequence
}
}--scene datas,returned
local sceneInit={
quit=love.event.quit,
load=function()
@@ -49,6 +50,7 @@ local sceneInit={
curBG="none"
BGM("blank")
destroyPlayers()
mapCam.zoomK=scene.swap.tar=="mode"and 5 or 1
end,
custom=function()
sceneTemp=1--option select
@@ -58,7 +60,12 @@ local sceneInit={
end,
draw=function()
curBG="none"
sceneTemp={sure=0,pen=1,x=1,y=1}
sceneTemp={
sure=0,
pen=1,
x=1,y=1,
demo=false,
}
end,
play=function()
love.keyboard.setKeyRepeat(false)
@@ -72,7 +79,25 @@ local sceneInit={
curBG=modeEnv.bg
end,
pause=function()
curBG=modeEnv.bg
local S=players[1].stat
sceneTemp={
S.key,
S.rotate,
S.hold,
S.piece.." "..(int(S.piece/S.time*100)*.01).."PPS",
S.row.." "..(int(S.row/S.time*600)*.1).."LPM",
S.atk.." "..(int(S.atk/S.time*600)*.1).."APM",
S.send,
S.recv,
S.pend,
S.clear_1.."/"..S.clear_2.."/"..S.clear_3.."/"..S.clear_4,
"["..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,
max(100-int(S.extraRate/S.piece*10000)*.01,0).."%",
}
end,
setting_game=function()
curBG="none"
@@ -105,10 +130,32 @@ local sceneInit={
help=function()
curBG="none"
end,
stat=function()
local S=stat
sceneTemp={
S.run,
S.game,
format("%0.1fHr",S.time*2.78e-4),
S.key,
S.rotate,
S.hold,
S.piece,
S.row,
S.atk,
S.send,
S.recv,
S.pend,
S.clear_1.."/"..S.clear_2.."/"..S.clear_3.."/"..S.clear_4,
"["..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).."%]",
}
end,
history=function()
updateLog=require"updateLog"
curBG="lightGrey"
sceneTemp=1--scroll pos
sceneTemp={require("updateLog"),1}--scroll pos
end,
quit=function()
love.timer.sleep(.3)
@@ -128,19 +175,24 @@ local swapDeck_data={
}--Block id [ZSLJTOI] ,dir,x,y
local gc=love.graphics
local swap={
none={1,0,nil,NULL},
flash={8,1,nil,function()gc.clear(1,1,1)end},
fade={30,15,"swipe",function(t)
none={1,0,NULL},
flash={8,1,function()gc.clear(1,1,1)end},
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)
end},
slowFade={180,90,nil,function(t)
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)
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,nil,function(t)
deck={50,8,function(t)
gc.setColor(1,1,1)
if t>8 then
local t=t<15 and 15 or t
@@ -166,12 +218,12 @@ local backFunc={
pause=function()
love.keyboard.setKeyRepeat(true)
updateStat()
saveData()
saveStat()
clearTask("play")
end,
setting_game=function()
saveSetting()
end,
setting_game= function()saveSetting()end,
setting_graphic=function()saveSetting()end,
setting_sound= function()saveSetting()end,
}
function scene.init(s)
if sceneInit[s]then sceneInit[s]()end
@@ -196,8 +248,7 @@ function scene.swapTo(tar,style)
local swap=swap[style]
S.time=swap[1]
S.mid=swap[2]
if swap[3]then SFX(swap[3])end
S.draw=swap[4]
S.draw=swap[3]
widget_sel=nil
end
end

View File

@@ -1,2 +0,0 @@
gc=love.graphics
shader_glow=gc.newShader("shader/glow.cs")

View File

@@ -32,8 +32,8 @@ function SFX(s,v,pos)
end
end
function getVoice(str)
local n=1
local L=voiceBank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then

Some files were not shown because too many files have changed in this diff Show More