Compare commits

..

15 Commits

Author SHA1 Message Date
Ishaan Bhardwaj
57c7d9c4c3 v0.3-beta1: Sakura done 2021-01-04 18:01:29 -05:00
Ishaan Bhardwaj
9f52d8bf10 relocated non bgm to modpack 2021-01-04 14:43:39 -05:00
Ishaan Bhardwaj
57bd6a8286 Almost done with Sakura 2021-01-03 23:18:57 -05:00
Oshisaure
1a68cd8fce More work on sakura, Xray and colour block effects implemented. Added Grid:drawCustom() to handle custom opacity/tint effects. 2021-01-03 00:05:54 +00:00
Ishaan Bhardwaj
56baf46839 Sakura *should* be complete now, please bug-report 2021-01-02 14:31:53 -05:00
Ishaan Bhardwaj
305d07e10a Sakura beta v2.k 2021-01-02 14:10:01 -05:00
Ishaan Bhardwaj
8d954cabc2 Sakura Beta v2.j 2021-01-02 12:56:52 -05:00
Ishaan Bhardwaj
0281220ea0 Sakura Beta v2.i 2021-01-02 12:51:00 -05:00
Ishaan Bhardwaj
aef5d88d3f Sakura Beta v2.h 2021-01-02 12:36:26 -05:00
Ishaan Bhardwaj
3676f7697c Sakura Beta v2 2021-01-02 12:21:10 -05:00
Ishaan Bhardwaj
acb0eb1a71 Sakura mode beta 2020-12-30 15:19:53 -05:00
Ishaan Bhardwaj
a89bf05cab Fixed an issue with controllers on the menu 2020-12-29 22:55:51 -05:00
Ishaan Bhardwaj
8008315994 Condensed ARE canceling code a bit 2020-12-29 14:00:11 -05:00
Ishaan Bhardwaj
90f62cb7dd Refactored ARE cancel 2020-12-28 23:32:41 -05:00
Oshisaure
eaee5fc7f0 Tweaked rotation/manipulation behaviour on SRS rules.
Also changed order of operations to call onPieceRotate in Rulesets after actually rotating the piece.
2020-12-28 03:41:26 +00:00
21 changed files with 723 additions and 54 deletions

View File

@@ -49,6 +49,18 @@ blocks = {
F = love.graphics.newImage("res/img/bone.png"), F = love.graphics.newImage("res/img/bone.png"),
A = love.graphics.newImage("res/img/bone.png"), A = love.graphics.newImage("res/img/bone.png"),
X = love.graphics.newImage("res/img/bone.png"), X = love.graphics.newImage("res/img/bone.png"),
},
["gem"] = {
R = love.graphics.newImage("res/img/gem1.png"),
O = love.graphics.newImage("res/img/gem3.png"),
Y = love.graphics.newImage("res/img/gem7.png"),
G = love.graphics.newImage("res/img/gem6.png"),
C = love.graphics.newImage("res/img/gem2.png"),
B = love.graphics.newImage("res/img/gem4.png"),
M = love.graphics.newImage("res/img/gem5.png"),
F = love.graphics.newImage("res/img/gem9.png"),
A = love.graphics.newImage("res/img/gem9.png"),
X = love.graphics.newImage("res/img/gem9.png"),
} }
} }

Binary file not shown.

Binary file not shown.

BIN
res/img/gem1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

BIN
res/img/gem2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

BIN
res/img/gem3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

BIN
res/img/gem4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

BIN
res/img/gem5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

BIN
res/img/gem6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
res/img/gem7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

BIN
res/img/gem9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

View File

@@ -102,7 +102,7 @@ function TitleScene:onInputPress(e)
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
love.event.quit() love.event.quit()
else else
self.text = self.text .. e.scancode self.text = self.text .. (e.scancode ~= nil and e.scancode or "")
if self.text == "ffffff" then if self.text == "ffffff" then
self.text_flag = true self.text_flag = true
end end

View File

@@ -273,6 +273,43 @@ function Grid:checkSecretGrade()
return sgrade return sgrade
end end
function Grid:hasGemBlocks()
for y = 1, 24 do
for x = 1, 10 do
if self.grid[y][x].skin == "gem" then
return true
end
end
end
return false
end
function Grid:mirror()
local new_grid = {}
for y = 1, 24 do
new_grid[y] = {}
for x = 1, 10 do
new_grid[y][x] = empty
end
end
for y = 1, 24 do
for x = 1, 10 do
new_grid[y][x] = self.grid[y][11 - x]
end
end
self.grid = new_grid
end
function Grid:applyMap(map)
for y, row in pairs(map) do
for x, block in pairs(row) do
self.grid_age[y][x] = 0
self.grid[y][x] = block
end
end
end
function Grid:update() function Grid:update()
for y = 1, 24 do for y = 1, 24 do
for x = 1, 10 do for x = 1, 10 do
@@ -380,4 +417,44 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_fla
end end
end end
function Grid:drawCustom(colour_function, gamestate)
--[[
colour_function: (game, block, x, y, age) -> (R, G, B, A, outlineA)
When called, calls the supplied function on every block passing the block itself as argument
as well as coordinates and the grid_age value of the same cell.
Should return a RGBA colour for the block, as well as the opacity of the stack outline (0 for no outline).
gamestate: the gamemode instance itself to pass in colour_function
]]
for y = 5, 24 do
for x = 1, 10 do
local block = self.grid[y][x]
if block ~= empty then
local R, G, B, A, outline = colour_function(gamestate, block, x, y, self.grid_age[y][x])
if self.grid[y][x].colour == "X" then
A = 1
end
love.graphics.setColor(R, G, B, A)
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
if outline > 0 and self.grid[y][x].colour ~= "X" then
love.graphics.setColor(0.64, 0.64, 0.64, outline)
love.graphics.setLineWidth(1)
if y > 1 and self.grid[y-1][x] == empty then
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
end
if y < 24 and self.grid[y+1][x] == empty then
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
end
if x > 1 and self.grid[y][x-1] == empty then
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
end
if x < 10 and self.grid[y][x+1] == empty then
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
end
end
end
end
end
end
return Grid return Grid

