Compare commits

..

33 Commits
v0.1.8 ... v0.2

Author SHA1 Message Date
Ishaan Bhardwaj
062ab2005e v0.2 release commit - hold piece darken 2020-11-03 16:56:08 -05:00
Ishaan Bhardwaj
468025fc80 last commit to core modes before release 2020-11-03 12:17:36 -05:00
Ishaan Bhardwaj
c8544975d6 Fix interval training 2020-11-03 11:55:30 -05:00
Ishaan Bhardwaj
6776229bfb Small push to Cambridge modes 2020-11-03 11:52:52 -05:00
Ishaan Bhardwaj
84b4dc5073 World Bone Blocks 2020-11-03 10:58:21 -05:00
Ishaan Bhardwaj
35dafb6615 keep leaving debug code in new commits 2020-11-02 22:51:16 -05:00
Ishaan Bhardwaj
3641d85fcb Major changes, including modpack support 2020-11-02 22:47:58 -05:00
Ishaan Bhardwaj
9b89c4d1de G/O line fix 2020-11-02 21:17:13 -05:00
Ishaan Bhardwaj
2dba120919 Green line and orange line for TAP Master 2020-11-02 20:43:10 -05:00
Ishaan Bhardwaj
9224f271b1 Hotfix for last 2020-11-02 16:20:22 -05:00
Ishaan Bhardwaj
febb5d546c Score overhauls 2020-11-02 16:12:05 -05:00
Ishaan Bhardwaj
c6482c423e 4w optimization and green/orange line adding for applicable modes 2020-11-02 13:46:16 -05:00
Ishaan Bhardwaj
6beb313c6b Debug fixes 2020-11-02 12:44:15 -05:00
Ishaan Bhardwaj
eb70f55b6e TGM2 fixes and cool fixes 2020-11-02 12:21:12 -05:00
Ishaan Bhardwaj
0badcde9ad Basset: the only person to leave debug code in a repo 2020-11-01 13:44:35 -05:00
Ishaan Bhardwaj
6f39b591d3 Hotfix for TGM+ 2020-11-01 13:28:13 -05:00
Ishaan Bhardwaj
129237f0b0 TGM+ 2020-11-01 13:24:52 -05:00
Ishaan Bhardwaj
741c246244 second lol 2020-11-01 12:04:07 -05:00
Ishaan Bhardwaj
b5937af8b2 lol 2020-11-01 12:01:26 -05:00
Ishaan Bhardwaj
33b8533d8e Fixes to TAP M-roll requirements 2020-11-01 11:06:43 -05:00
Ishaan Bhardwaj
69959ff687 TA Death level advance formula is very bugged 2020-10-30 21:36:05 -04:00
Ishaan Bhardwaj
f91cd99dfd Minor fixes to TGM modes 2020-10-30 21:28:39 -04:00
Ishaan Bhardwaj
be59727ca5 Some demon mode fixes 2020-10-30 13:09:49 -04:00
Ishaan Bhardwaj
cca295066c Fix. 2020-10-29 23:05:49 -04:00
Ishaan Bhardwaj
f2862b4d93 Some score fixes for core TGM modes 2020-10-29 23:03:54 -04:00
Ishaan Bhardwaj
2aafd30253 Fixed secret grade detection 2020-10-29 22:14:34 -04:00
Ishaan Bhardwaj
b27ba335ba Improved secret grade 2020-10-29 21:40:50 -04:00
Ishaan Bhardwaj
33244736b8 Secret grade for sprint? Also ARR and DAS change so remember to change it in the lua file 2020-10-29 20:56:18 -04:00
Ishaan Bhardwaj
285108ca08 ACTUALLY fixed TI Master torikan 2020-10-26 14:07:09 -04:00
Ishaan Bhardwaj
4b1fed727c Update marathon_a3.lua 2020-10-26 14:03:09 -04:00
Ishaan Bhardwaj
9fca272e8d Update ck.lua 2020-10-24 09:12:12 -04:00
Ishaan Bhardwaj
5a21c8244b Update README.md 2020-10-23 21:28:32 -04:00
Ishaan Bhardwaj
4923b2e2d4 Removed debug code 2020-10-23 21:23:45 -04:00
28 changed files with 611 additions and 319 deletions

View File

