Marathon C99

pull/4/head
Ishaan Bhardwaj 2021-01-12 21:36:58 -05:00
parent 984ac866cb
commit eb983e3c16
2 changed files with 320 additions and 0 deletions

View File

@ -0,0 +1,291 @@
local GameMode = require 'tetris.modes.gamemode'
local Grid = require 'tetris.components.grid'
local SegaRandomizer = require 'tetris.randomizers.sega'
local PowerOnSequence = require 'tetris.randomizers.poweron'
local MarathonC99Game = GameMode:extend()
MarathonC99Game.name = "Marathon C99"
MarathonC99Game.hash = "MarathonC99"
MarathonC99Game.tagline = "A recreation of Sega ***ris Naomi / Dreamcast!"
local lines_to_next_level = {
[0] = 6, 6, 7, 9, 6, 9,
9, 9, 10, 10, 20, 16, 16,
16, 16, 0, 1, math.huge
}
local score_table = {
[0] = 0, 50, 200, 450, 1000, 2000, 3000, 4000
}
local slots_table = {
50, 10000, 50000, 100000
}
function MarathonC99Game:new()
self.super:new()
self.grid = Grid(10, 22)
self.roll_frames = -57
self.lines_to_next_level = lines_to_next_level[self.level]
self.slots = {}
self.tetris_slots = 0
self.ccw_bonus = 10 ^ 7
self.irs = false
self.enable_hard_drop = false
self.lock_drop = false
self.next_queue_length = 1
end
function MarathonC99Game:getARE()
if self.level == 0 then return 31
elseif self.level == 1 then return 28
elseif self.level <= 3 then return 26
elseif self.level == 4 then return 28
elseif self.level <= 15 then return 26
elseif self.level == 16 then return 31
else return 17 end
end
function MarathonC99Game:getLineARE()
return self:getARE()
end
function MarathonC99Game:getLineClearDelay()
return 57
end
function MarathonC99Game:getDasLimit()
return 15
end
function MarathonC99Game:getGravity()
if self.level == 0 then return 1/24
elseif self.level == 1 then return 1/15
elseif self.level == 2 then return 1/10
elseif self.level == 3 then return 1/3
elseif self.level == 4 then return 1/20
elseif self.level == 5 then return 1/3
elseif self.level <= 9 then return 1/2
elseif self.level <= 15 then return 1
elseif self.level == 16 then return 1/24
else return 1 end
end
function MarathonC99Game:getLockDelay()
if self.level == 0 then return 44
elseif self.level == 1 then return 39
elseif self.level == 2 then return 34
elseif self.level == 3 then return 30
elseif self.level == 4 then return 39
elseif self.level <= 7 then return 29
elseif self.level <= 9 then return 28
elseif self.level <= 12 then return 24
elseif self.level <= 14 then return 20
elseif self.level == 15 then return 19
elseif self.level == 16 then return 44
else return 18 end
end
function MarathonC99Game:getSlotMultiplier()
if self.level == 17 then return 10
elseif self.level >= 15 then return 5
else return math.ceil((self.level + 1) / 5) end
end
function MarathonC99Game:getScoreMultiplier()
if self.level == 17 then return 20
else return self.level + 1 end
end
function MarathonC99Game:startRightDAS()
self.move = "right"
self.das.direction = "right"
if self:getDasLimit() == 0 then
self:continueDAS()
end
end
function MarathonC99Game:startLeftDAS()
self.move = "left"
self.das.direction = "left"
if self:getDasLimit() == 0 then
self:continueDAS()
end
end
function MarathonC99Game:onSoftDrop(dropped_row_count)
self.score = self.score + dropped_row_count
end
function MarathonC99Game:advanceOneFrame(inputs, ruleset)
if self.clear then
if self.level == 17 then
self.roll_frames = self.roll_frames + 1
if self.roll_frames >= frameTime(3,19) then
self.score = self.score + self.ccw_bonus
self.completed = true
end
end
if inputs.rotate_right or inputs.rotate_right2 or
(inputs.rotate_180 and ruleset:get180RotationValue() ~= 3)
and self.piece ~= nil then
self.ccw_bonus = 0
end
elseif self.ready_frames == 0 then
self.frames = self.frames + 1
if inputs.rotate_right or inputs.rotate_right2 or
(inputs.rotate_180 and ruleset:get180RotationValue() ~= 3)
and self.piece ~= nil then
self.ccw_bonus = 0
end
end
end
function MarathonC99Game:onLineClear(cleared_row_count)
self.lines = self.lines + cleared_row_count
local score_to_add = score_table[cleared_row_count]
local highest_row_cleared
for i = 1, 22 do
if self.grid:isRowFull(i) then
highest_row_cleared = i
break
end
end
if highest_row_cleared + 1 <= 22 and self.grid:isRowFull(highest_row_cleared + 1) and
highest_row_cleared + 2 <= 22 and not self.grid:isRowFull(highest_row_cleared + 2) and
highest_row_cleared + 3 <= 22 and self.grid:isRowFull(highest_row_cleared + 3) then
score_to_add = 1
elseif (cleared_row_count == 2 or cleared_row_count == 3) and
highest_row_cleared + 1 <= 22 and not self.grid:isRowFull(highest_row_cleared + 1) then
score_to_add = score_to_add + 100
end
if (#self.slots == 2) then
if (self.slots[1] == self.slots[2] and self.slots[1] == cleared_row_count) then
if cleared_row_count == 4 then
self.tetris_slots = (self.tetris_slots + 1) % 10
end
if cleared_row_count == 4 and self.tetris_slots == 0 then
self.score = self.score + 999999
else
self.score = self.score + slots_table[cleared_row_count] * self:getSlotMultiplier()
end
end
self.slots = {}
else
table.insert(self.slots, cleared_row_count)
end
if self.grid:checkForBravo(cleared_row_count) then
self.score = self.score + 200000 * self:getSlotMultiplier()
else
self.score = self.score + score_to_add * self:getScoreMultiplier()
end
if cleared_row_count >= self.lines_to_next_level then
self.level = self.level + 1
if self.level == 15 then
self.lines_to_next_level = 300 - self.lines
else
self.lines_to_next_level = lines_to_next_level[self.level]
end
if self.level == 16 then
self.clear = true
self.grid:clear()
if self.used_randomizer.possible_pieces == 7 then
self.used_randomizer = PowerOnSequence()
self.next_queue[1].shape = self.used_randomizer:nextPiece()
end
end
else
self.lines_to_next_level = self.lines_to_next_level - cleared_row_count
end
for i = 1, 4 do
self.grid:clearSpecificRow(i)
end
end
function MarathonC99Game:drawGrid()
self.grid:draw()
end
function MarathonC99Game: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) ..
self.drop_bonus
)
love.graphics.printf("NEXT", 64, 40, 40, "left")
love.graphics.printf("LEVEL", 240, 120, 80, "left")
love.graphics.printf("LINES: " .. self.lines .. "/300", 240, 180, 200, "left")
if self.level <= 15 then
love.graphics.printf("LINES TO NEXT LEVEL", 240, 220, 200, "left")
elseif self.level == 17 then
love.graphics.printf("TIME REMAINING", 240, 220, 200, "left")
end
love.graphics.setFont(font_3x5_4)
love.graphics.printf(formatBigNum(self.score), 64, 400, 160, "center")
love.graphics.setFont(font_3x5_3)
love.graphics.setColor(
(self.slots[1] and self.slots[2] and
self.slots[1] == self.slots[2] and
(self.frames + self.roll_frames) % 4 < 2) and
{0.3, 1, 0.3, 1} or
{1, 1, 1, 1}
)
if self.ready_frames == 0 then
love.graphics.printf(
(self.slots[1] and self.slots[1] or math.random(4)) .. " " ..
(self.slots[2] and self.slots[2] or math.random(4)) .. " " ..
math.random(4),
240, 80, 100, "left"
)
end
love.graphics.setColor(1, 1, 1, 1)
if self.level <= 15 then
love.graphics.printf(self.lines_to_next_level, 240, 240, 200, "left")
elseif self.level == 17 then
love.graphics.printf(formatTime(frameTime(3,19) - self.roll_frames), 240, 240, 200, "left")
end
love.graphics.setFont(font_8x11)
love.graphics.printf(formatTime(self.frames), 240, 300, 160, "left")
love.graphics.printf(self.level, 290, 120, 80, "left")
end
function MarathonC99Game:getBackground()
if self.level == 17 then
return math.floor(math.min(math.max(0, self.roll_frames * 20 / frameTime(3,19)), 19))
end
return self.level
end
function MarathonC99Game:getHighscoreData()
return {
score = self.score,
lines = self.lines,
level = self.level,
frames = self.frames,
}
end
return MarathonC99Game

