Merge branch 'MillaBasset:main' into main

This commit is contained in:
TERPYDERP32 2023-03-25 23:26:34 -05:00 committed by GitHub
commit 722e9f2b4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 266 additions and 59 deletions

4
.gitignore vendored
View File

@ -3,4 +3,6 @@ skins/donotupload/*
ss ss
ss/* ss/*
*.sav *.sav
res/bgm/track* res/bgm/track*
replays
replays/*

View File

@ -1,4 +1,5 @@
local GameMode = require 'tetris.modes.gamemode' local GameMode = require 'tetris.modes.gamemode'
local Bag7Randomizer = require 'tetris.randomizers.bag7'
local MarathonWBGame = GameMode:extend() local MarathonWBGame = GameMode:extend()
@ -15,6 +16,7 @@ function MarathonWBGame:new()
self.instant_soft_drop = false self.instant_soft_drop = false
self.enable_hold = true self.enable_hold = true
self.next_queue_length = 6 self.next_queue_length = 6
self.randomizer = Bag7Randomizer()
self.keystrokes = 0 self.keystrokes = 0
self.pieces = 0 self.pieces = 0

View File

@ -41,13 +41,13 @@ function DualityA1Game:afterLineClear(cleared_row_count)
end end
local function fadeOut(game, block, x, y, age) local function fadeOut(game, block, x, y, age)
local opacity = game.are / (game:getARE() / 2) - 1 local opacity = 2 * game.are / game:getARE() - 1
return 0.5, 0.5, 0.5, opacity, opacity return 0.5, 0.5, 0.5, opacity, opacity
end end
local function fadeIn(game, block, x, y, age) local function fadeIn(game, block, x, y, age)
local opacity = game.are / (game:getARE() / 2) - 1 local opacity = 1 - (2 * game.are / game:getARE())
return 0.5, 0.5, 0.5, 1 - opacity, 1 - opacity return 0.5, 0.5, 0.5, opacity, opacity
end end
function DualityA1Game:drawGrid() function DualityA1Game:drawGrid()
@ -62,4 +62,4 @@ function DualityA1Game:drawGrid()
end end
end end
return DualityA1Game return DualityA1Game

View File

@ -1,4 +1,5 @@
local GameMode = require 'tetris.modes.gamemode' local GameMode = require 'tetris.modes.gamemode'
local Bag7Randomizer = require 'tetris.randomizers.bag7'
local MarathonWLJGame = GameMode:extend() local MarathonWLJGame = GameMode:extend()
@ -15,6 +16,7 @@ function MarathonWLJGame:new()
self.instant_soft_drop = false self.instant_soft_drop = false
self.enable_hold = true self.enable_hold = true
self.next_queue_length = 6 self.next_queue_length = 6
self.randomizer = Bag7Randomizer()
self.pieces = 0 self.pieces = 0
self.b2b = false self.b2b = false

View File

@ -40,8 +40,7 @@ function MarathonC88Game:new(secret_inputs)
self.irs = false self.irs = false
self.grid.getCell = function(self, x, y) self.grid.getCell = function(self, x, y)
if x < 1 or x > self.width or y < 5 or y > self.height then return oob if x < 1 or x > self.width or y < 5 or y > self.height then return nil
elseif y < 1 then return empty
else return self.grid[y][x] else return self.grid[y][x]
end end
end end

View File

@ -124,7 +124,7 @@ function MarathonSTGame:advanceOneFrame()
end end
return false return false
end end
if self.roll_frames > 3694 then if self.roll_frames > 3701 then
switchBGM(nil) switchBGM(nil)
self.completed = true self.completed = true
end end

View File

@ -14,9 +14,9 @@ function LudicrousSpeed:new()
self.super:new() self.super:new()
self.time_limit = 300 self.time_limit = 300
self.pps = {} self.delays = {}
self.last_piece = 0
self.pps_limit = 1 self.pps_limit = 1
self.pieces = 0
self.randomizer = Bag7Randomizer() self.randomizer = Bag7Randomizer()
@ -28,6 +28,16 @@ function LudicrousSpeed:new()
self.next_queue_length = 6 self.next_queue_length = 6
end end
local function mean(t)
local sum = 0
for _, v in pairs(t) do
sum = sum + v
end
return sum / #t
end
function LudicrousSpeed:getGravity() function LudicrousSpeed:getGravity()
if self.lines < 180 then if self.lines < 180 then
return (0.8 - (math.floor(self.lines / 10) * 0.007)) ^ -math.floor(self.lines / 10) / 60 return (0.8 - (math.floor(self.lines / 10) * 0.007)) ^ -math.floor(self.lines / 10) / 60
@ -42,41 +52,31 @@ function LudicrousSpeed:getARR() return config.arr end
function LudicrousSpeed:getDasCutDelay() return config.dcd end function LudicrousSpeed:getDasCutDelay() return config.dcd end
function LudicrousSpeed:getDropSpeed() return 20 end function LudicrousSpeed:getDropSpeed() return 20 end
local function mean(t) function LudicrousSpeed:getPPS()
local sum = 0 if #self.delays == 0 then return 0 end
local count = 0 local delays = copy(self.delays)
delays[0] = self.frames - self.last_piece
for k, v in pairs(t) do return 60 / mean(delays)
if type(v) == 'number' then
sum = sum + v
count = count + 1
end
end
return (sum / count)
end end
function LudicrousSpeed:advanceOneFrame() function LudicrousSpeed:advanceOneFrame()
if self.ready_frames == 0 then if self.ready_frames == 0 then
self.frames = self.frames + 1 self.frames = self.frames + 1
if mean(self.pps) * 60 < self.pps_limit then if self:getPPS() < self.pps_limit then
self.time_limit = self.time_limit - 1 self.time_limit = self.time_limit - 1
self.game_over = self.time_limit <= 0 self.game_over = self.time_limit <= 0
else self.time_limit = 300 end else self.time_limit = 300 end
if self.frames ~= 0 then
if table.getn(self.pps) == 750 then
table.remove(self.pps, 1)
table.insert(self.pps, self.pieces)
else table.insert(self.pps, self.pieces) end
self.pieces = 0
end
end end
return true return true
end end
function LudicrousSpeed:onPieceLock() function LudicrousSpeed:onPieceLock(...)
self.super:onPieceLock() self.super:onPieceLock(...)
self.pieces = self.pieces + 1 self.delays[#self.delays + 1] = self.frames - self.last_piece
if #self.delays >= 25 then
table.remove(self.delays, 1)
end
self.last_piece = self.frames
end end
function LudicrousSpeed:onLineClear(cleared_row_count) function LudicrousSpeed:onLineClear(cleared_row_count)
@ -104,6 +104,13 @@ function LudicrousSpeed:drawScoringInfo()
love.graphics.printf("LINES", text_x, 120, 80, "left") love.graphics.printf("LINES", text_x, 120, 80, "left")
love.graphics.printf("piece/sec", text_x, 180, 80, "left") love.graphics.printf("piece/sec", text_x, 180, 80, "left")
love.graphics.printf("REQUIRED PPS", text_x, 240, 120, "left") love.graphics.printf("REQUIRED PPS", text_x, 240, 120, "left")
if self.time_limit < 300 then
if self.time_limit % 4 < 2 and self.time_limit ~= 0 then
love.graphics.setColor(1, 0.3, 0.3, 1)
end
love.graphics.printf("SPEED UP!", text_x, 300, 120, "left")
love.graphics.setColor(1, 1, 1, 1)
end
love.graphics.print( love.graphics.print(
self.das.direction .. " " .. self.das.direction .. " " ..
@ -114,13 +121,13 @@ function LudicrousSpeed:drawScoringInfo()
love.graphics.setFont(font_3x5_4) love.graphics.setFont(font_3x5_4)
if self.time_limit < 300 then if self.time_limit < 300 then
love.graphics.printf(formatTime(self.time_limit), text_x, 320, 160, "left") love.graphics.printf(formatTime(self.time_limit):sub(-4, -1), text_x, 320, 160, "left")
end end
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.lines, text_x, 140, 80, "left") love.graphics.printf(self.lines, text_x, 140, 80, "left")
love.graphics.printf(string.format("%.02f", self.frames > 0 and mean(self.pps) * 60 or 0), text_x, 200, 80, "left") love.graphics.printf(("%.02f"):format(self:getPPS()), text_x, 200, 80, "left")
love.graphics.printf(string.format("%.02f", self.pps_limit), text_x, 260, 80, "left") love.graphics.printf(("%.02f"):format(self.pps_limit), text_x, 260, 80, "left")
love.graphics.setFont(font_8x11) love.graphics.setFont(font_8x11)
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center") love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
@ -137,4 +144,4 @@ function LudicrousSpeed:getHighscoreData()
} }
end end
return LudicrousSpeed return LudicrousSpeed

View File

@ -56,6 +56,25 @@ function SurvivalGTEGame:onLineClear(cleared_row_count)
self.completed = self.lines >= 300 self.completed = self.lines >= 300
end end
local function getLowestBlockY(offsets)
local res = -math.huge
for _, o in pairs(offsets) do
if o.y > res then
res = o.y
end
end
return res
end
function SurvivalGTEGame:onEnterOrHold(...)
while (
getLowestBlockY(self.piece:getBlockOffsets()) + self.piece.position.y
) < 4 do
self.piece.position.y = self.piece.position.y + 1
end
self.super.onEnterOrHold(self, ...)
end
function SurvivalGTEGame:advanceOneFrame() function SurvivalGTEGame:advanceOneFrame()
if self.ready_frames == 0 then if self.ready_frames == 0 then
self.frames = self.frames + 1 self.frames = self.frames + 1

170
tetris/rulesets/bliss.lua Normal file
View File

@ -0,0 +1,170 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local BlissRS = Ruleset:extend()
BlissRS.name = "Blissful"
BlissRS.hash = "Bliss"
BlissRS.world = true
BlissRS.spawn_above_field = true
BlissRS.softdrop_lock = false
BlissRS.harddrop_lock = true
BlissRS.colourscheme = {
I = "C",
L = "O",
J = "B",
S = "G",
Z = "R",
O = "Y",
T = "M",
}
BlissRS.spawn_positions = {
I = { x=5, y=5 },
J = { x=4, y=5 },
L = { x=4, y=5 },
O = { x=5, y=5 },
S = { x=4, y=5 },
T = { x=4, y=5 },
Z = { x=4, y=5 },
}
BlissRS.big_spawn_positions = {
I = { x=3, y=2 },
J = { x=2, y=3 },
L = { x=2, y=3 },
O = { x=3, y=3 },
S = { x=2, y=3 },
T = { x=2, y=3 },
Z = { x=2, y=3 },
}
BlissRS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=0, y=1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=0, y=1} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
},
Z={
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
}
}
BlissRS.wallkicks_3x3 = {
[0]={
[1]={{x=0, y=1}, {x=1, y=0}, {x=-1, y=0}},
[2]={{x=0, y=1}},
[3]={{x=0, y=1}, {x=-1, y=0}, {x=1, y=0}},
},
[1]={
[0]={{x=0, y=1}, {x=-1, y=0}, {x=1, y=0}},
[2]={{x=0, y=1}, {x=1, y=0}, {x=-1, y=0}},
[3]={{x=1, y=0}},
},
[2]={
[0]={{x=0, y=1}},
[1]={{x=0, y=1}, {x=-1, y=0}, {x=1, y=0}},
[3]={{x=0, y=1}, {x=1, y=0}, {x=-1, y=0}},
},
[3]={
[0]={{x=0, y=1}, {x=1, y=0}, {x=-1, y=0}},
[1]={{x=-1, y=0}},
[2]={{x=0, y=1}, {x=-1, y=0}, {x=1, y=0}},
}
}
BlissRS.wallkicks_line = {
[0]={
[1]={{x=0, y=1}, {x=0, y=-1}, {x=-1, y=1}},
[2]={{x=0, y=0}},
[3]={{x=0, y=1}, {x=-1, y=1}, {x=0, y=-1}},
},
[1]={
[0]={{x=0, y=1}, {x=1, y=1}, {x=-1, y=0}, {x=1, y=0}, {x=2, y=0}},
[2]={{x=0, y=1}, {x=1, y=1}, {x=1, y=0}, {x=-1, y=0}, {x=2, y=0}},
[3]={{x=0, y=0}},
},
[2]={
[1]={{x=0, y=1}, {x=-1, y=1}, {x=0, y=-1}},
[2]={{x=0, y=0}},
[3]={{x=0, y=1}, {x=0, y=-1}, {x=-1, y=1}},
},
[3]={
[0]={{x=0, y=1}, {x=1, y=1}, {x=-1, y=0}, {x=1, y=0}, {x=2, y=0}},
[2]={{x=0, y=1}, {x=1, y=1}, {x=1, y=0}, {x=-1, y=0}, {x=2, y=0}},
[3]={{x=0, y=0}},
}
}
-- Component functions.
function BlissRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
local kicks
if piece.shape == "O" then
return
elseif piece.shape == "I" then
kicks = BlissRS.wallkicks_line[piece.rotation][new_piece.rotation]
else
kicks = BlissRS.wallkicks_3x3[piece.rotation][new_piece.rotation]
end
assert(piece.rotation ~= new_piece.rotation)
for idx, offset in pairs(kicks) do
kicked_piece = new_piece:withOffset(offset)
if grid:canPlacePiece(kicked_piece) then
piece:setRelativeRotation(rot_dir)
piece:setOffset(offset)
self:onPieceRotate(piece, grid)
return
end
end
end
function BlissRS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
end
function BlissRS:getAboveFieldOffset()
return 1
end
function BlissRS:get180RotationValue() return 2 end
return BlissRS

View File

@ -7,12 +7,12 @@ Nintendo.hash = "NintendoR"
Nintendo.spawn_positions = { Nintendo.spawn_positions = {
I = { x=5, y=4 }, I = { x=5, y=4 },
J = { x=4, y=5 }, J = { x=5, y=5 },
L = { x=4, y=5 }, L = { x=5, y=5 },
O = { x=5, y=5 }, O = { x=5, y=5 },
S = { x=4, y=5 }, S = { x=5, y=5 },
T = { x=4, y=5 }, T = { x=5, y=5 },
Z = { x=4, y=5 }, Z = { x=5, y=5 },
} }
Nintendo.big_spawn_positions = { Nintendo.big_spawn_positions = {

View File

@ -21,28 +21,34 @@ function Trans:attemptRotate(new_inputs, piece, grid, initial)
end end
local new_piece = piece:withRelativeRotation(rot_dir) local new_piece = piece:withRelativeRotation(rot_dir)
if initial then
if (grid:canPlacePiece(new_piece)) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir)
end
else
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
end
end
function Trans:attemptWallkicks(piece, new_piece, rot_dir, grid)
local pieces = {"I", "J", "L", "O", "S", "T", "Z"} local pieces = {"I", "J", "L", "O", "S", "T", "Z"}
repeat repeat
new_piece.shape = pieces[math.random(7)] new_piece.shape = pieces[math.random(7)]
until piece.shape ~= new_piece.shape until piece.shape ~= new_piece.shape
if (grid:canPlacePiece(new_piece)) then local offsets = {{x=0, y=0}, {x=1, y=0}, {x=-1, y=0}}
self:onPieceRotate(piece, grid) for _, o in pairs(offsets) do
piece:setRelativeRotation(rot_dir) local kicked_piece = new_piece:withOffset(o)
piece.shape = new_piece.shape if (grid:canPlacePiece(kicked_piece)) then
else self:onPieceRotate(piece, grid)
if not(initial and self.enable_IRS_wallkicks == false) then piece:setRelativeRotation(rot_dir)
if (grid:canPlacePiece(new_piece:withOffset({x=1, y=0}))) then piece:setOffset(o)
self:onPieceRotate(piece, grid) piece.shape = new_piece.shape
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0}) return
piece.shape = new_piece.shape end
elseif (grid:canPlacePiece(new_piece:withOffset({x=-1, y=0}))) then end
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
piece.shape = new_piece.shape
end
end
end
end end
return Trans return Trans