@@ -16,6 +16,7 @@ Credits
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting! - [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
- [joezeng](https://github.com/joezeng) for the original project. - [joezeng](https://github.com/joezeng) for the original project.
- [Hailey](https://github.com/haileylgbt) for some miscellaneous assets. - [Hailey](https://github.com/haileylgbt) for some miscellaneous assets.
- CylinderKnot for an amazing gamemode.
- MarkGamed7794 for some miscellaneous contributions. - MarkGamed7794 for some miscellaneous contributions.
- Mizu for the Cambridge logo and the [Cambridge launcher](https://github.com/rexxt/cambridge-launcher). - Mizu for the Cambridge logo and the [Cambridge launcher](https://github.com/rexxt/cambridge-launcher).
- MattMayuga for the Cambridge banner. - MattMayuga for the Cambridge banner.

View File

@@ -30,6 +30,28 @@ function love.load()
if config.current_ruleset then current_ruleset = config.current_ruleset end if config.current_ruleset then current_ruleset = config.current_ruleset end
scene = TitleScene() scene = TitleScene()
end end
game_modes = {}
mode_list = love.filesystem.getDirectoryItems("tetris/modes")
for i=1,#mode_list do
if(mode_list[i] ~= "gamemode.lua" and mode_list[i] ~= "unrefactored_modes") then
game_modes[#game_modes+1] = require ("tetris.modes."..string.sub(mode_list[i],1,-5))
end
end
rulesets = {}
rule_list = love.filesystem.getDirectoryItems("tetris/rulesets")
for i=1,#rule_list do
if(rule_list[i] ~= "ruleset.lua" and rule_list[i] ~= "unrefactored_rulesets") then
rulesets[#rulesets+1] = require ("tetris.rulesets."..string.sub(rule_list[i],1,-5))
end
end
--sort mode/rule lists
local function padnum(d) return ("%03d%s"):format(#d, d) end
table.sort(game_modes, function(a,b)
return tostring(a.name):gsub("%d+",padnum) < tostring(b.name):gsub("%d+",padnum) end)
table.sort(rulesets, function(a,b)
return tostring(a.name):gsub("%d+",padnum) < tostring(b.name):gsub("%d+",padnum) end)
end end
local TARGET_FPS = 60 local TARGET_FPS = 60

BIN
res/img/bonew.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

View File

@@ -5,44 +5,6 @@ ModeSelectScene.title = "Game Start"
current_mode = 1 current_mode = 1
current_ruleset = 1 current_ruleset = 1
game_modes = {
require 'tetris.modes.marathon_2020',
require 'tetris.modes.survival_2020',
require 'tetris.modes.ck',
--require 'tetris.modes.strategy',
--require 'tetris.modes.interval_training',
--require 'tetris.modes.pacer_test',
require 'tetris.modes.demon_mode',
require 'tetris.modes.phantom_mania',
require 'tetris.modes.phantom_mania2',
require 'tetris.modes.phantom_mania_n',
require 'tetris.modes.race_40',
require 'tetris.modes.marathon_a1',
require 'tetris.modes.marathon_a2',
require 'tetris.modes.marathon_a3',
require 'tetris.modes.marathon_ax4',
require 'tetris.modes.marathon_c89',
require 'tetris.modes.survival_a1',
require 'tetris.modes.survival_a2',
require 'tetris.modes.survival_a3',
require 'tetris.modes.big_a2',
require 'tetris.modes.konoha',
}
rulesets = {
require 'tetris.rulesets.cambridge',
require 'tetris.rulesets.arika',
require 'tetris.rulesets.arika_ti',
require 'tetris.rulesets.ti_srs',
require 'tetris.rulesets.arika_ace',
require 'tetris.rulesets.arika_ace2',
require 'tetris.rulesets.arika_srs',
require 'tetris.rulesets.standard_exp',
--require 'tetris.rulesets.bonkers',
--require 'tetris.rulesets.shirase',
--require 'tetris.rulesets.super302',
}
function ModeSelectScene:new() function ModeSelectScene:new()
self.menu_state = { self.menu_state = {
mode = current_mode, mode = current_mode,
@@ -70,14 +32,14 @@ function ModeSelectScene:render()
elseif self.menu_state.select == "ruleset" then elseif self.menu_state.select == "ruleset" then
love.graphics.setColor(1, 1, 1, 0.25) love.graphics.setColor(1, 1, 1, 0.25)
end end
love.graphics.rectangle("fill", 20, 78 + 20 * self.menu_state.mode, 240, 22) love.graphics.rectangle("fill", 20, 258, 240, 22)
if self.menu_state.select == "mode" then if self.menu_state.select == "mode" then
love.graphics.setColor(1, 1, 1, 0.25) love.graphics.setColor(1, 1, 1, 0.25)
elseif self.menu_state.select == "ruleset" then elseif self.menu_state.select == "ruleset" then
love.graphics.setColor(1, 1, 1, 0.5) love.graphics.setColor(1, 1, 1, 0.5)
end end
love.graphics.rectangle("fill", 340, 78 + 20 * self.menu_state.ruleset, 200, 22) love.graphics.rectangle("fill", 340, 258, 200, 22)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
@@ -85,10 +47,14 @@ function ModeSelectScene:render()
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
for idx, mode in pairs(game_modes) do for idx, mode in pairs(game_modes) do
love.graphics.printf(mode.name, 40, 80 + 20 * idx, 200, "left") if(idx >= self.menu_state.mode-9 and idx <= self.menu_state.mode+9) then
love.graphics.printf(mode.name, 40, (260 - 20*(self.menu_state.mode)) + 20 * idx, 200, "left")
end
end end
for idx, ruleset in pairs(rulesets) do for idx, ruleset in pairs(rulesets) do
love.graphics.printf(ruleset.name, 360, 80 + 20 * idx, 160, "left") if(idx >= self.menu_state.ruleset-9 and idx <= self.menu_state.ruleset+9) then
love.graphics.printf(ruleset.name, 360, (260 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left")
end
end end
end end

View File

@@ -4,6 +4,7 @@ local Grid = Object:extend()
local empty = { skin = "", colour = "" } local empty = { skin = "", colour = "" }
local oob = { skin = "", colour = "" } local oob = { skin = "", colour = "" }
local block = { skin = "2tie", colour = "X" }
function Grid:new() function Grid:new()
self.grid = {} self.grid = {}
@@ -141,14 +142,34 @@ function Grid:copyBottomRow()
self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty} self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty}
self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
for col = 1, 10 do for col = 1, 10 do
self.grid[24][col] = (self.grid[23][col] == empty) and empty or { self.grid[24][col] = (self.grid[23][col] == empty) and empty or block
skin = self.grid[23][col].skin,
colour = "X"
}
end end
return true return true
end end
function Grid:garbageRise(row_vals)
for row = 1, 23 do
self.grid[row] = self.grid[row+1]
self.grid_age[row] = self.grid_age[row+1]
end
self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty}
self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
for col = 1, 10 do
self.grid[24][col] = (row_vals[col] == "e") and empty or block
end
end
function Grid:applyFourWide()
for row = 1, 24 do
local x = self.grid[row]
x[1] = x[1]~=block and block or x[1]
x[2] = x[2]~=block and block or x[2]
x[3] = x[3]~=block and block or x[3]
x[8] = x[8]~=block and block or x[8]
x[9] = x[9]~=block and block or x[9]
x[10] = x[10]~=block and block or x[10]
end
end
function Grid:applyPiece(piece) function Grid:applyPiece(piece)
if piece.big then if piece.big then
self:applyBigPiece(piece) self:applyBigPiece(piece)
@@ -216,7 +237,7 @@ function Grid:checkSecretGrade()
if(validLine) then if(validLine) then
sgrade = sgrade + 1 sgrade = sgrade + 1
else else
-- return sgrade return sgrade
end end
end end
--[[ --[[
@@ -239,7 +260,7 @@ function Grid:update()
end end
function Grid:draw() function Grid:draw()
for y = 1, 24 do for y = 5, 24 do
for x = 1, 10 do for x = 1, 10 do
if self.grid[y][x] ~= empty then if self.grid[y][x] ~= empty then
if self.grid_age[y][x] < 1 then if self.grid_age[y][x] < 1 then
@@ -271,7 +292,7 @@ function Grid:draw()
end end
function Grid:drawInvisible(opacity_function, garbage_opacity_function) function Grid:drawInvisible(opacity_function, garbage_opacity_function)
for y = 1, 24 do for y = 5, 24 do
for x = 1, 10 do for x = 1, 10 do
if self.grid[y][x] ~= empty then if self.grid[y][x] ~= empty then
if self.grid[y][x].colour == "X" then if self.grid[y][x].colour == "X" then

39
tetris/modes/4wide.lua Normal file
View File

@@ -0,0 +1,39 @@
require 'funcs'
local SurvivalA3Game = require 'tetris.modes.survival_a3'
local FourWideGame = SurvivalA3Game:extend()
FourWideGame.name = "4-wide Simulator"
FourWideGame.hash = "4wide"
FourWideGame.tagline = "The board has gotten narrower! Can you survive the increasing speeds?"
function FourWideGame:initialize(ruleset)
self.super:initialize(ruleset)
self.grid:applyFourWide()
end
local cleared_row_levels = {1, 2, 4, 6}
function FourWideGame:onLineClear(cleared_row_count)
if not self.clear then
local new_level = self.level + cleared_row_levels[cleared_row_count]
self:updateSectionTimes(self.level, new_level)
if new_level >= 1300 or self:hitTorikan(self.level, new_level) then
self.clear = true
if new_level >= 1300 then
self.level = 1300
self.grid:clear()
self.roll_frames = -150
else
self.game_over = true
end
else
self.level = math.min(new_level, 1300)
end
self:advanceBottomRow(-cleared_row_count)
end
self.grid:applyFourWide()
end
return FourWideGame

View File

@@ -19,13 +19,10 @@ function MarathonA2Game:new()
self.big_mode = true self.big_mode = true
self.roll_frames = 0 self.roll_frames = 0
self.combo = 1 self.combo = 1
self.randomizer = History6RollsRandomizer()
self.grade = 0 self.grade = 0
self.grade_points = 0 self.grade_points = 0
self.grade_point_decay_counter = 0 self.grade_point_decay_counter = 0
self.section_start_time = 0
self.section_times = { [0] = 0 }
self.section_tetrises = { [0] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
self.randomizer = History6RollsRandomizer() self.randomizer = History6RollsRandomizer()
@@ -103,11 +100,9 @@ end
function MarathonA2Game:advanceOneFrame() function MarathonA2Game:advanceOneFrame()
if self.clear then if self.clear then
self.roll_frames = self.roll_frames + 1 self.roll_frames = self.roll_frames + 1
if self.roll_frames < 0 then return false end
if self.roll_frames > 3694 then if self.roll_frames > 3694 then
self.completed = true self.completed = true
if self.grade == 32 then
self.grade = 33
end
end end
elseif self.ready_frames == 0 then elseif self.ready_frames == 0 then
self.frames = self.frames + 1 self.frames = self.frames + 1
@@ -123,43 +118,29 @@ end
function MarathonA2Game:onLineClear(cleared_row_count) function MarathonA2Game:onLineClear(cleared_row_count)
cleared_row_count = cleared_row_count / 2 cleared_row_count = cleared_row_count / 2
self:updateSectionTimes(self.level, self.level + cleared_row_count)
self.level = math.min(self.level + cleared_row_count, 999) self.level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 and not self.clear then if self.level == 999 and not self.clear then
self.clear = true self.clear = true
if self:qualifiesForMRoll() then
self.grade = 32
end
self.grid:clear() self.grid:clear()
self.roll_frames = -150 self.roll_frames = -150
end end
end end
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines) function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end if not self.clear then
cleared_lines = cleared_lines / 2 cleared_lines = cleared_lines / 2
self:updateGrade(cleared_lines) self:updateGrade(cleared_lines)
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + 2 * drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.combo * self.bravo cleared_lines * self.combo * self.bravo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + 2 * (cleared_lines - 1)
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
end self.drop_bonus = 0
function MarathonA2Game:updateSectionTimes(old_level, new_level)
if self.clear then return end
if math.floor(old_level / 100) < math.floor(new_level / 100) or
new_level >= 999 then
-- record new section
section_time = self.frames - self.section_start_time
self.section_times[math.floor(old_level / 100)] = section_time
self.section_start_time = self.frames
end end
end end
@@ -224,7 +205,7 @@ local grade_conversion = {
1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7,
7, 8, 8, 8, 9, 9, 9, 10, 11, 12, 7, 8, 8, 8, 9, 9, 9, 10, 11, 12,
12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
17, 18, 19 17
} }
function MarathonA2Game:updateGrade(cleared_lines) function MarathonA2Game:updateGrade(cleared_lines)
@@ -249,49 +230,12 @@ function MarathonA2Game:updateGrade(cleared_lines)
end end
end end
local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }
function MarathonA2Game:qualifiesForMRoll()
if not self.clear then return false end
-- tetris requirements
for section = 0, 9 do
if self.section_tetrises[section] < tetris_requirements[section] then
return false
end
end
-- section time requirements
local section_average = 0
for section = 0, 4 do
section_average = section_average + self.section_times[section]
if self.section_times[section] > frameTime(1,05) then
return false
end
end
-- section time average requirements
if self.section_times[5] > section_average / 5 then
return false
end
for section = 6, 9 do
if self.section_times[section] > self.section_times[section - 1] + 120 then
return false
end
end
if self.grade < 17 or self.frames > frameTime(8,45) then
return false
end
return true
end
function MarathonA2Game:getLetterGrade() function MarathonA2Game:getLetterGrade()
local grade = grade_conversion[self.grade] local grade = grade_conversion[self.grade]
if grade < 9 then if grade < 9 then
return tostring(9 - grade) return tostring(9 - grade)
elseif grade < 18 then elseif grade < 18 then
return "S" .. tostring(grade - 8) return "S" .. tostring(grade - 8)
elseif grade == 18 then
return "M"
else
return "GM"
end end
end end
@@ -301,18 +245,9 @@ MarathonA2Game.rollOpacityFunction = function(age)
else return 1 - (age - 240) / 60 end else return 1 - (age - 240) / 60 end
end end
MarathonA2Game.mRollOpacityFunction = function(age)
if age > 4 then return 0
else return 1 - age / 4 end
end
function MarathonA2Game:drawGrid(ruleset) function MarathonA2Game:drawGrid(ruleset)
if self.clear and not (self.completed or self.game_over) then if self.clear and not (self.completed or self.game_over) then
if self:qualifiesForMRoll() then
self.grid:drawInvisible(self.mRollOpacityFunction)
else
self.grid:drawInvisible(self.rollOpacityFunction) self.grid:drawInvisible(self.rollOpacityFunction)
end
else else
self.grid:draw() self.grid:draw()
if self.piece ~= nil and self.level < 100 then if self.piece ~= nil and self.level < 100 then
@@ -336,7 +271,10 @@ function MarathonA2Game:drawScoringInfo()
love.graphics.printf("LEVEL", 240, 320, 40, "left") love.graphics.printf("LEVEL", 240, 320, 40, "left")
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
if self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left") love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.score, 240, 220, 90, "left") love.graphics.printf(self.score, 240, 220, 90, "left")
love.graphics.printf(self.level, 240, 340, 40, "right") love.graphics.printf(self.level, 240, 340, 40, "right")
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right") love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")

View File

@@ -18,8 +18,7 @@ function SurvivalCKGame:new()
self.roll_frames = 0 self.roll_frames = 0
self.combo = 1 self.combo = 1
self.grade = 0 self.grade = 0
self.level = 99 self.level = 0
self.frames = 55 * 60
self.randomizer = History6RollsRandomizer() self.randomizer = History6RollsRandomizer()
@@ -173,17 +172,18 @@ function SurvivalCKGame:onPieceLock(piece, cleared_row_count)
end end
function SurvivalCKGame:updateScore(level, drop_bonus, cleared_lines) function SurvivalCKGame:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function SurvivalCKGame:updateSectionTimes(old_level, new_level) function SurvivalCKGame:updateSectionTimes(old_level, new_level)
@@ -309,7 +309,7 @@ end
function SurvivalCKGame:getHighscoreData() function SurvivalCKGame:getHighscoreData()
return { return {
grade = self:getLetterGrade(), grade = self.grade,
level = self.level, level = self.level,
frames = self.frames, frames = self.frames,
} }

View File

@@ -167,6 +167,7 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
else else
self.level = math.min(new_level, 2500) self.level = math.min(new_level, 2500)
self.skip_failed = true self.skip_failed = true
self.grade = self.grade + 1
end end
-- record new section -- record new section
section_time = self.frames - self.section_start_time section_time = self.frames - self.section_start_time
@@ -178,6 +179,7 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
self.level = 500 self.level = 500
self.game_over = true self.game_over = true
end end
self.grade = math.min(self.grade + 1, 4)
end end
else else
self.level = math.min(new_level, 2500) self.level = math.min(new_level, 2500)
@@ -185,17 +187,18 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
end end
function DemonModeGame:updateScore(level, drop_bonus, cleared_lines) function DemonModeGame:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
local letter_grades = { local letter_grades = {

View File

@@ -366,7 +366,8 @@ function GameMode:drawNextQueue(ruleset)
end end
end end
if self.hold_queue ~= nil then if self.hold_queue ~= nil then
self:setHoldOpacity() local hold_color = self.held and 0.6 or 1
self:setHoldOpacity(1, hold_color)
drawPiece( drawPiece(
self.hold_queue.shape, self.hold_queue.shape,
self.hold_queue.skin, self.hold_queue.skin,
@@ -377,8 +378,16 @@ function GameMode:drawNextQueue(ruleset)
return false return false
end end
function GameMode:setNextOpacity(i) love.graphics.setColor(1, 1, 1, 1) end function GameMode:setNextOpacity(i, j)
function GameMode:setHoldOpacity() love.graphics.setColor(1, 1, 1, 1) end i = i ~= nil and i or 1
j = j ~= nil and j or 1
love.graphics.setColor(j, j, j, i)
end
function GameMode:setHoldOpacity(i, j)
i = i ~= nil and i or 1
j = j ~= nil and j or 1
love.graphics.setColor(j, j, j, i)
end
function GameMode:drawScoringInfo() function GameMode:drawScoringInfo()
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)

View File

@@ -3,7 +3,7 @@ require 'funcs'
local GameMode = require 'tetris.modes.gamemode' local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls' local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
local IntervalTrainingGame = GameMode:extend() local IntervalTrainingGame = GameMode:extend()
@@ -15,11 +15,12 @@ IntervalTrainingGame.tagline = "Can you clear the time hurdles when the game goe
function IntervalTrainingGame:new() function IntervalTrainingGame:new()
self.level = 0
IntervalTrainingGame.super:new() IntervalTrainingGame.super:new()
self.roll_frames = 0 self.roll_frames = 0
self.combo = 1 self.combo = 1
self.randomizer = History6RollsRandomizer() self.randomizer = History6RollsRandomizer()
self.section_time_limit = 1800
self.section_start_time = 0 self.section_start_time = 0
self.section_times = { [0] = 0 } self.section_times = { [0] = 0 }
self.lock_drop = true self.lock_drop = true
@@ -27,20 +28,26 @@ function IntervalTrainingGame:new()
self.next_queue_length = 3 self.next_queue_length = 3
end end
function IntervalTrainingGame:initialize(ruleset)
self.section_time_limit = 1800
if ruleset.world then self.section_time_limit = 37 * 60 end
self.super.initialize(self, ruleset)
end
function IntervalTrainingGame:getARE() function IntervalTrainingGame:getARE()
return 4 return 6
end end
function IntervalTrainingGame:getLineARE() function IntervalTrainingGame:getLineARE()
return 4 return 6
end end
function IntervalTrainingGame:getDasLimit() function IntervalTrainingGame:getDasLimit()
return 6 return 7
end end
function IntervalTrainingGame:getLineClearDelay() function IntervalTrainingGame:getLineClearDelay()
return 6 return 4
end end
function IntervalTrainingGame:getLockDelay() function IntervalTrainingGame:getLockDelay()
@@ -61,7 +68,6 @@ function IntervalTrainingGame:advanceOneFrame()
if self.roll_frames > 2968 then if self.roll_frames > 2968 then
self.completed = true self.completed = true
end end
return false
elseif self.ready_frames == 0 then elseif self.ready_frames == 0 then
self.frames = self.frames + 1 self.frames = self.frames + 1
if self:getSectionTime() >= self.section_time_limit then if self:getSectionTime() >= self.section_time_limit then
@@ -72,14 +78,15 @@ function IntervalTrainingGame:advanceOneFrame()
end end
function IntervalTrainingGame:onPieceEnter() function IntervalTrainingGame:onPieceEnter()
if (self.level % 100 ~= 99 or self.level == 998) and not self.clear and self.frames ~= 0 then if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
self.level = self.level + 1 self.level = self.level + 1
end end
end end
function IntervalTrainingGame:onLineClear(cleared_row_count) function IntervalTrainingGame:onLineClear(cleared_row_count)
local cleared_level_bonus = {1, 2, 4, 6}
if not self.clear then if not self.clear then
local new_level = self.level + cleared_row_count local new_level = self.level + cleared_level_bonus[cleared_row_count]
self:updateSectionTimes(self.level, new_level) self:updateSectionTimes(self.level, new_level)
self.level = math.min(new_level, 999) self.level = math.min(new_level, 999)
if self.level == 999 then if self.level == 999 then
@@ -97,8 +104,6 @@ function IntervalTrainingGame:updateSectionTimes(old_level, new_level)
-- record new section -- record new section
table.insert(self.section_times, self:getSectionTime()) table.insert(self.section_times, self:getSectionTime())
self.section_start_time = self.frames self.section_start_time = self.frames
else
self.level = math.min(new_level, 999)
end end
end end
@@ -123,7 +128,7 @@ function IntervalTrainingGame:drawScoringInfo()
strTrueValues(self.prev_inputs) strTrueValues(self.prev_inputs)
) )
love.graphics.printf("NEXT", 64, 40, 40, "left") love.graphics.printf("NEXT", 64, 40, 40, "left")
love.graphics.printf("TIME LEFT", 240, 250, 80, "left") if not self.clear then love.graphics.printf("TIME LEFT", 240, 250, 80, "left") end
love.graphics.printf("LEVEL", 240, 320, 40, "left") love.graphics.printf("LEVEL", 240, 320, 40, "left")
local current_section = math.floor(self.level / 100) + 1 local current_section = math.floor(self.level / 100) + 1
@@ -134,10 +139,10 @@ function IntervalTrainingGame:drawScoringInfo()
-- draw time left, flash red if necessary -- draw time left, flash red if necessary
local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0) local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0)
if not self.game_over and not self.clear and time_left < frameTime(0,10) and time_left % 4 < 2 then if not self.game_over and time_left < frameTime(0,10) and time_left % 4 < 2 then
love.graphics.setColor(1, 0.3, 0.3, 1) love.graphics.setColor(1, 0.3, 0.3, 1)
end end
love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") if not self.clear then love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") end
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right") love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")

View File

@@ -36,6 +36,8 @@ function Marathon2020Game:new()
self.grade_points = 0 self.grade_points = 0
self.grade_point_decay_counter = 0 self.grade_point_decay_counter = 0
self.max_grade_points = 0 self.max_grade_points = 0
self.cool_timer = 0
end end
function Marathon2020Game:getARE() function Marathon2020Game:getARE()
@@ -327,6 +329,7 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
self.section_cool_count = self.section_cool_count + 1 self.section_cool_count = self.section_cool_count + 1
self.delay_level = math.min(20, self.delay_level + 1) self.delay_level = math.min(20, self.delay_level + 1)
table.insert(self.section_status, "cool") table.insert(self.section_status, "cool")
self.cool_timer = 300
end end
local section = getSectionForLevel(old_level) local section = getSectionForLevel(old_level)
@@ -430,6 +433,11 @@ function Marathon2020Game:drawScoringInfo()
self:drawSectionTimesWithSecondary(current_section) self:drawSectionTimesWithSecondary(current_section)
if (self.cool_timer > 0) then
love.graphics.printf("COOL!!", 64, 400, 160, "center")
self.cool_timer = self.cool_timer - 1
end
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self:getTotalGrade(), text_x, 120, 90, "left") love.graphics.printf(self:getTotalGrade(), text_x, 120, 90, "left")
love.graphics.printf(self.grade_points, text_x, 220, 90, "left") love.graphics.printf(self.grade_points, text_x, 220, 90, "left")

View File

@@ -137,15 +137,15 @@ function MarathonA1Game:onLineClear(cleared_row_count)
self:checkGMRequirements(self.level, self.level + cleared_row_count) self:checkGMRequirements(self.level, self.level + cleared_row_count)
if not self.clear then if not self.clear then
local new_level = math.min(self.level + cleared_row_count, 999) local new_level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 then if new_level == 999 then
self.clear = true self.clear = true
else
self.level = new_level
end end
self.level = new_level
end end
end end
function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines) function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if self.grid:checkForBravo(cleared_lines) then if self.grid:checkForBravo(cleared_lines) then
self.bravo = 4 self.bravo = 4
self.bravos = self.bravos + 1 self.bravos = self.bravos + 1
@@ -156,25 +156,25 @@ function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines)
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.combo * self.bravo cleared_lines * self.combo * self.bravo
) )
self.lines = self.lines + cleared_lines
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function MarathonA1Game:checkGMRequirements(old_level, new_level) function MarathonA1Game:checkGMRequirements(old_level, new_level)
if old_level < 300 and new_level >= 300 then if old_level < 300 and new_level >= 300 then
if self.score > 12000 and self.frames <= frameTime(4,15) then if self.score >= 12000 and self.frames <= frameTime(4,15) then
self.gm_conditions["level300"] = true self.gm_conditions["level300"] = true
end end
elseif old_level < 500 and new_level >= 500 then elseif old_level < 500 and new_level >= 500 then
if self.score > 40000 and self.frames <= frameTime(7,30) then if self.score >= 40000 and self.frames <= frameTime(7,30) then
self.gm_conditions["level500"] = true self.gm_conditions["level500"] = true
end end
elseif old_level < 999 and new_level >= 999 then elseif old_level < 999 and new_level >= 999 then
if self.score > 126000 and self.frames <= frameTime(13,30) then if self.score >= 126000 and self.frames <= frameTime(13,30) then
self.gm_conditions["level900"] = true self.gm_conditions["level999"] = true
end end
end end
end end
@@ -210,7 +210,7 @@ function MarathonA1Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, 240, 220, 90, "left") love.graphics.printf(self.score, 240, 220, 90, "left")
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level900"] then if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level999"] then
love.graphics.printf("GM", 240, 140, 90, "left") love.graphics.printf("GM", 240, 140, 90, "left")
else else
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left") love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")

