Skip to content

Commit 9f9d418

Browse files
committed
invis模式新增haunted子模式
1 parent df8e091 commit 9f9d418

File tree

2 files changed

+211
-46
lines changed

2 files changed

+211
-46
lines changed

assets/game/mechanicLib/brik/misc.lua

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -469,10 +469,10 @@ do -- Variabal Next
469469
end
470470

471471
do -- Haunted
472+
local default_spreadTime=26
473+
local default_lifeTime=260
472474
local default_lightVisTimer=1000
473475
local default_lightFadeTime=800
474-
local default_spreadTime=50
475-
local default_lifeTime=1000
476476

477477
---@class Techmino.Mech.Brik.HauntedLight
478478
---@field x integer
@@ -483,6 +483,21 @@ do -- Haunted
483483
---@field listKey number
484484
---@field mapKey string
485485

486+
local function delLight(P,c0)
487+
local md=P.modeData
488+
---@type Techmino.Mech.Brik.HauntedLight[]
489+
local list=md.ghostLight_List
490+
---@type Map<Techmino.Mech.Brik.HauntedLight>
491+
local map=md.ghostLight_Map
492+
493+
map[c0.mapKey]=nil
494+
if c0.listKey==#list then
495+
list[c0.listKey]=nil
496+
else
497+
list[#list].listKey=c0.listKey
498+
list[c0.listKey],list[#list]=list[#list],nil
499+
end
500+
end
486501
local function newLight(P,x,y,power)
487502
local md=P.modeData
488503
if not (x>=1 and x<=P.settings.fieldW and y>=1 and y<=P.field:getHeight()) then return end
@@ -515,23 +530,9 @@ do -- Haunted
515530
}
516531
list[l.listKey],map[x..','..y]=l,l
517532
end
518-
local function delLight(P,c0)
519-
local md=P.modeData
520-
---@type Techmino.Mech.Brik.HauntedLight[]
521-
local list=md.ghostLight_List
522-
---@type Map<Techmino.Mech.Brik.HauntedLight>
523-
local map=md.ghostLight_Map
524-
525-
map[c0.mapKey]=nil
526-
if c0.listKey==#list then
527-
list[c0.listKey]=nil
528-
else
529-
list[#list].listKey=c0.listKey
530-
list[c0.listKey],list[#list]=list[#list],nil
531-
end
532-
end
533-
misc.haunted_newLight=newLight
534533
misc.haunted_delLight=delLight
534+
misc.haunted_newLight=newLight
535+
---@type fun(P:Techmino.Player.Brik,spreadTime:number,lifeTime:number,visTime:number,fadeTime:number)
535536
function misc.haunted_turnOn(P,spreadTime,lifeTime,visTime,fadeTime)
536537
if not P.modeData.ghostLight_powerID then
537538
P.modeData.ghostLight_powerID=0
@@ -541,17 +542,18 @@ do -- Haunted
541542
P:addEvent('afterLock',mechLib.brik.misc.haunted_afterLock)
542543
-- P:addEvent('drawInField',mechLib.brik.misc.haunted_drawInField)
543544
end
544-
P.modeData.ghostLight_lightVisTimer=visTime or P.modeData.ghostLight_lightVisTimer or default_lightVisTimer
545-
P.modeData.ghostLight_lightFadeTime=fadeTime or P.modeData.ghostLight_lightFadeTime or default_lightFadeTime
546545
P.modeData.ghostLight_spreadTime=spreadTime or P.modeData.ghostLight_spreadTime or default_spreadTime
547546
P.modeData.ghostLight_lifeTime=lifeTime or P.modeData.ghostLight_lifeTime or default_lifeTime
547+
P.modeData.ghostLight_lightVisTimer=visTime or P.modeData.ghostLight_lightVisTimer or default_lightVisTimer
548+
P.modeData.ghostLight_lightFadeTime=fadeTime or P.modeData.ghostLight_lightFadeTime or default_lightFadeTime
548549
end
549550
function misc.haunted_always(P)
550551
local list=P.modeData.ghostLight_List
551552
for i=#list,1,-1 do
552553
---@type Techmino.Mech.Brik.HauntedLight
553554
local c=list[i]
554555
local x,y=c.x,c.y
556+
local discard
555557
if c.spreadTimer then
556558
c.spreadTimer=c.spreadTimer-1
557559
if c.spreadTimer<=0 then
@@ -561,16 +563,27 @@ do -- Haunted
561563
newLight(P,x,y+1,c.power)
562564
c.spreadTimer=nil
563565
end
566+
elseif not P.field:getCell(x,y) then
567+
discard=true
568+
else
569+
c.lifeTimer=c.lifeTimer-1
570+
if c.lifeTimer<=0 then
571+
discard=true
572+
end
564573
end
565-
c.lifeTimer=c.lifeTimer-1
566-
if c.lifeTimer<=0 or not P.field:getCell(x,y) then
574+
if discard then
567575
delLight(P,c)
568576
end
569577
end
570578
end
571579
function misc.haunted_afterLock(P)
572-
P.modeData.ghostLight_powerID=P.modeData.ghostLight_powerID+1
573-
newLight(P,P.handX,P.handY,P.modeData.ghostLight_powerID)
580+
local powID=P.modeData.ghostLight_powerID+1
581+
P.modeData.ghostLight_powerID=powID
582+
local bx,by=P.handX-1,P.handY-1
583+
local B=P.hand.matrix
584+
for y=1,#B do for x=1,#B[1] do
585+
if B[y][x] then newLight(P,bx+x,by+y,powID) end
586+
end end
574587
end
575588
function misc.haunted_drawInField(P)
576589
-- Debugging use

assets/game/mode/brik/exterior/invis.lua

Lines changed: 174 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
local max,min=math.max,math.min
2+
local floor,abs=math.floor,math.abs
3+
local ins=table.insert
4+
local cIntp=MATH.clampInterpolate
5+
6+
-- Speed of Invisible EP:
7+
-- Phase 1: 126 BPM (476.2 ms/Beat)
8+
-- Phase 2: 143 BPM (419.6 ms/Beat)
9+
-- Phase 3: 160 BPM (375.0 ms/Beat)
10+
11+
local function haunted_p2_afterSpawn(P)
12+
local N=P.nextQueue[#P.nextQueue]
13+
if not N then return end
14+
N=N.matrix
15+
local cellList={}
16+
for y=1,#N do for x=1,#N[1] do if N[y][x] then
17+
ins(cellList,N[y][x])
18+
end end end
19+
for _,cell in next,cellList do
20+
if P:roll(P.modeData.cyanizeRate/100) then
21+
cell.color=186
22+
end
23+
end
24+
end
25+
local function haunted_p3_afterSpawn(P)
26+
local N=P.nextQueue[#P.nextQueue]
27+
if not N then return end
28+
N=N.matrix
29+
local cellList={}
30+
for y=1,#N do for x=1,#N[1] do if N[y][x] then
31+
ins(cellList,N[y][x])
32+
end end end
33+
for _,cell in next,cellList do
34+
if P:roll(P.modeData.deColorRate/100) then
35+
cell.color=P:roll(P.modeData.darkRate/100) and 222 or 444
36+
end
37+
end
38+
end
39+
regFuncLib(haunted_p2_afterSpawn,'exterior_invis.haunted_p2_afterSpawn')
40+
regFuncLib(haunted_p3_afterSpawn,'exterior_invis.haunted_p3_afterSpawn')
41+
142
---@type Techmino.Mode
243
return {
344
initialize=function()
@@ -6,43 +47,154 @@ return {
647
playBgm('sugar fairy')
748
end,
849
settings={brik={
50+
pieceVisTime=1000,
51+
pieceFadeTime=1000,
952
event={
1053
playerInit=function(P)
11-
P.settings.pieceVisTime=260
12-
P.settings.pieceFadeTime=260
1354
P.modeData.maxSimplicity=0
1455
P.modeData.simplicity=0
1556
P.modeData.target.line=100
16-
mechLib.common.music.set(P,{path='stat.line',s=50,e=100},'afterClear')
57+
58+
local T=mechLib.common.task
59+
T.install(P)
60+
T.add(P,'invis_haunted','modeTask_invis_haunted_title','modeTask_invis_haunted_desc','(0/4)')
61+
if PROGRESS.getExteriorModeScore('invis','showHaunted') then
62+
T.add(P,'invis_hidden','modeTask_invis_hidden_title','modeTask_invis_hidden_desc')
63+
end
64+
if not PROGRESS.getExteriorModeScore('invis','showHaunted') then
65+
T.add(P,'invis_hidden','modeTask_invis_hidden_title','modeTask_invis_hidden_desc')
66+
end
1767
end,
1868
afterClear={
19-
mechLib.brik.misc.lineClear_event_afterClear,
2069
function(P,clear)
21-
if clear.line<4 then
22-
P.modeData.simplicity=P.modeData.simplicity+(5-clear.line)
70+
local T=mechLib.common.task
71+
T.set(P,'invis_haunted',P.stat.line/4,"("..P.stat.line.."/4)")
72+
if clear.line>=4 then
73+
P.modeData.subMode='hidden'
74+
T.set(P,'invis_hidden',true)
2375
else
24-
P.modeData.simplicity=P.modeData.simplicity-2
76+
if P.stat.line>=4 then
77+
P.modeData.subMode='haunted'
78+
T.set(P,'invis_haunted',true,"(4/4)")
79+
end
80+
end
81+
if P.modeData.subMode then
82+
if P.modeData.subMode=='haunted' then
83+
-- Haunted Phase 1 init
84+
P.settings.spawnDelay=238
85+
P.settings.clearDelay=476
86+
playBgm('invisible')
87+
PROGRESS.setBgmUnlocked('invisible mode',1)
88+
if FMOD.music.getParam('section')>0 then
89+
FMOD.music.setParam('section',0)
90+
FMOD.music.seek(0)
91+
end
92+
elseif P.modeData.subMode=='hidden' then
93+
P.settings.pieceVisTime=260
94+
P.settings.pieceFadeTime=260
95+
mechLib.common.music.set(P,{path='stat.line',s=50,e=100},'afterClear')
96+
end
97+
return true
98+
end
99+
end,
100+
function(P,clear)
101+
---@cast P Techmino.Player.Brik
102+
if P.modeData.subMode=='haunted' then
103+
local bLine,curLine=P.stat.line-clear.line,P.stat.line
104+
if bLine<100 and curLine>=100 then
105+
-- Haunted Phase 2 init
106+
P.modeData.target.line=200
107+
P.settings.spawnDelay=210
108+
P.settings.clearDelay=420
109+
P:addEvent('afterSpawn',haunted_p2_afterSpawn)
110+
FMOD.music.setParam('section',1)
111+
PROGRESS.setBgmUnlocked('invisible mode 2',1)
112+
elseif bLine<200 and curLine>=200 then
113+
-- Haunted Phase 3 init
114+
P.modeData.target.line=260
115+
P.settings.spawnDelay=375
116+
P.settings.clearDelay=0
117+
P.settings.dropDelay=94
118+
P:delEvent('afterSpawn',haunted_p2_afterSpawn)
119+
P:addEvent('afterSpawn',haunted_p3_afterSpawn)
120+
mechLib.brik.misc.haunted_turnOn(P,62,120,600,1000)
121+
FMOD.music.setParam('section',2)
122+
PROGRESS.setBgmUnlocked('total mayhem',1)
123+
elseif bLine<260 and curLine>=260 then
124+
P:finish('win')
125+
FMOD.music.setParam('section',3)
126+
return true
127+
end
128+
129+
if curLine<100 then
130+
-- Haunted Phase 1 step
131+
P.settings.dropDelay=floor(cIntp(20,476,80,238,MATH.clamp(curLine,20,80)))
132+
mechLib.brik.misc.haunted_turnOn(P,
133+
floor(cIntp(70,5,90,20,curLine)),
134+
260,
135+
floor(cIntp(0,1600,80,600,curLine)),
136+
floor(cIntp(0,600,80,300,curLine))
137+
)
138+
elseif curLine<200 then
139+
-- Haunted Phase 2 step
140+
P.settings.dropDelay=floor(cIntp(120,210,180,105,MATH.clamp(curLine,120,180)))
141+
P.modeData.cyanizeRate=floor(cIntp(102,16,126,100,curLine))
142+
mechLib.brik.misc.haunted_turnOn(P,
143+
floor(cIntp(100,26,200,42,curLine)),
144+
260,
145+
floor(cIntp(100,500,150,300,curLine)),
146+
floor(cIntp(100,300,150,200,curLine))
147+
)
148+
else
149+
-- Haunted Phase 3 step
150+
P.modeData.deColorRate=floor(cIntp(200,0,230,42,curLine))
151+
P.modeData.darkRate=floor(cIntp(220,26,240,62,curLine))
152+
end
153+
elseif P.modeData.subMode=='hidden' then
154+
if P.stat.line>=P.modeData.target.line then
155+
P:finish('win')
156+
else
157+
if clear.line<4 then
158+
P.modeData.simplicity=P.modeData.simplicity+(5-clear.line)
159+
else
160+
P.modeData.simplicity=P.modeData.simplicity-2
161+
end
162+
P.modeData.simplicity=min(P.modeData.simplicity,62-floor(P.stat.line/5))
163+
P.modeData.maxSimplicity=max(P.modeData.maxSimplicity,P.modeData.simplicity)
164+
P.settings.pieceVisTime=floor(MATH.cLerp(260,2e3,P.modeData.simplicity/62))
165+
P.settings.pieceFadeTime=floor(MATH.cLerp(260,1e3,P.modeData.simplicity/62))
166+
end
25167
end
26-
P.modeData.simplicity=math.min(P.modeData.simplicity,62-math.floor(P.stat.line/5))
27-
P.modeData.maxSimplicity=math.max(P.modeData.maxSimplicity,P.modeData.simplicity)
28-
P.settings.pieceVisTime=math.floor(MATH.cLerp(260,2e3,P.modeData.simplicity/62))
29-
P.settings.pieceFadeTime=math.floor(MATH.cLerp(260,1e3,P.modeData.simplicity/62))
30168
end,
31169
},
32170
drawInField=mechLib.brik.misc.lineClear_event_drawInField,
33-
drawOnPlayer=mechLib.brik.misc.lineClear_event_drawOnPlayer,
171+
drawOnPlayer=function(P)
172+
P:drawInfoPanel(-380,-80,160,160)
173+
GC.setColor(COLOR.L)
174+
FONT.set(70)
175+
GC.mStr(P.stat.line,-300,-90)
176+
GC.rectangle('fill',-375,-2,150,4)
177+
GC.mStr(P.modeData.target.line,-300,-5)
178+
end,
34179
gameOver=function(P,reason)
35-
PROGRESS.setExteriorScore('invis','line',math.min(P.stat.line,100))
36-
if reason=='AC' then
37-
PROGRESS.setExteriorScore('invis','easy',P.gameTime,'<')
38-
if P.modeData.maxSimplicity<=12 then
39-
PROGRESS.setExteriorScore('invis','hard',P.gameTime,'<')
40-
P:showInvis(1,P.settings.pieceFadeTime/2)
41-
else
42-
P:showInvis(2,P.settings.pieceFadeTime)
180+
if P.modeData.subMode=='haunted' then
181+
PROGRESS.setExteriorScore('invis','haunted',min(P.stat.line,260),'>')
182+
if reason=='AC' then
183+
PROGRESS.setExteriorScore('invis','haunted_time',P.gameTime,'<')
43184
end
44-
if P.stat.clears[1]+P.stat.clears[2]+P.stat.clears[3]==0 then
45-
PROGRESS.setSecret('exterior_invis_superBrain')
185+
elseif P.modeData.subMode=='hidden' then
186+
PROGRESS.setExteriorScore('invis','line',min(P.stat.line,100),'>')
187+
if reason=='AC' then
188+
PROGRESS.setExteriorScore('invis','easy',P.gameTime,'<')
189+
if P.modeData.maxSimplicity<=12 then
190+
PROGRESS.setExteriorScore('invis','hard',P.gameTime,'<')
191+
P:showInvis(1,P.settings.pieceFadeTime/2)
192+
else
193+
P:showInvis(2,P.settings.pieceFadeTime)
194+
end
195+
if P.stat.clears[1]+P.stat.clears[2]+P.stat.clears[3]==0 then
196+
PROGRESS.setSecret('exterior_invis_superBrain')
197+
end
46198
end
47199
end
48200
end,

0 commit comments

Comments
 (0)