Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Classic Beyond" mode #778

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions parts/eventsets/classic_beyond.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
local function GetGravity(lvl) -- note: uses G units, not frames per block
return math.pow(lvl/4+1,.7)
end
local function GetDAS(lvl) -- if these seem random, i was plotting the graph and this seemed like the perfect curve
return math.max(math.floor(5-math.pow(lvl,0.6)),2)
end
local function GetPlayableARE(lvl) -- delay between the piece spawning and it actually starting to fall. subtracted from actual ARE, hence named "Playable ARE"
return math.min(math.floor(2+math.pow(3*lvl,0.37)),9)
end
local function LinesUntilNextLife(lvl,lives)
if lives>=3 then return math.huge end
if lvl<2 then
return math.pow(3,lives+1)
elseif lvl<5 then
return math.pow(2,lives+1)
else
return math.pow(2,lives)
end
end

return {
das=5,arr=2,
sddas=1e99,sdarr=1e99,
irs=true,ihs=true,-- also IRS and IHS is enabled because we want it to actually be playable after 1.3G
drop=1e99,lock=1, -- use custom drop method for classic levels
wait=8,fall=25,
freshLimit=0,
fieldH=19,
nextCount=1,
holdCount=0,
RS='C2_sym', -- for basic finesse and a few basic kicks, no up kicks
sequence=function(P) -- rndES
local rndGen=P.seqRND
do --start without bad pieces
local goodPieces={3,4,5,7}
P:getNext(goodPieces[rndGen:random(4)])
end
while true do
while #P.nextQueue<10 do
P:getNext(rndGen:random(7))
end
coroutine.yield()
end
end,
noTele=true,
keyCancel={6}, -- 180 enabled so you don't have to break your fingers at 2G
mesDisp=function(P)
setFont(60)
GC.mStr(('%.2f'):format(P.modeData.grav),47,220)
setFont(30)
GC.mStr("G",120,252)
mText(TEXTOBJ.speed,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.nextLife<1e99 then
mText(TEXTOBJ.nextLife,63,20)
GC.mStr(P.modeData.nextLife,63,40)
mText(TEXTOBJ.line,63,80)
end
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
GC.setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
GC.setColor(1,gb,gb)
end
setFont(50)
GC.mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
local D=P.modeData
D.grav=1
D.target=10
D.nextLife=3
D.gravCounter=0
D.gravPause=100
D.areConv=2
D.plare=0
local prevY
while true do
while not P.cur do coroutine.yield() end
prevY=P:getCenterY()
while D.gravPause>0 or D.plare>0 do
print(D.gravPause,D.plare)
coroutine.yield()
if D.gravPause>0 then D.gravPause=D.gravPause-1 end
if D.plare>0 then D.plare=D.plare-1 end
if P.cur and P:getCenterY()<prevY then
D.gravPause,D.plare=0,0
break
end
end
coroutine.yield()
D.gravCounter=D.gravCounter+D.grav
if P.curY-math.floor(D.gravCounter)<P.ghoY then -- custom gravity logic since the player's gravity logic doesn't support unusual decimal numbers
P.curY=P.ghoY
if P.cur then P:drop(true) end
else
if P.gameEnv.moveFX then
for i=1,math.floor(D.gravCounter) do
P:createMoveFX('down')
P.curY=P.curY-1
end
else
P.curY=P.curY-math.floor(D.gravCounter)
end
end
D.gravCounter=D.gravCounter%1
end
end,
hook_drop=function(P)
local D,E=P.modeData,P.gameEnv
D.drought=P.lastPiece.id==7 and 0 or D.drought+1
if P.lastPiece.row>0 then
D.nextLife=D.nextLife-P.lastPiece.row
if D.nextLife<=0 then
P.life=P.life+1
D.nextLife=D.nextLife+LinesUntilNextLife(math.floor(P.stat.row/10),P.life)
end
end
if P.stat.row>=D.target then
local lvl=math.floor(P.stat.row/10)
SFX.play('reach')
D.grav=GetGravity(lvl)
D.target=D.target+10
D.nextLife=math.min(D.nextLife,LinesUntilNextLife(lvl,P.life))
D.areConv=GetPlayableARE(lvl)
E.das,E.arr=GetDAS(lvl),1
E.nextCount=math.min(math.ceil(D.grav),6)
E.wait=10-D.areConv
end
D.plare=D.areConv
end,
hook_die=function(P)
if P.life>0 then
P.modeData.nextLife=math.min(
P.modeData.nextLife,
LinesUntilNextLife(math.floor(P.stat.row/10),P.life-1)
)
local goodPieces={3,4,5,7}
local id=P.cur.id
if id==1 or id==2 or id==6 then
P.cur=P:getBlock(goodPieces[P.seqRND:random(4)])
P:resetBlock()
end
end
P.modeData.gravCounter=0
P.modeData.gravPause=120
end
}
2 changes: 1 addition & 1 deletion parts/gameTables.lua
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ do-- TEXTOBJ
gameover=T(90),
pause=T(90),

speedLV=T(20),
speedLV=T(20),speed=T(20),nextLife=T(20),
piece=T(25),line=T(25),atk=T(20),eff=T(20),
rpm=T(35),tsd=T(35),
grade=T(25),techrash=T(25),
Expand Down
3 changes: 2 additions & 1 deletion parts/language/lang_en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ return {
speedup="Speed Up!",
missionFailed="Wrong Clear",

speedLV="Speed Level",
speedLV="Speed Level",speed="Speed",nextLife="Next life in",
piece="Piece",line="Lines",atk="Attack",eff="Efficiency",
rpm="RPM",tsd="TSD",
grade="Grade",techrash="Techrash",
Expand Down Expand Up @@ -885,6 +885,7 @@ return {
['classic_h']= {"Classic", "HARD", "A medium-speed recreation from the 80s"},
['classic_l']= {"Classic", "LUNATIC", "A high-speed recreation from the 80s"},
['classic_u']= {"Classic", "ULTIMATE", "A very high-speed recreation from the 80s"},
['classic_beyond']= {"Classic", "BEYOND", "Going beyond 1G requires additional mechanics."},
['survivor_e']= {"Survival", "EASY", "How long can you survive?"},
['survivor_n']= {"Survival", "NORMAL", "How long can you survive?"},
['survivor_h']= {"Survival", "HARD", "How long can you survive?"},
Expand Down
1 change: 1 addition & 0 deletions parts/language/lang_id.lua
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ return {
['classic_h']= {"Klasik", "SULIT", "Rekreasi berkecepatan medium dari tahun 80-an"},
['classic_l']= {"Klasik", "GILA", "Rekreasi berkecepatan medium-tinggi dari tahun 80-an"},
['classic_u']= {"Klasik", "TERAKHIR", "Rekreasi berkecepatan tinggi dari tahun 80-an"},
['classic_beyond']= {"Klasik", "MELAMPAU", "Rekreasi berkecepatan ultra tinggi dari tahun 80-an"},
['survivor_e']= {"Bertahan", "MUDAH", "Berapa lama Anda bisa bertahan?"},
['survivor_n']= {"Bertahan", "NORMAL", "Berapa lama Anda bisa bertahan?"},
['survivor_h']= {"Bertahan", "SULIT", "Berapa lama Anda bisa bertahan?"},
Expand Down
11 changes: 6 additions & 5 deletions parts/language/lang_zh.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ return {
speedup="速度加快",
missionFailed="非任务消除",

speedLV="速度等级",
speedLV="速度等级",speed="速度",nextLife="下辈子在",
piece="块数",line="行数",atk="攻击",eff="效率",
rpm="RPM",tsd="T2",
grade="段位",techrash="Techrash",
Expand Down Expand Up @@ -881,10 +881,11 @@ return {
['blind_l']= {"隐形", "瞬隐+", "最强大脑"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_e']= {"高速经典", "简单", "高速经典"},
['classic_h']= {"高速经典", "困难", "飞速经典"},
['classic_l']= {"高速经典", "疯狂", "极速经典"},
['classic_u']= {"高速经典", "极限", "光速经典"},
['classic_e']= {"高速经典", "简单", "低速经典"},
['classic_h']= {"高速经典", "困难", "高速经典"},
['classic_l']= {"高速经典", "疯狂", "飞速经典"},
['classic_u']= {"高速经典", "极限", "极速经典"},
['classic_beyond']= {"高速经典", "超越", "光速经典"},
['survivor_e']= {"生存", "简单", "你能存活多久?"},
['survivor_n']= {"生存", "普通", "你能存活多久?"},
['survivor_h']= {"生存", "困难", "你能存活多久?"},
Expand Down
3 changes: 2 additions & 1 deletion parts/modes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ return {
{name='classic_e', x=-200, y=-850, size=40,shape=1,icon="classic", unlock={'classic_h'}},
{name='classic_h', x=-300, y=-950, size=40,shape=3,icon="classic", unlock={'classic_l'}},
{name='classic_l', x=-400, y=-1050, size=35,shape=3,icon="classic", unlock={'classic_u'}},
{name='classic_u', x=-500, y=-1150, size=30,shape=2,icon="classic"},
{name='classic_u', x=-500, y=-1150, size=30,shape=2,icon="classic", unlock={'classic_beyond'}},
{name='classic_beyond',x=-600, y=-1250, size=30,shape=4,icon="classic"},

{name='survivor_e', x=450, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_n'}},
{name='survivor_n', x=650, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_h','attacker_h','defender_n','dig_h'}},
Expand Down
23 changes: 23 additions & 0 deletions parts/modes/classic_beyond.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
return {
env={
center=0,ghost=0,
smooth=false,
face={0,0,2,2,2,0,0},
eventSet='classic_beyond',
bg='rgb',bgm='1980s',
},
slowMark=true,
score=function(P) return {P.stat.score,P.stat.row} end,
scoreDisp=function(D) return D[1].." "..D[2].." Lines" 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>=62 and 5 or
L>=45 and 4 or
L>=30 and 3 or
L>=15 and 2 or
L>=5 and 1 or
L>=1 and 0
end,
}
37 changes: 37 additions & 0 deletions parts/scenes/mode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local ms,kb,tc=love.mouse,love.keyboard,love.touch

local max,min=math.max,math.min
local int,abs=math.floor,math.abs
local sin,cos,pi=math.sin,math.cos,math.pi

local mapCam={
sel=false,-- Selected mode ID
Expand Down Expand Up @@ -47,6 +48,19 @@ local function _getPos()
return mapCam.xOy:inverseTransformPoint(0,0)
end

local star={}
local starRad=.5 -- inner radius (outer radius is 1)
for i=1,20,4 do
local j=(i-1)/2
local r=starRad
star[i]=sin(pi*j/5)
star[i+1]=-cos(pi*j/5)
j=j+1
star[i+2]=r*sin(pi*j/5)
star[i+3]=-r*cos(pi*j/5)
end
local star_tri=love.math.triangulate(star)

local function _onModeRaw(x,y)
for name,M in next,MODES do
if visibleModes[name] and M.x then
Expand All @@ -57,6 +71,14 @@ local function _onModeRaw(x,y)
if abs(x-M.x)+abs(y-M.y)<s+12 then return name end
elseif M.shape==3 then
if (x-M.x)^2+(y-M.y)^2<(s+6)^2 then return name end
elseif M.shape==4 then
if x>M.x+s or x<M.x-s or y>M.y+s or y<M.y-s then
-- if not in a square containing the star, then it's not in the star
-- shortcut for far away x/y because _isPointInPolygon is kinda slow
goto continue
end
if MATH.PointInPolygon((x-M.x)*.022,(y-M.y)*.022,star) then return name end
::continue::
end
end
end
Expand Down Expand Up @@ -206,13 +228,28 @@ local baseRankColor={
{.85,.5,.4,.3},
{.85,.3,.8,.3},
}

local function _drawModeShape(M,S,drawType)
if M.shape==1 then-- Rectangle
gc_rectangle(drawType,M.x-S,M.y-S,2*S,2*S)
elseif M.shape==2 then-- Diamond
gc_circle(drawType,M.x,M.y,S+12,4)
elseif M.shape==3 then-- Octagon
gc_circle(drawType,M.x,M.y,S+6,8)
elseif M.shape==4 then-- Star
gc_push()
gc_translate(M.x,M.y)
gc_scale(S*1.5)
gc_setLineWidth(.1)
GC.polygon("line",star)
if drawType=='fill' then
gc_setLineWidth(0)
for i=1,#star_tri do
GC.polygon(drawType,star_tri[i])
end
end
gc_setLineWidth(4)
gc_pop()
end
end
function scene.draw()
Expand Down