View File

@@ -33,8 +33,6 @@ function MarathonA2Game:new()
"GM" "GM"
} }
self.randomizer = History6RollsRandomizer()
self.lock_drop = false self.lock_drop = false
self.enable_hold = false self.enable_hold = false
self.next_queue_length = 1 self.next_queue_length = 1
@@ -109,6 +107,7 @@ end
function MarathonA2Game:advanceOneFrame() function MarathonA2Game:advanceOneFrame()
if self.clear then if self.clear then
self.roll_frames = self.roll_frames + 1 self.roll_frames = self.roll_frames + 1
if self.roll_frames < 0 then return false end
if self.roll_frames > 3694 then if self.roll_frames > 3694 then
self.completed = true self.completed = true
if self.grade == 32 then if self.grade == 32 then
@@ -127,33 +126,31 @@ function MarathonA2Game:onPieceEnter()
end end
end end
function MarathonA2Game:onLineClear(cleared_row_count)
self:updateSectionTimes(self.level, self.level + cleared_row_count)
self.level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 and not self.clear then
self.clear = true
if self:qualifiesForMRoll() then
self.grade = 32
end
self.grid:clear()
self.roll_frames = -150
end
end
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines) function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
self:updateGrade(cleared_lines) self:updateGrade(cleared_lines)
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + 2 * drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.combo * self.bravo cleared_lines * self.combo * self.bravo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + (cleared_lines - 1) * 2
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
else self.lines = self.lines + cleared_lines end
end
function MarathonA2Game:onLineClear(cleared_row_count)
self.level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 and not self.clear then
self.clear = true
self.grid:clear()
if self:qualifiesForMRoll() then self.grade = 32 end
self.roll_frames = -150
end
end end
function MarathonA2Game:updateSectionTimes(old_level, new_level) function MarathonA2Game:updateSectionTimes(old_level, new_level)
@@ -253,7 +250,7 @@ function MarathonA2Game:updateGrade(cleared_lines)
end end
end end
local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 } local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 0 }
function MarathonA2Game:qualifiesForMRoll() function MarathonA2Game:qualifiesForMRoll()
if not self.clear then return false end if not self.clear then return false end
@@ -280,7 +277,7 @@ function MarathonA2Game:qualifiesForMRoll()
return false return false
end end
end end
if self.grade < 17 or self.frames > frameTime(9,30) then if self.grade < 31 or self.frames > frameTime(8,45) then
return false return false
end end
return true return true
@@ -344,7 +341,17 @@ function MarathonA2Game:drawScoringInfo()
end end
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
if self.clear then
if self:qualifiesForMRoll() then
if self.lines >= 32 and self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
else love.graphics.setColor(0, 1, 0, 1) end
else
if self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
else love.graphics.setColor(0, 1, 0, 1) end
end
end
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left") love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.score, 240, 220, 90, "left") love.graphics.printf(self.score, 240, 220, 90, "left")
love.graphics.printf(self.level, 240, 340, 40, "right") love.graphics.printf(self.level, 240, 340, 40, "right")
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right") love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")