View File

@@ -162,6 +162,7 @@ function GameMode:update(inputs, ruleset)
not self.hard_drop_locked then not self.hard_drop_locked then
self:onHardDrop(piece_dy) self:onHardDrop(piece_dy)
if self.lock_on_hard_drop then if self.lock_on_hard_drop then
self.piece_hard_dropped = true
self.piece.locked = true self.piece.locked = true
end end
end end
@@ -311,6 +312,15 @@ function GameMode:chargeDAS(inputs)
end end
end end
function GameMode:areCancel(inputs, ruleset)
if ruleset.are_cancel and self.piece_hard_dropped and
not self.prev_inputs.up and
strTrueValues(inputs) ~= "" then
self.lcd = 0
self.are = 0
end
end
function GameMode:processDelays(inputs, ruleset, drop_speed) function GameMode:processDelays(inputs, ruleset, drop_speed)
if self.ready_frames == 100 then if self.ready_frames == 100 then
playedReadySE = false playedReadySE = false
@@ -331,18 +341,7 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
end end
elseif self.lcd > 0 then elseif self.lcd > 0 then
self.lcd = self.lcd - 1 self.lcd = self.lcd - 1
if ruleset.are_cancel and self:areCancel(inputs, ruleset)
(self.move == "none" and not self.prev_inputs["up"] and
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
not self.prev_inputs["rotate_180"]) and
(inputs["left"] or inputs["right"] or inputs["up"] or
inputs["rotate_left"] or inputs["rotate_left2"] or
inputs["rotate_right"] or inputs["rotate_right2"] or
inputs["rotate_180"]) then
self.lcd = 0
self.are = 0
end
if self.lcd == 0 then if self.lcd == 0 then
self.grid:clearClearedRows() self.grid:clearClearedRows()
playSE("fall") playSE("fall")
@@ -352,17 +351,7 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
end end
elseif self.are > 0 then elseif self.are > 0 then
self.are = self.are - 1 self.are = self.are - 1
if ruleset.are_cancel and self:areCancel(inputs, ruleset)
(self.move == "none" and not self.prev_inputs["up"] and
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
not self.prev_inputs["rotate_180"]) and
(inputs["left"] or inputs["right"] or inputs["up"] or
inputs["rotate_left"] or inputs["rotate_left2"] or
inputs["rotate_right"] or inputs["rotate_right2"] or
inputs["rotate_180"]) then
self.are = 0
end
if self.are == 0 then if self.are == 0 then
self:initializeOrHold(inputs, ruleset) self:initializeOrHold(inputs, ruleset)
end end
@@ -407,6 +396,7 @@ function GameMode:hold(inputs, ruleset, ihs)
end end
function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next_piece) function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next_piece)
self.piece_hard_dropped = false
local gravity = self:getGravity() local gravity = self:getGravity()
self.piece = ruleset:initializePiece( self.piece = ruleset:initializePiece(
inputs, piece_data, self.grid, gravity, inputs, piece_data, self.grid, gravity,

568
tetris/modes/sakura.lua Normal file
View File

@@ -0,0 +1,568 @@
require 'funcs'
local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece'
local SakuraRandomizer = require 'tetris.randomizers.sakura'
local SakuraGame = GameMode:extend()
SakuraGame.name = "Sakura A3"
SakuraGame.hash = "SakuraA3"
SakuraGame.tagline = "Clear away the Gem Blocks as fast as possible!"
local b = {
["r"] = { skin = "2tie", colour = "R" },
["o"] = { skin = "2tie", colour = "O" },
["y"] = { skin = "2tie", colour = "Y" },
["g"] = { skin = "2tie", colour = "G" },
["c"] = { skin = "2tie", colour = "C" },
["b"] = { skin = "2tie", colour = "B" },
["m"] = { skin = "2tie", colour = "M" },
["R"] = { skin = "gem", colour = "R" },
["O"] = { skin = "gem", colour = "O" },
["Y"] = { skin = "gem", colour = "Y" },
["G"] = { skin = "gem", colour = "G" },
["C"] = { skin = "gem", colour = "C" },
["B"] = { skin = "gem", colour = "B" },
["M"] = { skin = "gem", colour = "M" },
}
local effects = {
[4] = "mirror",
[8] = "xray",
[12] = "color",
[13] = "mirror",
[16] = "roll",
[23] = "big"
}
local maps = {
[1] = {
[22] = {nil, nil, b.O, b.R, nil, nil, b.M, b.m, nil, nil},
[23] = {nil, b.G, b.c, b.c, b.c, b.c, b.c, b.c, b.Y, nil},
[24] = {nil, b.C, b.y, b.y, b.y, b.y, b.y, b.y, b.B, nil},
},
[2] = {
[20] = {nil, nil, nil, nil, b.G, b.b, b.b, b.M, nil, nil},
[21] = {nil, nil, nil, nil, b.c, b.c, b.c, b.c, nil, nil},
[22] = {nil, nil, nil, nil, nil, b.R, b.Y, b.O, nil, nil},
[23] = {nil, b.B, b.c, b.c, b.c, b.c, b.c, b.c, b.c, nil},
[24] = {nil, b.b, b.b, b.b, b.b, b.b, b.b, b.b, b.C, nil},
},
[3] = {
[20] = {nil, nil, nil, b.R, b.m, b.o, b.M, nil, nil, nil},
[21] = {nil, nil, nil, nil, b.o, b.O, nil, nil, nil, nil},
[22] = {nil, nil, nil, nil, b.G, b.Y, nil, nil, nil, nil},
[23] = {nil, b.m, b.o, b.m, b.o, b.m, b.o, b.m, b.o, nil},
[24] = {nil, b.B, b.m, b.o, b.m, b.o, b.m, b.o, b.C, nil},
},
[4] = {
[21] = {nil, nil, b.O, b.g, b.g, b.g, b.g, nil, nil, nil},
[22] = {nil, nil, nil, b.R, b.M, b.b, b.b, nil, nil, nil},
[23] = {b.G, nil, b.Y, b.g, b.g, b.g, b.g, b.g, nil, nil},
[24] = {b.b, b.C, b.b, b.b, b.b, b.b, b.b, b.b, b.B, nil},
},
[5] = {
[16] = {nil, b.B, b.c, b.y, b.c, b.G, b.c, b.y, b.C, nil},
[22] = {nil, nil, b.c, b.y, b.c, b.y, b.c, b.y, nil, nil},
[23] = {nil, b.O, b.y, b.c, b.y, b.c, b.y, b.c, b.Y, nil},
[24] = {nil, b.R, b.c, b.y, b.c, b.y, b.c, b.y, b.M, nil},
},
[6] = {
[21] = {nil, nil, nil, nil, b.O, b.Y, nil, nil, nil, nil},
[22] = {nil, nil, b.R, nil, b.b, b.y, nil, b.M, nil, nil},
[23] = {nil, nil, nil, nil, b.y, b.b, nil, nil, nil, nil},
[24] = {nil, b.G, b.y, b.b, b.C, b.y, b.b, b.y, b.B, nil},
},
[7] = {
[20] = {nil, b.C, b.G, nil, b.r, b.g, b.r, b.g, nil, nil},
[21] = {nil, nil, nil, nil, b.R, b.M, b.g, b.r, nil, nil},
[22] = {b.r, nil, nil, nil, b.r, b.g, b.O, b.Y, nil, nil},
[23] = {b.g, b.r, b.g, b.r, b.g, b.r, b.g, b.r, nil, nil},
[24] = {b.r, b.g, b.r, b.g, b.r, b.g, b.r, b.g, b.B, nil},
},
[8] = {
[15] = {nil, nil, nil, b.B, b.m, b.m, b.m, b.m, b.m, b.C},
[16] = {nil, nil, nil, nil, nil, nil, nil, nil, nil, b.m},
[17] = {nil, nil, nil, nil, nil, nil, nil, nil, nil, b.m},
[18] = {nil, b.Y, b.y, b.y, b.y, b.y, b.y, b.y, b.y, b.G},
[21] = {b.b, b.b, b.b, b.b, b.b, b.b, b.O, nil, nil, nil},
[22] = {b.b, nil, nil, nil, nil, nil, nil, nil, nil, nil},
[23] = {b.M, nil, nil, nil, nil, nil, nil, nil, nil, nil},
[24] = {b.o, b.o, b.o, b.o, b.o, b.o, b.o, b.o, b.R, nil},
},
[9] = {
[18] = {nil, nil, nil, b.Y, b.m, b.m, b.m, b.m, nil, nil},
[19] = {nil, nil, nil, b.c, b.c, b.c, b.c, b.G, nil, nil},
[20] = {b.m, b.m, b.m, b.O, b.M, b.R, nil, nil, nil, nil},
[21] = {b.c, b.c, b.c, b.c, b.c, b.c, b.c, b.c, nil, nil},
[22] = {b.m, b.m, b.m, b.m, b.m, b.m, b.m, b.m, nil, nil},
[23] = {b.c, b.c, b.c, b.c, b.c, b.c, b.c, b.c, b.C, nil},
[24] = {b.m, b.m, b.m, b.m, b.m, b.m, b.m, b.m, b.B, nil},
},
[10] = {
[18] = {nil, nil, nil, b.C, b.g, b.g, b.B, nil, nil, nil},
[19] = {nil, nil, b.G, b.g, b.g, b.g, b.g, b.Y, nil, nil},
[20] = {nil, b.M, b.g, b.g, b.g, b.g, b.g, b.g, b.O, nil},
[21] = {nil, nil, nil, nil, b.c, nil, nil, nil, nil, nil},
[22] = {nil, nil, nil, nil, b.c, nil, nil, nil, nil, nil},
[23] = {nil, nil, nil, nil, b.c, nil, b.o, nil, nil, nil},
[24] = {nil, nil, nil, nil, b.R, b.o, b.o, nil, nil, nil},
},
[11] = {
[18] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[19] = {nil, nil, nil, nil, b.R, nil, nil, nil, nil, nil},
[20] = {nil, nil, nil, nil, b.r, b.O, nil, nil, nil, nil},
[21] = {nil, nil, nil, nil, nil, b.M, nil, nil, nil, nil},
[22] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[23] = {nil, nil, nil, nil, b.G, b.Y, nil, nil, nil, nil},
[24] = {b.C, b.g, b.g, nil, b.o, b.o, nil, b.g, b.g, b.B},
},
[12] = {
[21] = {nil, nil, nil, nil, nil, nil, nil, b.g, b.g, b.Y},
[22] = {nil, nil, b.r, b.G, b.r, nil, nil, nil, b.O, b.g},
[23] = {nil, b.r, b.C, b.r, b.B, b.r, nil, nil, nil, b.M},
[24] = {b.r, b.r, b.r, b.R, b.r, b.r, b.r, nil, nil, nil},
},
[13] = {
[20] = {b.c, nil, nil, nil, nil, nil, nil, nil, nil, b.B},
[21] = {b.c, b.c, nil, nil, nil, nil, nil, nil, b.C, b.c},
[22] = {b.c, b.c, b.c, nil, nil, nil, nil, b.G, b.c, b.c},
[23] = {b.b, b.b, b.b, b.b, nil, nil, b.Y, b.b, b.b, b.b},
[24] = {nil, b.M, b.b, b.b, b.b, b.O, b.b, b.b, b.R, nil},
},
[14] = {
[20] = {nil, nil, nil, b.y, b.r, b.y, nil, nil, nil, nil},
[21] = {b.R, nil, nil, b.Y, b.y, b.r, b.G, nil, nil, nil},
[22] = {nil, nil, nil, b.y, b.r, b.y, b.r, b.y, b.r, b.B},
[23] = {nil, nil, nil, nil, nil, nil, nil, b.O, b.y, b.r},
[24] = {nil, nil, nil, nil, nil, nil, b.M, b.y, b.r, b.C},
},
[15] = {
[17] = {nil, nil, b.b, nil, nil, nil, nil, b.b, nil, nil},
[18] = {nil, nil, b.b, b.y, b.b, b.b, b.y, b.b, nil, nil},
[19] = {nil, nil, nil, b.y, b.b, b.b, b.y, nil, nil, nil},
[20] = {nil, nil, nil, nil, b.O, b.Y, nil, nil, nil, nil},
[22] = {nil, nil, nil, nil, b.M, b.R, nil, nil, nil, nil},
[23] = {nil, nil, nil, b.G, b.y, b.y, b.C, nil, nil, nil},
[24] = {nil, nil, b.B, b.y, b.y, b.y, b.y, b.y, nil, nil},
},
[16] = {
[18] = {nil, nil, b.O, nil, nil, nil, nil, b.B, nil, nil},
[19] = {nil, nil, b.c, nil, nil, b.G, nil, b.c, nil, nil},
[20] = {nil, nil, b.c, nil, b.C, b.R, nil, b.c, nil, nil},
[21] = {nil, nil, b.c, nil, nil, nil, nil, b.c, nil, nil},
[22] = {nil, nil, b.Y, b.c, b.c, b.c, b.c, b.M, nil, nil},
},
[17] = {
[15] = {b.O, nil, nil, b.g, nil, nil, b.m, nil, nil, b.Y},
[16] = {nil, nil, nil, b.g, nil, nil, b.m, nil, nil, nil},
[17] = {nil, nil, nil, b.g, nil, nil, b.R, nil, nil, nil},
[18] = {nil, nil, nil, b.g, nil, nil, b.m, nil, nil, nil},
[19] = {nil, nil, nil, b.M, nil, nil, b.m, nil, nil, nil},
[20] = {nil, nil, nil, b.g, nil, nil, b.m, nil, nil, nil},
[21] = {nil, nil, nil, b.g, nil, nil, b.G, nil, nil, nil},
[22] = {nil, nil, nil, b.g, nil, nil, b.m, nil, nil, nil},
[23] = {nil, nil, nil, b.g, nil, nil, b.m, nil, nil, nil},
[24] = {nil, b.m, b.m, b.m, b.B, b.C, b.g, b.g, b.g, nil},
},
[18] = {
[19] = {nil, nil, nil, b.y, b.B, b.y, b.y, nil, nil, nil},
[20] = {nil, nil, b.y, nil, nil, nil, nil, b.y, nil, nil},
[21] = {nil, b.o, nil, nil, b.C, b.R, nil, nil, b.O, nil},
[22] = {nil, b.M, nil, nil, b.Y, b.G, nil, nil, b.o, nil},
[23] = {nil, b.r, b.o, nil, nil, nil, nil, b.o, b.r, nil},
[24] = {nil, b.r, b.r, b.o, b.o, b.o, b.o, b.r, b.r, nil},
},
[19] = {
[15] = {nil, nil, nil, nil, nil, nil, b.O, nil, nil, nil},
[16] = {nil, nil, nil, nil, nil, b.o, nil, nil, nil, nil},
[17] = {nil, nil, nil, nil, b.o, b.r, b.o, nil, nil, nil},
[18] = {nil, b.o, nil, nil, b.o, b.r, b.r, b.o, nil, nil},
[19] = {nil, b.o, b.o, nil, nil, b.R, b.r, b.r, nil, nil},
[20] = {nil, nil, b.M, b.r, nil, b.r, b.r, b.r, b.r, nil},
[21] = {nil, nil, b.r, b.r, b.r, b.r, b.y, b.G, b.o, b.o},
[22] = {nil, b.r, b.o, b.y, b.Y, b.y, b.y, b.y, b.y, b.o},
[23] = {nil, b.o, b.o, b.y, b.y, b.c, b.c, b.c, b.c, b.C},
[24] = {nil, nil, b.o, b.y, b.b, b.b, b.B, b.b, b.b, b.b},
},
[20] = {
[20] = {nil, nil, b.B, b.b, b.b, b.b, b.b, b.b, nil, nil},
[21] = {b.c, nil, nil, b.C, b.c, b.c, b.c, nil, nil, b.c},
[22] = {b.g, b.g, nil, nil, b.G, b.g, nil, nil, b.g, b.g},
[23] = {b.y, b.y, b.o, nil, nil, nil, nil, b.Y, b.y, b.y},
[24] = {b.r, b.r, b.r, b.R, nil, nil, b.M, b.r, b.r, b.r},
},
[21] = {
[16] = {nil, nil, b.g, b.g, b.g, b.g, b.g, nil, nil, nil},
[17] = {nil, b.g, b.g, b.g, b.g, b.g, b.g, b.B, b.g, nil},
[18] = {b.g, b.g, b.g, b.g, b.g, b.g, b.g, b.g, b.C, nil},
[19] = {b.g, nil, nil, b.g, b.o, b.o, b.g, nil, nil, b.g},
[20] = {nil, b.R, nil, b.g, b.o, b.o, nil, b.M, nil, b.G},
[21] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[22] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[23] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[24] = {nil, nil, nil, nil, b.Y, b.O, nil, nil, nil, nil},
},
[22] = {
[15] = {nil, nil, b.b, nil, nil, nil, nil, b.b, nil, nil},
[16] = {nil, b.b, b.O, b.b, nil, nil, b.b, b.Y, b.b, nil},
[17] = {nil, nil, b.b, nil, nil, nil, nil, b.b, nil, nil},
[20] = {nil, nil, nil, nil, b.R, b.M, nil, nil, nil, nil},
[23] = {nil, nil, nil, b.b, b.C, b.G, b.b, nil, nil, nil},
[24] = {nil, nil, nil, b.b, b.b, b.B, b.b, nil, nil, nil},
},
[23] = {
[13] = {nil, nil, nil, nil, nil, nil, nil, nil, b.c, b.m},
[14] = {nil, nil, nil, nil, nil, nil, nil, nil, b.y, b.g},
[15] = {b.G, b.B, nil, nil, nil, nil, nil, nil, nil, nil},
[16] = {b.r, b.O, nil, nil, nil, nil, nil, nil, nil, nil},
[23] = {nil, nil, nil, nil, b.C, b.M, nil, nil, nil, nil},
[24] = {nil, nil, nil, nil, b.R, b.Y, nil, nil, nil, nil},
},
[24] = {
[20] = {b.g, b.g, b.g, b.g, b.G, nil, nil, nil, nil, nil},
[21] = {nil, nil, nil, nil, nil, b.O, b.y, b.y, b.y, b.Y},
[23] = {b.M, b.r, b.r, b.r, b.R, nil, nil, nil, nil, nil},
[24] = {nil, nil, nil, nil, nil, b.M, b.r, b.r, b.r, b.R},
},
[25] = {
[18] = {nil, nil, nil, nil, nil, b.B, nil, nil, nil, nil},
[19] = {nil, nil, nil, b.G, nil, nil, nil, b.C, nil, nil},
[20] = {nil, nil, nil, nil, nil, b.Y, nil, nil, nil, nil},
[21] = {nil, nil, nil, b.M, nil, nil, nil, b.O, nil, nil},
[22] = {nil, nil, nil, nil, nil, b.R, nil, nil, nil, nil},
},
[26] = {
[13] = {nil, nil, nil, nil, b.r, b.r, nil, nil, nil, nil},
[14] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[15] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[16] = {nil, nil, nil, nil, b.o, b.o, nil, nil, nil, nil},
[17] = {nil, nil, nil, b.O, b.o, b.o, b.Y, nil, nil, nil},
[18] = {nil, nil, b.o, b.c, b.c, b.c, b.c, b.o, nil, nil},
[19] = {nil, nil, b.o, b.c, b.c, b.c, b.c, b.o, nil, nil},
[20] = {nil, nil, b.o, nil, nil, b.G, nil, b.o, nil, nil},
[21] = {nil, nil, b.o, nil, b.M, b.R, nil, b.o, nil, nil},
[22] = {nil, nil, b.o, b.b, b.b, b.b, b.B, b.o, nil, nil},
[23] = {nil, nil, b.o, b.C, b.b, b.b, b.b, b.o, nil, nil},
[24] = {nil, nil, b.o, b.o, b.o, b.o, b.o, b.o, nil, nil},
},
[27] = {
[15] = {nil, b.C, b.o, b.g, b.g, b.g, b.g, b.g, b.B, nil},
[16] = {b.g, nil, b.y, b.o, b.g, b.g, b.g, b.g, nil, b.y},
[17] = {b.g, b.g, nil, b.y, b.o, b.g, b.g, nil, b.y, b.o},
[18] = {b.g, b.g, b.g, nil, b.y, b.o, nil, b.y, b.o, b.g},
[19] = {b.g, b.g, b.g, b.o, nil, b.G, b.y, b.o, b.g, b.g},
[20] = {b.g, b.g, b.o, b.o, b.Y, nil, b.o, b.g, b.g, b.g},
[21] = {b.g, b.o, b.y, nil, b.o, b.O, nil, b.g, b.g, b.g},
[22] = {b.o, b.y, nil, b.g, b.g, b.o, b.y, nil, b.g, b.g},
[23] = {b.y, nil, b.g, b.g, b.g, b.g, b.o, b.y, nil, b.g},
[24] = {nil, b.M, b.g, b.g, b.g, b.g, b.g, b.o, b.R, nil},
},
}
local STAGE_TRANSITION_TIME = 300
function SakuraGame:new()
self.super:new()
self.randomizer = SakuraRandomizer()
self.current_map = 1
self.time_limit = 10800
self.cleared_frames = STAGE_TRANSITION_TIME
self.stage_frames = 0
self.time_extend = 0
self.maps_cleared = 0
self.map_20_time = 0
self.stage_pieces = 0
self.grid:applyMap(maps[self.current_map])
self.lock_drop = true
self.lock_hard_drop = true
self.enable_hold = true
self.next_queue_length = 3
end
function SakuraGame:checkRequirements()
if self.maps_cleared >= 14 + 2 * (self.current_map - 20) and
self.map_20_time <= frameTime(8,00) - frameTime(0,30) * (self.current_map - 20)
then
return false
end
return true
end
function SakuraGame:getGravity()
if self.level < 8 then return 4/256
elseif self.level < 19 then return 5/256
elseif self.level < 35 then return 6/256
elseif self.level < 40 then return 8/256
elseif self.level < 50 then return 10/256
elseif self.level < 60 then return 12/256
elseif self.level < 70 then return 16/256
elseif self.level < 80 then return 32/256
elseif self.level < 90 then return 48/256
elseif self.level < 100 then return 64/256
elseif self.level < 108 then return 4/256
elseif self.level < 119 then return 5/256
elseif self.level < 125 then return 6/256
elseif self.level < 131 then return 8/256
elseif self.level < 139 then return 12/256
elseif self.level < 149 then return 32/256
elseif self.level < 156 then return 48/256
elseif self.level < 164 then return 80/256
elseif self.level < 174 then return 112/256
elseif self.level < 180 then return 128/256
elseif self.level < 200 then return 144/256
elseif self.level < 212 then return 16/256
elseif self.level < 221 then return 48/256
elseif self.level < 232 then return 80/256
elseif self.level < 244 then return 112/256
elseif self.level < 256 then return 144/256
elseif self.level < 267 then return 176/256
elseif self.level < 277 then return 192/256
elseif self.level < 287 then return 208/256
elseif self.level < 295 then return 224/256
elseif self.level < 300 then return 240/256
else return 20 end
end
function SakuraGame:onLineClear(cleared_row_count)
self.level = self.level + cleared_row_count
for i = 13, 24 do
for j = 1, 10 do
local block = self.grid.grid[i][j]
if block and block.skin == "gem" and block.colour == "X" then
self.time_limit = self.time_limit + 60
end
end
end
end
function SakuraGame:onPieceEnter()
if self.level % 100 ~= 99 and not self.clear and self.stage_frames ~= 0 then
self.level = self.level + 1
end
if effects[self.current_map] == "mirror" and
self.stage_pieces % 3 == 0 and self.stage_pieces ~= 0
then
self.grid:mirror()
end
self.stage_pieces = self.stage_pieces + 1
end
function SakuraGame:advanceOneFrame(inputs, ruleset)
if self.ready_frames == 0 then
if self.lcd > 0 then
if self.stage_frames <= frameTime(0,10) then self.time_extend = 600
elseif self.stage_frames <= frameTime(0,30) then self.time_extend = 300
else self.time_extend = 0 end
end
if not self.grid:hasGemBlocks() or
(self.stage_frames >= 3600 and self.current_map <= 20) then
self.lcd = 0
self.are = 0
if self.stage_frames >= 3600 then self.time_extend = 0 end
self.piece = nil
-- transition to next map
if self.cleared_frames > 0 then
self.cleared_frames = self.cleared_frames - 1
if self.time_extend > 0 then
self.time_limit = self.time_limit + 3
self.time_extend = self.time_extend - 3
end
return false
end
self.hold_queue = nil
if self.current_map > 20 or (self.stage_frames < 3600 and self.current_map <= 20) then self.maps_cleared = self.maps_cleared + 1 end
self.stage_frames = -1
self.level = 0
self.grid:clear()
if (self.current_map == 20) then self.map_20_time = self.frames end
if self.current_map >= 20 and self:checkRequirements() then
self.clear = true
self.completed = true
return false
else
self.current_map = self.current_map + 1
self.big_mode = effects[self.current_map] == "big"
self.ready_frames = 100
self.stage_pieces = 0
self.grid:applyMap(maps[self.current_map])
end
-- this is necessary to fix timer
self.frames = self.frames - 1
self.time_limit = self.time_limit + 1
end
self.frames = self.frames + 1
self.stage_frames = self.stage_frames + 1
self.time_limit = self.time_limit - 1
if self.time_limit <= 0 then self.game_over = true end
if self.piece ~= nil and self.frames % 30 == 0 and
effects[self.current_map] == "roll"
then
ruleset:attemptRotate(
{[config.gamesettings.world_reverse == 3 or
(ruleset.world and config.gamesettings.world_reverse == 2)
and "rotate_left" or "rotate_right"] = true},
self.piece, self.grid, false
)
end
else
self.cleared_frames = STAGE_TRANSITION_TIME
if not self.prev_inputs.hold and inputs.hold then
self.hold_queue = table.remove(self.next_queue, 1)
table.insert(self.next_queue, self:getNextPiece(ruleset))
end
end
return true
end
local function colourXRay(game, block, x, y, age)
local r, g, b, a = .5,.5,.5
if ((game.stage_frames/2 - x) % 30 < 1)
or game.stage_frames == 0
or game.cleared_frames ~= STAGE_TRANSITION_TIME
or game.stage_pieces % 2 == 0
then
a = 1
else
a = 1 - age / 4
end
return r, g, b, a, a
end
local function colourColor(game, block, x, y, age)
local r, g, b, a = .5,.5,.5
if game.stage_frames == 0 or game.cleared_frames ~= STAGE_TRANSITION_TIME then
a = 1
else
a = (game.stage_frames/30 + (y + math.abs(x-5.5))/5) % 1
end
return r, g, b, a, 0
end
function SakuraGame:drawGrid()
if effects[self.current_map] == "xray" then
self.grid:drawCustom(colourXRay, self)
elseif effects[self.current_map] == "color" then
self.grid:drawCustom(colourColor, self)
else
self.grid:draw()
-- if self.piece ~= nil and self.level < 100 then
self:drawGhostPiece(ruleset)
-- end
end
end
function SakuraGame: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)
)
love.graphics.printf("NEXT", 64, 40, 40, "left")
love.graphics.printf("STAGE", 240, 120, 80, "left")
love.graphics.printf("TIME LIMIT", 240, 180, 80, "left")
love.graphics.printf("LEVEL", 240, 320, 40, "left")
if self.current_map <= 20 then
love.graphics.printf("STAGE LIMIT", 240, 240, 100, "left")
end
if effects[self.current_map] then
love.graphics.printf("EFFECT: " .. effects[self.current_map], 240, 300, 160, "left")
end
love.graphics.setFont(font_3x5_3)
love.graphics.setColor(
(self.time_limit % 4 < 2 and
self.time_limit <= frameTime(0,10) and
self.grid:hasGemBlocks() and
self.time_limit ~= 0) and
{ 1, 0.3, 0.3, 1 } or
{ 1, 1, 1, 1 }
)
love.graphics.printf(formatTime(self.time_limit), 240, 200, 120, "left")
love.graphics.setColor(1, 1, 1, 1)
if self.current_map <= 20 then
love.graphics.printf(formatTime(3600 - self.stage_frames), 240, 260, 120, "left")
end
love.graphics.printf(self.level, 240, 340, 40, "right")
love.graphics.printf(math.floor((self.level + 100) / 100) * 100, 240, 370, 40, "right")
love.graphics.setFont(font_8x11)
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
love.graphics.printf(self.current_map, 290, 110, 80, "left")
end
function SakuraGame:drawCustom()
love.graphics.setColor(1, 1, 1, 1)
if self.ready_frames ~= 0 and not self.clear then
love.graphics.setFont(font_3x5_4)
love.graphics.printf("STAGE " .. self.current_map, 64, 170, 160, "center")
love.graphics.setFont(font_3x5_3)
if effects[self.current_map] then
love.graphics.printf("EFFECT: " .. effects[self.current_map], 64, 270, 160, "center")
end
end
if self.cleared_frames > 0 and
(not self.grid:hasGemBlocks() or
(self.stage_frames >= 3600 and self.current_map <= 20)) then
love.graphics.setFont(font_3x5_2)
love.graphics.printf("TIME LIMIT", 64, 180, 160, "center")
love.graphics.printf("TIME EXTEND", 64, 240, 160, "center")
love.graphics.printf("STAGE TIME", 64, 300, 160, "center")
love.graphics.setFont(font_3x5_3)
love.graphics.printf("STAGE " .. self.current_map, 64, 100, 160, "center")
love.graphics.setColor(
self.cleared_frames % 4 < 2 and
{ 1, 1, 0.3, 1 } or
{ 1, 1, 1, 1 }
)
love.graphics.printf(formatTime(self.time_limit), 64, 200, 160, "center")
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(formatTime(self.time_extend), 64, 260, 160, "center")
love.graphics.printf(formatTime(self.stage_frames), 64, 320, 160, "center")
love.graphics.setFont(font_3x5_4)
love.graphics.printf((self.stage_frames >= 3600 and self.current_map <= 20) and "" or "CLEAR!", 64, 130, 160, "center")
end
if self.clear then
love.graphics.setFont(font_3x5_3)
love.graphics.printf("EXCELLENT!", 64, 180, 160, "center")
love.graphics.setFont(font_3x5_2)
if self.current_map ~= 27 then
love.graphics.printf("...but let's go\nbetter next time", 64, 220, 160, "center")
end
end
end
function SakuraGame:getBackground()
return (self.current_map - 1) % 20
end
function SakuraGame:getHighscoreData()
return {
maps = self.maps_cleared,
current_map = self.current_map,
frames = self.frames,
}
end
return SakuraGame

