mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52da36bf7 | ||
|
|
76142c1dff | ||
|
|
a3458e2413 | ||
|
|
7eba9c012f | ||
|
|
4d2868b7b6 | ||
|
|
2e6fcd232b | ||
|
|
10833f2ec1 | ||
|
|
abb2b9491e | ||
|
|
062ab2005e | ||
|
|
468025fc80 | ||
|
|
c8544975d6 | ||
|
|
6776229bfb | ||
|
|
84b4dc5073 | ||
|
|
35dafb6615 | ||
|
|
3641d85fcb | ||
|
|
9b89c4d1de | ||
|
|
2dba120919 | ||
|
|
9224f271b1 | ||
|
|
febb5d546c | ||
|
|
c6482c423e | ||
|
|
6beb313c6b | ||
|
|
eb70f55b6e | ||
|
|
0badcde9ad | ||
|
|
6f39b591d3 | ||
|
|
129237f0b0 | ||
|
|
741c246244 | ||
|
|
b5937af8b2 | ||
|
|
33b8533d8e | ||
|
|
69959ff687 | ||
|
|
f91cd99dfd | ||
|
|
be59727ca5 | ||
|
|
cca295066c | ||
|
|
f2862b4d93 | ||
|
|
2aafd30253 | ||
|
|
b27ba335ba | ||
|
|
33244736b8 | ||
|
|
285108ca08 | ||
|
|
4b1fed727c | ||
|
|
9fca272e8d | ||
|
|
5a21c8244b | ||
|
|
4923b2e2d4 | ||
|
|
8810f24e7a | ||
|
|
57a9f6ef55 | ||
|
|
342036bc28 | ||
|
|
78dcfe43c4 | ||
|
|
cdf6b5cf33 |
57
README.md
57
README.md
@@ -12,40 +12,24 @@ Join our Discord server for help and a welcoming community! https://discord.gg/m
|
|||||||
Credits
|
Credits
|
||||||
-------
|
-------
|
||||||
|
|
||||||
- [Lilla Oshisaure](https://www.youtube.com/user/LeSpyroshisaure) for their amazing contributions to my life in general!
|
- [Lilla Oshisaure](https://www.youtube.com/user/LeSpyroshisaure) for being my co-dev!
|
||||||
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
|
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
|
||||||
|
- [The Absolute Plus](https://discord.gg/6Gf2awJ) for being another source of motivation!
|
||||||
- [joezeng](https://github.com/joezeng) for the original project.
|
- [joezeng](https://github.com/joezeng) for the original project.
|
||||||
- [Hailey](https://github.com/haileylgbt) for some miscellaneous assets.
|
|
||||||
- MarkGamed7794 for some miscellaneous contributions.
|
The following people in no particular order also helped with the project:
|
||||||
- Mizu for the Cambridge logo and the [Cambridge launcher](https://github.com/rexxt/cambridge-launcher).
|
- [Hailey](https://github.com/haileylgbt)
|
||||||
- MattMayuga for the Cambridge banner.
|
- CylinderKnot
|
||||||
|
- MarkGamed7794
|
||||||
|
- [Mizu](https://github.com/rexxt)
|
||||||
|
- MattMayuga
|
||||||
|
- Kitaru
|
||||||
|
- switchpalacecorner
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Installation instructions
|
Playing the game
|
||||||
-------------------------
|
----------------
|
||||||
|
|
||||||
Pre-built releases are available on the releases page.
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
Unzip the exe file and run it directly. All assets are currently bundled inside the executable.
|
|
||||||
|
|
||||||
### macOS
|
|
||||||
|
|
||||||
For the time being, the file `cambridge.love` only works on the command line. Install `love` with [Homebrew](https://brew.sh), and run:
|
|
||||||
|
|
||||||
$ love cambridge.love
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
|
|
||||||
Same as macOS, except install `love` with your favourite package manager.
|
|
||||||
|
|
||||||
|
|
||||||
Running from source
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
If you want the bleeding-edge release, you can also clone the code straight from this repository.
|
|
||||||
|
|
||||||
### macOS, Linux
|
### macOS, Linux
|
||||||
|
|
||||||
@@ -55,12 +39,27 @@ Clone the repository in git:
|
|||||||
|
|
||||||
git clone https://github.com/SashLilac/cambridge
|
git clone https://github.com/SashLilac/cambridge
|
||||||
|
|
||||||
|
Alternatively, download the source code ZIP in the latest release.
|
||||||
|
|
||||||
Then, navigate to the root directory that you just cloned, and type:
|
Then, navigate to the root directory that you just cloned, and type:
|
||||||
|
|
||||||
love .
|
love .
|
||||||
|
|
||||||
It should run automatically!
|
It should run automatically!
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
You do not need LÖVE on Windows, as it comes bundled with the program. Download the source code ZIP in the latest release, or if you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
||||||
|
|
||||||
|
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
|
||||||
|
|
||||||
|
dist\windows\love.exe .
|
||||||
|
|
||||||
|
Alternatively, if you're on a 32-bit system, run this instead:
|
||||||
|
|
||||||
|
dist\win32\love.exe .
|
||||||
|
|
||||||
|
32-bit systems do not support rich presence integration.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
22
main.lua
22
main.lua
@@ -30,6 +30,28 @@ function love.load()
|
|||||||
if config.current_ruleset then current_ruleset = config.current_ruleset end
|
if config.current_ruleset then current_ruleset = config.current_ruleset end
|
||||||
scene = TitleScene()
|
scene = TitleScene()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
game_modes = {}
|
||||||
|
mode_list = love.filesystem.getDirectoryItems("tetris/modes")
|
||||||
|
for i=1,#mode_list do
|
||||||
|
if(mode_list[i] ~= "gamemode.lua" and mode_list[i] ~= "unrefactored_modes") then
|
||||||
|
game_modes[#game_modes+1] = require ("tetris.modes."..string.sub(mode_list[i],1,-5))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rulesets = {}
|
||||||
|
rule_list = love.filesystem.getDirectoryItems("tetris/rulesets")
|
||||||
|
for i=1,#rule_list do
|
||||||
|
if(rule_list[i] ~= "ruleset.lua" and rule_list[i] ~= "unrefactored_rulesets") then
|
||||||
|
rulesets[#rulesets+1] = require ("tetris.rulesets."..string.sub(rule_list[i],1,-5))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--sort mode/rule lists
|
||||||
|
local function padnum(d) return ("%03d%s"):format(#d, d) end
|
||||||
|
table.sort(game_modes, function(a,b)
|
||||||
|
return tostring(a.name):gsub("%d+",padnum) < tostring(b.name):gsub("%d+",padnum) end)
|
||||||
|
table.sort(rulesets, function(a,b)
|
||||||
|
return tostring(a.name):gsub("%d+",padnum) < tostring(b.name):gsub("%d+",padnum) end)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local TARGET_FPS = 60
|
local TARGET_FPS = 60
|
||||||
|
|||||||
BIN
res/img/bonew.png
Normal file
BIN
res/img/bonew.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 229 B |
@@ -5,43 +5,6 @@ ModeSelectScene.title = "Game Start"
|
|||||||
current_mode = 1
|
current_mode = 1
|
||||||
current_ruleset = 1
|
current_ruleset = 1
|
||||||
|
|
||||||
game_modes = {
|
|
||||||
require 'tetris.modes.marathon_2020',
|
|
||||||
require 'tetris.modes.survival_2020',
|
|
||||||
--require 'tetris.modes.strategy',
|
|
||||||
--require 'tetris.modes.interval_training',
|
|
||||||
--require 'tetris.modes.pacer_test',
|
|
||||||
require 'tetris.modes.demon_mode',
|
|
||||||
require 'tetris.modes.phantom_mania',
|
|
||||||
require 'tetris.modes.phantom_mania2',
|
|
||||||
require 'tetris.modes.phantom_mania_n',
|
|
||||||
require 'tetris.modes.race_40',
|
|
||||||
require 'tetris.modes.marathon_a1',
|
|
||||||
require 'tetris.modes.marathon_a2',
|
|
||||||
require 'tetris.modes.marathon_a3',
|
|
||||||
require 'tetris.modes.marathon_ax4',
|
|
||||||
require 'tetris.modes.marathon_c89',
|
|
||||||
require 'tetris.modes.survival_a1',
|
|
||||||
require 'tetris.modes.survival_a2',
|
|
||||||
require 'tetris.modes.survival_a3',
|
|
||||||
require 'tetris.modes.big_a2',
|
|
||||||
require 'tetris.modes.konoha',
|
|
||||||
}
|
|
||||||
|
|
||||||
rulesets = {
|
|
||||||
require 'tetris.rulesets.cambridge',
|
|
||||||
require 'tetris.rulesets.arika',
|
|
||||||
require 'tetris.rulesets.arika_ti',
|
|
||||||
require 'tetris.rulesets.ti_srs',
|
|
||||||
require 'tetris.rulesets.arika_ace',
|
|
||||||
require 'tetris.rulesets.arika_ace2',
|
|
||||||
require 'tetris.rulesets.arika_srs',
|
|
||||||
require 'tetris.rulesets.standard_exp',
|
|
||||||
--require 'tetris.rulesets.bonkers',
|
|
||||||
--require 'tetris.rulesets.shirase',
|
|
||||||
--require 'tetris.rulesets.super302',
|
|
||||||
}
|
|
||||||
|
|
||||||
function ModeSelectScene:new()
|
function ModeSelectScene:new()
|
||||||
self.menu_state = {
|
self.menu_state = {
|
||||||
mode = current_mode,
|
mode = current_mode,
|
||||||
@@ -69,14 +32,14 @@ function ModeSelectScene:render()
|
|||||||
elseif self.menu_state.select == "ruleset" then
|
elseif self.menu_state.select == "ruleset" then
|
||||||
love.graphics.setColor(1, 1, 1, 0.25)
|
love.graphics.setColor(1, 1, 1, 0.25)
|
||||||
end
|
end
|
||||||
love.graphics.rectangle("fill", 20, 78 + 20 * self.menu_state.mode, 240, 22)
|
love.graphics.rectangle("fill", 20, 258, 240, 22)
|
||||||
|
|
||||||
if self.menu_state.select == "mode" then
|
if self.menu_state.select == "mode" then
|
||||||
love.graphics.setColor(1, 1, 1, 0.25)
|
love.graphics.setColor(1, 1, 1, 0.25)
|
||||||
elseif self.menu_state.select == "ruleset" then
|
elseif self.menu_state.select == "ruleset" then
|
||||||
love.graphics.setColor(1, 1, 1, 0.5)
|
love.graphics.setColor(1, 1, 1, 0.5)
|
||||||
end
|
end
|
||||||
love.graphics.rectangle("fill", 340, 78 + 20 * self.menu_state.ruleset, 200, 22)
|
love.graphics.rectangle("fill", 340, 258, 200, 22)
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
|
||||||
@@ -84,10 +47,14 @@ function ModeSelectScene:render()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_2)
|
love.graphics.setFont(font_3x5_2)
|
||||||
for idx, mode in pairs(game_modes) do
|
for idx, mode in pairs(game_modes) do
|
||||||
love.graphics.printf(mode.name, 40, 80 + 20 * idx, 200, "left")
|
if(idx >= self.menu_state.mode-9 and idx <= self.menu_state.mode+9) then
|
||||||
|
love.graphics.printf(mode.name, 40, (260 - 20*(self.menu_state.mode)) + 20 * idx, 200, "left")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
for idx, ruleset in pairs(rulesets) do
|
for idx, ruleset in pairs(rulesets) do
|
||||||
love.graphics.printf(ruleset.name, 360, 80 + 20 * idx, 160, "left")
|
if(idx >= self.menu_state.ruleset-9 and idx <= self.menu_state.ruleset+9) then
|
||||||
|
love.graphics.printf(ruleset.name, 360, (260 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local Grid = Object:extend()
|
|||||||
|
|
||||||
local empty = { skin = "", colour = "" }
|
local empty = { skin = "", colour = "" }
|
||||||
local oob = { skin = "", colour = "" }
|
local oob = { skin = "", colour = "" }
|
||||||
|
local block = { skin = "2tie", colour = "X" }
|
||||||
|
|
||||||
function Grid:new()
|
function Grid:new()
|
||||||
self.grid = {}
|
self.grid = {}
|
||||||
@@ -141,14 +142,34 @@ function Grid:copyBottomRow()
|
|||||||
self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty}
|
self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty}
|
||||||
self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
for col = 1, 10 do
|
for col = 1, 10 do
|
||||||
self.grid[24][col] = (self.grid[23][col] == empty) and empty or {
|
self.grid[24][col] = (self.grid[23][col] == empty) and empty or block
|
||||||
skin = self.grid[23][col].skin,
|
|
||||||
colour = "X"
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Grid:garbageRise(row_vals)
|
||||||
|
for row = 1, 23 do
|
||||||
|
self.grid[row] = self.grid[row+1]
|
||||||
|
self.grid_age[row] = self.grid_age[row+1]
|
||||||
|
end
|
||||||
|
self.grid[24] = {empty, empty, empty, empty, empty, empty, empty, empty, empty, empty}
|
||||||
|
self.grid_age[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
for col = 1, 10 do
|
||||||
|
self.grid[24][col] = (row_vals[col] == "e") and empty or block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Grid:applyFourWide()
|
||||||
|
for row = 1, 24 do
|
||||||
|
local x = self.grid[row]
|
||||||
|
x[1] = x[1]~=block and block or x[1]
|
||||||
|
x[2] = x[2]~=block and block or x[2]
|
||||||
|
x[3] = x[3]~=block and block or x[3]
|
||||||
|
x[8] = x[8]~=block and block or x[8]
|
||||||
|
x[9] = x[9]~=block and block or x[9]
|
||||||
|
x[10] = x[10]~=block and block or x[10]
|
||||||
|
end
|
||||||
|
end
|
||||||
function Grid:applyPiece(piece)
|
function Grid:applyPiece(piece)
|
||||||
if piece.big then
|
if piece.big then
|
||||||
self:applyBigPiece(piece)
|
self:applyBigPiece(piece)
|
||||||
@@ -216,7 +237,7 @@ function Grid:checkSecretGrade()
|
|||||||
if(validLine) then
|
if(validLine) then
|
||||||
sgrade = sgrade + 1
|
sgrade = sgrade + 1
|
||||||
else
|
else
|
||||||
-- return sgrade
|
return sgrade
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--[[
|
--[[
|
||||||
@@ -239,7 +260,7 @@ function Grid:update()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Grid:draw()
|
function Grid:draw()
|
||||||
for y = 1, 24 do
|
for y = 5, 24 do
|
||||||
for x = 1, 10 do
|
for x = 1, 10 do
|
||||||
if self.grid[y][x] ~= empty then
|
if self.grid[y][x] ~= empty then
|
||||||
if self.grid_age[y][x] < 1 then
|
if self.grid_age[y][x] < 1 then
|
||||||
@@ -271,7 +292,7 @@ function Grid:draw()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Grid:drawInvisible(opacity_function, garbage_opacity_function)
|
function Grid:drawInvisible(opacity_function, garbage_opacity_function)
|
||||||
for y = 1, 24 do
|
for y = 5, 24 do
|
||||||
for x = 1, 10 do
|
for x = 1, 10 do
|
||||||
if self.grid[y][x] ~= empty then
|
if self.grid[y][x] ~= empty then
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ end
|
|||||||
|
|
||||||
function Piece:dropToBottom(grid)
|
function Piece:dropToBottom(grid)
|
||||||
local piece_y = self.position.y
|
local piece_y = self.position.y
|
||||||
self:dropSquares(24, grid)
|
self:dropSquares(math.huge, grid)
|
||||||
self.gravity = 0
|
self.gravity = 0
|
||||||
if self.position.y > piece_y then
|
if self.position.y > piece_y then
|
||||||
-- if it got dropped any, also reset lock delay
|
-- if it got dropped any, also reset lock delay
|
||||||
|
|||||||
39
tetris/modes/4wide.lua
Normal file
39
tetris/modes/4wide.lua
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
require 'funcs'
|
||||||
|
|
||||||
|
local SurvivalA3Game = require 'tetris.modes.survival_a3'
|
||||||
|
|
||||||
|
local FourWideGame = SurvivalA3Game:extend()
|
||||||
|
|
||||||
|
FourWideGame.name = "4-wide Simulator"
|
||||||
|
FourWideGame.hash = "4wide"
|
||||||
|
FourWideGame.tagline = "The board has gotten narrower! Can you survive the increasing speeds?"
|
||||||
|
|
||||||
|
function FourWideGame:initialize(ruleset)
|
||||||
|
self.super:initialize(ruleset)
|
||||||
|
self.grid:applyFourWide()
|
||||||
|
end
|
||||||
|
|
||||||
|
local cleared_row_levels = {1, 2, 4, 6}
|
||||||
|
|
||||||
|
function FourWideGame: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
|
||||||
|
self.clear = true
|
||||||
|
if new_level >= 1300 then
|
||||||
|
self.level = 1300
|
||||||
|
self.grid:clear()
|
||||||
|
self.roll_frames = -150
|
||||||
|
else
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.level = math.min(new_level, 1300)
|
||||||
|
end
|
||||||
|
self:advanceBottomRow(-cleared_row_count)
|
||||||
|
end
|
||||||
|
self.grid:applyFourWide()
|
||||||
|
end
|
||||||
|
|
||||||
|
return FourWideGame
|
||||||
@@ -19,13 +19,10 @@ function MarathonA2Game:new()
|
|||||||
self.big_mode = true
|
self.big_mode = true
|
||||||
self.roll_frames = 0
|
self.roll_frames = 0
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
self.randomizer = History6RollsRandomizer()
|
|
||||||
self.grade = 0
|
self.grade = 0
|
||||||
self.grade_points = 0
|
self.grade_points = 0
|
||||||
self.grade_point_decay_counter = 0
|
self.grade_point_decay_counter = 0
|
||||||
self.section_start_time = 0
|
|
||||||
self.section_times = { [0] = 0 }
|
|
||||||
self.section_tetrises = { [0] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
|
||||||
|
|
||||||
self.randomizer = History6RollsRandomizer()
|
self.randomizer = History6RollsRandomizer()
|
||||||
|
|
||||||
@@ -103,11 +100,9 @@ end
|
|||||||
function MarathonA2Game:advanceOneFrame()
|
function MarathonA2Game:advanceOneFrame()
|
||||||
if self.clear then
|
if self.clear then
|
||||||
self.roll_frames = self.roll_frames + 1
|
self.roll_frames = self.roll_frames + 1
|
||||||
|
if self.roll_frames < 0 then return false end
|
||||||
if self.roll_frames > 3694 then
|
if self.roll_frames > 3694 then
|
||||||
self.completed = true
|
self.completed = true
|
||||||
if self.grade == 32 then
|
|
||||||
self.grade = 33
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
elseif self.ready_frames == 0 then
|
elseif self.ready_frames == 0 then
|
||||||
self.frames = self.frames + 1
|
self.frames = self.frames + 1
|
||||||
@@ -123,43 +118,29 @@ end
|
|||||||
|
|
||||||
function MarathonA2Game:onLineClear(cleared_row_count)
|
function MarathonA2Game:onLineClear(cleared_row_count)
|
||||||
cleared_row_count = cleared_row_count / 2
|
cleared_row_count = cleared_row_count / 2
|
||||||
self:updateSectionTimes(self.level, self.level + cleared_row_count)
|
|
||||||
self.level = math.min(self.level + cleared_row_count, 999)
|
self.level = math.min(self.level + cleared_row_count, 999)
|
||||||
if self.level == 999 and not self.clear then
|
if self.level == 999 and not self.clear then
|
||||||
self.clear = true
|
self.clear = true
|
||||||
if self:qualifiesForMRoll() then
|
|
||||||
self.grade = 32
|
|
||||||
end
|
|
||||||
self.grid:clear()
|
self.grid:clear()
|
||||||
self.roll_frames = -150
|
self.roll_frames = -150
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
|
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
|
if not self.clear then
|
||||||
cleared_lines = cleared_lines / 2
|
cleared_lines = cleared_lines / 2
|
||||||
self:updateGrade(cleared_lines)
|
self:updateGrade(cleared_lines)
|
||||||
|
if self.grid:checkForBravo(cleared_lines) then self.bravo = 4 else self.bravo = 1 end
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + 2 * drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * self.combo * self.bravo
|
cleared_lines * self.combo * self.bravo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + 2 * (cleared_lines - 1)
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
end
|
self.drop_bonus = 0
|
||||||
|
|
||||||
function MarathonA2Game:updateSectionTimes(old_level, new_level)
|
|
||||||
if self.clear then return end
|
|
||||||
if math.floor(old_level / 100) < math.floor(new_level / 100) or
|
|
||||||
new_level >= 999 then
|
|
||||||
-- record new section
|
|
||||||
section_time = self.frames - self.section_start_time
|
|
||||||
self.section_times[math.floor(old_level / 100)] = section_time
|
|
||||||
self.section_start_time = self.frames
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -224,7 +205,7 @@ local grade_conversion = {
|
|||||||
1, 2, 3, 4, 5, 5, 6, 6, 7, 7,
|
1, 2, 3, 4, 5, 5, 6, 6, 7, 7,
|
||||||
7, 8, 8, 8, 9, 9, 9, 10, 11, 12,
|
7, 8, 8, 8, 9, 9, 9, 10, 11, 12,
|
||||||
12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||||
17, 18, 19
|
17
|
||||||
}
|
}
|
||||||
|
|
||||||
function MarathonA2Game:updateGrade(cleared_lines)
|
function MarathonA2Game:updateGrade(cleared_lines)
|
||||||
@@ -249,49 +230,12 @@ function MarathonA2Game:updateGrade(cleared_lines)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }
|
|
||||||
|
|
||||||
function MarathonA2Game:qualifiesForMRoll()
|
|
||||||
if not self.clear then return false end
|
|
||||||
-- tetris requirements
|
|
||||||
for section = 0, 9 do
|
|
||||||
if self.section_tetrises[section] < tetris_requirements[section] then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- section time requirements
|
|
||||||
local section_average = 0
|
|
||||||
for section = 0, 4 do
|
|
||||||
section_average = section_average + self.section_times[section]
|
|
||||||
if self.section_times[section] > frameTime(1,05) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- section time average requirements
|
|
||||||
if self.section_times[5] > section_average / 5 then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
for section = 6, 9 do
|
|
||||||
if self.section_times[section] > self.section_times[section - 1] + 120 then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if self.grade < 17 or self.frames > frameTime(8,45) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function MarathonA2Game:getLetterGrade()
|
function MarathonA2Game:getLetterGrade()
|
||||||
local grade = grade_conversion[self.grade]
|
local grade = grade_conversion[self.grade]
|
||||||
if grade < 9 then
|
if grade < 9 then
|
||||||
return tostring(9 - grade)
|
return tostring(9 - grade)
|
||||||
elseif grade < 18 then
|
elseif grade < 18 then
|
||||||
return "S" .. tostring(grade - 8)
|
return "S" .. tostring(grade - 8)
|
||||||
elseif grade == 18 then
|
|
||||||
return "M"
|
|
||||||
else
|
|
||||||
return "GM"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -301,18 +245,9 @@ MarathonA2Game.rollOpacityFunction = function(age)
|
|||||||
else return 1 - (age - 240) / 60 end
|
else return 1 - (age - 240) / 60 end
|
||||||
end
|
end
|
||||||
|
|
||||||
MarathonA2Game.mRollOpacityFunction = function(age)
|
|
||||||
if age > 4 then return 0
|
|
||||||
else return 1 - age / 4 end
|
|
||||||
end
|
|
||||||
|
|
||||||
function MarathonA2Game:drawGrid(ruleset)
|
function MarathonA2Game:drawGrid(ruleset)
|
||||||
if self.clear and not (self.completed or self.game_over) then
|
if self.clear and not (self.completed or self.game_over) then
|
||||||
if self:qualifiesForMRoll() then
|
|
||||||
self.grid:drawInvisible(self.mRollOpacityFunction)
|
|
||||||
else
|
|
||||||
self.grid:drawInvisible(self.rollOpacityFunction)
|
self.grid:drawInvisible(self.rollOpacityFunction)
|
||||||
end
|
|
||||||
else
|
else
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
if self.piece ~= nil and self.level < 100 then
|
if self.piece ~= nil and self.level < 100 then
|
||||||
@@ -336,7 +271,10 @@ function MarathonA2Game:drawScoringInfo()
|
|||||||
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
if self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
|
||||||
|
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
|
||||||
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.printf(self.score, 240, 220, 90, "left")
|
love.graphics.printf(self.score, 240, 220, 90, "left")
|
||||||
love.graphics.printf(self.level, 240, 340, 40, "right")
|
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||||
|
|||||||
326
tetris/modes/ck.lua
Normal file
326
tetris/modes/ck.lua
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
require 'funcs'
|
||||||
|
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
|
||||||
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
||||||
|
|
||||||
|
local SurvivalCKGame = GameMode:extend()
|
||||||
|
|
||||||
|
SurvivalCKGame.name = "Survival CK"
|
||||||
|
SurvivalCKGame.hash = "SurvivalCK"
|
||||||
|
SurvivalCKGame.tagline = "An endurance mode created by CylinderKnot! Watch out for the fading pieces..."
|
||||||
|
|
||||||
|
function SurvivalCKGame:new()
|
||||||
|
SurvivalCKGame.super:new()
|
||||||
|
|
||||||
|
self.garbage = 0
|
||||||
|
self.roll_frames = 0
|
||||||
|
self.combo = 1
|
||||||
|
self.grade = 0
|
||||||
|
self.level = 0
|
||||||
|
|
||||||
|
self.randomizer = History6RollsRandomizer()
|
||||||
|
|
||||||
|
self.enable_hold = true
|
||||||
|
self.next_queue_length = 3
|
||||||
|
|
||||||
|
self.coolregret_timer = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getARE()
|
||||||
|
if self.level < 100 then return 15
|
||||||
|
elseif self.level < 200 then return 14
|
||||||
|
elseif self.level < 300 then return 13
|
||||||
|
elseif self.level < 400 then return 12
|
||||||
|
elseif self.level < 500 then return 11
|
||||||
|
elseif self.level < 600 then return 10
|
||||||
|
elseif self.level < 700 then return 9
|
||||||
|
elseif self.level < 800 then return 8
|
||||||
|
elseif self.level < 900 then return 7
|
||||||
|
elseif self.level < 1000 then return 6
|
||||||
|
elseif self.level < 2500 then return 5
|
||||||
|
else return 7 end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SurvivalCKGame:getLineARE()
|
||||||
|
return SurvivalCKGame:getARE()
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getDasLimit()
|
||||||
|
if self.level < 700 then return 10
|
||||||
|
elseif self.level < 900 then return 9
|
||||||
|
elseif self.level < 1100 then return 8
|
||||||
|
elseif self.level < 1300 then return 7
|
||||||
|
elseif self.level < 1600 then return 6
|
||||||
|
else return 5 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getLineClearDelay()
|
||||||
|
if self.level < 100 then return 10
|
||||||
|
elseif self.level < 200 then return 8
|
||||||
|
elseif self.level < 300 then return 7
|
||||||
|
elseif self.level < 400 then return 6
|
||||||
|
else return 5 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getLockDelay()
|
||||||
|
if self.level < 600 then return 20
|
||||||
|
elseif self.level < 700 then return 19
|
||||||
|
elseif self.level < 800 then return 18
|
||||||
|
elseif self.level < 900 then return 17
|
||||||
|
elseif self.level < 1000 then return 16
|
||||||
|
elseif self.level < 1200 then return 15
|
||||||
|
elseif self.level < 1400 then return 14
|
||||||
|
elseif self.level < 1700 then return 13
|
||||||
|
elseif self.level < 2100 then return 12
|
||||||
|
elseif self.level < 2200 then return 11
|
||||||
|
elseif self.level < 2300 then return 10
|
||||||
|
elseif self.level < 2400 then return 9
|
||||||
|
elseif self.level < 2500 then return 8
|
||||||
|
else return 15 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getGravity()
|
||||||
|
return 20
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getGarbageLimit()
|
||||||
|
if self.level < 1000 then return 20
|
||||||
|
elseif self.level < 1100 then return 17
|
||||||
|
elseif self.level < 1200 then return 14
|
||||||
|
elseif self.level < 1300 then return 11
|
||||||
|
else return 8 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getRegretTime()
|
||||||
|
if self.level < 500 then return frameTime(0,55)
|
||||||
|
elseif self.level < 1000 then return frameTime(0,50)
|
||||||
|
elseif self.level < 1500 then return frameTime(0,40)
|
||||||
|
elseif self.level < 2000 then return frameTime(0,35)
|
||||||
|
else return frameTime(0,30) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getNextPiece(ruleset)
|
||||||
|
return {
|
||||||
|
skin = self.level >= 2000 and "bone" or "2tie",
|
||||||
|
shape = self.randomizer:nextPiece(),
|
||||||
|
orientation = ruleset:getDefaultOrientation(),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local torikan_times = {300, 330, 360, 390, 420, 450, 478, 504, 528, 550, 570}
|
||||||
|
|
||||||
|
function SurvivalCKGame:hitTorikan(old_level, new_level)
|
||||||
|
for i = 1, 11 do
|
||||||
|
if old_level < (900 + i * 100) and new_level >= (900 + i * 100) and self.frames > torikan_times[i] * 60 then
|
||||||
|
self.level = 900 + i * 100
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame: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)
|
||||||
|
if self.grade ~= 20 then self.grade = self.grade + 1 end
|
||||||
|
self.completed = true
|
||||||
|
end
|
||||||
|
elseif self.ready_frames == 0 then
|
||||||
|
self.frames = self.frames + 1
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:onPieceEnter()
|
||||||
|
if (self.level % 100 ~= 99) and not self.clear and self.frames ~= 0 then
|
||||||
|
self.level = self.level + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:onLineClear(cleared_row_count)
|
||||||
|
if not self.clear then
|
||||||
|
local new_level = self.level + cleared_row_count * 2
|
||||||
|
self:updateSectionTimes(self.level, new_level)
|
||||||
|
if new_level >= 2500 or self:hitTorikan(self.level, new_level) then
|
||||||
|
self.clear = true
|
||||||
|
if new_level >= 2500 then
|
||||||
|
self.level = 2500
|
||||||
|
self.grid:clear()
|
||||||
|
self.big_mode = true
|
||||||
|
self.roll_frames = -150
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.level = math.min(new_level, 2500)
|
||||||
|
end
|
||||||
|
self:advanceBottomRow(-cleared_row_count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:onPieceLock(piece, cleared_row_count)
|
||||||
|
if cleared_row_count == 0 then self:advanceBottomRow(1) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
|
self.score = self.score + (
|
||||||
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
|
cleared_lines * self.combo
|
||||||
|
)
|
||||||
|
else
|
||||||
|
self.combo = 1
|
||||||
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame: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 <= self:getRegretTime(self.level) then
|
||||||
|
self.grade = self.grade + 1
|
||||||
|
else
|
||||||
|
self.coolregret_message = "REGRET!!"
|
||||||
|
self.coolregret_timer = 300
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:advanceBottomRow(dx)
|
||||||
|
if self.level >= 1000 and self.level < 1500 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 SurvivalCKGame:drawGrid()
|
||||||
|
if self.level >= 1500 and self.level < 1600 then
|
||||||
|
self.grid:drawInvisible(self.rollOpacityFunction1)
|
||||||
|
elseif self.level >= 1600 and self.level < 1700 then
|
||||||
|
self.grid:drawInvisible(self.rollOpacityFunction2)
|
||||||
|
elseif self.level >= 1700 and self.level < 1800 then
|
||||||
|
self.grid:drawInvisible(self.rollOpacityFunction3)
|
||||||
|
elseif self.level >= 1800 and self.level < 1900 then
|
||||||
|
self.grid:drawInvisible(self.rollOpacityFunction4)
|
||||||
|
elseif self.level >= 1900 and self.level < 2000 then
|
||||||
|
self.grid:drawInvisible(self.rollOpacityFunction5)
|
||||||
|
else
|
||||||
|
self.grid:draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- screw trying to make this work efficiently
|
||||||
|
-- lua function variables are so garbage
|
||||||
|
|
||||||
|
SurvivalCKGame.rollOpacityFunction1 = function(age)
|
||||||
|
if age < 420 then return 1
|
||||||
|
elseif age > 480 then return 0
|
||||||
|
else return 1 - (age - 420) / 60 end
|
||||||
|
end
|
||||||
|
|
||||||
|
SurvivalCKGame.rollOpacityFunction2 = function(age)
|
||||||
|
if age < 360 then return 1
|
||||||
|
elseif age > 420 then return 0
|
||||||
|
else return 1 - (age - 360) / 60 end
|
||||||
|
end
|
||||||
|
|
||||||
|
SurvivalCKGame.rollOpacityFunction3 = function(age)
|
||||||
|
if age < 300 then return 1
|
||||||
|
elseif age > 360 then return 0
|
||||||
|
else return 1 - (age - 300) / 60 end
|
||||||
|
end
|
||||||
|
|
||||||
|
SurvivalCKGame.rollOpacityFunction4 = function(age)
|
||||||
|
if age < 240 then return 1
|
||||||
|
elseif age > 300 then return 0
|
||||||
|
else return 1 - (age - 240) / 60 end
|
||||||
|
end
|
||||||
|
|
||||||
|
SurvivalCKGame.rollOpacityFunction5 = function(age)
|
||||||
|
if age < 180 then return 1
|
||||||
|
elseif age > 240 then return 0
|
||||||
|
else return 1 - (age - 180) / 60 end
|
||||||
|
end
|
||||||
|
|
||||||
|
local master_grades = { "M", "MK", "MV", "MO", "MM" }
|
||||||
|
|
||||||
|
function SurvivalCKGame:getLetterGrade()
|
||||||
|
if self.grade == 0 then
|
||||||
|
return "1"
|
||||||
|
elseif self.grade < 10 then
|
||||||
|
return "S" .. tostring(self.grade)
|
||||||
|
elseif self.grade < 21 then
|
||||||
|
return "m" .. tostring(self.grade - 9)
|
||||||
|
elseif self.grade < 26 then
|
||||||
|
return master_grades[self.grade - 20]
|
||||||
|
else
|
||||||
|
return "GM"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:drawScoringInfo()
|
||||||
|
SurvivalCKGame.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")
|
||||||
|
|
||||||
|
if (self.coolregret_timer > 0) then
|
||||||
|
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
|
||||||
|
self.coolregret_timer = self.coolregret_timer - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_section = math.floor(self.level / 100) + 1
|
||||||
|
self:drawSectionTimesWithSplits(current_section)
|
||||||
|
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.printf(self:getLetterGrade(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 SurvivalCKGame:getHighscoreData()
|
||||||
|
return {
|
||||||
|
grade = self.grade,
|
||||||
|
level = self.level,
|
||||||
|
frames = self.frames,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getSectionEndLevel()
|
||||||
|
return math.floor(self.level / 100 + 1) * 100
|
||||||
|
end
|
||||||
|
|
||||||
|
function SurvivalCKGame:getBackground()
|
||||||
|
return math.min(math.floor(self.level / 100), 19)
|
||||||
|
end
|
||||||
|
|
||||||
|
return SurvivalCKGame
|
||||||
@@ -167,6 +167,7 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
|
|||||||
else
|
else
|
||||||
self.level = math.min(new_level, 2500)
|
self.level = math.min(new_level, 2500)
|
||||||
self.skip_failed = true
|
self.skip_failed = true
|
||||||
|
self.grade = self.grade + 1
|
||||||
end
|
end
|
||||||
-- record new section
|
-- record new section
|
||||||
section_time = self.frames - self.section_start_time
|
section_time = self.frames - self.section_start_time
|
||||||
@@ -178,6 +179,7 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
|
|||||||
self.level = 500
|
self.level = 500
|
||||||
self.game_over = true
|
self.game_over = true
|
||||||
end
|
end
|
||||||
|
self.grade = math.min(self.grade + 1, 4)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.level = math.min(new_level, 2500)
|
self.level = math.min(new_level, 2500)
|
||||||
@@ -185,17 +187,18 @@ function DemonModeGame:updateSectionTimes(old_level, new_level)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function DemonModeGame:updateScore(level, drop_bonus, cleared_lines)
|
function DemonModeGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local letter_grades = {
|
local letter_grades = {
|
||||||
@@ -259,7 +262,7 @@ function DemonModeGame:getHighscoreData()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function DemonModeGame:getBackground()
|
function DemonModeGame:getBackground()
|
||||||
return math.floor(self.level / 100)
|
return math.min(math.floor(self.level / 100), 19)
|
||||||
end
|
end
|
||||||
|
|
||||||
return DemonModeGame
|
return DemonModeGame
|
||||||
|
|||||||
@@ -366,7 +366,8 @@ function GameMode:drawNextQueue(ruleset)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self.hold_queue ~= nil then
|
if self.hold_queue ~= nil then
|
||||||
self:setHoldOpacity()
|
local hold_color = self.held and 0.6 or 1
|
||||||
|
self:setHoldOpacity(1, hold_color)
|
||||||
drawPiece(
|
drawPiece(
|
||||||
self.hold_queue.shape,
|
self.hold_queue.shape,
|
||||||
self.hold_queue.skin,
|
self.hold_queue.skin,
|
||||||
@@ -377,8 +378,16 @@ function GameMode:drawNextQueue(ruleset)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:setNextOpacity(i) love.graphics.setColor(1, 1, 1, 1) end
|
function GameMode:setNextOpacity(i, j)
|
||||||
function GameMode:setHoldOpacity() love.graphics.setColor(1, 1, 1, 1) end
|
i = i ~= nil and i or 1
|
||||||
|
j = j ~= nil and j or 1
|
||||||
|
love.graphics.setColor(j, j, j, i)
|
||||||
|
end
|
||||||
|
function GameMode:setHoldOpacity(i, j)
|
||||||
|
i = i ~= nil and i or 1
|
||||||
|
j = j ~= nil and j or 1
|
||||||
|
love.graphics.setColor(j, j, j, i)
|
||||||
|
end
|
||||||
|
|
||||||
function GameMode:drawScoringInfo()
|
function GameMode:drawScoringInfo()
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ require 'funcs'
|
|||||||
local GameMode = require 'tetris.modes.gamemode'
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
|
|
||||||
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls'
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
||||||
|
|
||||||
local IntervalTrainingGame = GameMode:extend()
|
local IntervalTrainingGame = GameMode:extend()
|
||||||
|
|
||||||
@@ -15,11 +15,12 @@ IntervalTrainingGame.tagline = "Can you clear the time hurdles when the game goe
|
|||||||
|
|
||||||
|
|
||||||
function IntervalTrainingGame:new()
|
function IntervalTrainingGame:new()
|
||||||
|
self.level = 0
|
||||||
IntervalTrainingGame.super:new()
|
IntervalTrainingGame.super:new()
|
||||||
self.roll_frames = 0
|
self.roll_frames = 0
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
self.randomizer = History6RollsRandomizer()
|
self.randomizer = History6RollsRandomizer()
|
||||||
self.section_time_limit = 1800
|
|
||||||
self.section_start_time = 0
|
self.section_start_time = 0
|
||||||
self.section_times = { [0] = 0 }
|
self.section_times = { [0] = 0 }
|
||||||
self.lock_drop = true
|
self.lock_drop = true
|
||||||
@@ -27,20 +28,26 @@ function IntervalTrainingGame:new()
|
|||||||
self.next_queue_length = 3
|
self.next_queue_length = 3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function IntervalTrainingGame:initialize(ruleset)
|
||||||
|
self.section_time_limit = 1800
|
||||||
|
if ruleset.world then self.section_time_limit = 37 * 60 end
|
||||||
|
self.super.initialize(self, ruleset)
|
||||||
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:getARE()
|
function IntervalTrainingGame:getARE()
|
||||||
return 4
|
return 6
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:getLineARE()
|
function IntervalTrainingGame:getLineARE()
|
||||||
return 4
|
return 6
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:getDasLimit()
|
function IntervalTrainingGame:getDasLimit()
|
||||||
return 6
|
return 7
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:getLineClearDelay()
|
function IntervalTrainingGame:getLineClearDelay()
|
||||||
return 6
|
return 4
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:getLockDelay()
|
function IntervalTrainingGame:getLockDelay()
|
||||||
@@ -61,7 +68,6 @@ function IntervalTrainingGame:advanceOneFrame()
|
|||||||
if self.roll_frames > 2968 then
|
if self.roll_frames > 2968 then
|
||||||
self.completed = true
|
self.completed = true
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
elseif self.ready_frames == 0 then
|
elseif self.ready_frames == 0 then
|
||||||
self.frames = self.frames + 1
|
self.frames = self.frames + 1
|
||||||
if self:getSectionTime() >= self.section_time_limit then
|
if self:getSectionTime() >= self.section_time_limit then
|
||||||
@@ -72,14 +78,15 @@ function IntervalTrainingGame:advanceOneFrame()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:onPieceEnter()
|
function IntervalTrainingGame:onPieceEnter()
|
||||||
if (self.level % 100 ~= 99 or self.level == 998) and not self.clear and self.frames ~= 0 then
|
if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
|
||||||
self.level = self.level + 1
|
self.level = self.level + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:onLineClear(cleared_row_count)
|
function IntervalTrainingGame:onLineClear(cleared_row_count)
|
||||||
|
local cleared_level_bonus = {1, 2, 4, 6}
|
||||||
if not self.clear then
|
if not self.clear then
|
||||||
local new_level = self.level + cleared_row_count
|
local new_level = self.level + cleared_level_bonus[cleared_row_count]
|
||||||
self:updateSectionTimes(self.level, new_level)
|
self:updateSectionTimes(self.level, new_level)
|
||||||
self.level = math.min(new_level, 999)
|
self.level = math.min(new_level, 999)
|
||||||
if self.level == 999 then
|
if self.level == 999 then
|
||||||
@@ -97,12 +104,10 @@ function IntervalTrainingGame:updateSectionTimes(old_level, new_level)
|
|||||||
-- record new section
|
-- record new section
|
||||||
table.insert(self.section_times, self:getSectionTime())
|
table.insert(self.section_times, self:getSectionTime())
|
||||||
self.section_start_time = self.frames
|
self.section_start_time = self.frames
|
||||||
else
|
|
||||||
self.level = math.min(new_level, 999)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function IntervalTrainingGame:drawGrid(ruleset)
|
function IntervalTrainingGame:drawGrid()
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -123,7 +128,7 @@ function IntervalTrainingGame:drawScoringInfo()
|
|||||||
strTrueValues(self.prev_inputs)
|
strTrueValues(self.prev_inputs)
|
||||||
)
|
)
|
||||||
love.graphics.printf("NEXT", 64, 40, 40, "left")
|
love.graphics.printf("NEXT", 64, 40, 40, "left")
|
||||||
love.graphics.printf("TIME LEFT", 240, 250, 80, "left")
|
if not self.clear then love.graphics.printf("TIME LEFT", 240, 250, 80, "left") end
|
||||||
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
||||||
|
|
||||||
local current_section = math.floor(self.level / 100) + 1
|
local current_section = math.floor(self.level / 100) + 1
|
||||||
@@ -134,10 +139,10 @@ function IntervalTrainingGame:drawScoringInfo()
|
|||||||
|
|
||||||
-- draw time left, flash red if necessary
|
-- draw time left, flash red if necessary
|
||||||
local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0)
|
local time_left = self.section_time_limit - math.max(self:getSectionTime(), 0)
|
||||||
if not self.game_over and not self.clear and time_left < frameTime(0,10) and time_left % 4 < 2 then
|
if not self.game_over and time_left < frameTime(0,10) and time_left % 4 < 2 then
|
||||||
love.graphics.setColor(1, 0.3, 0.3, 1)
|
love.graphics.setColor(1, 0.3, 0.3, 1)
|
||||||
end
|
end
|
||||||
love.graphics.printf(formatTime(time_left), 240, 270, 160, "left")
|
if not self.clear then love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") end
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ function Marathon2020Game:new()
|
|||||||
self.grade_points = 0
|
self.grade_points = 0
|
||||||
self.grade_point_decay_counter = 0
|
self.grade_point_decay_counter = 0
|
||||||
self.max_grade_points = 0
|
self.max_grade_points = 0
|
||||||
|
|
||||||
|
self.cool_timer = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function Marathon2020Game:getARE()
|
function Marathon2020Game:getARE()
|
||||||
@@ -327,6 +329,7 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
|||||||
self.section_cool_count = self.section_cool_count + 1
|
self.section_cool_count = self.section_cool_count + 1
|
||||||
self.delay_level = math.min(20, self.delay_level + 1)
|
self.delay_level = math.min(20, self.delay_level + 1)
|
||||||
table.insert(self.section_status, "cool")
|
table.insert(self.section_status, "cool")
|
||||||
|
self.cool_timer = 300
|
||||||
end
|
end
|
||||||
|
|
||||||
local section = getSectionForLevel(old_level)
|
local section = getSectionForLevel(old_level)
|
||||||
@@ -430,6 +433,11 @@ function Marathon2020Game:drawScoringInfo()
|
|||||||
|
|
||||||
self:drawSectionTimesWithSecondary(current_section)
|
self:drawSectionTimesWithSecondary(current_section)
|
||||||
|
|
||||||
|
if (self.cool_timer > 0) then
|
||||||
|
love.graphics.printf("COOL!!", 64, 400, 160, "center")
|
||||||
|
self.cool_timer = self.cool_timer - 1
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self:getTotalGrade(), text_x, 120, 90, "left")
|
love.graphics.printf(self:getTotalGrade(), text_x, 120, 90, "left")
|
||||||
love.graphics.printf(self.grade_points, text_x, 220, 90, "left")
|
love.graphics.printf(self.grade_points, text_x, 220, 90, "left")
|
||||||
|
|||||||
@@ -137,15 +137,15 @@ function MarathonA1Game:onLineClear(cleared_row_count)
|
|||||||
self:checkGMRequirements(self.level, self.level + cleared_row_count)
|
self:checkGMRequirements(self.level, self.level + cleared_row_count)
|
||||||
if not self.clear then
|
if not self.clear then
|
||||||
local new_level = math.min(self.level + cleared_row_count, 999)
|
local new_level = math.min(self.level + cleared_row_count, 999)
|
||||||
if self.level == 999 then
|
if new_level == 999 then
|
||||||
self.clear = true
|
self.clear = true
|
||||||
else
|
|
||||||
self.level = new_level
|
|
||||||
end
|
end
|
||||||
|
self.level = new_level
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines)
|
function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if self.grid:checkForBravo(cleared_lines) then
|
if self.grid:checkForBravo(cleared_lines) then
|
||||||
self.bravo = 4
|
self.bravo = 4
|
||||||
self.bravos = self.bravos + 1
|
self.bravos = self.bravos + 1
|
||||||
@@ -156,25 +156,25 @@ function MarathonA1Game:updateScore(level, drop_bonus, cleared_lines)
|
|||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * self.combo * self.bravo
|
cleared_lines * self.combo * self.bravo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA1Game:checkGMRequirements(old_level, new_level)
|
function MarathonA1Game:checkGMRequirements(old_level, new_level)
|
||||||
if old_level < 300 and new_level >= 300 then
|
if old_level < 300 and new_level >= 300 then
|
||||||
if self.score > 12000 and self.frames <= frameTime(4,15) then
|
if self.score >= 12000 and self.frames <= frameTime(4,15) then
|
||||||
self.gm_conditions["level300"] = true
|
self.gm_conditions["level300"] = true
|
||||||
end
|
end
|
||||||
elseif old_level < 500 and new_level >= 500 then
|
elseif old_level < 500 and new_level >= 500 then
|
||||||
if self.score > 40000 and self.frames <= frameTime(7,30) then
|
if self.score >= 40000 and self.frames <= frameTime(7,30) then
|
||||||
self.gm_conditions["level500"] = true
|
self.gm_conditions["level500"] = true
|
||||||
end
|
end
|
||||||
elseif old_level < 999 and new_level >= 999 then
|
elseif old_level < 999 and new_level >= 999 then
|
||||||
if self.score > 126000 and self.frames <= frameTime(13,30) then
|
if self.score >= 126000 and self.frames <= frameTime(13,30) then
|
||||||
self.gm_conditions["level900"] = true
|
self.gm_conditions["level999"] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -210,7 +210,7 @@ function MarathonA1Game:drawScoringInfo()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self.score, 240, 220, 90, "left")
|
love.graphics.printf(self.score, 240, 220, 90, "left")
|
||||||
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level900"] then
|
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level999"] then
|
||||||
love.graphics.printf("GM", 240, 140, 90, "left")
|
love.graphics.printf("GM", 240, 140, 90, "left")
|
||||||
else
|
else
|
||||||
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")
|
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ function MarathonA2Game:new()
|
|||||||
"GM"
|
"GM"
|
||||||
}
|
}
|
||||||
|
|
||||||
self.randomizer = History6RollsRandomizer()
|
|
||||||
|
|
||||||
self.lock_drop = false
|
self.lock_drop = false
|
||||||
self.enable_hold = false
|
self.enable_hold = false
|
||||||
self.next_queue_length = 1
|
self.next_queue_length = 1
|
||||||
@@ -109,6 +107,7 @@ end
|
|||||||
function MarathonA2Game:advanceOneFrame()
|
function MarathonA2Game:advanceOneFrame()
|
||||||
if self.clear then
|
if self.clear then
|
||||||
self.roll_frames = self.roll_frames + 1
|
self.roll_frames = self.roll_frames + 1
|
||||||
|
if self.roll_frames < 0 then return false end
|
||||||
if self.roll_frames > 3694 then
|
if self.roll_frames > 3694 then
|
||||||
self.completed = true
|
self.completed = true
|
||||||
if self.grade == 32 then
|
if self.grade == 32 then
|
||||||
@@ -127,33 +126,31 @@ function MarathonA2Game:onPieceEnter()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA2Game:onLineClear(cleared_row_count)
|
|
||||||
self:updateSectionTimes(self.level, self.level + cleared_row_count)
|
|
||||||
self.level = math.min(self.level + cleared_row_count, 999)
|
|
||||||
if self.level == 999 and not self.clear then
|
|
||||||
self.clear = true
|
|
||||||
if self:qualifiesForMRoll() then
|
|
||||||
self.grade = 32
|
|
||||||
end
|
|
||||||
self.grid:clear()
|
|
||||||
self.roll_frames = -150
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
|
function MarathonA2Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
self:updateGrade(cleared_lines)
|
self:updateGrade(cleared_lines)
|
||||||
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
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + 2 * drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * self.combo * self.bravo
|
cleared_lines * self.combo * self.bravo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + (cleared_lines - 1) * 2
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
else self.lines = self.lines + cleared_lines end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MarathonA2Game:onLineClear(cleared_row_count)
|
||||||
|
self.level = math.min(self.level + cleared_row_count, 999)
|
||||||
|
if self.level == 999 and not self.clear then
|
||||||
|
self.clear = true
|
||||||
|
self.grid:clear()
|
||||||
|
if self:qualifiesForMRoll() then self.grade = 32 end
|
||||||
|
self.roll_frames = -150
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA2Game:updateSectionTimes(old_level, new_level)
|
function MarathonA2Game:updateSectionTimes(old_level, new_level)
|
||||||
@@ -253,7 +250,7 @@ function MarathonA2Game:updateGrade(cleared_lines)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }
|
local tetris_requirements = { [0] = 2, 2, 2, 2, 2, 1, 1, 1, 1, 0 }
|
||||||
|
|
||||||
function MarathonA2Game:qualifiesForMRoll()
|
function MarathonA2Game:qualifiesForMRoll()
|
||||||
if not self.clear then return false end
|
if not self.clear then return false end
|
||||||
@@ -280,7 +277,7 @@ function MarathonA2Game:qualifiesForMRoll()
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self.grade < 17 or self.frames > frameTime(9,30) then
|
if self.grade < 31 or self.frames > frameTime(8,45) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@@ -344,7 +341,17 @@ function MarathonA2Game:drawScoringInfo()
|
|||||||
end
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
if self.clear then
|
||||||
|
if self:qualifiesForMRoll() then
|
||||||
|
if self.lines >= 32 and self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
|
||||||
|
else love.graphics.setColor(0, 1, 0, 1) end
|
||||||
|
else
|
||||||
|
if self.roll_frames > 3694 then love.graphics.setColor(1, 0.5, 0, 1)
|
||||||
|
else love.graphics.setColor(0, 1, 0, 1) end
|
||||||
|
end
|
||||||
|
end
|
||||||
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.printf(self.score, 240, 220, 90, "left")
|
love.graphics.printf(self.score, 240, 220, 90, "left")
|
||||||
love.graphics.printf(self.level, 240, 340, 40, "right")
|
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ function MarathonA3Game:new()
|
|||||||
self.section_start_time = 0
|
self.section_start_time = 0
|
||||||
self.section_70_times = { [0] = 0 }
|
self.section_70_times = { [0] = 0 }
|
||||||
self.section_times = { [0] = 0 }
|
self.section_times = { [0] = 0 }
|
||||||
|
self.section_cool = false
|
||||||
|
|
||||||
self.randomizer = History6RollsRandomizer()
|
self.randomizer = History6RollsRandomizer()
|
||||||
|
|
||||||
@@ -45,6 +46,8 @@ self.SGnames = {
|
|||||||
|
|
||||||
self.coolregret_message = "COOL!!"
|
self.coolregret_message = "COOL!!"
|
||||||
self.coolregret_timer = 0
|
self.coolregret_timer = 0
|
||||||
|
|
||||||
|
self.torikan_passed = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA3Game:getARE()
|
function MarathonA3Game:getARE()
|
||||||
@@ -149,6 +152,7 @@ function MarathonA3Game:onPieceEnter()
|
|||||||
self:updateSectionTimes(self.level, self.level + 1)
|
self:updateSectionTimes(self.level, self.level + 1)
|
||||||
self.level = self.level + 1
|
self.level = self.level + 1
|
||||||
self.speed_level = self.speed_level + 1
|
self.speed_level = self.speed_level + 1
|
||||||
|
self.torikan_passed = self.level >= 500 and true or false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -166,6 +170,10 @@ function MarathonA3Game:onLineClear(cleared_row_count)
|
|||||||
self.grid:clear()
|
self.grid:clear()
|
||||||
self.roll_frames = -150
|
self.roll_frames = -150
|
||||||
end
|
end
|
||||||
|
if not self.torikan_passed and self.level >= 500 and self.frames >= 25200 then
|
||||||
|
self.level = 500
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local cool_cutoffs = {
|
local cool_cutoffs = {
|
||||||
@@ -188,49 +196,54 @@ function MarathonA3Game:updateSectionTimes(old_level, new_level)
|
|||||||
table.insert(self.section_times, section_time)
|
table.insert(self.section_times, section_time)
|
||||||
self.section_start_time = self.frames
|
self.section_start_time = self.frames
|
||||||
|
|
||||||
|
self.speed_level = self.section_cool and self.speed_level + 100 or self.speed_level
|
||||||
|
|
||||||
if section_time > regret_cutoffs[section] then
|
if section_time > regret_cutoffs[section] then
|
||||||
self.section_cool_grade = self.section_cool_grade - 1
|
self.section_cool_grade = self.section_cool_grade - 1
|
||||||
table.insert(self.section_status, "regret")
|
table.insert(self.section_status, "regret")
|
||||||
self.coolregret_message = "REGRET!!"
|
self.coolregret_message = "REGRET!!"
|
||||||
self.coolregret_timer = 300
|
self.coolregret_timer = 300
|
||||||
elseif section <= 9 and self.section_status[section - 1] == "cool" and
|
elseif self.section_cool then
|
||||||
self.section_70_times[section] < self.section_70_times[section - 1] + 120 then
|
|
||||||
self.section_cool_grade = self.section_cool_grade + 1
|
self.section_cool_grade = self.section_cool_grade + 1
|
||||||
self.speed_level = self.speed_level + 100
|
|
||||||
table.insert(self.section_status, "cool")
|
table.insert(self.section_status, "cool")
|
||||||
self.coolregret_message = "COOL!!"
|
|
||||||
self.coolregret_timer = 300
|
|
||||||
elseif self.section_status[section - 1] == "cool" then
|
|
||||||
table.insert(self.section_status, "none")
|
|
||||||
elseif section <= 9 and self.section_70_times[section] < cool_cutoffs[section] then
|
|
||||||
self.section_cool_grade = self.section_cool_grade + 1
|
|
||||||
self.speed_level = self.speed_level + 100
|
|
||||||
table.insert(self.section_status, "cool")
|
|
||||||
self.coolregret_message = "COOL!!"
|
|
||||||
self.coolregret_timer = 300
|
|
||||||
else
|
else
|
||||||
table.insert(self.section_status, "none")
|
table.insert(self.section_status, "none")
|
||||||
end
|
end
|
||||||
elseif section <= 9 and old_level % 100 < 70 and new_level % 100 >= 70 then
|
|
||||||
|
self.section_cool = false
|
||||||
|
elseif old_level % 100 < 70 and new_level % 100 >= 70 then
|
||||||
-- record section 70 time
|
-- record section 70 time
|
||||||
section_70_time = self.frames - self.section_start_time
|
section_70_time = self.frames - self.section_start_time
|
||||||
table.insert(self.section_70_times, section_70_time)
|
table.insert(self.section_70_times, section_70_time)
|
||||||
|
|
||||||
|
if section <= 9 and self.section_status[section - 1] == "cool" and
|
||||||
|
self.section_70_times[section] < self.section_70_times[section - 1] + 120 then
|
||||||
|
self.section_cool = true
|
||||||
|
self.coolregret_message = "COOL!!"
|
||||||
|
self.coolregret_timer = 300
|
||||||
|
elseif self.section_status[section - 1] == "cool" then self.section_cool = false
|
||||||
|
elseif section <= 9 and self.section_70_times[section] < cool_cutoffs[section] then
|
||||||
|
self.section_cool = true
|
||||||
|
self.coolregret_message = "COOL!!"
|
||||||
|
self.coolregret_timer = 300
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines)
|
function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
self:updateGrade(cleared_lines)
|
self:updateGrade(cleared_lines)
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local grade_point_bonuses = {
|
local grade_point_bonuses = {
|
||||||
@@ -423,7 +436,7 @@ function MarathonA3Game:drawScoringInfo()
|
|||||||
current_x = section_70_x
|
current_x = section_70_x
|
||||||
end
|
end
|
||||||
|
|
||||||
love.graphics.printf(formatTime(self.frames - self.section_start_time), current_x, 40 + 20 * current_section, 90, "left")
|
if not self.clear then love.graphics.printf(formatTime(self.frames - self.section_start_time), current_x, 40 + 20 * current_section, 90, "left") end
|
||||||
|
|
||||||
if(self.coolregret_timer > 0) then
|
if(self.coolregret_timer > 0) then
|
||||||
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
|
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
|
||||||
@@ -432,7 +445,10 @@ function MarathonA3Game:drawScoringInfo()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self.score, 240, 220, 90, "left")
|
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.clear then love.graphics.setColor(0, 1, 0, 1) end
|
||||||
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
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")
|
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||||
if sg >= 5 then
|
if sg >= 5 then
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ function MarathonAX4Game:onLineClear(cleared_row_count)
|
|||||||
self:updateSectionTimes(self.lines, new_lines)
|
self:updateSectionTimes(self.lines, new_lines)
|
||||||
self.lines = math.min(new_lines, 150)
|
self.lines = math.min(new_lines, 150)
|
||||||
if self.lines == 150 then
|
if self.lines == 150 then
|
||||||
|
self.grid:clear()
|
||||||
self.clear = true
|
self.clear = true
|
||||||
self.roll_frames = -150
|
self.roll_frames = -150
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -117,17 +117,18 @@ function PhantomManiaGame:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function PhantomManiaGame:updateScore(level, drop_bonus, cleared_lines)
|
function PhantomManiaGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
PhantomManiaGame.rollOpacityFunction = function(age)
|
PhantomManiaGame.rollOpacityFunction = function(age)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ PhantomMania2Game.tagline = "The blocks disappear even faster now! Can you make
|
|||||||
|
|
||||||
function PhantomMania2Game:new()
|
function PhantomMania2Game:new()
|
||||||
PhantomMania2Game.super:new()
|
PhantomMania2Game.super:new()
|
||||||
self.level = 0
|
|
||||||
self.grade = 0
|
self.grade = 0
|
||||||
self.garbage = 0
|
self.garbage = 0
|
||||||
self.clear = false
|
self.clear = false
|
||||||
@@ -38,6 +37,9 @@ function PhantomMania2Game:new()
|
|||||||
self.lock_drop = true
|
self.lock_drop = true
|
||||||
self.enable_hold = true
|
self.enable_hold = true
|
||||||
self.next_queue_length = 3
|
self.next_queue_length = 3
|
||||||
|
|
||||||
|
self.coolregret_message = ""
|
||||||
|
self.coolregret_timer = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function PhantomMania2Game:getARE()
|
function PhantomMania2Game:getARE()
|
||||||
@@ -179,17 +181,18 @@ function PhantomMania2Game:onHold()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function PhantomMania2Game:updateScore(level, drop_bonus, cleared_lines)
|
function PhantomMania2Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -213,8 +216,13 @@ function PhantomMania2Game:updateSectionTimes(old_level, new_level)
|
|||||||
self.section_start_time = self.frames
|
self.section_start_time = self.frames
|
||||||
if section_time <= cool_cutoffs[section] then
|
if section_time <= cool_cutoffs[section] then
|
||||||
self.grade = self.grade + 2
|
self.grade = self.grade + 2
|
||||||
|
self.coolregret_message = "COOL!!"
|
||||||
|
self.coolregret_timer = 300
|
||||||
elseif section_time <= regret_cutoffs[section] then
|
elseif section_time <= regret_cutoffs[section] then
|
||||||
self.grade = self.grade + 1
|
self.grade = self.grade + 1
|
||||||
|
else
|
||||||
|
self.coolregret_message = "REGRET!!"
|
||||||
|
self.coolregret_timer = 300
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -296,6 +304,11 @@ function PhantomMania2Game:drawScoringInfo()
|
|||||||
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
|
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if(self.coolregret_timer > 0) then
|
||||||
|
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
|
||||||
|
self.coolregret_timer = self.coolregret_timer - 1
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left")
|
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.score, text_x, 220, 90, "left")
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ function Race40Game:new()
|
|||||||
|
|
||||||
self.roll_frames = 0
|
self.roll_frames = 0
|
||||||
|
|
||||||
|
self.SGnames = {
|
||||||
|
[0] = "",
|
||||||
|
"9", "8", "7", "6", "5", "4", "3", "2", "1",
|
||||||
|
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
|
||||||
|
"GM"
|
||||||
|
}
|
||||||
|
self.upstacked = false
|
||||||
|
|
||||||
self.lock_drop = true
|
self.lock_drop = true
|
||||||
self.lock_hard_drop = true
|
self.lock_hard_drop = true
|
||||||
self.instant_hard_drop = true
|
self.instant_hard_drop = true
|
||||||
@@ -35,7 +43,7 @@ function Race40Game:getDropSpeed()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getARR()
|
function Race40Game:getARR()
|
||||||
return 0
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getARE()
|
function Race40Game:getARE()
|
||||||
@@ -47,7 +55,7 @@ function Race40Game:getLineARE()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getDasLimit()
|
function Race40Game:getDasLimit()
|
||||||
return 6
|
return 10
|
||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getLineClearDelay()
|
function Race40Game:getLineClearDelay()
|
||||||
@@ -55,7 +63,7 @@ function Race40Game:getLineClearDelay()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getLockDelay()
|
function Race40Game:getLockDelay()
|
||||||
return 15
|
return 30
|
||||||
end
|
end
|
||||||
|
|
||||||
function Race40Game:getGravity()
|
function Race40Game:getGravity()
|
||||||
@@ -102,6 +110,12 @@ function Race40Game:getHighscoreData()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Race40Game:getSecretGrade(sg)
|
||||||
|
if sg == 19 then self.upstacked = true end
|
||||||
|
if self.upstacked then return self.SGnames[14 + math.floor((20 - sg) / 4)]
|
||||||
|
else return self.SGnames[math.floor((sg / 19) * 14)] end
|
||||||
|
end
|
||||||
|
|
||||||
function Race40Game:drawScoringInfo()
|
function Race40Game:drawScoringInfo()
|
||||||
Race40Game.super.drawScoringInfo(self)
|
Race40Game.super.drawScoringInfo(self)
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
@@ -113,10 +127,17 @@ function Race40Game:drawScoringInfo()
|
|||||||
love.graphics.printf("LINES", text_x, 320, 40, "left")
|
love.graphics.printf("LINES", text_x, 320, 40, "left")
|
||||||
love.graphics.printf("line/min", text_x, 160, 80, "left")
|
love.graphics.printf("line/min", text_x, 160, 80, "left")
|
||||||
love.graphics.printf("piece/sec", text_x, 220, 80, "left")
|
love.graphics.printf("piece/sec", text_x, 220, 80, "left")
|
||||||
|
local sg = self.grid:checkSecretGrade()
|
||||||
|
if sg >= 7 or self.upstacked then
|
||||||
|
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(string.format("%.02f", self.lines / math.max(1, self.frames) * 3600), text_x, 180, 80, "left")
|
love.graphics.printf(string.format("%.02f", self.lines / math.max(1, self.frames) * 3600), text_x, 180, 80, "left")
|
||||||
love.graphics.printf(string.format("%.04f", self.pieces / math.max(1, self.frames) * 60), text_x, 240, 80, "left")
|
love.graphics.printf(string.format("%.04f", self.pieces / math.max(1, self.frames) * 60), text_x, 240, 80, "left")
|
||||||
|
if sg >= 7 or self.upstacked then
|
||||||
|
love.graphics.printf(self:getSecretGrade(sg), 240, 450, 180, "left")
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_4)
|
love.graphics.setFont(font_3x5_4)
|
||||||
love.graphics.printf(math.max(0, self.line_goal - self.lines), text_x, 340, 40, "left")
|
love.graphics.printf(math.max(0, self.line_goal - self.lines), text_x, 340, 40, "left")
|
||||||
|
|||||||
189
tetris/modes/scoredrain.lua
Normal file
189
tetris/modes/scoredrain.lua
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
require 'funcs'
|
||||||
|
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
|
||||||
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
||||||
|
|
||||||
|
local ScoreDrainGame = GameMode:extend()
|
||||||
|
|
||||||
|
ScoreDrainGame.name = "Score Drain"
|
||||||
|
ScoreDrainGame.hash = "ScoreDrain"
|
||||||
|
ScoreDrainGame.tagline = "Your score goes down over time! Avoid hitting 0 points, or your game is over!"
|
||||||
|
|
||||||
|
function ScoreDrainGame:new()
|
||||||
|
self.super:new()
|
||||||
|
|
||||||
|
self.score = 2500
|
||||||
|
self.drain_rate = 50
|
||||||
|
self.combo = 1
|
||||||
|
self.randomizer = History6RollsRandomizer()
|
||||||
|
|
||||||
|
self.lock_drop = true
|
||||||
|
self.lock_hard_drop = true
|
||||||
|
self.enable_hold = true
|
||||||
|
self.next_queue_length = 3
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getARE()
|
||||||
|
if self.level < 700 then return 27
|
||||||
|
elseif self.level < 800 then return 18
|
||||||
|
elseif self.level < 1000 then return 14
|
||||||
|
elseif self.level < 1100 then return 8
|
||||||
|
elseif self.level < 1200 then return 7
|
||||||
|
else return 6 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getLineARE()
|
||||||
|
if self.level < 600 then return 27
|
||||||
|
elseif self.level < 700 then return 18
|
||||||
|
elseif self.level < 800 then return 14
|
||||||
|
elseif self.level < 1100 then return 8
|
||||||
|
elseif self.level < 1200 then return 7
|
||||||
|
else return 6 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getDasLimit()
|
||||||
|
if self.level < 500 then return 15
|
||||||
|
elseif self.level < 900 then return 9
|
||||||
|
else return 7 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getLineClearDelay()
|
||||||
|
if self.level < 500 then return 40
|
||||||
|
elseif self.level < 600 then return 25
|
||||||
|
elseif self.level < 700 then return 16
|
||||||
|
elseif self.level < 800 then return 12
|
||||||
|
elseif self.level < 1100 then return 6
|
||||||
|
elseif self.level < 1200 then return 5
|
||||||
|
else return 4 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getLockDelay()
|
||||||
|
if self.level < 900 then return 30
|
||||||
|
elseif self.level < 1100 then return 17
|
||||||
|
else return 15 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getGravity()
|
||||||
|
if (self.level < 30) then return 4/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 < 120) then return 80/256
|
||||||
|
elseif (self.level < 140) then return 96/256
|
||||||
|
elseif (self.level < 160) then return 112/256
|
||||||
|
elseif (self.level < 170) then return 128/256
|
||||||
|
elseif (self.level < 200) then return 144/256
|
||||||
|
elseif (self.level < 220) then return 4/256
|
||||||
|
elseif (self.level < 230) then return 32/256
|
||||||
|
elseif (self.level < 233) then return 64/256
|
||||||
|
elseif (self.level < 236) then return 96/256
|
||||||
|
elseif (self.level < 239) then return 128/256
|
||||||
|
elseif (self.level < 243) then return 160/256
|
||||||
|
elseif (self.level < 247) then return 192/256
|
||||||
|
elseif (self.level < 251) then return 224/256
|
||||||
|
elseif (self.level < 300) then return 1
|
||||||
|
elseif (self.level < 330) then return 2
|
||||||
|
elseif (self.level < 360) then return 3
|
||||||
|
elseif (self.level < 400) then return 4
|
||||||
|
elseif (self.level < 420) then return 5
|
||||||
|
elseif (self.level < 450) then return 4
|
||||||
|
elseif (self.level < 500) then return 3
|
||||||
|
else return 20
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:advanceOneFrame()
|
||||||
|
if self.ready_frames == 0 then
|
||||||
|
self.frames = self.frames + 1
|
||||||
|
self.score = math.max(0, self.score - self.drain_rate / 60)
|
||||||
|
self.game_over = self.score <= 0 and true or false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:onPieceEnter()
|
||||||
|
if (self.level % 100 ~= 99) and self.frames ~= 0 then
|
||||||
|
self.level = self.level + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local cleared_row_levels = {1, 2, 4, 6}
|
||||||
|
|
||||||
|
function ScoreDrainGame:onLineClear(cleared_row_count)
|
||||||
|
local new_level = self.level + cleared_row_levels[cleared_row_count]
|
||||||
|
self.drain_rate = math.floor(self.level / 100) < math.floor(new_level / 100) and self.drain_rate * 1.5 or self.drain_rate
|
||||||
|
self.level = new_level
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
|
self.score = self.score + (
|
||||||
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
|
cleared_lines * self.combo
|
||||||
|
)
|
||||||
|
else
|
||||||
|
self.combo = 1
|
||||||
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:drawGrid()
|
||||||
|
self.grid:draw()
|
||||||
|
if self.piece ~= nil and self.level < 100 then
|
||||||
|
self:drawGhostPiece(ruleset)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame: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("DRAIN RATE", 240, 90, 80, "left")
|
||||||
|
love.graphics.printf("SCORE", 240, 170, 40, "left")
|
||||||
|
love.graphics.printf("TIME LEFT", 240, 250, 80, "left")
|
||||||
|
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
||||||
|
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.printf(math.floor(self.drain_rate).."/s", 240, 110, 120, "left")
|
||||||
|
local frames_left = self.score / self.drain_rate * 60
|
||||||
|
if frames_left <= 600 and frames_left % 4 < 2 and not self.game_over then love.graphics.setColor(1, 0.3, 0.3, 1) end
|
||||||
|
love.graphics.printf(formatTime(frames_left), 240, 270, 120, "left")
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.printf(math.floor(self.score), 240, 190, 90, "left")
|
||||||
|
love.graphics.printf(self.level, 240, 340, 50, "right")
|
||||||
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 50, "right")
|
||||||
|
|
||||||
|
love.graphics.setFont(font_8x11)
|
||||||
|
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getHighscoreData()
|
||||||
|
return {
|
||||||
|
level = self.level,
|
||||||
|
frames = self.frames,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getSectionEndLevel()
|
||||||
|
return math.floor(self.level / 100 + 1) * 100
|
||||||
|
end
|
||||||
|
|
||||||
|
function ScoreDrainGame:getBackground()
|
||||||
|
return math.floor(self.level / 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ScoreDrainGame
|
||||||
@@ -16,7 +16,6 @@ StrategyGame.tagline = "You have lots of time to think! Can you use it to place
|
|||||||
|
|
||||||
function StrategyGame:new()
|
function StrategyGame:new()
|
||||||
StrategyGame.super:new()
|
StrategyGame.super:new()
|
||||||
self.level = 0
|
|
||||||
self.clear = false
|
self.clear = false
|
||||||
self.completed = false
|
self.completed = false
|
||||||
self.roll_frames = 0
|
self.roll_frames = 0
|
||||||
@@ -84,7 +83,7 @@ function StrategyGame:advanceOneFrame()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:onPieceEnter()
|
function StrategyGame:onPieceEnter()
|
||||||
if (self.level % 100 ~= 99) and not self.clear and self.frames ~= 0 then
|
if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
|
||||||
self.level = self.level + 1
|
self.level = self.level + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -99,17 +98,18 @@ function StrategyGame:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:updateScore(level, drop_bonus, cleared_lines)
|
function StrategyGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:setNextOpacity(i)
|
function StrategyGame:setNextOpacity(i)
|
||||||
@@ -135,11 +135,11 @@ function StrategyGame:drawScoringInfo()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self.score, text_x, 220, 90, "left")
|
love.graphics.printf(self.score, text_x, 220, 90, "left")
|
||||||
love.graphics.printf(self.level, text_x, 340, 50, "right")
|
love.graphics.printf(self.level, text_x, 340, 40, "right")
|
||||||
if self.clear then
|
if self.clear then
|
||||||
love.graphics.printf(self.level, text_x, 370, 50, "right")
|
love.graphics.printf(self.level, text_x, 370, 40, "right")
|
||||||
else
|
else
|
||||||
love.graphics.printf(math.floor(self.level / 100 + 1) * 100, text_x, 370, 50, "right")
|
love.graphics.printf(self.level < 900 and math.floor(self.level / 100 + 1) * 100 or 999, text_x, 370, 40, "right")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -174,17 +174,18 @@ function Survival2020Game:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Survival2020Game:updateScore(level, drop_bonus, cleared_lines)
|
function Survival2020Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Survival2020Game:updateSectionTimes(old_level, new_level)
|
function Survival2020Game:updateSectionTimes(old_level, new_level)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function SurvivalA1Game:onLineClear(cleared_row_count)
|
|||||||
self:checkGMRequirements(self.level, self.level + cleared_row_count)
|
self:checkGMRequirements(self.level, self.level + cleared_row_count)
|
||||||
if not self.clear then
|
if not self.clear then
|
||||||
local new_level = math.min(self.level + cleared_row_count, 999)
|
local new_level = math.min(self.level + cleared_row_count, 999)
|
||||||
if self.level == 999 then
|
if new_level == 999 then
|
||||||
self.clear = true
|
self.clear = true
|
||||||
else
|
else
|
||||||
self.level = new_level
|
self.level = new_level
|
||||||
@@ -118,35 +118,36 @@ function SurvivalA1Game:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA1Game:updateScore(level, drop_bonus, cleared_lines)
|
function SurvivalA1Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if self.grid:checkForBravo(cleared_lines) then
|
if self.grid:checkForBravo(cleared_lines) then
|
||||||
self.bravo = 4
|
self.bravo = 4
|
||||||
self.bravos = self.bravos + 1
|
self.bravos = self.bravos + 1
|
||||||
else self.bravo = 1 end
|
else self.bravo = 1 end
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * self.bravo * self.combo
|
cleared_lines * self.combo * self.bravo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + (cleared_lines - 1) * 2
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA1Game:checkGMRequirements(old_level, new_level)
|
function SurvivalA1Game:checkGMRequirements(old_level, new_level)
|
||||||
if old_level < 300 and new_level >= 300 then
|
if old_level < 300 and new_level >= 300 then
|
||||||
if self.score > 12000 and self.frames <= frameTime(4,15) then
|
if self.score >= 12000 and self.frames <= frameTime(4,15) then
|
||||||
self.gm_conditions["level300"] = true
|
self.gm_conditions["level300"] = true
|
||||||
end
|
end
|
||||||
elseif old_level < 500 and new_level >= 500 then
|
elseif old_level < 500 and new_level >= 500 then
|
||||||
if self.score > 40000 and self.frames <= frameTime(7,30) then
|
if self.score >= 40000 and self.frames <= frameTime(7,30) then
|
||||||
self.gm_conditions["level500"] = true
|
self.gm_conditions["level500"] = true
|
||||||
end
|
end
|
||||||
elseif old_level < 999 and new_level >= 999 then
|
elseif old_level < 999 and new_level >= 999 then
|
||||||
if self.score > 126000 and self.frames <= frameTime(13,30) then
|
if self.score >= 126000 and self.frames <= frameTime(13,30) then
|
||||||
self.gm_conditions["level900"] = true
|
self.gm_conditions["level999"] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -179,7 +180,7 @@ function SurvivalA1Game:drawScoringInfo()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self.score, 240, 220, 90, "left")
|
love.graphics.printf(self.score, 240, 220, 90, "left")
|
||||||
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level900"] then
|
if self.gm_conditions["level300"] and self.gm_conditions["level500"] and self.gm_conditions["level999"] then
|
||||||
love.graphics.printf("GM", 240, 140, 90, "left")
|
love.graphics.printf("GM", 240, 140, 90, "left")
|
||||||
else
|
else
|
||||||
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")
|
love.graphics.printf(getRankForScore(self.score).rank, 240, 140, 90, "left")
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ function SurvivalA2Game:advanceOneFrame()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:onPieceEnter()
|
function SurvivalA2Game:onPieceEnter()
|
||||||
if (self.level % 100 ~= 99 or self.level == 998) and not self.clear and self.frames ~= 0 then
|
if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
|
||||||
self.level = self.level + 1
|
self.level = self.level + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -98,6 +98,9 @@ function SurvivalA2Game:onLineClear(cleared_row_count)
|
|||||||
local new_level = math.min(self.level + cleared_row_count, 999)
|
local new_level = math.min(self.level + cleared_row_count, 999)
|
||||||
if self.level == 999 or self:hitTorikan(self.level, new_level) then
|
if self.level == 999 or self:hitTorikan(self.level, new_level) then
|
||||||
self.clear = true
|
self.clear = true
|
||||||
|
if self.level < 999 then
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self.level = new_level
|
self.level = new_level
|
||||||
end
|
end
|
||||||
@@ -105,23 +108,25 @@ function SurvivalA2Game:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:updateScore(level, drop_bonus, cleared_lines)
|
function SurvivalA2Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
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
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * self.bravo * self.combo
|
cleared_lines * self.combo * self.bravo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + (cleared_lines - 1) * 2
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:getLetterGrade()
|
function SurvivalA2Game:getLetterGrade()
|
||||||
if self.level >= 999 then return "GM"
|
if self.level >= 999 then return "GM"
|
||||||
elseif self.level >= 500 then return "M"
|
elseif self.level > 500 then return "M"
|
||||||
|
elseif self.level == 500 and not self.clear then return "M"
|
||||||
else return "" end
|
else return "" end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -152,6 +157,8 @@ function SurvivalA2Game:drawScoringInfo()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.printf(self.score, text_x, 220, 90, "left")
|
love.graphics.printf(self.score, text_x, 220, 90, "left")
|
||||||
|
if self.roll_frames > 2968 then love.graphics.setColor(1, 0.5, 0, 1)
|
||||||
|
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
|
||||||
if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end
|
if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end
|
||||||
love.graphics.printf(self.level, text_x, 340, 40, "right")
|
love.graphics.printf(self.level, text_x, 340, 40, "right")
|
||||||
love.graphics.printf(self:getSectionEndLevel(), text_x, 370, 40, "right")
|
love.graphics.printf(self:getSectionEndLevel(), text_x, 370, 40, "right")
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ SurvivalA3Game.tagline = "The blocks turn black and white! Can you make it to le
|
|||||||
|
|
||||||
function SurvivalA3Game:new()
|
function SurvivalA3Game:new()
|
||||||
SurvivalA3Game.super:new()
|
SurvivalA3Game.super:new()
|
||||||
self.level = 0
|
|
||||||
self.grade = 0
|
self.grade = 0
|
||||||
self.garbage = 0
|
self.garbage = 0
|
||||||
self.clear = false
|
self.clear = false
|
||||||
@@ -140,20 +139,21 @@ function SurvivalA3Game:onPieceEnter()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local cleared_row_levels = {1, 2, 4, 6}
|
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)
|
function SurvivalA3Game:onLineClear(cleared_row_count)
|
||||||
if not self.clear then
|
if not self.clear then
|
||||||
local new_level = self.level + cleared_row_levels[cleared_row_count]
|
local new_level = self.level + cleared_row_levels[cleared_row_count]
|
||||||
self:updateSectionTimes(self.level, new_level)
|
self:updateSectionTimes(self.level, new_level)
|
||||||
if new_level >= 1300 or self:hitTorikan(self.level, new_level) then
|
if new_level >= 1300 or self:hitTorikan(self.level, new_level) then
|
||||||
|
self.clear = true
|
||||||
if new_level >= 1300 then
|
if new_level >= 1300 then
|
||||||
self.level = 1300
|
self.level = 1300
|
||||||
end
|
|
||||||
self.clear = true
|
|
||||||
self.grid:clear()
|
self.grid:clear()
|
||||||
self.big_mode = true
|
self.big_mode = true
|
||||||
self.roll_frames = -150
|
self.roll_frames = -150
|
||||||
|
else
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self.level = math.min(new_level, 1300)
|
self.level = math.min(new_level, 1300)
|
||||||
end
|
end
|
||||||
@@ -166,17 +166,18 @@ function SurvivalA3Game:onPieceLock(piece, cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA3Game:updateScore(level, drop_bonus, cleared_lines)
|
function SurvivalA3Game:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
if cleared_lines > 0 then
|
if cleared_lines > 0 then
|
||||||
|
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||||
self.score = self.score + (
|
self.score = self.score + (
|
||||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
cleared_lines * (cleared_lines * 2 - 1) * (self.combo * 2 - 1)
|
cleared_lines * self.combo
|
||||||
)
|
)
|
||||||
self.lines = self.lines + cleared_lines
|
|
||||||
self.combo = self.combo + cleared_lines - 1
|
|
||||||
else
|
else
|
||||||
self.drop_bonus = 0
|
|
||||||
self.combo = 1
|
self.combo = 1
|
||||||
end
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA3Game:updateSectionTimes(old_level, new_level)
|
function SurvivalA3Game:updateSectionTimes(old_level, new_level)
|
||||||
@@ -241,7 +242,10 @@ function SurvivalA3Game:drawScoringInfo()
|
|||||||
self:drawSectionTimesWithSplits(current_section)
|
self:drawSectionTimesWithSplits(current_section)
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1)
|
||||||
|
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
|
||||||
love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left")
|
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")
|
love.graphics.printf(self.score, text_x, 220, 90, "left")
|
||||||
love.graphics.printf(self.level, text_x, 340, 50, "right")
|
love.graphics.printf(self.level, text_x, 340, 50, "right")
|
||||||
if self.clear then
|
if self.clear then
|
||||||
|
|||||||
209
tetris/modes/tgmplus.lua
Normal file
209
tetris/modes/tgmplus.lua
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
require 'funcs'
|
||||||
|
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
|
||||||
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls'
|
||||||
|
|
||||||
|
local TGMPlusGame = GameMode:extend()
|
||||||
|
|
||||||
|
TGMPlusGame.name = "Marathon A2+"
|
||||||
|
TGMPlusGame.hash = "A2Plus"
|
||||||
|
TGMPlusGame.tagline = "The garbage rises steadily! Can you make it to level 999?"
|
||||||
|
|
||||||
|
function TGMPlusGame:new()
|
||||||
|
TGMPlusGame.super:new()
|
||||||
|
|
||||||
|
self.roll_frames = 0
|
||||||
|
self.combo = 1
|
||||||
|
|
||||||
|
self.SGnames = {
|
||||||
|
"9", "8", "7", "6", "5", "4", "3", "2", "1",
|
||||||
|
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
|
||||||
|
"GM"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.randomizer = History6RollsRandomizer()
|
||||||
|
|
||||||
|
self.lock_drop = false
|
||||||
|
self.enable_hold = false
|
||||||
|
self.next_queue_length = 1
|
||||||
|
|
||||||
|
self.garbage_queue = 0
|
||||||
|
self.garbage_pos = 0
|
||||||
|
self.garbage_rows = {
|
||||||
|
[0] = {"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"e", "e", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"e", "b", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "e", "e"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "b", "e"},
|
||||||
|
{"b", "b", "e", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "e", "e", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "e", "b", "b", "b", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "e", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "e", "e", "b"},
|
||||||
|
{"b", "b", "b", "b", "b", "b", "b", "b", "e", "b"},
|
||||||
|
{"b", "b", "b", "b", "e", "e", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "e", "e", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "b", "e", "b", "b", "b", "b", "b"},
|
||||||
|
{"b", "b", "b", "e", "e", "e", "b", "b", "b", "b"},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:getARE() return 25 end
|
||||||
|
function TGMPlusGame:getDasLimit() return 15 end
|
||||||
|
function TGMPlusGame:getLockDelay() return 30 end
|
||||||
|
function TGMPlusGame:getLineClearDelay() return 40 end
|
||||||
|
|
||||||
|
function TGMPlusGame:getGravity()
|
||||||
|
if (self.level < 30) then return 4/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 < 120) then return 80/256
|
||||||
|
elseif (self.level < 140) then return 96/256
|
||||||
|
elseif (self.level < 160) then return 112/256
|
||||||
|
elseif (self.level < 170) then return 128/256
|
||||||
|
elseif (self.level < 200) then return 144/256
|
||||||
|
elseif (self.level < 220) then return 4/256
|
||||||
|
elseif (self.level < 230) then return 32/256
|
||||||
|
elseif (self.level < 233) then return 64/256
|
||||||
|
elseif (self.level < 236) then return 96/256
|
||||||
|
elseif (self.level < 239) then return 128/256
|
||||||
|
elseif (self.level < 243) then return 160/256
|
||||||
|
elseif (self.level < 247) then return 192/256
|
||||||
|
elseif (self.level < 251) then return 224/256
|
||||||
|
elseif (self.level < 300) then return 1
|
||||||
|
elseif (self.level < 330) then return 2
|
||||||
|
elseif (self.level < 360) then return 3
|
||||||
|
elseif (self.level < 400) then return 4
|
||||||
|
elseif (self.level < 420) then return 5
|
||||||
|
elseif (self.level < 450) then return 4
|
||||||
|
elseif (self.level < 500) then return 3
|
||||||
|
else return 20
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:getGarbageLimit() return 13 - math.floor(self.level / 100) end
|
||||||
|
|
||||||
|
function TGMPlusGame:advanceOneFrame()
|
||||||
|
if self.clear then
|
||||||
|
self.roll_frames = self.roll_frames + 1
|
||||||
|
if self.roll_frames > 3694 then
|
||||||
|
self.completed = true
|
||||||
|
end
|
||||||
|
elseif self.ready_frames == 0 then
|
||||||
|
self.frames = self.frames + 1
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:onPieceEnter()
|
||||||
|
if (self.level % 100 ~= 99 and self.level ~= 998) and not self.clear and self.frames ~= 0 then
|
||||||
|
self.level = self.level + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:onPieceLock(piece, cleared_row_count)
|
||||||
|
if cleared_row_count == 0 then self:advanceBottomRow() end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:onLineClear(cleared_row_count)
|
||||||
|
self.level = math.min(self.level + cleared_row_count, 999)
|
||||||
|
if self.level == 999 and not self.clear then self.clear = true end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:advanceBottomRow()
|
||||||
|
self.garbage_queue = self.garbage_queue + 1
|
||||||
|
if self.garbage_queue >= self:getGarbageLimit() then
|
||||||
|
self.grid:garbageRise(self.garbage_rows[self.garbage_pos])
|
||||||
|
self.garbage_queue = 0
|
||||||
|
self.garbage_pos = (self.garbage_pos + 1) % 24
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:updateScore(level, drop_bonus, cleared_lines)
|
||||||
|
if not self.clear then
|
||||||
|
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
|
||||||
|
self.score = self.score + (
|
||||||
|
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||||
|
cleared_lines * self.combo * self.bravo
|
||||||
|
)
|
||||||
|
else
|
||||||
|
self.combo = 1
|
||||||
|
end
|
||||||
|
self.drop_bonus = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:drawGrid(ruleset)
|
||||||
|
self.grid:draw()
|
||||||
|
if self.piece ~= nil and self.level < 100 then
|
||||||
|
self:drawGhostPiece(ruleset)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:getHighscoreData()
|
||||||
|
return {
|
||||||
|
score = self.score,
|
||||||
|
level = self.level,
|
||||||
|
frames = self.frames,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:getSectionEndLevel()
|
||||||
|
if self.level >= 900 then return 999
|
||||||
|
else return math.floor(self.level / 100 + 1) * 100 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame:getBackground()
|
||||||
|
return math.floor(self.level / 100)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TGMPlusGame: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("SCORE", 240, 200, 40, "left")
|
||||||
|
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
||||||
|
local sg = self.grid:checkSecretGrade()
|
||||||
|
if sg >= 5 then
|
||||||
|
love.graphics.printf("SECRET GRADE", 240, 430, 180, "left")
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.printf(self.score, 240, 220, 90, "left")
|
||||||
|
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||||
|
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||||
|
if sg >= 5 then
|
||||||
|
love.graphics.printf(self.SGnames[sg], 240, 450, 180, "left")
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setFont(font_8x11)
|
||||||
|
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return TGMPlusGame
|
||||||
@@ -50,9 +50,6 @@ function PacerTest:new()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function PacerTest:initialize(ruleset)
|
function PacerTest:initialize(ruleset)
|
||||||
for i = 1, 30 do
|
|
||||||
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
|
||||||
end
|
|
||||||
self.level_frames = getLevelFrames(1)
|
self.level_frames = getLevelFrames(1)
|
||||||
switchBGM("pacer_test")
|
switchBGM("pacer_test")
|
||||||
end
|
end
|
||||||
@@ -18,8 +18,6 @@ SRS.colourscheme = {
|
|||||||
SRS.softdrop_lock = false
|
SRS.softdrop_lock = false
|
||||||
SRS.harddrop_lock = true
|
SRS.harddrop_lock = true
|
||||||
|
|
||||||
SRS.enable_IRS_wallkicks = true
|
|
||||||
|
|
||||||
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 },
|
||||||
|
|||||||
173
tetris/rulesets/crap.lua
Normal file
173
tetris/rulesets/crap.lua
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||||
|
|
||||||
|
local CRAP = Ruleset:extend()
|
||||||
|
|
||||||
|
CRAP.name = "C.R.A.P."
|
||||||
|
CRAP.hash = "Completely Random Auto-Positioner"
|
||||||
|
CRAP.world = true
|
||||||
|
CRAP.colors={"C","O","M","R","G","Y","B"}
|
||||||
|
CRAP.colourscheme = {
|
||||||
|
I = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
L = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
J = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
S = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
Z = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
O = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
T = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
}
|
||||||
|
CRAP.softdrop_lock = true
|
||||||
|
CRAP.harddrop_lock = false
|
||||||
|
|
||||||
|
CRAP.enable_IRS_wallkicks = true
|
||||||
|
|
||||||
|
CRAP.spawn_positions = {
|
||||||
|
I = { x=5, y=4 },
|
||||||
|
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 },
|
||||||
|
}
|
||||||
|
|
||||||
|
CRAP.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 },
|
||||||
|
}
|
||||||
|
|
||||||
|
CRAP.block_offsets = {
|
||||||
|
I={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
|
||||||
|
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1} },
|
||||||
|
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2} },
|
||||||
|
},
|
||||||
|
J={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1} },
|
||||||
|
},
|
||||||
|
L={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
},
|
||||||
|
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=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||||
|
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||||
|
},
|
||||||
|
T={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0} },
|
||||||
|
},
|
||||||
|
Z={
|
||||||
|
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||||
|
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0} },
|
||||||
|
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Component functions.
|
||||||
|
|
||||||
|
function CRAP:attemptRotate(new_inputs, piece, grid, initial)
|
||||||
|
local rot_dir = 0
|
||||||
|
|
||||||
|
if (new_inputs["rotate_left"] or new_inputs["rotate_left2"]) then
|
||||||
|
rot_dir = 3
|
||||||
|
elseif (new_inputs["rotate_right"] or new_inputs["rotate_right2"]) then
|
||||||
|
rot_dir = 1
|
||||||
|
elseif (new_inputs["rotate_180"]) then
|
||||||
|
rot_dir = self:get180RotationValue()
|
||||||
|
end
|
||||||
|
|
||||||
|
if rot_dir == 0 then return end
|
||||||
|
if self.world and config.gamesettings.world_reverse == 2 then
|
||||||
|
rot_dir = 4 - rot_dir
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||||
|
|
||||||
|
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
|
||||||
|
for i=1,20 do
|
||||||
|
dx=math.floor(math.random(11))-5
|
||||||
|
dy=math.floor(math.random(11))-5
|
||||||
|
if grid:canPlacePiece(new_piece:withOffset({x=dx, y=dy})) then
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=dx, y=dy})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:onPieceCreate(piece, grid)
|
||||||
|
CRAP:randomizeColours()
|
||||||
|
piece.manipulations = 0
|
||||||
|
piece.rotations = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:onPieceDrop(piece, grid)
|
||||||
|
CRAP:randomizeColours()
|
||||||
|
piece.lock_delay = 0 -- step reset
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:onPieceMove(piece, grid)
|
||||||
|
CRAP:randomizeColours()
|
||||||
|
piece.lock_delay = 0 -- move reset
|
||||||
|
if piece:isDropBlocked(grid) then
|
||||||
|
piece.manipulations = piece.manipulations + 1
|
||||||
|
if piece.manipulations >= 10 then
|
||||||
|
piece.locked = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:onPieceRotate(piece, grid)
|
||||||
|
CRAP:randomizeColours()
|
||||||
|
piece.lock_delay = 0 -- rotate reset
|
||||||
|
if piece:isDropBlocked(grid) then
|
||||||
|
piece.rotations = piece.rotations + 1
|
||||||
|
if piece.rotations >= 8 then
|
||||||
|
piece.locked = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CRAP:get180RotationValue() return 2 end
|
||||||
|
|
||||||
|
function CRAP:randomizeColours()
|
||||||
|
CRAP.colourscheme = {
|
||||||
|
I = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
L = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
J = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
S = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
Z = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
O = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
T = CRAP.colors[math.ceil(math.random(7))],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return CRAP
|
||||||
153
tetris/rulesets/dtet.lua
Normal file
153
tetris/rulesets/dtet.lua
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||||
|
|
||||||
|
local DTET = Ruleset:extend()
|
||||||
|
|
||||||
|
DTET.name = "D.R.S."
|
||||||
|
DTET.hash = "DTET"
|
||||||
|
|
||||||
|
DTET.spawn_positions = {
|
||||||
|
I = { x=5, y=4 },
|
||||||
|
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 },
|
||||||
|
}
|
||||||
|
|
||||||
|
DTET.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 },
|
||||||
|
}
|
||||||
|
|
||||||
|
DTET.block_offsets = {
|
||||||
|
I={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=-1, y=-1}, {x=-1, y=-2}, {x=-1, y=0}, {x=-1, 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=-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} },
|
||||||
|
{ {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} },
|
||||||
|
},
|
||||||
|
L={
|
||||||
|
{ {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} },
|
||||||
|
{ {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} },
|
||||||
|
},
|
||||||
|
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=0}, {x=0, y=0}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=1, y=0}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||||
|
},
|
||||||
|
T={
|
||||||
|
{ {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} },
|
||||||
|
{ {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} },
|
||||||
|
},
|
||||||
|
Z={
|
||||||
|
{ {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||||
|
{ {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=1, y=-2}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- clockwise kicks: {{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
-- counterclockwise kicks: {{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
|
||||||
|
DTET.wallkicks_3x3 = {
|
||||||
|
[0]={
|
||||||
|
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
[1]={
|
||||||
|
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
[2]={
|
||||||
|
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[3]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
},
|
||||||
|
[3]={
|
||||||
|
[0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
DTET.wallkicks_line = {
|
||||||
|
[0]={
|
||||||
|
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
[1]={
|
||||||
|
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
[2]={
|
||||||
|
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
[3]={
|
||||||
|
[0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||||
|
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function DTET:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
|
||||||
|
local kicks
|
||||||
|
if piece.shape == "O" then
|
||||||
|
return
|
||||||
|
elseif piece.shape == "I" then
|
||||||
|
kicks = DTET.wallkicks_line[piece.rotation][new_piece.rotation]
|
||||||
|
else
|
||||||
|
kicks = DTET.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 DTET:onPieceDrop(piece, grid)
|
||||||
|
piece.lock_delay = 0 -- step reset
|
||||||
|
end
|
||||||
|
|
||||||
|
function DTET:getDefaultOrientation() return 1 end
|
||||||
|
|
||||||
|
return DTET
|
||||||
45
tetris/rulesets/eheart.lua
Normal file
45
tetris/rulesets/eheart.lua
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
local ARS = require 'tetris.rulesets.arika'
|
||||||
|
|
||||||
|
local EHeart = ARS:extend()
|
||||||
|
|
||||||
|
EHeart.name = "E-Heart ARS"
|
||||||
|
EHeart.hash = "EHeartARS"
|
||||||
|
|
||||||
|
function EHeart:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
|
||||||
|
-- I and O don't kick
|
||||||
|
if (piece.shape == "I" or piece.shape == "O") then return end
|
||||||
|
|
||||||
|
-- center column rule (kicks)
|
||||||
|
local offsets = new_piece:getBlockOffsets()
|
||||||
|
table.sort(offsets, function(A, B) return A.y < B.y or A.y == B.y and A.x < B.y end)
|
||||||
|
for index, offset in pairs(offsets) do
|
||||||
|
if grid:isOccupied(piece.position.x + offset.x, piece.position.y + offset.y) then
|
||||||
|
-- individual checks for all 9 cells, in the given order
|
||||||
|
if offset.y < 0 then
|
||||||
|
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||||
|
elseif offset.x == 0 then return
|
||||||
|
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||||
|
elseif offset.y == 0 then
|
||||||
|
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||||
|
elseif offset.x == 0 then return
|
||||||
|
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||||
|
elseif offset.y > 0 then
|
||||||
|
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||||
|
elseif offset.x == 0 then return
|
||||||
|
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function EHeart:lateralKick(dx, piece, new_piece, rot_dir, grid)
|
||||||
|
if (grid:canPlacePiece(new_piece:withOffset({x=dx, y=0}))) then
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=dx, y=0})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return EHeart
|
||||||
102
tetris/rulesets/pptprs.lua
Normal file
102
tetris/rulesets/pptprs.lua
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
local Piece = require 'tetris.components.piece'
|
||||||
|
local SRS = require 'tetris.rulesets.standard_exp'
|
||||||
|
|
||||||
|
local PPTPRS = SRS:extend()
|
||||||
|
|
||||||
|
PPTPRS.name = "PPTPRS"
|
||||||
|
PPTPRS.hash = "Puyo Tetris Pentos"
|
||||||
|
|
||||||
|
PPTPRS.block_offsets = {
|
||||||
|
I={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0}, {x=-3, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2}, {x=0, y=-2} },
|
||||||
|
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1}, {x=2, y=1} },
|
||||||
|
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2}, {x=-1, y=3} },
|
||||||
|
},
|
||||||
|
J={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1}, {x=0, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1}, {x=0, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1}, {x=1, y=0} },
|
||||||
|
},
|
||||||
|
L={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1}, {x=-1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1}, {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=1} },
|
||||||
|
},
|
||||||
|
O={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=-1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=-2, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=0} },
|
||||||
|
},
|
||||||
|
S={
|
||||||
|
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0} },
|
||||||
|
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2} },
|
||||||
|
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0}, {x=2, y=0} },
|
||||||
|
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||||
|
},
|
||||||
|
T={
|
||||||
|
{ {x=0, y=0}, {x=-1, 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=1}, {x=1, y=0}, {x=2, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=1, 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=-1}, {x=-1, y=0}, {x=-2, y=0} },
|
||||||
|
},
|
||||||
|
Z={
|
||||||
|
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0}, {x=1, y=1} },
|
||||||
|
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1}, {x=-1, y=1} },
|
||||||
|
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1} },
|
||||||
|
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PPTPRS.wallkicks_O = {
|
||||||
|
[0]={
|
||||||
|
[1]={{x=0, y=1}},
|
||||||
|
[2]={{x=0, y=1}},
|
||||||
|
[3]={{x=-1, y=0}},
|
||||||
|
},
|
||||||
|
[1]={
|
||||||
|
[0]={{x=0, y=-1}},
|
||||||
|
[2]={{x=-1, y=0}},
|
||||||
|
[3]={{x=-1, y=0}},
|
||||||
|
},
|
||||||
|
[2]={
|
||||||
|
[0]={{x=0, y=-1}},
|
||||||
|
[1]={{x=1, y=0}},
|
||||||
|
[3]={{x=0, y=-1}},
|
||||||
|
},
|
||||||
|
[3]={
|
||||||
|
[0]={{x=1, y=0}},
|
||||||
|
[1]={{x=1, y=0}},
|
||||||
|
[2]={{x=0, y=1}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function PPTPRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
local kicks
|
||||||
|
|
||||||
|
if piece.shape == "O" then
|
||||||
|
kicks = PPTPRS.wallkicks_O[piece.rotation][new_piece.rotation]
|
||||||
|
elseif piece.shape == "I" then
|
||||||
|
kicks = SRS.wallkicks_line[piece.rotation][new_piece.rotation]
|
||||||
|
else
|
||||||
|
kicks = SRS.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
|
||||||
|
|
||||||
|
return PPTPRS
|
||||||
@@ -24,6 +24,29 @@ Ruleset.enable_IRS_wallkicks = false
|
|||||||
|
|
||||||
-- Component functions.
|
-- Component functions.
|
||||||
|
|
||||||
|
function Ruleset:new()
|
||||||
|
blocks["bone"] = (not self.world) and
|
||||||
|
{
|
||||||
|
R = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
O = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
Y = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
G = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
C = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
B = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
M = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
X = love.graphics.newImage("res/img/bone.png"),
|
||||||
|
} or {
|
||||||
|
R = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
O = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
Y = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
G = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
C = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
B = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
M = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
X = love.graphics.newImage("res/img/bonew.png"),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial)
|
function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial)
|
||||||
local new_inputs = {}
|
local new_inputs = {}
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,16 @@ SRS.wallkicks_line = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function SRS:check_new_low(piece)
|
||||||
|
for _, block in pairs(piece:getBlockOffsets()) do
|
||||||
|
local y = piece.position.y + block.y
|
||||||
|
if y > piece.lowest_y then
|
||||||
|
piece.manipulations = 0
|
||||||
|
piece.lowest_y = y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Component functions.
|
-- Component functions.
|
||||||
|
|
||||||
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
@@ -159,19 +169,24 @@ function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SRS:onPieceCreate(piece, grid)
|
function SRS:onPieceCreate(piece, grid)
|
||||||
piece.rotate_counter = 0
|
piece.manipulations = 0
|
||||||
piece.move_counter = 0
|
piece.lowest_y = -math.huge
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:onPieceDrop(piece, grid)
|
function SRS:onPieceDrop(piece, grid)
|
||||||
|
self:check_new_low(piece)
|
||||||
|
if piece.manipulations >= 15 and piece:isDropBlocked(grid) then
|
||||||
|
piece.locked = true
|
||||||
|
else
|
||||||
piece.lock_delay = 0 -- step reset
|
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.move_counter = piece.move_counter + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.move_counter >= 24 then
|
if piece.manipulations >= 15 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -179,9 +194,10 @@ end
|
|||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
|
self:check_new_low(piece)
|
||||||
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.rotate_counter = piece.rotate_counter + 1
|
if piece.manipulations >= 15 then
|
||||||
if piece.rotate_counter >= 12 then
|
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ SRS.colourscheme = {
|
|||||||
SRS.softdrop_lock = false
|
SRS.softdrop_lock = false
|
||||||
SRS.harddrop_lock = true
|
SRS.harddrop_lock = true
|
||||||
|
|
||||||
SRS.enable_IRS_wallkicks = true
|
|
||||||
|
|
||||||
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 },
|
||||||
|
|||||||
Reference in New Issue
Block a user