Compare commits
1 Commits
v0.3-beta2
...
highscore_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f570306f5 |
@@ -3,11 +3,19 @@ Game modes
|
|||||||
|
|
||||||
There are several classes of game modes. The modes that originate from other games are organized by suffix:
|
There are several classes of game modes. The modes that originate from other games are organized by suffix:
|
||||||
|
|
||||||
|
* The "C" series stand for "Classic" games, games that were produced before around 1992-1993 and generally have no wallkicks or lock delay.
|
||||||
|
* C84 - The original version from the Electronika 60.
|
||||||
|
* C88 - Sega Tetris.
|
||||||
|
* C89 - Nintendo / NES Tetris.
|
||||||
* The "A" series stand for "Arika" games, or games in the Tetris the Grand Master series.
|
* The "A" series stand for "Arika" games, or games in the Tetris the Grand Master series.
|
||||||
* A1 - Tetris The Grand Master (the original from 1998).
|
* A1 - Tetris The Grand Master (the original from 1998).
|
||||||
* A2 - Tetris The Absolute The Grand Master 2 PLUS.
|
* A2 - Tetris The Absolute The Grand Master 2 PLUS.
|
||||||
* A3 - Tetris The Grand Master 3 Terror-Instinct.
|
* A3 - Tetris The Grand Master 3 Terror-Instinct.
|
||||||
* AX - Tetris The Grand Master ACE (X for Xbox).
|
* AX - Tetris The Grand Master ACE (X for Xbox).
|
||||||
|
* The "G" series stand for "Guideline" games, or games that follow the Tetris Guideline.
|
||||||
|
* GF - Tetris Friends (2007-2019)
|
||||||
|
* GJ - Tetris Online Japan (2005-2011)
|
||||||
|
* N stands for Nullpomino, only used for Phantom Mania N.
|
||||||
|
|
||||||
MARATHON
|
MARATHON
|
||||||
--------
|
--------
|
||||||
@@ -20,6 +28,8 @@ From other games:
|
|||||||
* **MARATHON A1**: Tetris the Grand Master 1.
|
* **MARATHON A1**: Tetris the Grand Master 1.
|
||||||
* **MARATHON A2**: Tetris the Grand Master 2 (TAP Master).
|
* **MARATHON A2**: Tetris the Grand Master 2 (TAP Master).
|
||||||
* **MARATHON A3**: Tetris the Grand Master 3 (no exams).
|
* **MARATHON A3**: Tetris the Grand Master 3 (no exams).
|
||||||
|
* **MARATHON AX4**: Another mode from TGM Ace.
|
||||||
|
* **MARATHON C89**: Nintendo NES Tetris. Can you transition and make it to the killscreen?
|
||||||
|
|
||||||
|
|
||||||
SURVIVAL
|
SURVIVAL
|
||||||
@@ -33,7 +43,14 @@ From other games:
|
|||||||
* **SURVIVAL A1**: 20G mode from Tetris the Grand Master.
|
* **SURVIVAL A1**: 20G mode from Tetris the Grand Master.
|
||||||
* **SURVIVAL A2**: T.A. Death.
|
* **SURVIVAL A2**: T.A. Death.
|
||||||
* **SURVIVAL A3**: Ti Shirase.
|
* **SURVIVAL A3**: Ti Shirase.
|
||||||
* **SURVIVAL AX**: Another mode from TGM Ace.
|
|
||||||
|
|
||||||
|
RACE
|
||||||
|
----
|
||||||
|
|
||||||
|
Modes with no levels, just a single timed goal.
|
||||||
|
|
||||||
|
* **Race 40**: How fast can you clear 40 lines? No limits, no holds barred.
|
||||||
|
|
||||||
|
|
||||||
PHANTOM MANIA
|
PHANTOM MANIA
|
||||||
@@ -52,4 +69,8 @@ OTHER MODES
|
|||||||
|
|
||||||
* **Strategy**: How well can you plan ahead your movements? Can you handle only having a short time to place each piece?
|
* **Strategy**: How well can you plan ahead your movements? Can you handle only having a short time to place each piece?
|
||||||
|
|
||||||
* **Big A2**: Marathon A2 but all the pieces are BIG!
|
* **TetrisGram™ Pacer Test**: is a multi-stage piece-placing ability test that progressively gets more difficult as it continues.
|
||||||
|
|
||||||
|
* **Interval Training**: 30 seconds per section. 20G. 15 frames of lock delay. How long can you last?
|
||||||
|
|
||||||
|
* **Demon Mode**: An original mode from Oshisaure! Can you push through the ever faster levels and not get denied?
|
||||||
12
funcs.lua
@@ -80,13 +80,9 @@ end
|
|||||||
|
|
||||||
function table.contains(table, element)
|
function table.contains(table, element)
|
||||||
for _, value in pairs(table) do
|
for _, value in pairs(table) do
|
||||||
if value == element then
|
if value == element then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function clamp(a, b, c)
|
|
||||||
return math.min(a, math.max(b, c))
|
|
||||||
end
|
|
||||||
@@ -63,6 +63,9 @@ function bigint.new(num)
|
|||||||
end,
|
end,
|
||||||
__le = function(lhs, rhs)
|
__le = function(lhs, rhs)
|
||||||
return bigint.compare(lhs, rhs, "<=")
|
return bigint.compare(lhs, rhs, "<=")
|
||||||
|
end,
|
||||||
|
__tostring = function()
|
||||||
|
return bigint.unserialize(self, "s")
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
27
main.lua
@@ -15,9 +15,6 @@ function love.load()
|
|||||||
config["fullscreen"] = false
|
config["fullscreen"] = false
|
||||||
|
|
||||||
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
|
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
|
||||||
|
|
||||||
-- used for screenshots
|
|
||||||
GLOBAL_CANVAS = love.graphics.newCanvas()
|
|
||||||
|
|
||||||
-- init config
|
-- init config
|
||||||
if not config.das then config.das = 10 end
|
if not config.das then config.das = 10 end
|
||||||
@@ -111,10 +108,7 @@ function love.update(dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function love.draw()
|
function love.draw()
|
||||||
love.graphics.setCanvas(GLOBAL_CANVAS)
|
love.graphics.push()
|
||||||
love.graphics.clear()
|
|
||||||
|
|
||||||
love.graphics.push()
|
|
||||||
|
|
||||||
-- get offset matrix
|
-- get offset matrix
|
||||||
love.graphics.setDefaultFilter("linear", "nearest")
|
love.graphics.setDefaultFilter("linear", "nearest")
|
||||||
@@ -126,13 +120,9 @@ function love.draw()
|
|||||||
(height - scale_factor * 480) / 2
|
(height - scale_factor * 480) / 2
|
||||||
)
|
)
|
||||||
love.graphics.scale(scale_factor)
|
love.graphics.scale(scale_factor)
|
||||||
|
|
||||||
scene:render()
|
scene:render()
|
||||||
love.graphics.pop()
|
love.graphics.pop()
|
||||||
|
|
||||||
love.graphics.setCanvas()
|
|
||||||
love.graphics.setColor(1,1,1,1)
|
|
||||||
love.graphics.draw(GLOBAL_CANVAS)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.keypressed(key, scancode)
|
function love.keypressed(key, scancode)
|
||||||
@@ -150,14 +140,6 @@ function love.keypressed(key, scancode)
|
|||||||
scene.restart_message = true
|
scene.restart_message = true
|
||||||
if config.secret then playSE("mode_decide")
|
if config.secret then playSE("mode_decide")
|
||||||
else playSE("erase") end
|
else playSE("erase") end
|
||||||
-- f12 is reserved for saving screenshots
|
|
||||||
elseif scancode == "f12" then
|
|
||||||
local ss_name = os.date("ss/%Y-%m-%d_%H-%M-%S.png")
|
|
||||||
if not love.filesystem.getInfo("ss") then
|
|
||||||
love.filesystem.createDirectory("ss")
|
|
||||||
end
|
|
||||||
print("Saving screenshot as "..ss_name)
|
|
||||||
GLOBAL_CANVAS:newImageData():encode("png", ss_name)
|
|
||||||
-- function keys are reserved
|
-- function keys are reserved
|
||||||
elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f[1-9][0-9]+$") then
|
elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f[1-9][0-9]+$") then
|
||||||
return
|
return
|
||||||
@@ -279,8 +261,3 @@ function love.focus(f)
|
|||||||
pauseBGM()
|
pauseBGM()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.resize(w, h)
|
|
||||||
GLOBAL_CANVAS:release()
|
|
||||||
GLOBAL_CANVAS = love.graphics.newCanvas(w, h)
|
|
||||||
end
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
tar -a -c -f cambridge.zip libs load res scene tetris conf.lua main.lua scene.lua funcs.lua
|
tar -a -c -f cambridge.zip libs/binser.lua libs/classic.lua libs/simple-slider.lua libs/discordRPC.lua load res scene tetris conf.lua main.lua scene.lua funcs.lua
|
||||||
rename cambridge.zip cambridge.love
|
rename cambridge.zip cambridge.love
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.9 KiB |
@@ -139,8 +139,19 @@ function GameScene:onInputRelease(e)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function submitHighscore(hash, data)
|
function submitHighscore(hash, data)
|
||||||
|
function isHighscore(score, high)
|
||||||
|
for k, _ in pairs(score) do
|
||||||
|
if not high[k] or score[k] > high[k] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
if not highscores[hash] then highscores[hash] = {} end
|
if not highscores[hash] then highscores[hash] = {} end
|
||||||
table.insert(highscores[hash], data)
|
if isHighscore(data, highscores[hash]) then
|
||||||
|
highscores[hash] = data
|
||||||
|
end
|
||||||
saveHighscores()
|
saveHighscores()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -41,14 +41,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, 258, 240, 22)
|
love.graphics.rectangle("fill", 20, 198, 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, 258, 200, 22)
|
love.graphics.rectangle("fill", 340, 198, 200, 22)
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
|
||||||
@@ -56,13 +56,36 @@ 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
|
||||||
if(idx >= self.menu_state.mode-9 and idx <= self.menu_state.mode+9) then
|
if(idx >= self.menu_state.mode-6 and idx <= self.menu_state.mode+6) then
|
||||||
love.graphics.printf(mode.name, 40, (260 - 20*(self.menu_state.mode)) + 20 * idx, 200, "left")
|
love.graphics.printf(mode.name, 40, (200 - 20*(self.menu_state.mode)) + 20 * idx, 200, "left")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for idx, ruleset in pairs(rulesets) do
|
for idx, ruleset in pairs(rulesets) do
|
||||||
if(idx >= self.menu_state.ruleset-9 and idx <= self.menu_state.ruleset+9) then
|
if(idx >= self.menu_state.ruleset-6 and idx <= self.menu_state.ruleset+6) then
|
||||||
love.graphics.printf(ruleset.name, 360, (260 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left")
|
love.graphics.printf(ruleset.name, 360, (200 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- mode description and highscore
|
||||||
|
for midx, mode in pairs(game_modes) do
|
||||||
|
for ridx, ruleset in pairs(rulesets) do
|
||||||
|
if (midx == self.menu_state.mode) and (ridx == self.menu_state.ruleset) then
|
||||||
|
love.graphics.printf(
|
||||||
|
"Mode Description:\n\n" .. mode.tagline, 20, 350, 200, "left"
|
||||||
|
)
|
||||||
|
love.graphics.printf(
|
||||||
|
ruleset.name .. " Highscore:", 240, 350, 200, "right"
|
||||||
|
)
|
||||||
|
local highscore_string = ""
|
||||||
|
if highscores[mode.hash .. "-" .. ruleset.hash] then
|
||||||
|
for k, v in ipairs(highscores[mode.hash .. "-" .. ruleset.hash]) do
|
||||||
|
highscore_string = highscore_string .. k .. ": " .. v .. "\n"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
highscore_string = "You don't have any highscores yet!"
|
||||||
|
end
|
||||||
|
love.graphics.printf(highscore_string, 450, 350, 200, "left")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -405,11 +405,11 @@ function Grid:draw()
|
|||||||
if self.grid[y][x].skin ~= "bone" and self.grid[y][x].colour ~= "X" then
|
if self.grid[y][x].skin ~= "bone" and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 5 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < self.height and self.grid[y+1][x] == empty or
|
if y < self.height and self.grid[y+1][x] == empty or
|
||||||
(y + 1 <= self.height and self.grid[y+1][x].colour == "X") then
|
(y + 1 > self.height or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -434,11 +434,11 @@ function Grid:drawOutline()
|
|||||||
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= "X" then
|
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 5 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < self.height and self.grid[y+1][x] == empty or
|
if y < self.height and self.grid[y+1][x] == empty or
|
||||||
(y + 1 <= self.height and self.grid[y+1][x].colour == "X") then
|
(y + 1 > self.height or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -471,11 +471,11 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_fla
|
|||||||
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.64, 0.64, 0.64)
|
love.graphics.setColor(0.64, 0.64, 0.64)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 5 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < self.height and self.grid[y+1][x] == empty or
|
if y < self.height and self.grid[y+1][x] == empty or
|
||||||
(y + 1 <= self.height and self.grid[y+1][x].colour == "X") then
|
(y + 1 > self.height or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -513,11 +513,11 @@ function Grid:drawCustom(colour_function, gamestate)
|
|||||||
if outline > 0 and self.grid[y][x].colour ~= "X" then
|
if outline > 0 and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.64, 0.64, 0.64, outline)
|
love.graphics.setColor(0.64, 0.64, 0.64, outline)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 5 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < self.height and self.grid[y+1][x] == empty or
|
if y < self.height and self.grid[y+1][x] == empty or
|
||||||
(y + 1 <= self.height and self.grid[y+1][x].colour == "X") then
|
(y + 1 > self.height or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ local BagRandomizer = require 'tetris.randomizers.bag'
|
|||||||
|
|
||||||
local GameMode = Object:extend()
|
local GameMode = Object:extend()
|
||||||
|
|
||||||
GameMode.name = ""
|
|
||||||
GameMode.hash = ""
|
|
||||||
GameMode.tagline = ""
|
|
||||||
GameMode.rollOpacityFunction = function(age) return 0 end
|
GameMode.rollOpacityFunction = function(age) return 0 end
|
||||||
|
|
||||||
function GameMode:new(secret_inputs)
|
function GameMode:new(secret_inputs)
|
||||||
@@ -79,7 +76,6 @@ function GameMode:getLockDelay() return 30 end
|
|||||||
function GameMode:getLineClearDelay() return 40 end
|
function GameMode:getLineClearDelay() return 40 end
|
||||||
function GameMode:getDasLimit() return 15 end
|
function GameMode:getDasLimit() return 15 end
|
||||||
function GameMode:getDasCutDelay() return 0 end
|
function GameMode:getDasCutDelay() return 0 end
|
||||||
function GameMode:getGravity() return 1/64 end
|
|
||||||
|
|
||||||
function GameMode:getNextPiece(ruleset)
|
function GameMode:getNextPiece(ruleset)
|
||||||
return {
|
return {
|
||||||
@@ -105,7 +101,7 @@ function GameMode:initialize(ruleset, secret_inputs)
|
|||||||
BagRandomizer(ruleset.pieces)
|
BagRandomizer(ruleset.pieces)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for i = 1, math.max(self.next_queue_length, 1) do
|
for i = 1, self.next_queue_length do
|
||||||
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
||||||
end
|
end
|
||||||
self.lock_on_soft_drop = ({ruleset.softdrop_lock, self.instant_soft_drop, false, true })[config.gamesettings.manlock]
|
self.lock_on_soft_drop = ({ruleset.softdrop_lock, self.instant_soft_drop, false, true })[config.gamesettings.manlock]
|
||||||
@@ -171,9 +167,6 @@ function GameMode:update(inputs, ruleset)
|
|||||||
if self.enable_hold and inputs["hold"] == true and self.held == false and self.prev_inputs["hold"] == false then
|
if self.enable_hold and inputs["hold"] == true and self.held == false and self.prev_inputs["hold"] == false then
|
||||||
self:hold(inputs, ruleset)
|
self:hold(inputs, ruleset)
|
||||||
self.prev_inputs = inputs
|
self.prev_inputs = inputs
|
||||||
if not self.grid:canPlacePiece(self.piece) then
|
|
||||||
self.game_over = true
|
|
||||||
end
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -210,7 +203,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
) then
|
) then
|
||||||
self.das.frames = math.max(
|
self.das.frames = math.max(
|
||||||
self.das.frames - self:getDasCutDelay(),
|
self.das.frames - self:getDasCutDelay(),
|
||||||
-(self:getDasCutDelay() + 1)
|
-self:getDasCutDelay()
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -596,18 +589,6 @@ function GameMode:setHoldOpacity()
|
|||||||
love.graphics.setColor(colour, colour, colour, 1)
|
love.graphics.setColor(colour, colour, colour, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:getBackground()
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function GameMode:getHighscoreData()
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function GameMode:drawGrid()
|
|
||||||
self.grid:draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function GameMode:drawScoringInfo()
|
function GameMode:drawScoringInfo()
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.setFont(font_3x5_2)
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ local Piece = require 'tetris.components.piece'
|
|||||||
|
|
||||||
local Bag7NoSZOStartRandomizer = require 'tetris.randomizers.bag7noSZOstart'
|
local Bag7NoSZOStartRandomizer = require 'tetris.randomizers.bag7noSZOstart'
|
||||||
|
|
||||||
local SurvivalAXGame = GameMode:extend()
|
local MarathonAX4Game = GameMode:extend()
|
||||||
|
|
||||||
SurvivalAXGame.name = "Survival AX"
|
MarathonAX4Game.name = "Marathon AX4"
|
||||||
SurvivalAXGame.hash = "SurvivalAX"
|
MarathonAX4Game.hash = "MarathonAX4"
|
||||||
SurvivalAXGame.tagline = "Can you clear the time hurdles when the game goes this fast?"
|
MarathonAX4Game.tagline = "Can you clear the time hurdles when the game goes this fast?"
|
||||||
|
|
||||||
|
|
||||||
function SurvivalAXGame:new()
|
function MarathonAX4Game:new()
|
||||||
SurvivalAXGame.super:new()
|
MarathonAX4Game.super:new()
|
||||||
|
|
||||||
self.roll_frames = 0
|
self.roll_frames = 0
|
||||||
self.randomizer = Bag7NoSZOStartRandomizer()
|
self.randomizer = Bag7NoSZOStartRandomizer()
|
||||||
@@ -29,7 +29,7 @@ function SurvivalAXGame:new()
|
|||||||
self.next_queue_length = 3
|
self.next_queue_length = 3
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getARE()
|
function MarathonAX4Game:getARE()
|
||||||
if self.lines < 10 then return 18
|
if self.lines < 10 then return 18
|
||||||
elseif self.lines < 40 then return 14
|
elseif self.lines < 40 then return 14
|
||||||
elseif self.lines < 60 then return 12
|
elseif self.lines < 60 then return 12
|
||||||
@@ -39,24 +39,24 @@ function SurvivalAXGame:getARE()
|
|||||||
else return 6 end
|
else return 6 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getLineARE()
|
function MarathonAX4Game:getLineARE()
|
||||||
return self:getARE()
|
return self:getARE()
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getDasLimit()
|
function MarathonAX4Game:getDasLimit()
|
||||||
if self.lines < 20 then return 10
|
if self.lines < 20 then return 10
|
||||||
elseif self.lines < 50 then return 9
|
elseif self.lines < 50 then return 9
|
||||||
elseif self.lines < 70 then return 8
|
elseif self.lines < 70 then return 8
|
||||||
else return 7 end
|
else return 7 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getLineClearDelay()
|
function MarathonAX4Game:getLineClearDelay()
|
||||||
if self.lines < 10 then return 14
|
if self.lines < 10 then return 14
|
||||||
elseif self.lines < 30 then return 9
|
elseif self.lines < 30 then return 9
|
||||||
else return 5 end
|
else return 5 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getLockDelay()
|
function MarathonAX4Game:getLockDelay()
|
||||||
if self.lines < 10 then return 28
|
if self.lines < 10 then return 28
|
||||||
elseif self.lines < 20 then return 24
|
elseif self.lines < 20 then return 24
|
||||||
elseif self.lines < 30 then return 22
|
elseif self.lines < 30 then return 22
|
||||||
@@ -66,15 +66,15 @@ function SurvivalAXGame:getLockDelay()
|
|||||||
else return 13 end
|
else return 13 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getGravity()
|
function MarathonAX4Game:getGravity()
|
||||||
return 20
|
return 20
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getSection()
|
function MarathonAX4Game:getSection()
|
||||||
return math.floor(level / 100) + 1
|
return math.floor(level / 100) + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:advanceOneFrame()
|
function MarathonAX4Game: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
|
if self.roll_frames < 0 then
|
||||||
@@ -93,7 +93,7 @@ function SurvivalAXGame:advanceOneFrame()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:onLineClear(cleared_row_count)
|
function MarathonAX4Game:onLineClear(cleared_row_count)
|
||||||
if not self.clear then
|
if not self.clear then
|
||||||
local new_lines = self.lines + cleared_row_count
|
local new_lines = self.lines + cleared_row_count
|
||||||
self:updateSectionTimes(self.lines, new_lines)
|
self:updateSectionTimes(self.lines, new_lines)
|
||||||
@@ -106,11 +106,11 @@ function SurvivalAXGame:onLineClear(cleared_row_count)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getSectionTime()
|
function MarathonAX4Game:getSectionTime()
|
||||||
return self.frames - self.section_start_time
|
return self.frames - self.section_start_time
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:updateSectionTimes(old_lines, new_lines)
|
function MarathonAX4Game:updateSectionTimes(old_lines, new_lines)
|
||||||
if math.floor(old_lines / 10) < math.floor(new_lines / 10) then
|
if math.floor(old_lines / 10) < math.floor(new_lines / 10) then
|
||||||
-- record new section
|
-- record new section
|
||||||
table.insert(self.section_times, self:getSectionTime())
|
table.insert(self.section_times, self:getSectionTime())
|
||||||
@@ -119,23 +119,23 @@ function SurvivalAXGame:updateSectionTimes(old_lines, new_lines)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:onPieceEnter()
|
function MarathonAX4Game:onPieceEnter()
|
||||||
self.section_clear = false
|
self.section_clear = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:drawGrid(ruleset)
|
function MarathonAX4Game:drawGrid(ruleset)
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getHighscoreData()
|
function MarathonAX4Game:getHighscoreData()
|
||||||
return {
|
return {
|
||||||
lines = self.lines,
|
lines = self.lines,
|
||||||
frames = self.frames,
|
frames = self.frames,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:drawScoringInfo()
|
function MarathonAX4Game:drawScoringInfo()
|
||||||
SurvivalAXGame.super.drawScoringInfo(self)
|
MarathonAX4Game.super.drawScoringInfo(self)
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
|
||||||
@@ -165,12 +165,12 @@ function SurvivalAXGame:drawScoringInfo()
|
|||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getSectionEndLines()
|
function MarathonAX4Game:getSectionEndLines()
|
||||||
return math.floor(self.lines / 10 + 1) * 10
|
return math.floor(self.lines / 10 + 1) * 10
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalAXGame:getBackground()
|
function MarathonAX4Game:getBackground()
|
||||||
return math.floor(self.lines / 10)
|
return math.floor(self.lines / 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
return SurvivalAXGame
|
return MarathonAX4Game
|
||||||
@@ -437,8 +437,6 @@ function SakuraGame:advanceOneFrame(inputs, ruleset)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function SakuraGame:onGameComplete() end
|
|
||||||
|
|
||||||
local function colourXRay(game, block, x, y, age)
|
local function colourXRay(game, block, x, y, age)
|
||||||
local r, g, b, a = .5,.5,.5
|
local r, g, b, a = .5,.5,.5
|
||||||
if ((game.stage_frames/2 - x) % 30 < 1)
|
if ((game.stage_frames/2 - x) % 30 < 1)
|
||||||
@@ -469,11 +467,11 @@ function SakuraGame:drawGrid()
|
|||||||
elseif effects[self.current_map] == "color" then
|
elseif effects[self.current_map] == "color" then
|
||||||
self.grid:drawCustom(colourColor, self)
|
self.grid:drawCustom(colourColor, self)
|
||||||
else
|
else
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
end
|
-- if self.piece ~= nil and self.level < 100 then
|
||||||
if self.piece ~= nil and self.level < 100 then
|
self:drawGhostPiece(ruleset)
|
||||||
self:drawGhostPiece()
|
-- end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SakuraGame:drawScoringInfo()
|
function SakuraGame:drawScoringInfo()
|
||||||
|
|||||||
@@ -66,24 +66,24 @@ function SurvivalA1Game:getGravity()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function getRankForScore(score)
|
local function getRankForScore(score)
|
||||||
if score < 400 then return {rank = "9", next = 400}
|
if score < 400 then return {rank = "9", next = 400, grade = 0}
|
||||||
elseif score < 800 then return {rank = "8", next = 800}
|
elseif score < 800 then return {rank = "8", next = 800, grade = 1}
|
||||||
elseif score < 1400 then return {rank = "7", next = 1400}
|
elseif score < 1400 then return {rank = "7", next = 1400, grade = 2}
|
||||||
elseif score < 2000 then return {rank = "6", next = 2000}
|
elseif score < 2000 then return {rank = "6", next = 2000, grade = 3}
|
||||||
elseif score < 3500 then return {rank = "5", next = 3500}
|
elseif score < 3500 then return {rank = "5", next = 3500, grade = 4}
|
||||||
elseif score < 5500 then return {rank = "4", next = 5500}
|
elseif score < 5500 then return {rank = "4", next = 5500, grade = 5}
|
||||||
elseif score < 8000 then return {rank = "3", next = 8000}
|
elseif score < 8000 then return {rank = "3", next = 8000, grade = 6}
|
||||||
elseif score < 12000 then return {rank = "2", next = 12000}
|
elseif score < 12000 then return {rank = "2", next = 12000, grade = 7}
|
||||||
elseif score < 16000 then return {rank = "1", next = 16000}
|
elseif score < 16000 then return {rank = "1", next = 16000, grade = 8}
|
||||||
elseif score < 22000 then return {rank = "S1", next = 22000}
|
elseif score < 22000 then return {rank = "S1", next = 22000, grade = 9}
|
||||||
elseif score < 30000 then return {rank = "S2", next = 30000}
|
elseif score < 30000 then return {rank = "S2", next = 30000, grade = 10}
|
||||||
elseif score < 40000 then return {rank = "S3", next = 40000}
|
elseif score < 40000 then return {rank = "S3", next = 40000, grade = 11}
|
||||||
elseif score < 52000 then return {rank = "S4", next = 52000}
|
elseif score < 52000 then return {rank = "S4", next = 52000, grade = 12}
|
||||||
elseif score < 66000 then return {rank = "S5", next = 66000}
|
elseif score < 66000 then return {rank = "S5", next = 66000, grade = 13}
|
||||||
elseif score < 82000 then return {rank = "S6", next = 82000}
|
elseif score < 82000 then return {rank = "S6", next = 82000, grade = 14}
|
||||||
elseif score < 100000 then return {rank = "S7", next = 100000}
|
elseif score < 100000 then return {rank = "S7", next = 100000, grade = 15}
|
||||||
elseif score < 120000 then return {rank = "S8", next = 120000}
|
elseif score < 120000 then return {rank = "S8", next = 120000, grade = 16}
|
||||||
else return {rank = "S9", next = "???"}
|
else return {rank = "S9", next = "???", grade = 17}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -208,10 +208,15 @@ end
|
|||||||
|
|
||||||
function SurvivalA1Game:getHighscoreData()
|
function SurvivalA1Game:getHighscoreData()
|
||||||
return {
|
return {
|
||||||
grade = self.grade,
|
grade = (
|
||||||
|
(self.gm_conditions["level300"] and
|
||||||
|
self.gm_conditions["level500"] and
|
||||||
|
self.gm_conditions["level999"]) and
|
||||||
|
18 or getRankForScore(self.score).grade
|
||||||
|
),
|
||||||
|
frames = self.frames,
|
||||||
score = self.score,
|
score = self.score,
|
||||||
level = self.level,
|
level = self.level,
|
||||||
frames = self.frames,
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,13 @@ function ARS:onPieceDrop(piece, grid)
|
|||||||
piece.lock_delay = 0 -- step reset
|
piece.lock_delay = 0 -- step reset
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:get180RotationValue() return 3 end
|
function ARS:get180RotationValue()
|
||||||
|
if config.gamesettings.world_reverse == 3 then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,4 @@ function ARS:onPieceRotate(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:get180RotationValue() return 3 end
|
|
||||||
|
|
||||||
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -36,8 +36,4 @@ function ARS:onPieceRotate(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:get180RotationValue() return 3 end
|
|
||||||
|
|
||||||
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -4,19 +4,7 @@ local Ruleset = require 'tetris.rulesets.ti_srs'
|
|||||||
local SRS = Ruleset:extend()
|
local SRS = Ruleset:extend()
|
||||||
|
|
||||||
SRS.name = "ACE-SRS"
|
SRS.name = "ACE-SRS"
|
||||||
SRS.hash = "StandardACE"
|
SRS.hash = "ACE Standard"
|
||||||
SRS.world = true
|
|
||||||
SRS.colourscheme = {
|
|
||||||
I = "C",
|
|
||||||
L = "O",
|
|
||||||
J = "B",
|
|
||||||
S = "G",
|
|
||||||
Z = "R",
|
|
||||||
O = "Y",
|
|
||||||
T = "M",
|
|
||||||
}
|
|
||||||
SRS.softdrop_lock = false
|
|
||||||
SRS.harddrop_lock = true
|
|
||||||
|
|
||||||
SRS.MANIPULATIONS_MAX = 128
|
SRS.MANIPULATIONS_MAX = 128
|
||||||
|
|
||||||
|
|||||||
@@ -99,8 +99,4 @@ function ARS:onPieceRotate(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:get180RotationValue() return 3 end
|
|
||||||
|
|
||||||
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -364,9 +364,9 @@ function CRS:attemptRotate(new_inputs, piece, grid, initial)
|
|||||||
|
|
||||||
if rot_dir == 0 then return end
|
if rot_dir == 0 then return end
|
||||||
|
|
||||||
if config.gamesettings.world_reverse == 3 or (self.world and config.gamesettings.world_reverse == 2) then
|
if self.world and config.gamesettings.world_reverse == 2 then
|
||||||
rot_dir = 4 - rot_dir
|
rot_dir = 4 - rot_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
local new_piece = piece:withRelativeRotation(rot_dir)
|
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||||
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
|
||||||
local Ruleset = require 'tetris.rulesets.standard_exp'
|
|
||||||
|
|
||||||
local SRS = Ruleset:extend()
|
|
||||||
|
|
||||||
SRS.name = "Guideline SRS"
|
|
||||||
SRS.hash = "Standard"
|
|
||||||
SRS.softdrop_lock = false
|
|
||||||
SRS.harddrop_lock = true
|
|
||||||
|
|
||||||
SRS.MANIPULATIONS_MAX = 15
|
|
||||||
|
|
||||||
SRS.wallkicks_line = {
|
|
||||||
[0]={
|
|
||||||
[1]={{x=-2, y=0}, {x=1, y=0}, {x=-2, y=1}, {x=1, y=-2}},
|
|
||||||
[2]={{x=-1,y=0},{x=-2,y=0},{x=1,y=0},{x=2,y=0},{x=0,y=1}},
|
|
||||||
[3]={{x=-1, y=0}, {x=2, y=0}, {x=-1, y=-2}, {x=2, y=1}},
|
|
||||||
},
|
|
||||||
[1]={
|
|
||||||
[0]={{x=2, y=0}, {x=-1, y=0}, {x=2, y=-1}, {x=-1, y=2}},
|
|
||||||
[2]={{x=-1, y=0}, {x=2, y=0}, {x=-1, y=-2}, {x=2, y=1}},
|
|
||||||
[3]={{x=0,y=1},{x=0,y=2},{x=0,y=-1},{x=0,y=-2},{x=-1,y=0}},
|
|
||||||
},
|
|
||||||
[2]={
|
|
||||||
[0]={{x=1,y=0},{x=2,y=0},{x=-1,y=0},{x=-2,y=0},{x=0,y=-1}},
|
|
||||||
[1]={{x=1, y=0}, {x=-2, y=0}, {x=1, y=2}, {x=-2, y=-1}},
|
|
||||||
[3]={{x=2, y=0}, {x=-1, y=0}, {x=2, y=-1}, {x=-1, y=2}},
|
|
||||||
},
|
|
||||||
[3]={
|
|
||||||
[0]={{x=1, y=0}, {x=-2, y=0}, {x=1, y=2}, {x=-2, y=-1}},
|
|
||||||
[1]={{x=0,y=1},{x=0,y=2},{x=0,y=-1},{x=0,y=-2},{x=1,y=0}},
|
|
||||||
[2]={{x=-2, y=0}, {x=1, y=0}, {x=-2, y=1}, {x=1, y=-2}},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|
||||||
|
|
||||||
local kicks
|
|
||||||
if piece.shape == "O" then
|
|
||||||
return
|
|
||||||
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
|
|
||||||
|
|
||||||
function SRS:checkNewLow(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.rotations = 0
|
|
||||||
piece.lowest_y = y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SRS:onPieceDrop(piece, grid)
|
|
||||||
self:checkNewLow(piece)
|
|
||||||
if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
|
|
||||||
piece.locked = true
|
|
||||||
else
|
|
||||||
piece.lock_delay = 0 -- step reset
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SRS:onPieceMove(piece, grid)
|
|
||||||
piece.lock_delay = 0 -- move reset
|
|
||||||
if piece:isDropBlocked(grid) then
|
|
||||||
piece.manipulations = piece.manipulations + 1
|
|
||||||
if piece.manipulations >= SRS.MANIPULATIONS_MAX then
|
|
||||||
piece.locked = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
|
||||||
piece.lock_delay = 0 -- rotate reset
|
|
||||||
self:checkNewLow(piece)
|
|
||||||
piece.manipulations = piece.manipulations + 1
|
|
||||||
if piece:isDropBlocked(grid) then
|
|
||||||
if piece.manipulations >= SRS.MANIPULATIONS_MAX then
|
|
||||||
piece.locked = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return SRS
|
|
||||||
@@ -3,37 +3,46 @@ local Ruleset = require 'tetris.rulesets.arika_srs'
|
|||||||
|
|
||||||
local SRS = Ruleset:extend()
|
local SRS = Ruleset:extend()
|
||||||
|
|
||||||
SRS.name = "SRS-X"
|
SRS.name = "Guideline SRS"
|
||||||
SRS.hash = "StandardEXP"
|
SRS.hash = "Standard"
|
||||||
SRS.world = true
|
|
||||||
SRS.colourscheme = {
|
|
||||||
I = "C",
|
|
||||||
L = "O",
|
|
||||||
J = "B",
|
|
||||||
S = "G",
|
|
||||||
Z = "R",
|
|
||||||
O = "Y",
|
|
||||||
T = "M",
|
|
||||||
}
|
|
||||||
SRS.softdrop_lock = true
|
|
||||||
SRS.harddrop_lock = false
|
|
||||||
|
|
||||||
SRS.enable_IRS_wallkicks = true
|
SRS.enable_IRS_wallkicks = true
|
||||||
|
|
||||||
SRS.MANIPULATIONS_MAX = 24
|
SRS.MANIPULATIONS_MAX = 15
|
||||||
SRS.ROTATIONS_MAX = 12
|
|
||||||
|
|
||||||
function SRS:checkNewLow(piece)
|
function SRS:checkNewLow(piece)
|
||||||
for _, block in pairs(piece:getBlockOffsets()) do
|
for _, block in pairs(piece:getBlockOffsets()) do
|
||||||
local y = piece.position.y + block.y
|
local y = piece.position.y + block.y
|
||||||
if y > piece.lowest_y then
|
if y > piece.lowest_y then
|
||||||
--piece.manipulations = 0
|
piece.manipulations = 0
|
||||||
--piece.rotations = 0
|
|
||||||
piece.lowest_y = y
|
piece.lowest_y = y
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SRS.wallkicks_line = {
|
||||||
|
[0]={
|
||||||
|
[1]={{x=-2, y=0}, {x=1, y=0}, {x=-2, y=1}, {x=1, y=-2}},
|
||||||
|
[2]={},
|
||||||
|
[3]={{x=-1, y=0}, {x=2, y=0}, {x=-1, y=-2}, {x=2, y=1}},
|
||||||
|
},
|
||||||
|
[1]={
|
||||||
|
[0]={{x=2, y=0}, {x=-1, y=0}, {x=2, y=-1}, {x=-1, y=2}},
|
||||||
|
[2]={{x=-1, y=0}, {x=2, y=0}, {x=-1, y=-2}, {x=2, y=1}},
|
||||||
|
[3]={{x=0, y=1}, {x=0, y=-1}, {x=0, y=2}, {x=0, y=-2}},
|
||||||
|
},
|
||||||
|
[2]={
|
||||||
|
[0]={},
|
||||||
|
[1]={{x=1, y=0}, {x=-2, y=0}, {x=1, y=2}, {x=-2, y=-1}},
|
||||||
|
[3]={{x=2, y=0}, {x=-1, y=0}, {x=2, y=-1}, {x=-1, y=2}},
|
||||||
|
},
|
||||||
|
[3]={
|
||||||
|
[0]={{x=1, y=0}, {x=-2, y=0}, {x=1, y=2}, {x=-2, y=-1}},
|
||||||
|
[1]={{x=0, y=1}, {x=0, y=-1}, {x=0, y=2}, {x=0, y=-2}},
|
||||||
|
[2]={{x=-2, y=0}, {x=1, y=0}, {x=-2, y=1}, {x=1, y=-2}},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
-- Component functions.
|
-- Component functions.
|
||||||
|
|
||||||
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
@@ -63,7 +72,6 @@ end
|
|||||||
|
|
||||||
function SRS:onPieceCreate(piece, grid)
|
function SRS:onPieceCreate(piece, grid)
|
||||||
piece.manipulations = 0
|
piece.manipulations = 0
|
||||||
piece.rotations = 0
|
|
||||||
piece.lowest_y = -math.huge
|
piece.lowest_y = -math.huge
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -80,7 +88,7 @@ function SRS:onPieceMove(piece, grid)
|
|||||||
piece.lock_delay = 0 -- move reset
|
piece.lock_delay = 0 -- move reset
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= SRS.MANIPULATIONS_MAX then
|
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -89,9 +97,9 @@ end
|
|||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
self:checkNewLow(piece)
|
self:checkNewLow(piece)
|
||||||
if piece.rotations >= self.ROTATIONS_MAX then
|
piece.manipulations = piece.manipulations + 1
|
||||||
piece.rotations = piece.rotations + 1
|
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
||||||
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ local Ruleset = require 'tetris.rulesets.ruleset'
|
|||||||
local SRS = Ruleset:extend()
|
local SRS = Ruleset:extend()
|
||||||
|
|
||||||
SRS.name = "Ti-World"
|
SRS.name = "Ti-World"
|
||||||
SRS.hash = "StandardTI"
|
SRS.hash = "Bad I-kicks"
|
||||||
SRS.world = true
|
SRS.world = true
|
||||||
SRS.colourscheme = {
|
SRS.colourscheme = {
|
||||||
I = "C",
|
I = "C",
|
||||||
@@ -89,22 +89,22 @@ SRS.block_offsets = {
|
|||||||
SRS.wallkicks_3x3 = {
|
SRS.wallkicks_3x3 = {
|
||||||
[0]={
|
[0]={
|
||||||
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
||||||
[2]={{x=1,y=0},{x=2,y=0},{x=1,y=1},{x=2,y=1},{x=-1,y=0},{x=-2,y=0},{x=-1,y=1},{x=-2,y=1},{x=0,y=-1},{x=3,y=0},{x=-3,y=0}},
|
[2]={{x=0, y=1}, {x=0, y=-1}},
|
||||||
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
||||||
},
|
},
|
||||||
[1]={
|
[1]={
|
||||||
[0]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
|
[0]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
|
||||||
[2]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
|
[2]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
|
||||||
[3]={{x=0,y=1},{x=0,y=2},{x=-1,y=1},{x=-1,y=2},{x=0,y=-1},{x=0,y=-2},{x=-1,y=-1},{x=-1,y=-2},{x=1,y=0},{x=0,y=3},{x=0,y=-3}},
|
[3]={{x=0, y=1}, {x=0, y=-1}},
|
||||||
},
|
},
|
||||||
[2]={
|
[2]={
|
||||||
[0]={{x=-1,y=0},{x=-2,y=0},{x=-1,y=-1},{x=-2,y=-1},{x=1,y=0},{x=2,y=0},{x=1,y=-1},{x=2,y=-1},{x=0,y=1},{x=-3,y=0},{x=3,y=0}},
|
[0]={{x=0, y=1}, {x=0, y=-1}},
|
||||||
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
||||||
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
||||||
},
|
},
|
||||||
[3]={
|
[3]={
|
||||||
[0]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
[0]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
||||||
[1]={{x=0,y=1},{x=0,y=2},{x=1,y=1},{x=1,y=2},{x=0,y=-1},{x=0,y=-2},{x=1,y=-1},{x=1,y=-2},{x=-1,y=0},{x=0,y=3},{x=0,y=-3}},
|
[1]={{x=0, y=1}, {x=0, y=-1}},
|
||||||
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -112,22 +112,22 @@ SRS.wallkicks_3x3 = {
|
|||||||
SRS.wallkicks_line = {
|
SRS.wallkicks_line = {
|
||||||
[0]={
|
[0]={
|
||||||
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
||||||
[2]={{x=-1,y=0},{x=-2,y=0},{x=1,y=0},{x=2,y=0},{x=0,y=1}},
|
[2]={},
|
||||||
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
|
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
|
||||||
},
|
},
|
||||||
[1]={
|
[1]={
|
||||||
[0]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 2}},
|
[0]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 2}},
|
||||||
[2]={{x=-1, y= 0}, {x= 2, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
|
[2]={{x=-1, y= 0}, {x= 2, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
|
||||||
[3]={{x=0,y=1},{x=0,y=2},{x=0,y=-1},{x=0,y=-2},{x=-1,y=0}},
|
[3]={},
|
||||||
},
|
},
|
||||||
[2]={
|
[2]={
|
||||||
[0]={{x=1,y=0},{x=2,y=0},{x=-1,y=0},{x=-2,y=0},{x=0,y=-1}},
|
[0]={},
|
||||||
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 1}},
|
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 1}},
|
||||||
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 1}},
|
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 1}},
|
||||||
},
|
},
|
||||||
[3]={
|
[3]={
|
||||||
[0]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 2}},
|
[0]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 2}},
|
||||||
[1]={{x=0,y=1},{x=0,y=2},{x=0,y=-1},{x=0,y=-2},{x=1,y=0}},
|
[1]={},
|
||||||
[2]={{x= 1, y= 0}, {x=-2, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
[2]={{x= 1, y= 0}, {x=-2, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -192,6 +192,12 @@ function SRS:onPieceRotate(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:get180RotationValue() return 3 end
|
function SRS:get180RotationValue()
|
||||||
|
if config.gamesettings.world_reverse == 1 then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||