View File

@@ -0,0 +1,16 @@
local Randomizer = require 'tetris.randomizers.randomizer'
local Sequence = Randomizer:extend()
function Sequence:initialize()
self.sequence = "IJLOT"
self.counter = 0
end
function Sequence:generatePiece()
local piece = string.sub(self.sequence, self.counter + 1, self.counter + 1)
self.counter = (self.counter + 1) % string.len(self.sequence)
return piece
end
return Sequence

View File

@@ -0,0 +1,10 @@
local Sequence = require 'tetris.randomizers.fixed_sequence'
local Sakura = Sequence:extend()
function Sakura:initialize()
self.super:initialize()
self.sequence = "LIJOTSZILJOTISJZLOIJSZTIOJZTLSOZTISOLTJSIZTOJLIZSTOIZLTJOSILTZSOITJLZSTJJISOLJITSLZOIZSJOITSZLJTSZLISTJLZOTIOZSJILTZSOITZJSOLTJSZIOJLZIOJTZIZLOSIZTJOILZSOJIOSZTJILOSSILZOTJIZTSOLZTSOIJTZSILTZOSIJZTOLJISOLJTZSOLTZJSOTILZJTOLZIJSOZTJLOZSTLOZITSOLZTJIOSLZJTO"
end
return Sakura

