mirror of
https://github.com/SashLilac/cambridge.git
synced 2024-11-16 21:19:03 -06:00
96ac054cf6
Resolves #15. 1) Cleared row count is marked before the onPieceLock method is called, letting the piece lock procedure react to the count of rows the piece is about to clear. (In practice, only 0 and non-0 will be different.) 2) The modes with bottom-row garbage will not advance the garbage counter when the piece is about to clear lines, as should be the case. Also included: 3) Changed the Always O Randomizer to the Always Randomizer that takes which piece it should "always" produce as an argument in the constructor. 4) Fixed the torikan for level 800 in Phantom Mania 2. It should have been 4:45, not 4:40.
237 lines
5.9 KiB
Lua
237 lines
5.9 KiB
Lua
require 'funcs'
|
|
|
|
local GameMode = require 'tetris.modes.gamemode'
|
|
local Piece = require 'tetris.components.piece'
|
|
|
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
|
|
|
local SurvivalA3Game = GameMode:extend()
|
|
|
|
SurvivalA3Game.name = "Survival A3"
|
|
SurvivalA3Game.hash = "SurvivalA3"
|
|
SurvivalA3Game.tagline = "The blocks turn black and white! Can you make it to level 1300?"
|
|
|
|
|
|
|
|
|
|
function SurvivalA3Game:new()
|
|
SurvivalA3Game.super:new()
|
|
self.level = 0
|
|
self.grade = 0
|
|
self.garbage = 0
|
|
self.clear = false
|
|
self.completed = false
|
|
self.roll_frames = 0
|
|
self.combo = 1
|
|
self.randomizer = History6RollsRandomizer()
|
|
|
|
self.lock_drop = true
|
|
self.enable_hold = true
|
|
self.next_queue_length = 3
|
|
end
|
|
|
|
function SurvivalA3Game:getARE()
|
|
if self.level < 300 then return 12
|
|
else return 6 end
|
|
end
|
|
|
|
function SurvivalA3Game:getLineARE()
|
|
if self.level < 100 then return 8
|
|
elseif self.level < 200 then return 7
|
|
elseif self.level < 500 then return 6
|
|
elseif self.level < 1300 then return 5
|
|
else return 6 end
|
|
end
|
|
|
|
function SurvivalA3Game:getDasLimit()
|
|
if self.level < 200 then return 9
|
|
elseif self.level < 500 then return 7
|
|
else return 5 end
|
|
end
|
|
|
|
function SurvivalA3Game:getLineClearDelay()
|
|
return self:getLineARE() - 2
|
|
end
|
|
|
|
function SurvivalA3Game:getLockDelay()
|
|
if self.level < 200 then return 18
|
|
elseif self.level < 300 then return 17
|
|
elseif self.level < 500 then return 15
|
|
elseif self.level < 600 then return 13
|
|
elseif self.level < 1100 then return 12
|
|
elseif self.level < 1200 then return 10
|
|
else return 8 end
|
|
end
|
|
|
|
function SurvivalA3Game:getGravity()
|
|
return 20
|
|
end
|
|
|
|
function SurvivalA3Game:getGarbageLimit()
|
|
if self.level < 600 then return 20
|
|
elseif self.level < 700 then return 18
|
|
elseif self.level < 800 then return 10
|
|
elseif self.level < 900 then return 9
|
|
else return 8 end
|
|
end
|
|
|
|
function SurvivalA3Game:getNextPiece(ruleset)
|
|
return {
|
|
skin = self.level >= 1000 and "bone" or "2tie",
|
|
shape = self.randomizer:nextPiece(),
|
|
orientation = ruleset:getDefaultOrientation(),
|
|
}
|
|
end
|
|
|
|
function SurvivalA3Game:hitTorikan(old_level, new_level)
|
|
if old_level < 500 and new_level >= 500 and self.frames > sp(2,28) then
|
|
self.level = 500
|
|
return true
|
|
end
|
|
if old_level < 1000 and new_level >= 1000 and self.frames > sp(4,56) then
|
|
self.level = 1000
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function SurvivalA3Game:advanceOneFrame()
|
|
if self.clear then
|
|
self.roll_frames = self.roll_frames + 1
|
|
if self.roll_frames < 0 then
|
|
if self.roll_frames + 1 == 0 then
|
|
switchBGM("credit_roll", "gm3")
|
|
return true
|
|
end
|
|
return false
|
|
elseif self.roll_frames > 3238 then
|
|
switchBGM(nil)
|
|
self.completed = true
|
|
end
|
|
elseif self.ready_frames == 0 then
|
|
self.frames = self.frames + 1
|
|
end
|
|
return true
|
|
end
|
|
|
|
function SurvivalA3Game:onPieceEnter()
|
|
if (self.level % 100 ~= 99) and not self.clear and self.frames ~= 0 then
|
|
self.level = self.level + 1
|
|
end
|
|
end
|
|
|
|
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)
|
|
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
|
|
if new_level >= 1300 then
|
|
self.level = 1300
|
|
end
|
|
self.clear = true
|
|
self.grid:clear()
|
|
self.roll_frames = -150
|
|
else
|
|
self.level = math.min(new_level, 1300)
|
|
end
|
|
self:advanceBottomRow(-cleared_row_count)
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:onPieceLock(piece, cleared_row_count)
|
|
if cleared_row_count == 0 then self:advanceBottomRow(1) end
|
|
end
|
|
|
|
function SurvivalA3Game:updateScore(level, drop_bonus, cleared_lines)
|
|
if cleared_lines > 0 then
|
|
self.score = self.score + (
|
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
|
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
|
)
|
|
self.lines = self.lines + cleared_lines
|
|
self.combo = self.combo + cleared_lines - 1
|
|
else
|
|
self.drop_bonus = 0
|
|
self.combo = 1
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:updateSectionTimes(old_level, new_level)
|
|
if math.floor(old_level / 100) < math.floor(new_level / 100) then
|
|
local section = math.floor(old_level / 100) + 1
|
|
section_time = self.frames - self.section_start_time
|
|
table.insert(self.section_times, section_time)
|
|
self.section_start_time = self.frames
|
|
if section_time <= sp(1,00) then
|
|
self.grade = self.grade + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:advanceBottomRow(dx)
|
|
if self.level >= 500 and self.level < 1000 then
|
|
self.garbage = math.max(self.garbage + dx, 0)
|
|
if self.garbage >= self:getGarbageLimit() then
|
|
self.grid:copyBottomRow()
|
|
self.garbage = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:drawGrid()
|
|
self.grid:draw()
|
|
end
|
|
|
|
local function getLetterGrade(grade)
|
|
if grade == 0 then
|
|
return "1"
|
|
elseif grade <= 9 then
|
|
return "S" .. tostring(grade)
|
|
else
|
|
return "M" .. tostring(grade - 9)
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:drawScoringInfo()
|
|
SurvivalA3Game.super.drawScoringInfo(self)
|
|
|
|
love.graphics.setColor(1, 1, 1, 1)
|
|
|
|
local text_x = config["side_next"] and 320 or 240
|
|
|
|
love.graphics.setFont(font_3x5_2)
|
|
love.graphics.printf("GRADE", text_x, 120, 40, "left")
|
|
love.graphics.printf("SCORE", text_x, 200, 40, "left")
|
|
love.graphics.printf("LEVEL", text_x, 320, 40, "left")
|
|
|
|
local current_section = math.floor(self.level / 100) + 1
|
|
self:drawSectionTimesWithSplits(current_section)
|
|
|
|
love.graphics.setFont(font_3x5_3)
|
|
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.level, text_x, 340, 50, "right")
|
|
if self.clear then
|
|
love.graphics.printf(self.level, text_x, 370, 50, "right")
|
|
else
|
|
love.graphics.printf(math.floor(self.level / 100 + 1) * 100, text_x, 370, 50, "right")
|
|
end
|
|
end
|
|
|
|
function SurvivalA3Game:getBackground()
|
|
return math.floor(self.level / 100)
|
|
end
|
|
|
|
function SurvivalA3Game:getHighscoreData()
|
|
return {
|
|
level = self.level,
|
|
frames = self.frames,
|
|
grade = self.grade,
|
|
}
|
|
end
|
|
|
|
return SurvivalA3Game
|