View File

@ -0,0 +1,29 @@
local Sequence = require 'tetris.randomizers.fixed_sequence'
local PowerOnSequence = Sequence:extend()
function PowerOnSequence:initialize()
self.super:initialize()
self.sequence = "TITIIJILSJOZZJLSJISLZZZJIJJJOLZJSILTLJOIOOTJTOSZZO" ..
"ISLZTOJJLSJOIIZZZJSIIZLZZOIOOTSZZSSSTJOZITZOSLLTZJ" ..
"JZZJJIZOSOJLOZLZJLJIIOTTOOIZSJSSSTLZLJTZOLLOOILTSZ" ..
"TTOILZOJISLTILLZTSLISTTIIJSSZTTLLILJZOOZTIISZTIJIJ" ..
"TSOLTTLIITIOLTSJILIOOJSOZZLZZLLSZJZOSZLLLZZJITZTSL" ..
"OISOLLOSOOZLJSJOZJZISZSLLJITTISJZIIOOOOTJZZIOJOZOJ" ..
"JJSZJTJTJJSJSSSILOTLOITJISSZJIOOOZOISTSJLSTTSLLOSL" ..
"ZJSOLIJJLIZSTJISSSTTIJOJZJIOLLLIIOIZSLTOOLOOZJOJSS" ..
"LJSTZTZJLZITZTSJLIZSZSTITJZTJOJIJSJJLTOOSZLIOSIJOI" ..
"OOLSZJLSLJIZLSJIIJITSTLSISLZZOJZSSIOZTLZTJZIZSJTOT" ..
"TLOTSTTJLILJSOOJOLTLOILTSIJIJTZJLZIITIOOLZLLTIIJTZ" ..
"TLSITLSSISTTTLILISLTLTTTITLTJTJLLSIITLZLTSZJZOISOS" ..
"IOTSOJLJJSSZJOSOTOISLSTJLZSLZZSLISLJZTJLJSZZLSSSII" ..
"JTOJJSZLJLIZOIJSSJLSTSJOSJTOLLTTSTIJLZTOTZLSZLJTOL" ..
"SSTTLTIOSTTILSJZTLILIZIOTTZSOJLILSJOOIJOZIJJISIOII" ..
"OIZZLOIITTZTTIZTLIILSITTOSZOTZSSTJZOJJLOOSJZJLOIJS" ..
"TOZTZZTOZLOLOLJOZLOIISLJZIOZTTTZISOTOIIZZZLITSLTIZ" ..
"ZISZSJTIOZLZOLOSJSLIJLILOJTZJOJLTOLSOLIZJJOZIILTIT" ..
"IZZJTSTSTITILTSTLOJZZOLZOZLJJJOTITLTSSZTOSTZSTOTJJ" ..
"LZSIIZZSISJSSSZIJIIOIOZOIZJTJIJOIISTTJJTTTJITTITSI"
end
return PowerOnSequence