View File

@@ -6,6 +6,8 @@ local SRS = Ruleset:extend()
SRS.name = "ACE-SRS" SRS.name = "ACE-SRS"
SRS.hash = "ACE Standard" SRS.hash = "ACE Standard"
SRS.MANIPULATIONS_MAX = 128
SRS.spawn_positions = { SRS.spawn_positions = {
I = { x=5, y=2 }, I = { x=5, y=2 },
J = { x=4, y=3 }, J = { x=4, y=3 },
@@ -26,23 +28,11 @@ SRS.big_spawn_positions = {
Z = { x=2, y=1 }, Z = { x=2, y=1 },
} }
function SRS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 128 then
piece:dropToBottom(grid)
piece.locked = true
end
end
end
function SRS:onPieceRotate(piece, grid) function SRS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 128 then if piece.manipulations >= self.MANIPULATIONS_MAX then
piece:dropToBottom(grid)
piece.locked = true piece.locked = true
end end
end end

View File

@@ -115,8 +115,8 @@ function Ruleset:attemptRotate(new_inputs, piece, grid, initial)
local new_piece = piece:withRelativeRotation(rot_dir) local new_piece = piece:withRelativeRotation(rot_dir)
if (grid:canPlacePiece(new_piece)) then if (grid:canPlacePiece(new_piece)) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir) piece:setRelativeRotation(rot_dir)
self:onPieceRotate(piece, grid)
else else
if not(initial and self.enable_IRS_wallkicks == false) then if not(initial and self.enable_IRS_wallkicks == false) then
self:attemptWallkicks(piece, new_piece, rot_dir, grid) self:attemptWallkicks(piece, new_piece, rot_dir, grid)