View File

@@ -45,6 +45,8 @@ self.SGnames = {
self.coolregret_message = "COOL!!" self.coolregret_message = "COOL!!"
self.coolregret_timer = 0 self.coolregret_timer = 0
self.torikan_passed = false
end end
function MarathonA3Game:getARE() function MarathonA3Game:getARE()
@@ -166,10 +168,10 @@ function MarathonA3Game:onLineClear(cleared_row_count)
self.grid:clear() self.grid:clear()
self.roll_frames = -150 self.roll_frames = -150
end end
if self.level >= 500 and self.frames >= 25200 then if not self.torikan_passed and self.level >= 500 and self.frames >= 25200 then
self.level = 500 self.level = 500
self.game_over = true self.game_over = true
end elseif self.level >= 500 then self.torikan_passed = true end
end end
local cool_cutoffs = { local cool_cutoffs = {
@@ -223,18 +225,19 @@ function MarathonA3Game:updateSectionTimes(old_level, new_level)
end end
function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines) function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
self:updateGrade(cleared_lines) self:updateGrade(cleared_lines)
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
local grade_point_bonuses = { local grade_point_bonuses = {

View File

@@ -98,6 +98,7 @@ function MarathonAX4Game:onLineClear(cleared_row_count)
self:updateSectionTimes(self.lines, new_lines) self:updateSectionTimes(self.lines, new_lines)
self.lines = math.min(new_lines, 150) self.lines = math.min(new_lines, 150)
if self.lines == 150 then if self.lines == 150 then
self.grid:clear()
self.clear = true self.clear = true
self.roll_frames = -150 self.roll_frames = -150
end end

View File

@@ -117,17 +117,18 @@ function PhantomManiaGame:onLineClear(cleared_row_count)
end end
function PhantomManiaGame:updateScore(level, drop_bonus, cleared_lines) function PhantomManiaGame:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
PhantomManiaGame.rollOpacityFunction = function(age) PhantomManiaGame.rollOpacityFunction = function(age)

View File

@@ -16,7 +16,6 @@ PhantomMania2Game.tagline = "The blocks disappear even faster now! Can you make
function PhantomMania2Game:new() function PhantomMania2Game:new()
PhantomMania2Game.super:new() PhantomMania2Game.super:new()
self.level = 0
self.grade = 0 self.grade = 0
self.garbage = 0 self.garbage = 0
self.clear = false self.clear = false
@@ -38,6 +37,9 @@ function PhantomMania2Game:new()
self.lock_drop = true self.lock_drop = true
self.enable_hold = true self.enable_hold = true
self.next_queue_length = 3 self.next_queue_length = 3
self.coolregret_message = ""
self.coolregret_timer = 0
end end
function PhantomMania2Game:getARE() function PhantomMania2Game:getARE()
@@ -179,17 +181,18 @@ function PhantomMania2Game:onHold()
end end
function PhantomMania2Game:updateScore(level, drop_bonus, cleared_lines) function PhantomMania2Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
@@ -213,8 +216,13 @@ function PhantomMania2Game:updateSectionTimes(old_level, new_level)
self.section_start_time = self.frames self.section_start_time = self.frames
if section_time <= cool_cutoffs[section] then if section_time <= cool_cutoffs[section] then
self.grade = self.grade + 2 self.grade = self.grade + 2
self.coolregret_message = "COOL!!"
self.coolregret_timer = 300
elseif section_time <= regret_cutoffs[section] then elseif section_time <= regret_cutoffs[section] then
self.grade = self.grade + 1 self.grade = self.grade + 1
else
self.coolregret_message = "REGRET!!"
self.coolregret_timer = 300
end end
end end
end end
@@ -296,6 +304,11 @@ function PhantomMania2Game:drawScoringInfo()
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left") love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
end end
if(self.coolregret_timer > 0) then
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
self.coolregret_timer = self.coolregret_timer - 1
end
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left") love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left")
love.graphics.printf(self.score, text_x, 220, 90, "left") love.graphics.printf(self.score, text_x, 220, 90, "left")

View File

@@ -22,6 +22,14 @@ function Race40Game:new()
self.roll_frames = 0 self.roll_frames = 0
self.SGnames = {
[0] = "",
"9", "8", "7", "6", "5", "4", "3", "2", "1",
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
"GM"
}
self.upstacked = false
self.lock_drop = true self.lock_drop = true
self.lock_hard_drop = true self.lock_hard_drop = true
self.instant_hard_drop = true self.instant_hard_drop = true
@@ -35,7 +43,7 @@ function Race40Game:getDropSpeed()
end end
function Race40Game:getARR() function Race40Game:getARR()
return 0 return 1
end end
function Race40Game:getARE() function Race40Game:getARE()
@@ -47,7 +55,7 @@ function Race40Game:getLineARE()
end end
function Race40Game:getDasLimit() function Race40Game:getDasLimit()
return 6 return 10
end end
function Race40Game:getLineClearDelay() function Race40Game:getLineClearDelay()
@@ -55,7 +63,7 @@ function Race40Game:getLineClearDelay()
end end
function Race40Game:getLockDelay() function Race40Game:getLockDelay()
return 15 return 30
end end
function Race40Game:getGravity() function Race40Game:getGravity()
@@ -102,6 +110,12 @@ function Race40Game:getHighscoreData()
} }
end end
function Race40Game:getSecretGrade(sg)
if sg == 19 then self.upstacked = true end
if self.upstacked then return self.SGnames[14 + math.floor((20 - sg) / 4)]
else return self.SGnames[math.floor((sg / 19) * 14)] end
end
function Race40Game:drawScoringInfo() function Race40Game:drawScoringInfo()
Race40Game.super.drawScoringInfo(self) Race40Game.super.drawScoringInfo(self)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
@@ -113,10 +127,17 @@ function Race40Game:drawScoringInfo()
love.graphics.printf("LINES", text_x, 320, 40, "left") love.graphics.printf("LINES", text_x, 320, 40, "left")
love.graphics.printf("line/min", text_x, 160, 80, "left") love.graphics.printf("line/min", text_x, 160, 80, "left")
love.graphics.printf("piece/sec", text_x, 220, 80, "left") love.graphics.printf("piece/sec", text_x, 220, 80, "left")
local sg = self.grid:checkSecretGrade()
if sg >= 7 or self.upstacked then
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
end
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(string.format("%.02f", self.lines / math.max(1, self.frames) * 3600), text_x, 180, 80, "left") love.graphics.printf(string.format("%.02f", self.lines / math.max(1, self.frames) * 3600), text_x, 180, 80, "left")
love.graphics.printf(string.format("%.04f", self.pieces / math.max(1, self.frames) * 60), text_x, 240, 80, "left") love.graphics.printf(string.format("%.04f", self.pieces / math.max(1, self.frames) * 60), text_x, 240, 80, "left")
if sg >= 7 or self.upstacked then
love.graphics.printf(self:getSecretGrade(sg), 240, 450, 180, "left")
end
love.graphics.setFont(font_3x5_4) love.graphics.setFont(font_3x5_4)
love.graphics.printf(math.max(0, self.line_goal - self.lines), text_x, 340, 40, "left") love.graphics.printf(math.max(0, self.line_goal - self.lines), text_x, 340, 40, "left")

View File

@@ -16,7 +16,6 @@ StrategyGame.tagline = "You have lots of time to think! Can you use it to place
function StrategyGame:new() function StrategyGame:new()
StrategyGame.super:new() StrategyGame.super:new()
self.level = 0
self.clear = false self.clear = false
self.completed = false self.completed = false
self.roll_frames = 0 self.roll_frames = 0
@@ -84,7 +83,7 @@ function StrategyGame:advanceOneFrame()
end end
function StrategyGame:onPieceEnter() function StrategyGame:onPieceEnter()
if (self.level % 100 ~= 99) and not self.clear and self.frames ~= 0 then if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
self.level = self.level + 1 self.level = self.level + 1
end end
end end
@@ -99,17 +98,18 @@ function StrategyGame:onLineClear(cleared_row_count)
end end
function StrategyGame:updateScore(level, drop_bonus, cleared_lines) function StrategyGame:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function StrategyGame:setNextOpacity(i) function StrategyGame:setNextOpacity(i)
@@ -135,11 +135,11 @@ function StrategyGame:drawScoringInfo()
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, text_x, 220, 90, "left") love.graphics.printf(self.score, text_x, 220, 90, "left")
love.graphics.printf(self.level, text_x, 340, 50, "right") love.graphics.printf(self.level, text_x, 340, 40, "right")
if self.clear then if self.clear then
love.graphics.printf(self.level, text_x, 370, 50, "right") love.graphics.printf(self.level, text_x, 370, 40, "right")
else else
love.graphics.printf(math.floor(self.level / 100 + 1) * 100, text_x, 370, 50, "right") love.graphics.printf(self.level < 900 and math.floor(self.level / 100 + 1) * 100 or 999, text_x, 370, 40, "right")
end end
end end

