From 80c7c99bd7d333c6e58cbb3d0621debf39283879 Mon Sep 17 00:00:00 2001 From: Joe Zeng Date: Sun, 7 Jul 2019 18:55:03 -0400 Subject: [PATCH] Added Credits A3 mode. (#26) Also updated the documentation. --- docs/gamemodes.md | 13 +++- scene/mode_select.lua | 1 + tetris/modes/credits_a3.lua | 118 +++++++++++++++++++++++++++++ tetris/modes/gamemode.lua | 2 +- tetris/modes/interval_training.lua | 11 ++- 5 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 tetris/modes/credits_a3.lua diff --git a/docs/gamemodes.md b/docs/gamemodes.md index 828cf42..b70e6f1 100644 --- a/docs/gamemodes.md +++ b/docs/gamemodes.md @@ -15,7 +15,9 @@ There are several classes of game modes. The modes that originate from other gam * The "G" series stand for "Guideline" games, or games that follow the Tetris Guideline. * GF - Tetris Friends (2007-2019) * GJ - Tetris Online Japan (2005-2011) -* N stands for Nullpomino, only used for Phantom Mania N. +* The "N" series stands for Nullpomino, only used for Phantom Mania N. +* The "W" series stands for "Web" games, which are fanmade games released on the web. + * WCB - RainComplex.net's Cat Boi Quatro. MARATHON -------- @@ -23,6 +25,7 @@ MARATHON Modes in which the goal is to play as well as possible over a limited game interval. * **MARATHON 2020**: 2020 levels of pure pain. Can you make it all the way? +* **MARATHON WCB**: CatBoiQuatro! Can you control the pieces? From other games: * **MARATHON A1**: Tetris the Grand Master 1. @@ -57,6 +60,14 @@ Modes with no levels, just a single timed goal. * **Race 40**: How fast can you clear 40 lines? No limits, no holds barred. +CREDITS +------- + +Modes that are just the credit rolls of specific games. + +* **CREDITS A3**: Tetris the Grand Master 3's famous M-roll. + + PHANTOM MANIA ------------- diff --git a/scene/mode_select.lua b/scene/mode_select.lua index a2e1efd..4518690 100644 --- a/scene/mode_select.lua +++ b/scene/mode_select.lua @@ -31,6 +31,7 @@ game_modes = { require 'tetris.modes.survival_a3', require 'tetris.modes.survival_ax', require 'tetris.modes.survival_ax2', + require 'tetris.modes.credits_a3', } rulesets = { diff --git a/tetris/modes/credits_a3.lua b/tetris/modes/credits_a3.lua new file mode 100644 index 0000000..07f6a0f --- /dev/null +++ b/tetris/modes/credits_a3.lua @@ -0,0 +1,118 @@ +require 'funcs' + +local IntervalTrainingMode = require 'tetris.modes.interval_training' +local Piece = require 'tetris.components.piece' + +local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls' + +local CreditsA3Game = IntervalTrainingMode:extend() + +CreditsA3Game.name = "Credits A3" +CreditsA3Game.hash = "CreditsA3" +CreditsA3Game.tagline = "How consistently can you clear the Ti M-roll?" + +function CreditsA3Game:new() + CreditsA3Game.super:new() + self.section_time_limit = 3238 + self.norm = 0 + self.section = 0 +end + +function CreditsA3Game:advanceOneFrame(inputs, ruleset) + if self.frames == 0 then + switchBGM("credit_roll", "gm3") + end + if self.roll_frames > 0 then + self.roll_frames = self.roll_frames - 1 + if self.roll_frames == 0 then + -- reset + self.norm = 0 + self.frames = 0 + self.grid:clear() + switchBGM("credit_roll", "gm3") + self:initializeOrHold(inputs, ruleset) + else + return false + end + elseif self.ready_frames == 0 then + self.frames = self.frames + 1 + if self:getSectionTime() >= self.section_time_limit then + self.norm = self.norm + 16 + self.piece = nil + if self.norm >= 60 then + self.section = self.section + 1 + self.roll_frames = 150 + else + self.game_over = true + end + end + end + return true +end + +function CreditsA3Game:onPieceEnter() + -- do nothing +end + +function CreditsA3Game:onLineClear(cleared_row_count) + if not self.clear then + self.norm = self.norm + (cleared_row_count == 4 and 10 or cleared_row_count) + end +end + +CreditsA3Game.rollOpacityFunction = function(age) + if age > 4 then return 0 + else return 1 - age / 4 end +end + +function CreditsA3Game:drawGrid(ruleset) + if not self.game_over and self.roll_frames < 30 then + self.grid:drawInvisible(self.rollOpacityFunction) + else + self.grid:draw() + end +end + +function CreditsA3Game:drawScoringInfo() + love.graphics.setColor(1, 1, 1, 1) + + love.graphics.setFont(font_3x5_2) + love.graphics.print( + self.das.direction .. " " .. + self.das.frames .. " " .. + st(self.prev_inputs) + ) + love.graphics.printf("NEXT", 64, 40, 40, "left") + love.graphics.printf("TIME LEFT", 240, 250, 80, "left") + love.graphics.printf("NORM", 240, 320, 40, "left") + + self:drawSectionTimesWithSplits(self.section) + + love.graphics.setFont(font_3x5_3) + -- draw time left, flash red if necessary + local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0) + + if not self.game_over and not self.clear and time_left < sp(0,10) and time_left % 4 < 2 then + if self.norm >= 44 then + love.graphics.setColor(0.3, 1, 0.3, 1) -- flash green if goal has been cleared + else + love.graphics.setColor(1, 0.3, 0.3, 1) -- otherwise flash red + end + end + + love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") + + love.graphics.setColor(1, 1, 1, 1) + love.graphics.printf(self.norm, 240, 340, 40, "right") + if self.game_over or self.roll_frames > 0 then + love.graphics.printf("60", 240, 370, 40, "right") + else + love.graphics.printf("44", 240, 370, 40, "right") + end +end + +function CreditsA3Game:getBackground() + return self.section +end + +return CreditsA3Game diff --git a/tetris/modes/gamemode.lua b/tetris/modes/gamemode.lua index f437d2b..49c297a 100644 --- a/tetris/modes/gamemode.lua +++ b/tetris/modes/gamemode.lua @@ -91,7 +91,7 @@ function GameMode:update(inputs, ruleset) if self.completed then return end -- advance one frame - if self:advanceOneFrame(inputs) == false then return end + if self:advanceOneFrame(inputs, ruleset) == false then return end self:chargeDAS(inputs, self:getDasLimit(), self.getARR()) diff --git a/tetris/modes/interval_training.lua b/tetris/modes/interval_training.lua index b11fe5e..66cd5ef 100644 --- a/tetris/modes/interval_training.lua +++ b/tetris/modes/interval_training.lua @@ -28,19 +28,19 @@ function IntervalTrainingGame:new() end function IntervalTrainingGame:getARE() - return 4 + return 6 end function IntervalTrainingGame:getLineARE() - return 4 + return 6 end function IntervalTrainingGame:getDasLimit() - return 6 + return 7 end function IntervalTrainingGame:getLineClearDelay() - return 6 + return 4 end function IntervalTrainingGame:getLockDelay() @@ -130,8 +130,6 @@ function IntervalTrainingGame:drawScoringInfo() self:drawSectionTimesWithSplits(current_section) love.graphics.setFont(font_3x5_3) - love.graphics.printf(self.level, 240, 340, 40, "right") - -- draw time left, flash red if necessary local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0) if not self.game_over and not self.clear and time_left < sp(0,10) and time_left % 4 < 2 then @@ -140,6 +138,7 @@ function IntervalTrainingGame:drawScoringInfo() love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") love.graphics.setColor(1, 1, 1, 1) + love.graphics.printf(self.level, 240, 340, 40, "right") love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right") end