View File

@@ -8,6 +8,8 @@ SRS.hash = "Standard"
SRS.enable_IRS_wallkicks = true SRS.enable_IRS_wallkicks = true
SRS.MANIPULATIONS_MAX = 15
function SRS:check_new_low(piece) function SRS:check_new_low(piece)
for _, block in pairs(piece:getBlockOffsets()) do for _, block in pairs(piece:getBlockOffsets()) do
local y = piece.position.y + block.y local y = piece.position.y + block.y
@@ -75,7 +77,7 @@ end
function SRS:onPieceDrop(piece, grid) function SRS:onPieceDrop(piece, grid)
self:check_new_low(piece) self:check_new_low(piece)
if piece.manipulations >= 15 and piece:isDropBlocked(grid) then if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
piece.locked = true piece.locked = true
else else
piece.lock_delay = 0 -- step reset piece.lock_delay = 0 -- step reset
@@ -86,8 +88,7 @@ function SRS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 15 then if piece.manipulations >= self.MANIPULATIONS_MAX then
piece:dropToBottom(grid)
piece.locked = true piece.locked = true
end end
end end
@@ -97,12 +98,12 @@ function SRS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset piece.lock_delay = 0 -- rotate reset
self:check_new_low(piece) self:check_new_low(piece)
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece:isDropBlocked(grid) then if piece.manipulations >= self.MANIPULATIONS_MAX then
if piece.manipulations >= 15 then piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
piece:dropToBottom(grid) if piece:isDropBlocked(grid) then
piece.locked = true piece.locked = true
end end
end end
end end
function SRS:get180RotationValue() return 2 end function SRS:get180RotationValue() return 2 end