View File

@@ -174,17 +174,18 @@ function Survival2020Game:onLineClear(cleared_row_count)
end end
function Survival2020Game:updateScore(level, drop_bonus, cleared_lines) function Survival2020Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function Survival2020Game:updateSectionTimes(old_level, new_level) function Survival2020Game:updateSectionTimes(old_level, new_level)

View File

@@ -109,7 +109,7 @@ function SurvivalA1Game:onLineClear(cleared_row_count)
self:checkGMRequirements(self.level, self.level + cleared_row_count) self:checkGMRequirements(self.level, self.level + cleared_row_count)
if not self.clear then if not self.clear then
local new_level = math.min(self.level + cleared_row_count, 999) local new_level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 then if new_level == 999 then
self.clear = true self.clear = true
else else
self.level = new_level self.level = new_level
@@ -118,35 +118,36 @@ function SurvivalA1Game:onLineClear(cleared_row_count)
end end
function SurvivalA1Game:updateScore(level, drop_bonus, cleared_lines) function SurvivalA1Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if self.grid:checkForBravo(cleared_lines) then if self.grid:checkForBravo(cleared_lines) then
self.bravo = 4 self.bravo = 4
self.bravos = self.bravos + 1 self.bravos = self.bravos + 1
else self.bravo = 1 end else self.bravo = 1 end
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.bravo * self.combo cleared_lines * self.combo * self.bravo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + (cleared_lines - 1) * 2
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function SurvivalA1Game:checkGMRequirements(old_level, new_level) function SurvivalA1Game:checkGMRequirements(old_level, new_level)
if old_level < 300 and new_level >= 300 then if old_level < 300 and new_level >= 300 then
if self.score > 12000 and self.frames <= frameTime(4,15) then if self.score >= 12000 and self.frames <= frameTime(4,15) then
self.gm_conditions["level300"] = true self.gm_conditions["level300"] = true
end end
elseif old_level < 500 and new_level >= 500 then elseif old_level < 500 and new_level >= 500 then
if self.score > 40000 and self.frames <= frameTime(7,30) then if self.score >= 40000 and self.frames <= frameTime(7,30) then
self.gm_conditions["level500"] = true self.gm_conditions["level500"] = true
end end
elseif old_level < 999 and new_level >= 999 then elseif old_level < 999 and new_level >= 999 then
if self.score > 126000 and self.frames <= frameTime(13,30) then if self.score >= 126000 and self.frames <= frameTime(13,30) then
self.gm_conditions["level900"] = true self.gm_conditions["level999"] = true
end end
end end
end end
@@ -179,7 +180,7 @@ function SurvivalA1Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, 240, 220, 90, "left") love.graphics.printf(self.score, 240, 220, 90, "left")
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level900"] then if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level999"] then
love.graphics.printf("GM", 240, 140, 90, "left") love.graphics.printf("GM", 240, 140, 90, "left")
else else
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left") love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")

