diff --git a/load/version.lua b/load/version.lua index 2d6b1d7..f722ac9 100644 --- a/load/version.lua +++ b/load/version.lua @@ -1 +1 @@ -version = "v0.3-beta5.2" \ No newline at end of file +version = "v0.3-beta6" \ No newline at end of file diff --git a/scene/game.lua b/scene/game.lua index 7cdb00e..642b20b 100644 --- a/scene/game.lua +++ b/scene/game.lua @@ -42,36 +42,17 @@ function GameScene:update() end function GameScene:render() - self.game:drawBackground() - self.game:drawFrame() - self.game:drawGrid() - if self.game:canDrawLCA() then - self.game:drawLineClearAnimation() - end - self.game:drawPiece() - self.game:drawNextQueue(self.ruleset) - self.game:drawScoringInfo() - self.game:drawReadyGo() - self.game:drawCustom() - - love.graphics.setColor(1, 1, 1, 1) - love.graphics.setFont(font_3x5_2) - if config.gamesettings.display_gamemode == 1 then - love.graphics.printf(self.game.name .. " - " .. self.ruleset.name, 0, 460, 640, "left") - end - - love.graphics.setFont(font_3x5_3) - if self.paused then love.graphics.print("PAUSED!", 80, 100) end - - if self.game.completed then - self.game:onGameComplete() - elseif self.game.game_over then - self.game:onGameOver() - end + self.game:draw(self.paused) end function GameScene:onInputPress(e) - if (self.game.game_over or self.game.completed) and (e.input == "menu_decide" or e.input == "menu_back" or e.input == "retry") then + if ( + self.game.game_over or self.game.completed + ) and ( + e.input == "menu_decide" or + e.input == "menu_back" or + e.input == "retry" + ) then highscore_entry = self.game:getHighscoreData() highscore_hash = self.game.hash .. "-" .. self.ruleset.hash submitHighscore(highscore_hash, highscore_entry) diff --git a/scene/game_config.lua b/scene/game_config.lua index 249759b..6e5cb4b 100644 --- a/scene/game_config.lua +++ b/scene/game_config.lua @@ -17,7 +17,7 @@ ConfigScene.options = { {"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}}, {"synchroes_allowed", "Synchroes", false, {"Per ruleset", "On", "Off"}}, {"diagonal_input", "Diagonal Input", false, {"On", "Off"}}, - {"buffer_lock", "Buffer Lock Inputs", false, {"On", "Off"}}, + {"buffer_lock", "Buffer Lock Type", false, {"Off", "Hold", "Tap"}}, {"sfx_volume", "SFX", true, "sfxSlider"}, {"bgm_volume", "BGM", true, "bgmSlider"}, } diff --git a/tetris/modes/gamemode.lua b/tetris/modes/gamemode.lua index 5456a9e..7587784 100644 --- a/tetris/modes/gamemode.lua +++ b/tetris/modes/gamemode.lua @@ -85,10 +85,11 @@ function GameMode:getDasCutDelay() return 0 end function GameMode:getGravity() return 1/64 end function GameMode:getNextPiece(ruleset) + local shape = self.used_randomizer:nextPiece() return { skin = self:getSkin(), - shape = self.used_randomizer:nextPiece(), - orientation = ruleset:getDefaultOrientation(), + shape = shape, + orientation = ruleset:getDefaultOrientation(shape), } end @@ -178,7 +179,10 @@ function GameMode:update(inputs, ruleset) ruleset:processPiece( inputs, self.piece, self.grid, self:getGravity(), self.prev_inputs, - self.move, self:getLockDelay(), self:getDropSpeed(), + ( + inputs.up and self.lock_on_hard_drop and not self.hard_drop_locked + ) and "none" or self.move, + self:getLockDelay(), self:getDropSpeed(), self.drop_locked, self.hard_drop_locked, self.enable_hard_drop, self.additive_gravity, self.classic_lock ) @@ -426,18 +430,37 @@ function GameMode:areCancel(inputs, ruleset) end end +function GameMode:checkBufferedInputs(inputs) + if ( + config.gamesettings.buffer_lock ~= 1 and + not self.prev_inputs["up"] and inputs["up"] and + self.enable_hard_drop + ) then + self.buffer_hard_drop = true + elseif ( + config.gamesettings.buffer_lock == 2 and not inputs["up"] + ) then + self.buffer_hard_drop = false + end + if ( + config.gamesettings.buffer_lock ~= 1 and + not self.prev_inputs["down"] and inputs["down"] + ) then + self.buffer_soft_drop = true + elseif ( + config.gamesettings.buffer_lock == 2 and not inputs["down"] + ) then + self.buffer_soft_drop = false + end +end + function GameMode:processDelays(inputs, ruleset, drop_speed) if self.ready_frames == 100 then playedReadySE = false playedGoSE = false end if self.ready_frames > 0 then - if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then - self.buffer_hard_drop = true - end - if not self.prev_inputs["down"] and inputs["down"] then - self.buffer_soft_drop = true - end + self:checkBufferedInputs(inputs) if not playedReadySE then playedReadySE = true playSEOnce("ready") @@ -451,12 +474,7 @@ function GameMode:processDelays(inputs, ruleset, drop_speed) self:initializeOrHold(inputs, ruleset) end elseif self.lcd > 0 then - if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then - self.buffer_hard_drop = true - end - if not self.prev_inputs["down"] and inputs["down"] then - self.buffer_soft_drop = true - end + self:checkBufferedInputs(inputs) self.lcd = self.lcd - 1 self:areCancel(inputs, ruleset) if self.lcd == 0 then @@ -469,12 +487,7 @@ function GameMode:processDelays(inputs, ruleset, drop_speed) end end elseif self.are > 0 then - if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then - self.buffer_hard_drop = true - end - if not self.prev_inputs["down"] and inputs["down"] then - self.buffer_soft_drop = true - end + self:checkBufferedInputs(inputs) self.are = self.are - 1 self:areCancel(inputs, ruleset) if self.are == 0 then @@ -541,10 +554,8 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next ) and self.irs or false ) if self.buffer_hard_drop then - if config.gamesettings.buffer_lock == 1 then - self.piece:dropToBottom(self.grid) - if self.lock_on_hard_drop then self.piece.locked = true end - end + self.piece:dropToBottom(self.grid) + self.piece.locked = self.lock_on_hard_drop local above_field = ( (config.gamesettings.spawn_positions == 1 and ruleset.spawn_above_field) or @@ -563,8 +574,7 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next if self.buffer_soft_drop then if ( self.lock_on_soft_drop and - self.piece:isDropBlocked(self.grid) and - config.gamesettings.buffer_lock == 1 + self.piece:isDropBlocked(self.grid) ) then self.piece.locked = true end @@ -904,4 +914,38 @@ end function GameMode:drawCustom() end +function GameMode:draw(paused) + self:drawBackground() + self:drawFrame() + self:drawGrid() + self:drawPiece() + self:drawNextQueue(self.ruleset) + self:drawScoringInfo() + self:drawReadyGo() + self:drawCustom() + if self:canDrawLCA() then + self:drawLineClearAnimation() + end + + love.graphics.setColor(1, 1, 1, 1) + love.graphics.setFont(font_3x5_2) + if config.gamesettings.display_gamemode == 1 then + love.graphics.printf( + self.name .. " - " .. self.ruleset.name, + 0, 460, 640, "left" + ) + end + + love.graphics.setFont(font_3x5_3) + if paused then + love.graphics.printf("GAME PAUSED!", 64, 160, 160, "center") + end + + if self.completed then + self:onGameComplete() + elseif self.game_over then + self:onGameOver() + end +end + return GameMode diff --git a/tetris/modes/marathon_2020.lua b/tetris/modes/marathon_2020.lua index 4ebeba3..1e531d9 100644 --- a/tetris/modes/marathon_2020.lua +++ b/tetris/modes/marathon_2020.lua @@ -84,6 +84,7 @@ function Marathon2020Game:getLineClearDelay() end function Marathon2020Game:getLockDelay() + --[[ if self.delay_level < 6 then return 30 elseif self.delay_level < 7 then return 26 elseif self.delay_level < 8 then return 22 @@ -95,6 +96,7 @@ function Marathon2020Game:getLockDelay() elseif self.delay_level < 19 then return 10 elseif self.delay_level < 20 then return 9 else return 8 end + ]] return 1 end function Marathon2020Game:getGravity() @@ -144,7 +146,7 @@ function Marathon2020Game:advanceOneFrame() if self.roll_frames < 0 then return false elseif self.roll_frames > 4000 then - if self.grade >= 30 and self.section_cool_count >= 20 then self.grade = 31 end + if self:qualifiesForMRoll() then self.grade = 31 end self.completed = true end elseif self.ready_frames == 0 then @@ -227,13 +229,14 @@ local mid_cleared_line_points = {2, 6, 12, 24} local high_cleared_line_points = {1, 4, 9, 20} local function getGradeForGradePoints(points) - return math.floor(math.sqrt((points / 50) * 8 + 1) / 2 - 0.5) + return math.min(30, math.floor(math.sqrt((points / 50) * 8 + 1) / 2 - 0.5)) -- Don't be afraid of the above function. All it does is make it so that -- you need 50 points to get to grade 1, 100 points to grade 2, etc. end function Marathon2020Game:updateGrade(cleared_lines) -- update grade points and max grade points + if self.clear then return end local point_level = math.floor(self.level / 100) + self.delay_level local plus_points = math.max( low_cleared_line_points[cleared_lines], @@ -249,7 +252,6 @@ function Marathon2020Game:updateGrade(cleared_lines) end function Marathon2020Game:getTotalGrade() - if self.grade + self.section_cool_count > 50 then return "GM" end return self.grade + self.section_cool_count end @@ -331,14 +333,16 @@ end function Marathon2020Game:updateSectionTimes(old_level, new_level) function sectionCool(section) self.section_cool_count = self.section_cool_count + 1 - self.delay_level = math.min(20, self.delay_level + 1) - if section < 10 then table.insert(self.section_status, "cool") end + if section < 10 then + self.delay_level = math.min(20, self.delay_level + 1) + end + table.insert(self.section_status, "cool") self.cool_timer = 300 end local section = getSectionForLevel(old_level) - if section <= 19 and old_level % 100 < 70 and new_level >= math.floor(old_level / 100) * 100 + 70 then + if old_level % 100 < 70 and new_level >= math.floor(old_level / 100) * 100 + 70 then -- record section 70 time section_70_time = self.frames - self.section_start_time table.insert(self.secondary_section_times, section_70_time) @@ -355,14 +359,14 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level) self:checkClear(new_level) if ( - section <= 19 and self.section_status[section - 1] == "cool" and + self.section_status[section - 1] == "cool" and self.secondary_section_times[section] < self.secondary_section_times[section - 1] + 120 and self.secondary_section_times[section] < cool_cutoffs[section] ) then sectionCool(section) elseif self.section_status[section - 1] == "cool" then table.insert(self.section_status, "none") - elseif section <= 19 and self.secondary_section_times[section] < cool_cutoffs[section] then + elseif self.secondary_section_times[section] < cool_cutoffs[section] then sectionCool(section) else table.insert(self.section_status, "none") @@ -452,7 +456,13 @@ function Marathon2020Game:drawScoringInfo() end love.graphics.setFont(font_3x5_3) - love.graphics.printf(self:getTotalGrade(), text_x, 120, 90, "left") + + local grade = self:getTotalGrade() + love.graphics.printf( + grade > 50 and "GM" or grade, + text_x, 120, 90, "left" + ) + love.graphics.printf(self.grade_points, text_x, 220, 90, "left") love.graphics.printf(self.level, text_x, 340, 50, "right") @@ -466,7 +476,7 @@ end function Marathon2020Game:getHighscoreData() return { - grade = self.grade, + grade = self:getTotalGrade(), level = self.level, frames = self.frames, } diff --git a/tetris/modes/marathon_a2.lua b/tetris/modes/marathon_a2.lua index 2f63813..7d45f49 100644 --- a/tetris/modes/marathon_a2.lua +++ b/tetris/modes/marathon_a2.lua @@ -19,6 +19,7 @@ function MarathonA2Game:new() self.roll_frames = 0 self.combo = 1 + self.grade_combo = 1 self.randomizer = History6RollsRandomizer() self.grade = 0 self.grade_points = 0 @@ -135,15 +136,23 @@ function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines) if cleared_lines >= 4 then self.tetris_count = self.tetris_count + 1 end - 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 self.combo = self.combo + (cleared_lines - 1) * 2 + if cleared_lines > 1 then + self.grade_combo = self.grade_combo + 1 + end self.score = self.score + ( (math.ceil((level + cleared_lines) / 4) + drop_bonus) * cleared_lines * self.combo * self.bravo ) else self.combo = 1 + self.grade_combo = 1 end self.drop_bonus = 0 else self.lines = self.lines + cleared_lines end @@ -253,7 +262,7 @@ function MarathonA2Game:updateGrade(cleared_lines) self.grade_points = self.grade_points + ( math.ceil( grade_point_bonuses[self.grade + 1][cleared_lines] * - combo_multipliers[math.min(self.combo, 10)][cleared_lines] + combo_multipliers[math.min(self.grade_combo, 10)][cleared_lines] ) * (1 + math.floor(self.level / 250)) ) if self.grade_points >= 100 and self.grade < 31 then diff --git a/tetris/modes/marathon_a3.lua b/tetris/modes/marathon_a3.lua index 75961dc..1f20559 100644 --- a/tetris/modes/marathon_a3.lua +++ b/tetris/modes/marathon_a3.lua @@ -20,6 +20,7 @@ function MarathonA3Game:new() self.speed_level = 0 self.roll_frames = 0 self.combo = 1 + self.grade_combo = 1 self.grade = 0 self.grade_points = 0 self.roll_points = 0 @@ -236,12 +237,16 @@ function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines) if not self.clear then if cleared_lines > 0 then self.combo = self.combo + (cleared_lines - 1) * 2 + if cleared_lines > 1 then + self.grade_combo = self.grade_combo + 1 + end self.score = self.score + ( (math.ceil((level + cleared_lines) / 4) + drop_bonus) * cleared_lines * self.combo ) else self.combo = 1 + self.grade_combo = 1 end self.drop_bonus = 0 end @@ -335,7 +340,7 @@ function MarathonA3Game:updateGrade(cleared_lines) self.grade_points = self.grade_points + ( math.ceil( grade_point_bonuses[self.grade + 1][cleared_lines] * - combo_multipliers[math.min(self.combo, 10)][cleared_lines] + combo_multipliers[math.min(self.grade_combo, 10)][cleared_lines] ) * (1 + math.floor(self.level / 250)) ) if self.grade_points >= 100 and self.grade < 31 then @@ -468,7 +473,7 @@ function MarathonA3Game:drawScoringInfo() love.graphics.setFont(font_3x5_3) love.graphics.printf(self.score, 240, 220, 90, "left") if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1) - elseif self.level >= 999 and self.clear then love.graphics.setColor(0, 1, 0, 1) end + elseif self.level >= 999 then love.graphics.setColor(0, 1, 0, 1) end love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left") love.graphics.setColor(1, 1, 1, 1) love.graphics.printf(self.level, 240, 340, 40, "right") diff --git a/tetris/modes/survival_a3.lua b/tetris/modes/survival_a3.lua index 65b0262..25b6ceb 100644 --- a/tetris/modes/survival_a3.lua +++ b/tetris/modes/survival_a3.lua @@ -237,7 +237,7 @@ function SurvivalA3Game:drawScoringInfo() love.graphics.setFont(font_3x5_3) if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1) - elseif self.level >= 1300 and self.clear then love.graphics.setColor(0, 1, 0, 1) end + elseif self.level >= 1300 then love.graphics.setColor(0, 1, 0, 1) end 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") diff --git a/tetris/rulesets/ruleset.lua b/tetris/rulesets/ruleset.lua index cbe9a29..5865948 100644 --- a/tetris/rulesets/ruleset.lua +++ b/tetris/rulesets/ruleset.lua @@ -76,7 +76,7 @@ function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial) self:attemptRotate(new_inputs, piece, grid, initial) end - if not was_drop_blocked and piece:isDropBlocked(grid) then + if not initial and not was_drop_blocked and piece:isDropBlocked(grid) then playSE("bottom") end @@ -260,8 +260,6 @@ function Ruleset:processPiece( drop_locked, hard_drop_locked, hard_drop_enabled, additive_gravity, classic_lock ) - if piece.locked then return end - local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed] if synchroes_allowed then