View File

@@ -18,6 +18,9 @@ SRS.colourscheme = {
SRS.softdrop_lock = false SRS.softdrop_lock = false
SRS.harddrop_lock = true SRS.harddrop_lock = true
SRS.MANIPULATIONS_MAX = 10
SRS.ROTATIONS_MAX = 8
SRS.spawn_positions = { SRS.spawn_positions = {
I = { x=5, y=4 }, I = { x=5, y=4 },
J = { x=4, y=5 }, J = { x=4, y=5 },
@@ -162,15 +165,18 @@ function SRS:onPieceCreate(piece, grid)
end end
function SRS:onPieceDrop(piece, grid) function SRS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset if (piece.manipulations >= self.MANIPULATIONS_MAX or piece.rotations >= self.ROTATIONS_MAX) and piece:isDropBlocked(grid) then
piece.locked = true
else
piece.lock_delay = 0 -- step reset
end
end end
function SRS:onPieceMove(piece, grid) function SRS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 10 then if piece.manipulations >= self.MANIPULATIONS_MAX then
piece:dropToBottom(grid)
piece.locked = true piece.locked = true
end end
end end
@@ -179,9 +185,8 @@ end
function SRS:onPieceRotate(piece, grid) function SRS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.rotations = piece.rotations + 1 piece.rotations = piece.rotations + 1
if piece.rotations >= 8 then if piece.rotations >= self.ROTATIONS_MAX then
piece:dropToBottom(grid)
piece.locked = true piece.locked = true
end end
end end