View File

@@ -88,7 +88,7 @@ function SurvivalA2Game:advanceOneFrame()
end end
function SurvivalA2Game:onPieceEnter() function SurvivalA2Game:onPieceEnter()
if (self.level % 100 ~= 99 or self.level == 998) and not self.clear and self.frames ~= 0 then if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
self.level = self.level + 1 self.level = self.level + 1
end end
end end
@@ -108,18 +108,19 @@ function SurvivalA2Game:onLineClear(cleared_row_count)
end end
function SurvivalA2Game:updateScore(level, drop_bonus, cleared_lines) function SurvivalA2Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.bravo * self.combo cleared_lines * self.combo * self.bravo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + (cleared_lines - 1) * 2
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function SurvivalA2Game:getLetterGrade() function SurvivalA2Game:getLetterGrade()

View File

@@ -16,7 +16,6 @@ SurvivalA3Game.tagline = "The blocks turn black and white! Can you make it to le
function SurvivalA3Game:new() function SurvivalA3Game:new()
SurvivalA3Game.super:new() SurvivalA3Game.super:new()
self.level = 0
self.grade = 0 self.grade = 0
self.garbage = 0 self.garbage = 0
self.clear = false self.clear = false
@@ -140,7 +139,6 @@ function SurvivalA3Game:onPieceEnter()
end end
local cleared_row_levels = {1, 2, 4, 6} local cleared_row_levels = {1, 2, 4, 6}
local cleared_row_points = {0.02, 0.05, 0.15, 0.6}
function SurvivalA3Game:onLineClear(cleared_row_count) function SurvivalA3Game:onLineClear(cleared_row_count)
if not self.clear then if not self.clear then
@@ -168,17 +166,18 @@ function SurvivalA3Game:onPieceLock(piece, cleared_row_count)
end end
function SurvivalA3Game:updateScore(level, drop_bonus, cleared_lines) function SurvivalA3Game:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if cleared_lines > 0 then if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + ( self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) * (math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1) cleared_lines * self.combo
) )
self.lines = self.lines + cleared_lines
self.combo = self.combo + cleared_lines - 1
else else
self.drop_bonus = 0
self.combo = 1 self.combo = 1
end end
self.drop_bonus = 0
end
end end
function SurvivalA3Game:updateSectionTimes(old_level, new_level) function SurvivalA3Game:updateSectionTimes(old_level, new_level)
@@ -243,7 +242,10 @@ function SurvivalA3Game:drawScoringInfo()
self:drawSectionTimesWithSplits(current_section) self:drawSectionTimesWithSplits(current_section)
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left") love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left")
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.score, text_x, 220, 90, "left") love.graphics.printf(self.score, text_x, 220, 90, "left")
love.graphics.printf(self.level, text_x, 340, 50, "right") love.graphics.printf(self.level, text_x, 340, 50, "right")
if self.clear then if self.clear then

