diff --git a/parts/eventsets/master_g.lua b/parts/eventsets/master_g.lua index 9b711325..810a74e4 100644 --- a/parts/eventsets/master_g.lua +++ b/parts/eventsets/master_g.lua @@ -1,26 +1,18 @@ -local regretDelay=-1 -local int_grade=0 -local grade_points=0 -local int_grade_boosts={0,1,2,3,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,11,12,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26} -local coolList={false,false,false,false,false,false,false,false,false} -local regretList={false,false,false,false,false,false,false,false,false,false} -local gradeList={ - "9","8","7","6","5","4","3","2","1", - "S1","S2","S3","S4","S5","S6","S7","S8","S9", - "m1","m2","m3","m4","m5","m6","m7","m8","m9", - "M","MK","MV","MO","MM-","MM","MM+","GM-","GM","GM+","TM-","TM","TM+" -} -local spd_lvl=0 -local cools=0 -local regrets=0 -local prevSectTime=0 -local isInRoll=false -local rollGrades=0 +-- local regretDelay=-1 +-- local int_grade=0 +-- local grade_points=0 +local _igb={0,1,2,3,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,11,12,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26} +local function getInternalGradeBoosts(internal_grade) + return _igb[MATH.clamp(internal_grade+1,1,#_igb)] +end +-- local spd_lvl=0 +-- local cools=0 +-- local regrets=0 +-- local prevSectTime=0 +-- local isInRoll=false +-- local rollGrades=0 local cool_time={3120,3120,2940,2700,2700,2520,2520,2280,2280,0} -local reg_time= {5400,4500,4500,4080,3600,3600,3000,3000,3000,3000} -local prevDrop70=false -- determines if previous piece has level less than __70 -local nextSpeedUp=false -- determines if the next section speed should be boosted by 100 -local isInRollTrans=false +local regret_time= {5400,4500,4500,4080,3600,3600,3000,3000,3000,3000} local function getGrav(l) return l<30 and 64 or @@ -72,52 +64,87 @@ local function getDas(l) l<900 and 8 or 6 end -local function getGrade() - if int_grade==nil then int_grade=0 end - if rollGrades==nil then rollGrades=0 end - return gradeList[math.max(math.min(math.floor(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets),#gradeList),1)] +local function getCurrentGrade(D) + if not D.int_grade then D.int_grade=0 end + if not D.roll_grades then D.roll_grades=0 end + return math.floor(math.max(1,getInternalGradeBoosts(D.internal_grade)+D.rollGrades+D.cools+1-D.regrets)) end -local function addGrade(row, cmb, lvl) -- IGS = internal grade system +local function addGrade(D,row,cmb,lvl) -- IGS = internal grade system if row<1 then return end local pts=0 local cmb_mult=1.0 local lvl_mult=math.floor(lvl/250)+1 - if row==1 then - pts=int_grade<5 and 10 or int_grade<10 and 5 or 2 + pts=D.internal_grade<5 and 10 or D.internal_grade<10 and 5 or 2 cmb_mult=1.0 elseif row==2 then - pts=int_grade<3 and 20 or int_grade<6 and 15 or int_grade<10 and 10 or 12 + pts=D.internal_grade<3 and 20 or D.internal_grade<6 and 15 or D.internal_grade<10 and 10 or 12 cmb_mult=cmb==1 and 1 or cmb<4 and 1.2 or cmb<8 and 1.4 or cmb<10 and 1.5 or 2.0 elseif row==3 then - pts=int_grade==0 and 40 or int_grade<4 and 30 or int_grade<7 and 20 or int_grade<10 and 15 or 13 + pts=D.internal_grade==0 and 40 or D.internal_grade<4 and 30 or D.internal_grade<7 and 20 or D.internal_grade<10 and 15 or 13 cmb_mult=cmb==1 and 1 or cmb<10 and 1+(cmb+2)*0.1 or 2 else - pts=int_grade==0 and 50 or int_grade<5 and 40 or 30 + pts=D.internal_grade==0 and 50 or D.internal_grade<5 and 40 or 30 cmb_mult=cmb==1 and 1 or cmb==2 and 1.5 or cmb<6 and (0.2*cmb)+1.2 or cmb<10 and (0.1*cmb)+1.7 or 3 end - - grade_points=grade_points+(pts*cmb_mult*lvl_mult) - if grade_points>=100 then - grade_points=0 - int_grade=int_grade+1 + D.grade_points=D.grade_points+(pts*cmb_mult*lvl_mult) + if D.grade_points>=100 then + D.grade_points=0 + D.internal_grade=D.internal_grade+1 end end -local function getRollGoal() +local function getRollGoal(D,isGreenLine) + local invis=D.cools>8 -- get amount of grades needed for TM+ - local rem=#gradeList-(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets) + local rem=40-getCurrentGrade(D)-( + -- adjust for clear bonus + isGreenLine and 0 or + invis and 1.6 or .5 + ) if rem<=0 then return 0 end local goal=0 - if cools>8 then + if invis then goal=math.floor(rem)*4 rem=rem%1 return goal+(rem>0.3 and 4 or rem*10) else - goal=math.floor(rem/0.26)*4 - rem=rem%0.26 + goal=math.floor(rem/.26)*4 + rem=rem%.26 return goal+(rem>0.12 and 4 or rem*25) end end +local function getCurSection(D) + return math.ceil((D.pt+1)/100) +end +local function getSectionState(P,section) + local D=P.modeData + local cool,miss,regret=false,false,false + if D.coolList[section] then cool=true end + if D.regretList[section] then regret=true end + + if section==getCurSection(D) and P.stat.frame-D.prevSectTime>cool_time[section] then + miss=true + end + return cool,miss,regret +end +local function setSectionColor(cool,regret,isCurSection) + if not (cool or regret) then + GC.setColor(0.6,0.6,0.6,isCurSection and 0.25 or 0.6) + else + GC.setColor(regret and 1 or 0, cool and 1 or 0, 0, 1) + end +end +local function setCurSectionColor(cool, miss, regret) + if cool and regret then + GC.setColor(COLOR.Y) + elseif cool then + GC.setColor(COLOR.G) + elseif regret then + GC.setColor(COLOR.R) + elseif miss then + GC.setColor(COLOR.lX) + end +end return { drop=64, @@ -129,52 +156,47 @@ return { minsdarr=1, ihs=true,irs=true,ims=false, mesDisp=function(P) + local D=P.modeData GC.setColor(1,1,1,1) setFont(45) mText(TEXTOBJ.grade,63,180) setFont(60) - GC.mStr(getGrade(),63,110) -- draw grade + GC.mStr(getMasterGrade(getCurrentGrade(D)),63,110) -- draw grade for i=1,10 do -- draw cool/regret history - if not (coolList[i] or regretList[i]) then -- neither cool nor regret - GC.setColor(0.6,0.6,0.6,P.modeData.pt<(i-1)*100 and 0.25 or 0.6) - else - GC.setColor(regretList[i] and 1 or 0, coolList[i] and 1 or 0, 0, 1) - end + setSectionColor(D.coolList[i],D.regretList[i],i==getCurSection(D)) GC.circle('fill',-10,150+i*25,10) GC.setColor(1,1,1,1) end - if isInRoll then + if D.isInRoll then setFont(20) - GC.mStr(("%.1f"):format(rollGrades),63,208) -- draw roll grades + GC.mStr(("%.1f"):format(D.rollGrades),63,208) -- draw roll grades GC.setLineWidth(2) GC.setColor(.98,.98,.98,.8) GC.rectangle('line',0,240,126,80,4) GC.setColor(.98,.98,.98,.4) GC.rectangle('fill',0+2,240+2,126-4,80-4,2) -- draw time box - setFont(45) - local t=(P.stat.frame-prevSectTime)/60 + + setFont(45) -- Draw time text + local t=(P.stat.frame-D.prevSectTime)/60 local T=("%.1f"):format(60-t) GC.setColor(COLOR.dH) - GC.mStr(T,65,250) -- draw time + GC.mStr(T,65,250) t=t/60 GC.setColor(1.7*t,2.3-2*t,.3) GC.mStr(T,63,248) - PLY.draw.drawTargetLine(P,getRollGoal()) + + GC.setColor(COLOR.O) + PLY.draw.drawTargetLine(P,getRollGoal(D),true) + + GC.setColor(COLOR.G) + PLY.draw.drawTargetLine(P,getRollGoal(D,true),true) else - -- draw level counter + -- Not in roll setFont(20) - GC.mStr(grade_points,63,208) + GC.mStr(D.grade_points,63,208) setFont(45) - if coolList[math.ceil(P.modeData.pt/100+0.01)] then - GC.setColor(0,1,0,1) - elseif P.stat.frame-prevSectTime > cool_time[math.ceil(P.modeData.pt/100+0.01)] then - GC.setColor(0.7,0.7,0.7,1) - end - if coolList[math.ceil(P.modeData.pt/100+0.01)] and regretList[math.ceil(P.modeData.pt/100+0.01)] then - GC.setColor(1,1,0,1) - elseif regretList[math.ceil(P.modeData.pt/100+0.01)] then - GC.setColor(1,0,0,1) - end + + setCurSectionColor(getSectionState(P,getCurSection(D))) PLY.draw.drawProgress(P.modeData.pt,P.modeData.target) end end, @@ -183,59 +205,55 @@ return { local c=#P.clearedRow - if cools>8 and isInRoll then - rollGrades=rollGrades+(c==4 and 1 or 0.1*c) + if D.cools>8 and D.isInRoll then -- invis roll grades + D.rollGrades=D.rollGrades+(c==4 and 1 or 0.1*c) return - elseif isInRoll then - rollGrades=rollGrades+(c==4 and 0.26 or 0.04*c) + elseif D.isInRoll then -- fading roll grades + D.rollGrades=D.rollGrades+(c==4 and 0.26 or 0.04*c) return end if c==0 and D.pt+1>=D.target 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 + elseif P.combo>3 then s=s+1 end + + if not D.isInRoll then + addGrade(D,c,P.combo,D.pt) + D.pt=D.pt+s + D.speed_level=D.speed_level+s end - addGrade(c,P.combo,D.pt) - - D.pt=D.pt+s - spd_lvl=spd_lvl+1 - - P.gameEnv.drop=getGrav(spd_lvl) - - if (P.gameEnv.drop==0) then - P:set20G(true) - end - - if D.pt%100>70 and not prevDrop70 then - if P.stat.frame-prevSectTime < cool_time[math.ceil(D.pt/100)] then - cools=cools+1 - coolList[math.ceil(D.pt/100)]=true + if D.pt%100>70 and not D.prevDrop70 then + if P.stat.frame-D.prevSectTime=D.target then-- Level up! - spd_lvl=nextSpeedUp and spd_lvl+100 or spd_lvl - nextSpeedUp=false - prevDrop70=false + D.speed_level=D.nextSpeedUp and D.speed_level+100 or D.speed_level + D.nextSpeedUp=false + D.prevDrop70=false s=D.target/100 local E=P.gameEnv - E.lock=getLock(spd_lvl) - E.wait=getWait(spd_lvl) - E.fall=getFall(spd_lvl) - E.das=getDas(spd_lvl) + E.drop=getGrav(D.speed_level) + E.lock=getLock(D.speed_level) + E.wait=getWait(D.speed_level) + E.fall=getFall(D.speed_level) + E.das =getDas(D.speed_level) + if (E.drop==0) then P:set20G(true) end - if P.stat.frame-prevSectTime > reg_time[math.ceil(s)] then - regrets=regrets+1 - regretDelay=60 + if P.stat.frame-D.prevSectTime > regret_time[math.ceil(s)] then + D.regrets=D.regrets+1 + D.regretDelay=60 end - prevSectTime=P.stat.frame + D.prevSectTime=P.stat.frame if s==2 then BG.set('rainbow') elseif s==4 then @@ -252,7 +270,7 @@ return { elseif s==6 then BG.set('lightning') elseif s>9 then - if cools>8 then + if D.cools>8 then if E.lockFX and E.lockFX>1 then E.lockFX=1 end P:setInvisible(5) else @@ -261,7 +279,7 @@ return { D.pt=999 P.waiting=240 BGM.stop() - isInRollTrans=true + D.isInRollTrans=true return end D.target=D.target<900 and D.target+100 or 999 @@ -270,36 +288,36 @@ return { end end, task=function(P) - regretDelay=-1 - P.modeData.pt=0 - P.modeData.target=100 - int_grade=0 - grade_points=0 - rollGrades=0 - spd_lvl=0 - cools=0 - regrets=0 - prevSectTime=0 - isInRoll=false - isInRollTrans=false - prevDrop70=false - nextSpeedUp=false - coolList={false,false,false,false,false,false,false,false,false} - regretList={false,false,false,false,false,false,false,false,false,false} + local D=P.modeData + D.regretDelay=-1 + D.pt=0 + D.target=100 + D.int_grade=0 + D.grade_points=0 + D.rollGrades=0 + D.spd_lvl=0 + D.cools=0 + D.regrets=0 + D.prevSectTime=0 + D.isInRoll=false + D.isInRollTrans=false + D.prevDrop70=false + D.nextSpeedUp=false + D.coolList,D.regretList=TABLE.new(false,9),TABLE.new(false,10) local decayRate={125,80,80,50,45,45,45,40,40,40,40,40,30,30,30,20,20,20,20,20,15,15,15,15,15,15,15,15,15,15,10,10,10,9,9,9,8,8,8,7,7,7,6} local decayTimer=0 + while true do coroutine.yield() - P.modeData.grade=getGrade() - P.modeData.gradePts=math.max(math.min(math.floor(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets),#gradeList),1) - if P.stat.frame-prevSectTime > reg_time[math.ceil(P.modeData.pt/100+0.01)] and not (isInRoll or isInRollTrans) then - regretList[math.ceil(P.modeData.pt/100)]=true + D.gradePts=getCurrentGrade(D) + if P.stat.frame-D.prevSectTime > regret_time[getCurSection(D)] and not (D.isInRoll or D.isInRollTrans) then + D.regretList[math.ceil(D.pt/100)]=true end - if regretDelay>-1 then - regretDelay=regretDelay-1 - if regretDelay==-1 then P:_showText("REGRET!!",0,-120,80,'beat',.8) end + if D.regretDelay>-1 then + D.regretDelay=D.regretDelay-1 + if D.regretDelay==-1 then P:_showText("REGRET!!",0,-120,80,'beat',.8) end end - if isInRollTrans then + if D.isInRollTrans then if P.waiting>=220 then -- Make field invisible for y=1,#P.field do for x=1,10 do @@ -319,24 +337,22 @@ return { P:_showText("1",0,-120,120,'fly',1) elseif P.waiting==1 then playReadySFX(0,1) - isInRollTrans=false - isInRoll=true + D.isInRollTrans=false + D.isInRoll=true BGM.play('hope') BG.set('blockspace') - prevSectTime=P.stat.frame + D.prevSectTime=P.stat.frame end end - if P.waiting<=0 and grade_points>0 and not isInRoll then + if P.waiting<=0 and D.grade_points>0 and not D.isInRoll then decayTimer=decayTimer+1 - if decayTimer>=decayRate[math.min(int_grade+1,#decayRate)] then + if decayTimer>=decayRate[math.min(D.internal_grade+1,#decayRate)] then decayTimer=0 - grade_points=grade_points-1 + D.grade_points=D.grade_points-1 end - elseif isInRoll and P.stat.frame>=prevSectTime+3599 then - rollGrades=rollGrades+(cools>8 and 1.6 or 0.5) - P.modeData.grade=getGrade() - P.modeData.gradePts=math.min(math.floor(int_grade_boosts[math.min(int_grade+1,#int_grade_boosts)]+rollGrades+cools+1-regrets),#gradeList) - coroutine.yield() + elseif D.isInRoll and P.stat.frame>=D.prevSectTime+3599 then + D.rollGrades=D.rollGrades+(D.cools>8 and 1.6 or 0.5) + D.gradePts=getCurrentGrade(D) P:win('finish') end end diff --git a/parts/eventsets/secret_grade.lua b/parts/eventsets/secret_grade.lua index b93f44fc..729aebc1 100644 --- a/parts/eventsets/secret_grade.lua +++ b/parts/eventsets/secret_grade.lua @@ -8,29 +8,6 @@ local F={} -- local ranks={"10","9","8","7","6","5","4","3","2","1","S1","S2","S3","S4","S5","S6","S7","S8","S9","GM","GM+","TM","TM+","TM+₂","TM+₃", "TM+₄","TM+₅"} -- lines: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 -local function getSmallNum(num) - local smalldigit={[0]="₀","₁","₂","₃","₄","₅","₆","₇","₈","₉"} - local str=tostring(num) - local out="" - for i=1,#str do - out=out..smalldigit[tonumber(string.sub(str,i,i))] - end - return out -end - -local function getRank(index) - if index<11 then -- rank 10 - 1 - return tostring(11-index) - elseif index<20 then -- S1 - S9 ranks - return "S"..index-10 - elseif index<24 then -- GM, GM+, TM, TM+ ranks - local r={"GM","GM+","TM","TM+"} - return r[index-19] - else - return "TM+"..getSmallNum(index-22) - end -end - local function generateGuide(num) local l=#F if l>num then @@ -51,7 +28,7 @@ return { mText(TEXTOBJ.grade,63,190) mText(TEXTOBJ.line,63,310) setFont(55) - GC.mStr(getRank(P.modeData.rankPts),63,125) + GC.mStr(getSecretGrade(P.modeData.rankPts),63,125) GC.mStr(P.modeData.rankPts-1,63,245) ply_applyField(P) local mark=TEXTURE.puzzleMark @@ -73,7 +50,7 @@ return { end, hook_drop=function(P) local D=P.modeData - D.rankPts=1 + D.rankPts=0 for i=1,#P.field do local h=getOpenHole(i) local flag diff --git a/parts/gameFuncs.lua b/parts/gameFuncs.lua index 4e45a1e2..b6ade66c 100644 --- a/parts/gameFuncs.lua +++ b/parts/gameFuncs.lua @@ -13,7 +13,7 @@ local PLAYERS=PLAYERS --- System +------------------------------[System]------------------------------ do-- function tryBack() local sureTime=-1e99 function tryBack() @@ -186,7 +186,73 @@ do-- function applySettings() end end --- Royale mode +------------------------------[Generate Grades]------------------------------ +local smallDigits={[0]="₀","₁","₂","₃","₄","₅","₆","₇","₈","₉"} +local function getSmallNum(num) + local str=tostring(num) + local out="" + for i=1,#str do + out=out..smallDigits[tonumber(string.sub(str,i,i))] + end + return out +end +do -- Secret Grade + local r={"GM","GM+","TM","TM+"} + function getSecretGrade(index) + if index<11 then -- rank 10 - 1 + return tostring(11-index) + elseif index<20 then -- S1 - S9 ranks + return "S"..index-10 + elseif index<24 then -- GM, GM+, TM, TM+ ranks + return r[index-19] + else + return "TM+"..getSmallNum(index-22) + end + end +end +function getSecretGradeText(index) + if index<11 then + return "Grade "..tostring(11-index) + else + return getSecretGrade(index) + end +end + +do -- Master GRADED + local master_postm_grades={"M","MK","MV","MO","MM-","MM","MM+","GM-","GM","GM+","TM-","TM","TM+"} + function getMasterGrade(index) + if index<10 then + return tostring(10-index) + elseif index<19 then + return "S"..index-9 + elseif index<28 then + return "m"..index-18 + elseif index<41 then + return master_postm_grades[index-27] + else + return master_postm_grades[#master_postm_grades]..getSmallNum(index-39) + end + end + local master_postm_grades_text={ + "Master","MasterK","MasterV","MasterO","MasterM-","MasterM","MasterM+", + "Grand Master-","Grand Master","Grand Master+", + "Tech Master-","Tech Master","Tech Master+" + } + function getMasterGradeText(index) + if index<10 then + return "Grade "..tostring(10-index) + elseif index<19 then + return "S"..index-9 + elseif index<28 then + return "m"..index-18 + elseif index<41 then + return master_postm_grades_text[index-27] + else + return master_postm_grades_text[#master_postm_grades]..index-39 + end + end +end +------------------------------[Royale mode]------------------------------ function randomTarget(P)-- Return a random opponent for P local l=TABLE.shift(PLY_ALIVE,0) local count=0 @@ -292,7 +358,7 @@ function royaleLevelup() end end --- Sound shortcuts +------------------------------[Sound shortcuts]------------------------------ function playClearSFX(cc) if cc<=0 or cc%1~=0 then return end if cc<=4 then @@ -344,7 +410,7 @@ function playReadySFX(i,vol) end --- Game +------------------------------[Game]------------------------------ function getItem(itemName,amount) STAT.item[itemName]=STAT.item[itemName]+(amount or 1) end @@ -1063,7 +1129,7 @@ end --- Game draw +------------------------------[Graphics]------------------------------ do-- function drawSelfProfile() local name local textObj,scaleK,width,offY @@ -1113,7 +1179,7 @@ end --- Widget function shortcuts +------------------------------[Widget function shortcuts]------------------------------ function backScene() SCN.back() end do-- function goScene(name,style) local cache={} diff --git a/parts/modes.lua b/parts/modes.lua index d05e1994..87d9d33c 100644 --- a/parts/modes.lua +++ b/parts/modes.lua @@ -125,8 +125,8 @@ return { {name='tsd_u', x=1050, y=320, size=40,shape=1,icon="tsd"}, {name='backfire_n', x=640, y=420, size=40,shape=1,icon="backfire", unlock={'backfire_h'}}, - {name='backfire_h', x=790, y=470, size=40,shape=1,icon="backfire", unlock={'backfire_l'}}, - {name='backfire_l', x=930, y=460, size=40,shape=3,icon="backfire", unlock={'backfire_u'}}, + {name='backfire_h', x=790, y=450, size=40,shape=1,icon="backfire", unlock={'backfire_l'}}, + {name='backfire_l', x=930, y=450, size=40,shape=3,icon="backfire", unlock={'backfire_u'}}, {name='backfire_u', x=1070, y=450, size=35,shape=2,icon="backfire"}, {name='zen', x=-1000, y=-600, size=40,shape=1,icon="zen", unlock={'ultra','infinite','infinite_dig','marathon_inf'}}, diff --git a/parts/modes/master_g.lua b/parts/modes/master_g.lua index c990c2f7..035651d6 100644 --- a/parts/modes/master_g.lua +++ b/parts/modes/master_g.lua @@ -1,10 +1,3 @@ -local gradeList={ - "Grade 9","Grade 8","Grade 7","Grade 6","Grade 5","Grade 4","Grade 3","Grade 2","Grade 1", - "S1","S2","S3","S4","S5","S6","S7","S8","S9", - "m1","m2","m3","m4","m5","m6","m7","m8","m9", - "M","MK","MV","MO","MM-","MM","MM+","GM-","GM","GM+","TM-","TM","TM+" -} - return { env={ freshLimit=15, @@ -15,7 +8,7 @@ return { }, slowMark=true, score=function(P) return {P.modeData.gradePts,P.stat.time} end, - scoreDisp=function(D) return(gradeList[D[1]] or D[1]).." "..STRING.time(D[2]) end, + scoreDisp=function(D) return(getMasterGradeText(D[1]) or D[1]).." "..STRING.time(D[2]) end, comp=function(a,b) return a[1]>b[1] or (a[1]==b[1] and a[2]b[1] or a[1]==b[1] and a[2]0 then gc_setLineWidth(3) - gc_setColor(1,h>10 and 0 or .2+.8*rnd(),.5) + if not overrideColor then + gc_setColor(1,h>10 and 0 or .2+.8*rnd(),.5) + end _applyField(P) h=600-30*h if P.falling~=-1 then