mod系统初版(三个mod未完成)

This commit is contained in:
MrZ626
2020-11-21 20:20:48 +08:00
parent c38ef7c487
commit 046d173090
12 changed files with 401 additions and 143 deletions

View File

@@ -433,6 +433,13 @@ function loadGame(M,ifQuickPlay)
STAT.lastPlay=M
GAME.curMode=MODES[M]
GAME.modeEnv=GAME.curMode.env
GAME.unranked=false
for _,mod in next,MODOPT do
if mod.sel>0 and mod.unranked then
GAME.unranked=true
end
end
print(GAME.unranked)
drawableText.modeName:set(text.modes[M][1])
drawableText.levelName:set(text.modes[M][2])
GAME.init=true

View File

@@ -1,120 +1,144 @@
local function disableKey(P,key)
table.insert(P.gameEnv.keyCancel,key)
end
MODOPT={--Mod options
{
name="noRotation",
list={false,true},
sel=1,
code=function(P)end,
time=0,
noNext={id="NL",
key="q",x=80,y=230,color=COLOR.red,
conflict={"hideNext","fullNext"},
func=function(P)P.gameEnv.nextCount=0 end,
},
{
name="noMove",
list={false,true},
sel=1,
code=function(P)end,
time=0,
hideNext={id="FL",
key="w",x=200,y=230,color=COLOR.red,
list={1,2,3,4,5},
conflict={"noNext"},
func=function(P,M)P.gameEnv.nextStartPos=M.list[M.sel]+1 end,
},
{
name="suddenMove",
list={false,true},
sel=1,
code=function(P)end,
time=0,
fullNext={id="FN",
key="e",x=320,y=230,color=COLOR.water,
conflict={"noNext"},
func=function(P)P.gameEnv.nextCount=6 end,
unranked=true,
},
noHold={id="HL",
key="r",x=440,y=230,color=COLOR.red,
func=function(P)P.gameEnv.holdCount=0 end,
},
hideBlock={id="HB",
key="y",x=680,y=230,color=COLOR.orange,
func=function(P)P.gameEnv.block=false end,
},
hideGhost={id="HG",
key="u",x=800,y=230,color=COLOR.orange,
func=function(P)P.gameEnv.ghost=false end,
},
hidden={id="HD",
key="o",x=1040,y=230,color=COLOR.green,
list={"time","fast","none"},
conflict={"coverBoard"},
func=function(P,M)P.gameEnv.visible=M.list[M.sel]end,
unranked=true,
},
coverBoard={id="CB",
key="p",x=1160,y=230,color=COLOR.green,
list={"down","up","all"},
conflict={"hidden"},
func=function(P)LOG.print("该mod还没有做好!")end,
},
{
name="noNext",
list={false,true},
sel=1,
code=function(P)end,
time=0,
maxG={id="20G",
key="a",x=140,y=350,color=COLOR.red,
conflict={"minG","suddenLock"},
func=function(P)P.gameEnv.drop=0 end,
unranked=true,
},
{
name="noHold",
list={false,true},
sel=1,
code=function(P)end,
time=0,
suddenLock={id="SL",
key="s",x=260,y=350,color=COLOR.red,
conflict={"maxG","infLock"},
func=function(P)P.gameEnv.lock=0 end,
unranked=true,
},
{
name="hideNext",
list={0,1,2,3,4,5,6},
sel=1,
code=function(P)end,
time=0,
oneLife={id="SD",
key="d",x=380,y=350,color=COLOR.red,
conflict={"infLife"},
func=function(P)P.gameEnv.life=0 end,
unranked=true,
},
{
name="hideBlock",
list={false,true},
sel=1,
code=function(P)end,
time=0,
noTele={id="NT",
key="f",x=500,y=350,color=COLOR.red,
conflict={"teleMove"},
func=function(P)P.gameEnv.noTele=true end,
unranked=true,
},
{
name="hideGhost",
list={false,true},
sel=1,
code=function(P)end,
time=0,
forceB2B={id="FB",
key="h",x=740,y=350,color=COLOR.yellow,
func=function(P)P.gameEnv.b2bKill=true end,
},
forceFinesse={id="PF",
key="j",x=860,y=350,color=COLOR.yellow,
func=function(P)P.gameEnv.fineKill=true end,
},
mirror={id="MR",
key="k",x=980,y=350,color=COLOR.yellow,
func=function(P)LOG.print("该mod还没有做好!")end,
},
flip={id="HR",
key="l",x=1100,y=350,color=COLOR.yellow,
func=function(P)LOG.print("该mod还没有做好!")end,
},
{
name="mirror",
list={false,true},
sel=1,
code=function(P)end,
time=0,
minG={id="0G",
key="z",x=200,y=470,color=COLOR.cyan,
conflict={"maxG"},
func=function(P)P.gameEnv.drop=1e99 end,
unranked=true,
},
{
name="flip",
list={false,true},
sel=1,
code=function(P)end,
time=0,
infLock={id="IF",
key="x",x=320,y=470,color=COLOR.cyan,
conflict={"suddenLock"},
func=function(P)P.gameEnv.lock=1e99 end,
unranked=true,
},
{
name="hidden",
list={false,true},
sel=1,
code=function(P)end,
time=0,
infLife={id="NF",
key="c",x=440,y=470,color=COLOR.cyan,
conflict={"oneLife"},
func=function(P)P.gameEnv.life=1e99 end,
unranked=true,
},
{
name="hideUp",
list={false,true},
sel=1,
code=function(P)end,
time=0,
teleMove={id="TL",
key="v",x=560,y=470,color=COLOR.cyan,
conflict={"noTele"},
func=function(P)
P.gameEnv.das,P.gameEnv.arr=0,0
P.gameEnv.sddas,P.gameEnv.sdarr=0,0
disableKey(P,14)
disableKey(P,15)
disableKey(P,16)
end,
unranked=true,
},
{
name="hideDown",
list={false,true},
sel=1,
code=function(P)end,
time=0,
randSeq={id="RS",
key="b",x=680,y=470,color=COLOR.purple,
func=function(P)P.gameEnv.sequence="rnd"end,
unranked=true,
},
{
name="_20G",
list={false,true},
sel=1,
code=function(P)end,
time=0,
noRotation={id="FX",
key="n",x=800,y=470,color=COLOR.red,
func=function(P)
disableKey(P,3)
disableKey(P,4)
disableKey(P,5)
end,
},
{
name="suddenLock",
list={false,true},
sel=1,
code=function(P)end,
time=0,
noMove={id="ST",
key="m",x=920,y=470,color=COLOR.red,
func=function(P)
disableKey(P,1)disableKey(P,2)
disableKey(P,11)disableKey(P,12)
disableKey(P,17)disableKey(P,18)
disableKey(P,19)disableKey(P,20)
end,
},
{
name="infLives",
list={false,true},
sel=1,
code=function(P)end,
time=0,
},
}
}for _,M in next,MODOPT do M.sel,M.time=0,0 end
CUSTOMENV={--gameEnv for cutsom game
--Basic
@@ -147,6 +171,7 @@ CUSTOMENV={--gameEnv for cutsom game
noTele=false,
fineKill=false,
b2bKill=false,
missionKill=false,
easyFresh=true,
visible="show",
@@ -162,9 +187,7 @@ CUSTOMENV={--gameEnv for cutsom game
}
FIELD={}--Field(s) for custom game
BAG={}--Sequence for custom game
MISSION={}--Clearing mission for custom game
GAME={--Global game data
@@ -178,12 +201,15 @@ GAME={--Global game data
garbageSpeed=1, --Garbage timing speed
warnLVL0=0, --Warning level
warnLVL=0, --Warning level (show)
recording=false, --If recording
replaying=false, --If replaying
seed=math.random(2e6),--Game seed
seed=1046101471, --Game seed
curMode=nil, --Current gamemode object
modeEnv=nil, --Current gamemode environment
setting={}, --Game settings
rec={}, --Recording list, key,time,key,time...
recording=false, --If recording
replaying=false, --If replaying
unranked=nil, --unranked if specific mod is on
rank=nil, --Rank reached
prevBG=nil, --Previous background, for restore BG when quit setting page

View File

@@ -89,6 +89,8 @@ return{
errorMsg="An error has occurred and Techmino needs to restart.\nError info has been created, and you can send it to the author.",
-- modInstruction="",
-- modInfo={},--See lang_zh.lua
acts={
"Move Left:","Move Right:",
"Rotate Right:","Rotate Left:","Rotate 180°:",
@@ -186,8 +188,13 @@ return{
minigame="Mini Games",
},
mode={
mod="Mods (F1)",
start="Start",
},
mod={
title="Mods",
unranked="Unranked",
},
play={
pause="Pause",
},

View File

@@ -92,6 +92,8 @@ return{
errorMsg="Une erreur est survenue et Techmino doit redémarrer.\nDes informations concernant l'erreur ont été créées, et vous pouvez les envoyer au créateur.",
-- modInstruction="",
-- modInfo={},--See lang_en.lua
acts={
"Déplacement vers la gauche :","Déplacement vers la droite :",
"Rotation vers la droite:","Rotation vers la gauche :","180° :",
@@ -99,7 +101,6 @@ return{
"Déplacement instantané vers la gauche :","Déplacement instantané vers la droite : ","Chute sonique :","Descendre de 1 :","Descendre de 4 :","Descendre de 10 :",
"Chute à gauche :","Chute à droite :","Zangi gauche :","Zangi droite :",
},
load={[0]="Terminé","Chargement de la voix","Chargement de la musique","Chargement des effets sonores","Chargement des images","Chargement des polices","chargement des modes","Loading other things"},
pauseStat={
"Temps :",
"Touche/Rot./Réserve :",
@@ -190,8 +191,13 @@ return{
minigame="Minijeux",
},
mode={
-- mod="Mods (F1)",
start="Démarrer",
},
mod={
-- title="Mods",
-- unranked="Unranked",
},
play={
pause="Pause",
},

View File

@@ -92,6 +92,8 @@ return{
errorMsg="Ha ocurrido un error y Techmino necesita reiniciarse.\nSe creó un registro de error, puedes enviarlo al autor.",
-- modInstruction="",
-- modInfo={},--See lang_en.lua
acts={
"Mover a Izq.:","Mover a Der.:",
"Rotar Der.:","Rotar Izq.:","Rotar 180°:",
@@ -101,8 +103,6 @@ return{
"Izq. Instant.:","Der. Instant.:","Sonic Drop:","Abajo 1:","Abajo 4:","Abajo 10:",
"Caída a Izq.:","Caída a Der.:","Zangi a Izq.:","Zangi a Der.:",
},
load={[0]="Terminado","Cargando voces","Cargando bgm","Cargando sfx","Cargando imágenes","Cargando fuentes","Cargando modos","Cargando otras cosas"},
pauseStat={
"Tiempo:",
"Tecla/Rot./Reserva:",
@@ -194,8 +194,13 @@ return{
minigame="Minijuegos",
},
mode={
-- mod="Mods (F1)",
start="Empezar",
},
mod={
-- title="Mods",
-- unranked="Unranked",
},
play={
pause="Pausa",
},

View File

@@ -124,8 +124,13 @@ return{
minigame="^_^",
},
mode={
mod="?!?!?!(F1)",
start="!!!",
},
mod={
title="?!?!?!",
unranked="X!!!",
},
play={
pause="||",
},

View File

@@ -90,6 +90,32 @@ return{
errorMsg="Techmino遭受了雷击,需要重新启动.\n我们已收集了一些错误信息,你可以向作者进行反馈.",
modInstruction="选择你要使用的Mod!\n不同的Mod会用不同的方式改变游戏规则,来开发新玩法挑战自我吧!\n提醒:开启一些Mod会让成绩无效 你可以用键盘开关Mod,按tab重置",
modInfo={
noNext="无Next:\n禁用Next",
hideNext="隐藏Next:\n隐藏前几个Next",
fullNext="全Next:\n强制打开6Next",
noHold="无Hold:\n禁用Hold",
hideBlock="隐藏方块:\n隐藏当前方块",
hideGhost="隐藏阴影:\n隐藏提示阴影",
hidden="隐形:\n方块将会在锁定之后隐形",
coverBoard="遮挡:\n遮挡部分/全部场地",
maxG="20G:\n强制启用最高下落速度",
suddenLock="0锁延:\n强制启用0锁定延迟",
oneLife="一命:\n只有一条生命!",
noTele="简单操作:\n禁用10个高级操作按键",
forceB2B="禁断B2B:\nB2B条掉到启动线以下就会结束游戏",
forceFinesse="禁非极简:\n非极简操作将强制结束游戏",
mirror="镜像:\n场地左右颠倒",
flip="翻转:\n场地上下颠倒",
minG="0G:\n关闭重力",
infLock="无限锁延:\n方块将不会锁定",
infLife="不死:\n无限生命数",
teleMove="瞬移:\n强制启用0DAS和0ARR",
randSeq="随机序列:\n强制使用随机序列",
noRotation="无旋转:\n禁用旋转按键",
noMove="无移动:\n禁用移动按键",
},
acts={
"左移:","右移:",
"顺时针旋转:","逆时针旋转:","180°旋转:",
@@ -99,7 +125,6 @@ return{
"左瞬移:","右瞬移:","软降到底:","软降一格:","软降四格:","软降十格:",
"落在最左:","落在最右:","列在最左:","列在最右:",
},
pauseStat={
"时间:",
"按键/旋转/暂存:",
@@ -191,8 +216,13 @@ return{
minigame="小游戏",
},
mode={
mod="Mods (F1)",
start="开始",
},
mod={
title="Mods",
unranked="成绩无效",
},
play={
pause="暂停",
},

View File

@@ -27,6 +27,32 @@ return{
ranks={"","","","",""},
modInstruction="选择你要使用的模组!\n不同的模组会用不同的方式改变游戏规则,来开发新玩法挑战自我吧!\n提醒:开启一些模组会让成绩无效 你可以用键盘开关模组,按tab重置",
modInfo={
noNext="无预览:\n禁用预览",
hideNext="隐藏预览:\n隐藏前几个预览",
fullNext="全预览:\n强制打开6预览",
noHold="无暂存:\n禁用暂存",
hideBlock="隐藏方块:\n隐藏当前方块",
hideGhost="隐藏阴影:\n隐藏提示阴影",
hidden="隐形:\n方块将会在锁定之后隐形",
coverBoard="遮挡:\n遮挡部分/全部场地",
maxG="20G:\n强制启用最高下落速度",
suddenLock="0锁延:\n强制启用0锁定延迟",
oneLife="一命:\n只有一条生命!",
noTele="简单操作:\n禁用10个高级操作按键",
forceB2B="禁断满贯:\n满贯点数掉到启动线以下就会结束游戏",
forceFinesse="禁非极简:\n非极简操作将强制结束游戏",
mirror="镜像:\n场地左右颠倒",
flip="翻转:\n场地上下颠倒",
minG="0G:\n关闭重力",
infLock="无限锁延:\n方块将不会锁定",
infLife="不死:\n无限生命数",
teleMove="瞬移:\n强制启用0DAS和0ARR",
randSeq="随机序列:\n强制使用随机序列",
noRotation="无旋转:\n禁用旋转按键",
noMove="无移动:\n禁用移动按键",
},
pauseStat={
"时间:",
"按键/旋转/暂存:",
@@ -49,6 +75,12 @@ return{
"挖/分",
},
WidgetText={
mode={
mod="模组(F1)",
},
mod={
title="模组",
},
setting_control={
das="首次移动延迟",arr="移动重复延迟",
sddas="首次软降延迟",sdarr="软降重复延迟",
@@ -63,6 +95,15 @@ return{
spin6="",
spin7="",
},
custom_advance={
nextCount="Next个数",
holdCount="暂存个数",
infHold="无限暂存",
mindas="最小首次移动延迟",
minarr="最小移动重复延迟",
minsdarr="最小软降重复延迟",
},
music={
bgm="音乐",
},

View File

@@ -197,7 +197,7 @@ local function loadGameEnv(P)--Load gameEnv
--Load game settings
for k,v in next,gameEnv0 do
if GAME.modeEnv[k]~=nil then
v=GAME.modeEnv[k] --Mode setting
v=GAME.modeEnv[k] --Mode setting
-- DBP("mode-"..k..":"..tostring(v))
elseif GAME.setting[k]~=nil then
v=GAME.setting[k] --Game setting
@@ -214,6 +214,11 @@ local function loadGameEnv(P)--Load gameEnv
ENV[k]=copyTable(v)
end
end
for _,M in next,MODOPT do
if M.sel>0 then
M.func(P,M)
end
end
end
local function applyGameEnv(P)--Finish gameEnv processing
local ENV=P.gameEnv

View File

@@ -1342,45 +1342,49 @@ local function gameOver()--Save record
local P=PLAYERS[1]
R=R(P)--New rank
if R then
local r=RANKS[M.name]--Old rank
local needSave
if R>r then
RANKS[M.name]=R
needSave=true
end
if R>0 then
GAME.rank=R
if M.unlock then
for i=1,#M.unlock do
local m=M.unlock[i]
local n=MODES[m].name
if not RANKS[n]then
RANKS[n]=MODES[m].getRank and 0 or 6
needSave=true
end
if not GAME.unranked then
local r=RANKS[M.name]--Old rank
local needSave
if R>r then
RANKS[M.name]=R
needSave=true
end
if R>0 then
if M.unlock then
for i=1,#M.unlock do
local m=M.unlock[i]
local n=MODES[m].name
if not RANKS[n]then
RANKS[n]=MODES[m].getRank and 0 or 6
needSave=true
end
end
end
end
end
if needSave then
FILE.saveUnlock()
end
local D=M.score(P)
local L=M.records
local p=#L--Rank-1
if p>0 then
while M.comp(D,L[p])do--If higher rank
p=p-1
if p==0 then break end
if needSave then
FILE.saveUnlock()
end
end
if p<10 then
if p==0 then
P:showTextF(text.newRecord,0,-100,100,"beat",.5)
local D=M.score(P)
local L=M.records
local p=#L--Rank-1
if p>0 then
while M.comp(D,L[p])do--If higher rank
p=p-1
if p==0 then break end
end
end
if p<10 then
if p==0 then
P:showTextF(text.newRecord,0,-100,100,"beat",.5)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
FILE.saveRecord(M.name,L)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
FILE.saveRecord(M.name,L)
end
end
end

119
parts/scenes/mod.lua Normal file
View File

@@ -0,0 +1,119 @@
local gc=love.graphics
local function checkunranked()
for _,M in next,MODOPT do
if M.sel>0 and M.unranked then
return true
end
end
end
local function toggleMod(M)
if M.list then
M.sel=(M.sel+1)%(#M.list+1)
else
M.sel=1-M.sel
end
if M.sel>0 and M.conflict then
for _,v in next,M.conflict do
MODOPT[v].sel=0
end
end
sceneTemp.unranked=checkunranked()
SFX.play("move")
end
function sceneInit.mod()
sceneTemp={
sel=nil,--selected mod name
unranked=checkunranked(),--if unranked
}
BG.set("tunnel")
end
function mouseMove.mod(x,y)
sceneTemp.sel=nil
for N,M in next,MODOPT do
if(x-M.x)^2+(y-M.y)^2<1600 then
sceneTemp.sel=N
break
end
end
end
function mouseDown.mod(x,y,k)
if k==1 then
for _,M in next,MODOPT do
if(x-M.x)^2+(y-M.y)^2<1600 then
toggleMod(M)
break
end
end
elseif k==2 then
SCN.back()
end
end
function keyDown.mod(key)
if key=="tab"or key=="delete"or key=="`"then
for _,M in next,MODOPT do
M.sel=0
end
elseif #key==1 then
for N,M in next,MODOPT do
if key==M.key then
toggleMod(M)
sceneTemp.sel=N
break
end
end
elseif key=="escape"then
SCN.back()
end
end
function Tmr.mod()
for _,M in next,MODOPT do
if M.sel==0 then
if M.time>0 then
M.time=M.time-1
end
else
if M.time<10 then
M.time=M.time+1
end
end
end
end
function Pnt.mod()
setFont(40)
gc.setLineWidth(4)
for _,M in next,MODOPT do
gc.push("transform")
gc.translate(M.x,M.y)
local t=M.time*.01
gc.scale(1+3*t)
gc.rotate(t)
local color=M.color
gc.setColor(color[1],color[2],color[3],5*t)
gc.circle("fill",0,0,40)
gc.setColor(color)
gc.circle("line",0,0,40)
gc.setColor(1,1,1)
mStr(M.id,0,-28)
if M.sel>0 and M.list then
setFont(25)
gc.setColor(1,1,1,10*t)
mStr(M.list[M.sel],20,8)
setFont(40)
end
gc.pop()
end
setFont(30)
gc.printf(sceneTemp.sel and text.modInfo[sceneTemp.sel]or text.modInstruction,70,540,950)
end
WIDGET.init("mod",{
WIDGET.newText({name="title",x=80,y=50,font=70,align="L"}),
WIDGET.newText({name="unranked",x=1200,y=60,color="lRed",font=50,align="R",hide=function()return not sceneTemp.unranked end}),
WIDGET.newButton({name="back",x=1140,y=640,w=170,h=80,font=40,code=WIDGET.lnk_BACK}),
})

View File

@@ -123,6 +123,8 @@ function keyDown.mode(key)
SCN.push()
loadGame(mapCam.sel)
end
elseif key=="f1"then
SCN.go("mod")
elseif key=="escape"then
if mapCam.sel then
mapCam.sel=nil
@@ -307,6 +309,7 @@ function Pnt.mode()
end
WIDGET.init("mode",{
WIDGET.newButton({name="start",x=1040,y=655,w=180,h=80,font=40,code=WIDGET.lnk_pressKey("return"),hide=function()return not mapCam.sel end}),
WIDGET.newButton({name="back",x=1200,y=655,w=120,h=80,font=40,code=WIDGET.lnk_BACK}),
WIDGET.newKey({name="mod", x=140,y=655,w=210,h=80,font=35,code=WIDGET.lnk_goScene("mod")}),
WIDGET.newButton({name="start", x=1040,y=655,w=180,h=80,font=40,code=WIDGET.lnk_pressKey("return"),hide=function()return not mapCam.sel end}),
WIDGET.newButton({name="back", x=1200,y=655,w=120,h=80,font=40,code=WIDGET.lnk_BACK}),
})