209
tetris/modes/tgmplus.lua Normal file
View File

@@ -0,0 +1,209 @@
require 'funcs'
local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece'
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls'
local TGMPlusGame = GameMode:extend()
TGMPlusGame.name = "Marathon A2+"
TGMPlusGame.hash = "A2Plus"
TGMPlusGame.tagline = "The garbage rises steadily! Can you make it to level 999?"
function TGMPlusGame:new()
TGMPlusGame.super:new()
self.roll_frames = 0
self.combo = 1
self.SGnames = {
"9", "8", "7", "6", "5", "4", "3", "2", "1",
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
"GM"
}
self.randomizer = History6RollsRandomizer()
self.lock_drop = false
self.enable_hold = false
self.next_queue_length = 1
self.garbage_queue = 0
self.garbage_pos = 0
self.garbage_rows = {
[0] = {"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"e", "e", "b", "b", "b", "b", "b", "b", "b", "b"},
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
{"b", "b", "b", "b", "b", "b", "b", "b", "e", "e"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
{"b", "b", "e", "b", "b", "b", "b", "b", "b", "b"},
{"b", "e", "e", "b", "b", "b", "b", "b", "b", "b"},
{"b", "e", "b", "b", "b", "b", "b", "b", "b", "b"},
{"b", "b", "b", "b", "b", "b", "b", "e", "b", "b"},
{"b", "b", "b", "b", "b", "b", "b", "e", "e", "b"},
{"b", "b", "b", "b", "b", "b", "b", "b", "e", "b"},
{"b", "b", "b", "b", "e", "e", "b", "b", "b", "b"},
{"b", "b", "b", "b", "e", "e", "b", "b", "b", "b"},
{"b", "b", "b", "b", "e", "b", "b", "b", "b", "b"},
{"b", "b", "b", "e", "e", "e", "b", "b", "b", "b"},
}
end
function TGMPlusGame:getARE() return 25 end
function TGMPlusGame:getDasLimit() return 15 end
function TGMPlusGame:getLockDelay() return 30 end
function TGMPlusGame:getLineClearDelay() return 40 end
function TGMPlusGame:getGravity()
if (self.level < 30) then return 4/256
elseif (self.level < 35) then return 6/256
elseif (self.level < 40) then return 8/256
elseif (self.level < 50) then return 10/256
elseif (self.level < 60) then return 12/256
elseif (self.level < 70) then return 16/256
elseif (self.level < 80) then return 32/256
elseif (self.level < 90) then return 48/256
elseif (self.level < 100) then return 64/256
elseif (self.level < 120) then return 80/256
elseif (self.level < 140) then return 96/256
elseif (self.level < 160) then return 112/256
elseif (self.level < 170) then return 128/256
elseif (self.level < 200) then return 144/256
elseif (self.level < 220) then return 4/256
elseif (self.level < 230) then return 32/256
elseif (self.level < 233) then return 64/256
elseif (self.level < 236) then return 96/256
elseif (self.level < 239) then return 128/256
elseif (self.level < 243) then return 160/256
elseif (self.level < 247) then return 192/256
elseif (self.level < 251) then return 224/256
elseif (self.level < 300) then return 1
elseif (self.level < 330) then return 2
elseif (self.level < 360) then return 3
elseif (self.level < 400) then return 4
elseif (self.level < 420) then return 5
elseif (self.level < 450) then return 4
elseif (self.level < 500) then return 3
else return 20
end
end
function TGMPlusGame:getGarbageLimit() return 13 - math.floor(self.level / 100) end
function TGMPlusGame:advanceOneFrame()
if self.clear then
self.roll_frames = self.roll_frames + 1
if self.roll_frames > 3694 then
self.completed = true
end
elseif self.ready_frames == 0 then
self.frames = self.frames + 1
end
return true
end
function TGMPlusGame:onPieceEnter()
if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
self.level = self.level + 1
end
end
function TGMPlusGame:onPieceLock(piece, cleared_row_count)
if cleared_row_count == 0 then self:advanceBottomRow() end
end
function TGMPlusGame:onLineClear(cleared_row_count)
self.level = math.min(self.level + cleared_row_count, 999)
if self.level == 999 and not self.clear then self.clear = true end
end
function TGMPlusGame:advanceBottomRow()
self.garbage_queue = self.garbage_queue + 1
if self.garbage_queue >= self:getGarbageLimit() then
self.grid:garbageRise(self.garbage_rows[self.garbage_pos])
self.garbage_queue = 0
self.garbage_pos = (self.garbage_pos + 1) % 24
end
end
function TGMPlusGame:updateScore(level, drop_bonus, cleared_lines)
if not self.clear then
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
if cleared_lines > 0 then
self.combo = self.combo + (cleared_lines - 1) * 2
self.score = self.score + (
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
cleared_lines * self.combo * self.bravo
)
else
self.combo = 1
end
self.drop_bonus = 0
end
end
function TGMPlusGame:drawGrid(ruleset)
self.grid:draw()
if self.piece ~= nil and self.level < 100 then
self:drawGhostPiece(ruleset)
end
end
function TGMPlusGame:getHighscoreData()
return {
score = self.score,
level = self.level,
frames = self.frames,
}
end
function TGMPlusGame:getSectionEndLevel()
if self.level >= 900 then return 999
else return math.floor(self.level / 100 + 1) * 100 end
end
function TGMPlusGame:getBackground()
return math.floor(self.level / 100)
end
function TGMPlusGame:drawScoringInfo()
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setFont(font_3x5_2)
love.graphics.print(
self.das.direction .. " " ..
self.das.frames .. " " ..
strTrueValues(self.prev_inputs)
)
love.graphics.printf("NEXT", 64, 40, 40, "left")
love.graphics.printf("SCORE", 240, 200, 40, "left")
love.graphics.printf("LEVEL", 240, 320, 40, "left")
local sg = self.grid:checkSecretGrade()
if sg >= 5 then
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
end
love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, 240, 220, 90, "left")
love.graphics.printf(self.level, 240, 340, 40, "right")
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
if sg >= 5 then
love.graphics.printf(self.SGnames[sg], 240, 450, 180, "left")
end
love.graphics.setFont(font_8x11)
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
end
return TGMPlusGame

View File

@@ -50,9 +50,6 @@ function PacerTest:new()
end end
function PacerTest:initialize(ruleset) function PacerTest:initialize(ruleset)
for i = 1, 30 do
table.insert(self.next_queue, self:getNextPiece(ruleset))
end
self.level_frames = getLevelFrames(1) self.level_frames = getLevelFrames(1)
switchBGM("pacer_test") switchBGM("pacer_test")
end end

View File

@@ -24,6 +24,29 @@ Ruleset.enable_IRS_wallkicks = false
-- Component functions. -- Component functions.
function Ruleset:new()
blocks["bone"] = (not self.world) and
{
R = love.graphics.newImage("res/img/bone.png"),
O = love.graphics.newImage("res/img/bone.png"),
Y = love.graphics.newImage("res/img/bone.png"),
G = love.graphics.newImage("res/img/bone.png"),
C = love.graphics.newImage("res/img/bone.png"),
B = love.graphics.newImage("res/img/bone.png"),
M = love.graphics.newImage("res/img/bone.png"),
X = love.graphics.newImage("res/img/bone.png"),
} or {
R = love.graphics.newImage("res/img/bonew.png"),
O = love.graphics.newImage("res/img/bonew.png"),
Y = love.graphics.newImage("res/img/bonew.png"),
G = love.graphics.newImage("res/img/bonew.png"),
C = love.graphics.newImage("res/img/bonew.png"),
B = love.graphics.newImage("res/img/bonew.png"),
M = love.graphics.newImage("res/img/bonew.png"),
X = love.graphics.newImage("res/img/bonew.png"),
}
end
function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial) function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial)
local new_inputs = {} local new_inputs = {}