Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f31beffab8 | ||
|
|
2ff8fb5edc | ||
|
|
1bf8f91ef2 | ||
|
|
ba5f78d5f1 | ||
|
|
f7c4908062 | ||
|
|
3aa5bae7be | ||
|
|
40a2e78280 | ||
|
|
696da3fa3f | ||
|
|
4afe9f2bd4 | ||
|
|
1f686fb5d4 | ||
|
|
f4779c9847 | ||
|
|
06cbec4bc8 | ||
|
|
668564ffb0 | ||
|
|
e6edeea3d1 | ||
|
|
513cd6ba90 | ||
|
|
1beef8f157 | ||
|
|
d3b2b4c2d9 | ||
|
|
2b8b9d5084 | ||
|
|
2728780c45 | ||
|
|
ca592a3bcf | ||
|
|
b6f4158d70 | ||
|
|
e43f5c470a | ||
|
|
7bcdc517c0 | ||
|
|
1d30987f9a | ||
|
|
1dd46a11ef | ||
|
|
935c7aa14c | ||
|
|
aea115d953 | ||
|
|
3d5b33f41a | ||
|
|
29f07bb6ab | ||
|
|
891f96e814 | ||
|
|
36837a3af5 | ||
|
|
01b0f9f618 | ||
|
|
7c8c5bb11d | ||
|
|
acaa6bdbbf | ||
|
|
c37757f592 | ||
|
|
905e4bcc77 | ||
|
|
d956647678 | ||
|
|
10f032b49b | ||
|
|
5590e6c89b | ||
|
|
0393396d74 | ||
|
|
8c1eaec1aa | ||
|
|
957802a78e | ||
|
|
169a4e4d2f | ||
|
|
48aee18340 | ||
|
|
7b496d9412 | ||
|
|
7abb861446 | ||
|
|
21f8769228 | ||
|
|
44423fd2e8 | ||
|
|
6d326a142c | ||
|
|
b6f1072587 | ||
|
|
eef04ebf05 | ||
|
|
e24737a3b8 |
12
README.md
@@ -1,5 +1,11 @@
|
|||||||

|

|
||||||
|
|
||||||
|
Important notice
|
||||||
|
================
|
||||||
|
|
||||||
|
Tetra Online was recently struck by an illegal DMCA claim from the Tetris Company.
|
||||||
|
Please, spread awareness of this, and use the hashtag #DMCAgaming in your posts.
|
||||||
|
|
||||||
Cambridge
|
Cambridge
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@@ -42,7 +48,7 @@ You do not need LÖVE on Windows, as it comes bundled with the program.
|
|||||||
|
|
||||||
To get the stable release, simply download the ZIP in the latest release. All assets needed are bundled with the executable.
|
To get the stable release, simply download the ZIP in the latest release. All assets needed are bundled with the executable.
|
||||||
|
|
||||||
If you want the bleeding edge version, or want mod pack support, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
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:
|
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
|
||||||
|
|
||||||
@@ -74,9 +80,9 @@ It should run automatically!
|
|||||||
|
|
||||||
## Installing modpacks
|
## Installing modpacks
|
||||||
|
|
||||||
Simply drag your mode, ruleset, and randomizer Lua files into their respective directory, and they should appear automatically.
|
Simply drag your mode, ruleset, and randomizer Lua files into their respective [directory](https://love2d.org/wiki/love.filesystem), and they should appear automatically.
|
||||||
|
|
||||||
Alternatively, install [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
|
For more detailed instructions, install [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
10
SOURCES.md
@@ -8,7 +8,7 @@ Some of the assets are used without proper licenses. We aim to have fully licens
|
|||||||
Backgrounds
|
Backgrounds
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
1. Title: "Motus Glacies." Contributed by Daniel "Explo" McCarthy.
|
1. Title: Original picrute found on the Wikipedia article for Cambridge
|
||||||
|
|
||||||
1. *Gameplay level 0: "Quantum foam." Alex Sukontsev. https://www.flickr.com/photos/control9/14957509814/
|
1. *Gameplay level 0: "Quantum foam." Alex Sukontsev. https://www.flickr.com/photos/control9/14957509814/
|
||||||
2. *Gameplay level 1: No name. http://www.onekind.tv/univision-mqb/q5mqh5brlvuuj2nhdx7ch7eum183uu
|
2. *Gameplay level 1: No name. http://www.onekind.tv/univision-mqb/q5mqh5brlvuuj2nhdx7ch7eum183uu
|
||||||
@@ -34,6 +34,14 @@ Backgrounds
|
|||||||
Backgrounds marked with a * are placeholders that will be replaced in later versions due to incompatible licenses. We are generally aiming for public domain background images, but will also accept backgrounds given proper licenses to be included within Cambridge.
|
Backgrounds marked with a * are placeholders that will be replaced in later versions due to incompatible licenses. We are generally aiming for public domain background images, but will also accept backgrounds given proper licenses to be included within Cambridge.
|
||||||
|
|
||||||
|
|
||||||
|
Sounds
|
||||||
|
------
|
||||||
|
|
||||||
|
All piece sounds are (c) 2020 Damian Yerrick.
|
||||||
|
Other sounds from:
|
||||||
|
- NullpoMino
|
||||||
|
- DTET, (c) 2003 Mihys.
|
||||||
|
|
||||||
Music
|
Music
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
backgrounds = {
|
backgrounds = {
|
||||||
[0] = love.graphics.newImage("res/backgrounds/0-quantum-foam.png"),
|
[0] = love.graphics.newImage("res/backgrounds/0.png"),
|
||||||
love.graphics.newImage("res/backgrounds/100-big-bang.png"),
|
love.graphics.newImage("res/backgrounds/100.png"),
|
||||||
love.graphics.newImage("res/backgrounds/200-spiral-galaxy.png"),
|
love.graphics.newImage("res/backgrounds/200.png"),
|
||||||
love.graphics.newImage("res/backgrounds/300-sun-and-dust.png"),
|
love.graphics.newImage("res/backgrounds/300.png"),
|
||||||
love.graphics.newImage("res/backgrounds/400-earth-and-moon.png"),
|
love.graphics.newImage("res/backgrounds/400.png"),
|
||||||
love.graphics.newImage("res/backgrounds/500-cambrian-explosion.png"),
|
love.graphics.newImage("res/backgrounds/500.png"),
|
||||||
love.graphics.newImage("res/backgrounds/600-dinosaurs.png"),
|
love.graphics.newImage("res/backgrounds/600.png"),
|
||||||
love.graphics.newImage("res/backgrounds/700-asteroid.png"),
|
love.graphics.newImage("res/backgrounds/700.png"),
|
||||||
love.graphics.newImage("res/backgrounds/800-human-fire.png"),
|
love.graphics.newImage("res/backgrounds/800.png"),
|
||||||
love.graphics.newImage("res/backgrounds/900-early-civilization.png"),
|
love.graphics.newImage("res/backgrounds/900.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1000-vikings.png"),
|
love.graphics.newImage("res/backgrounds/1000.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1100-crusades.png"),
|
love.graphics.newImage("res/backgrounds/1100.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1200-genghis-khan.png"),
|
love.graphics.newImage("res/backgrounds/1200.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1300-black-death.png"),
|
love.graphics.newImage("res/backgrounds/1300.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1400-columbus-discovery.png"),
|
love.graphics.newImage("res/backgrounds/1400.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1500-aztecas.png"),
|
love.graphics.newImage("res/backgrounds/1500.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1600-telescope.png"),
|
love.graphics.newImage("res/backgrounds/1600.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1700-american-revolution.png"),
|
love.graphics.newImage("res/backgrounds/1700.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1800-railways.png"),
|
love.graphics.newImage("res/backgrounds/1800.png"),
|
||||||
love.graphics.newImage("res/backgrounds/1900-world-wide-web.png"),
|
love.graphics.newImage("res/backgrounds/1900.png"),
|
||||||
title = love.graphics.newImage("res/backgrounds/title_v0.1.png"),
|
title = love.graphics.newImage("res/backgrounds/title.png"),
|
||||||
input_config = love.graphics.newImage("res/backgrounds/options-pcb.png"),
|
input_config = love.graphics.newImage("res/backgrounds/options-input.png"),
|
||||||
game_config = love.graphics.newImage("res/backgrounds/options-gears.png"),
|
game_config = love.graphics.newImage("res/backgrounds/options-game.png"),
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks = {
|
blocks = {
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ sounds = {
|
|||||||
fall = love.audio.newSource("res/se/fall.wav", "static"),
|
fall = love.audio.newSource("res/se/fall.wav", "static"),
|
||||||
ready = love.audio.newSource("res/se/ready.wav", "static"),
|
ready = love.audio.newSource("res/se/ready.wav", "static"),
|
||||||
go = love.audio.newSource("res/se/go.wav", "static"),
|
go = love.audio.newSource("res/se/go.wav", "static"),
|
||||||
|
irs = love.audio.newSource("res/se/irs.wav", "static"),
|
||||||
|
ihs = love.audio.newSource("res/se/ihs.wav", "static"),
|
||||||
}
|
}
|
||||||
|
|
||||||
function playSE(sound, subsound)
|
function playSE(sound, subsound)
|
||||||
@@ -30,7 +32,7 @@ function playSE(sound, subsound)
|
|||||||
end
|
end
|
||||||
sounds[sound]:play()
|
sounds[sound]:play()
|
||||||
else
|
else
|
||||||
sounds[sound][subsound]:setVolume(0.1)
|
sounds[sound][subsound]:setVolume(0.6)
|
||||||
if sounds[sound][subsound]:isPlaying() then
|
if sounds[sound][subsound]:isPlaying() then
|
||||||
sounds[sound][subsound]:stop()
|
sounds[sound][subsound]:stop()
|
||||||
end
|
end
|
||||||
|
|||||||
7
main.lua
@@ -15,7 +15,12 @@ function love.load()
|
|||||||
|
|
||||||
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
|
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
|
||||||
|
|
||||||
if not config.gamesettings then config.gamesettings = {} end
|
if not config.gamesettings then
|
||||||
|
config.gamesettings = {}
|
||||||
|
config["das_last_key"] = false
|
||||||
|
else
|
||||||
|
config["das_last_key"] = config.gamesettings.das_last_key == 2
|
||||||
|
end
|
||||||
for _, option in ipairs(GameConfigScene.options) do
|
for _, option in ipairs(GameConfigScene.options) do
|
||||||
if not config.gamesettings[option[1]] then
|
if not config.gamesettings[option[1]] then
|
||||||
config.gamesettings[option[1]] = 1
|
config.gamesettings[option[1]] = 1
|
||||||
|
|||||||
4
release
@@ -4,6 +4,6 @@ mkdir dist/windows
|
|||||||
mkdir dist/win32
|
mkdir dist/win32
|
||||||
cp cambridge.love dist/
|
cp cambridge.love dist/
|
||||||
cat dist/windows/love.exe cambridge.love > dist/windows/cambridge.exe
|
cat dist/windows/love.exe cambridge.love > dist/windows/cambridge.exe
|
||||||
zip dist/cambridge-windows.zip dist/windows/* SOURCES.md LICENSE
|
zip dist/cambridge-windows.zip dist/windows/* SOURCES.md LICENSE.md
|
||||||
cat dist/win32/love.exe cambridge.love > dist/win32/cambridge.exe
|
cat dist/win32/love.exe cambridge.love > dist/win32/cambridge.exe
|
||||||
zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE
|
zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE.md
|
||||||
|
|||||||
0
res/backgrounds/0-quantum-foam.png → res/backgrounds/0.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
0
res/backgrounds/100-big-bang.png → res/backgrounds/100.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
0
res/backgrounds/1000-vikings.png → res/backgrounds/1000.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
0
res/backgrounds/1100-crusades.png → res/backgrounds/1100.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
0
res/backgrounds/1200-genghis-khan.png → res/backgrounds/1200.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
0
res/backgrounds/1300-black-death.png → res/backgrounds/1300.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
0
res/backgrounds/1400-columbus-discovery.png → res/backgrounds/1400.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 2.6 MiB |
0
res/backgrounds/1500-aztecas.png → res/backgrounds/1500.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
0
res/backgrounds/1600-telescope.png → res/backgrounds/1600.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
0
res/backgrounds/1700-american-revolution.png → res/backgrounds/1700.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
0
res/backgrounds/1800-railways.png → res/backgrounds/1800.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
0
res/backgrounds/1900-world-wide-web.png → res/backgrounds/1900.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
0
res/backgrounds/200-spiral-galaxy.png → res/backgrounds/200.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 1.6 MiB |
0
res/backgrounds/300-sun-and-dust.png → res/backgrounds/300.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
0
res/backgrounds/400-earth-and-moon.png → res/backgrounds/400.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
0
res/backgrounds/500-cambrian-explosion.png → res/backgrounds/500.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
0
res/backgrounds/600-dinosaurs.png → res/backgrounds/600.png
Executable file → Normal file
|
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.1 MiB |
0
res/backgrounds/700-asteroid.png → res/backgrounds/700.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
0
res/backgrounds/800-human-fire.png → res/backgrounds/800.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.7 MiB |
0
res/backgrounds/900-early-civilization.png → res/backgrounds/900.png
Executable file → Normal file
|
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
BIN
res/se/ihs.wav
Normal file
BIN
res/se/irs.wav
Normal file
@@ -68,6 +68,10 @@ function GameScene:render()
|
|||||||
|
|
||||||
self.game:drawCustom()
|
self.game:drawCustom()
|
||||||
|
|
||||||
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
if config.gamesettings.display_gamemode == 1 then
|
||||||
|
love.graphics.printf(self.game.name .. " - " .. self.ruleset.name, 0, 460, 640, "left")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameScene:onInputPress(e)
|
function GameScene:onInputPress(e)
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ ConfigScene.options = {
|
|||||||
{"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}},
|
{"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}},
|
||||||
{"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}},
|
{"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}},
|
||||||
{"world_reverse","A Button Rotation", {"Left" ,"Auto" ,"Right"}},
|
{"world_reverse","A Button Rotation", {"Left" ,"Auto" ,"Right"}},
|
||||||
|
{"display_gamemode", "Display Gamemode", {"On", "Off"}},
|
||||||
|
{"next_se", "Next Piece SFX", {"On", "Off"}},
|
||||||
|
{"das_last_key", "DAS Switch", {"Default", "Instant"}},
|
||||||
|
{"synchroes_allowed", "Synchroes", {"Per ruleset", "On", "Off"}},
|
||||||
|
{"diagonal_input", "Diagonal Input", {"On", "Off"}}
|
||||||
}
|
}
|
||||||
local optioncount = #ConfigScene.options
|
local optioncount = #ConfigScene.options
|
||||||
|
|
||||||
@@ -24,6 +29,7 @@ function ConfigScene:new()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function ConfigScene:update()
|
function ConfigScene:update()
|
||||||
|
config["das_last_key"] = config.gamesettings.das_last_key == 2
|
||||||
end
|
end
|
||||||
|
|
||||||
function ConfigScene:render()
|
function ConfigScene:render()
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ function ConfigScene:new()
|
|||||||
self.input_state = 1
|
self.input_state = 1
|
||||||
self.set_inputs = newSetInputs()
|
self.set_inputs = newSetInputs()
|
||||||
self.new_input = {}
|
self.new_input = {}
|
||||||
|
self.axis_timer = 0
|
||||||
|
|
||||||
DiscordRPC:update({
|
DiscordRPC:update({
|
||||||
details = "In menus",
|
details = "In menus",
|
||||||
@@ -63,6 +64,8 @@ function ConfigScene:render()
|
|||||||
love.graphics.print("press key or joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0)
|
love.graphics.print("press key or joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0)
|
||||||
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.axis_timer = self.axis_timer + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function addJoystick(input, name)
|
local function addJoystick(input, name)
|
||||||
@@ -118,7 +121,7 @@ function ConfigScene:onInputPress(e)
|
|||||||
self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state]
|
self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state]
|
||||||
self.input_state = self.input_state + 1
|
self.input_state = self.input_state + 1
|
||||||
elseif e.type == "joyaxis" then
|
elseif e.type == "joyaxis" then
|
||||||
if math.abs(e.value) >= 0.5 then
|
if (e.axis ~= self.last_axis or self.axis_timer > 30) and math.abs(e.value) >= 1 then
|
||||||
addJoystick(self.new_input, e.name)
|
addJoystick(self.new_input, e.name)
|
||||||
if not self.new_input.joysticks[e.name].axes then
|
if not self.new_input.joysticks[e.name].axes then
|
||||||
self.new_input.joysticks[e.name].axes = {}
|
self.new_input.joysticks[e.name].axes = {}
|
||||||
@@ -128,10 +131,12 @@ function ConfigScene:onInputPress(e)
|
|||||||
end
|
end
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] =
|
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||||
"jaxis " ..
|
"jaxis " ..
|
||||||
(e.value >= 0.5 and "+" or "-") .. e.axis ..
|
(e.value >= 1 and "+" or "-") .. e.axis ..
|
||||||
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
||||||
self.new_input.joysticks[e.name].axes[e.axis][e.value >= 0.5 and "positive" or "negative"] = configurable_inputs[self.input_state]
|
self.new_input.joysticks[e.name].axes[e.axis][e.value >= 1 and "positive" or "negative"] = configurable_inputs[self.input_state]
|
||||||
self.input_state = self.input_state + 1
|
self.input_state = self.input_state + 1
|
||||||
|
self.last_axis = e.axis
|
||||||
|
self.axis_timer = 0
|
||||||
end
|
end
|
||||||
elseif e.type == "joyhat" then
|
elseif e.type == "joyhat" then
|
||||||
if e.direction ~= "c" then
|
if e.direction ~= "c" then
|
||||||
|
|||||||
@@ -78,12 +78,15 @@ function Piece:setRelativeRotation(rot)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function Piece:moveInGrid(step, squares, grid)
|
function Piece:moveInGrid(step, squares, grid, instant)
|
||||||
local moved = false
|
local moved = false
|
||||||
for x = 1, squares do
|
for x = 1, squares do
|
||||||
if grid:canPlacePiece(self:withOffset(step)) then
|
if grid:canPlacePiece(self:withOffset(step)) then
|
||||||
moved = true
|
moved = true
|
||||||
self:setOffset(step)
|
self:setOffset(step)
|
||||||
|
if instant then
|
||||||
|
self:dropToBottom(grid)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ function GameMode:new()
|
|||||||
self.irs = true
|
self.irs = true
|
||||||
self.ihs = true
|
self.ihs = true
|
||||||
self.rpc_details = "In game"
|
self.rpc_details = "In game"
|
||||||
|
self.SGnames = {
|
||||||
|
"9", "8", "7", "6", "5", "4", "3", "2", "1",
|
||||||
|
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
|
||||||
|
"GM"
|
||||||
|
}
|
||||||
-- variables related to configurable parameters
|
-- variables related to configurable parameters
|
||||||
self.drop_locked = false
|
self.drop_locked = false
|
||||||
self.hard_drop_locked = false
|
self.hard_drop_locked = false
|
||||||
@@ -95,11 +100,31 @@ function GameMode:update(inputs, ruleset)
|
|||||||
end
|
end
|
||||||
if self.completed then return end
|
if self.completed then return end
|
||||||
|
|
||||||
|
if config.gamesettings.diagonal_input == 2 then
|
||||||
|
if inputs["left"] or inputs["right"] then
|
||||||
|
inputs["up"] = false
|
||||||
|
inputs["down"] = false
|
||||||
|
elseif inputs["up"] or inputs["down"] then
|
||||||
|
inputs["left"] = false
|
||||||
|
inputs["right"] = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- advance one frame
|
-- advance one frame
|
||||||
if self:advanceOneFrame(inputs) == false then return end
|
if self:advanceOneFrame(inputs, ruleset) == false then return end
|
||||||
|
|
||||||
self:chargeDAS(inputs, self:getDasLimit(), self.getARR())
|
self:chargeDAS(inputs, self:getDasLimit(), self.getARR())
|
||||||
|
|
||||||
|
-- set attempt flags
|
||||||
|
if inputs["left"] or inputs["right"] then self:onAttemptPieceMove(self.piece) end
|
||||||
|
if
|
||||||
|
inputs["rotate_left"] or inputs["rotate_right"] or
|
||||||
|
inputs["rotate_left2"] or inputs["rotate_right2"] or
|
||||||
|
inputs["rotate_180"]
|
||||||
|
then
|
||||||
|
self:onAttemptPieceRotate(self.piece)
|
||||||
|
end
|
||||||
|
|
||||||
if self.piece == nil then
|
if self.piece == nil then
|
||||||
self:processDelays(inputs, ruleset)
|
self:processDelays(inputs, ruleset)
|
||||||
else
|
else
|
||||||
@@ -200,6 +225,8 @@ end
|
|||||||
|
|
||||||
-- event functions
|
-- event functions
|
||||||
function GameMode:whilePieceActive() end
|
function GameMode:whilePieceActive() end
|
||||||
|
function GameMode:onAttemptPieceMove(piece) end
|
||||||
|
function GameMode:onAttemptPieceRotate(piece) end
|
||||||
function GameMode:onPieceLock(piece, cleared_row_count)
|
function GameMode:onPieceLock(piece, cleared_row_count)
|
||||||
playSE("lock")
|
playSE("lock")
|
||||||
end
|
end
|
||||||
@@ -207,9 +234,7 @@ end
|
|||||||
function GameMode:onLineClear(cleared_row_count) end
|
function GameMode:onLineClear(cleared_row_count) end
|
||||||
|
|
||||||
function GameMode:onPieceEnter() end
|
function GameMode:onPieceEnter() end
|
||||||
function GameMode:onHold()
|
function GameMode:onHold() end
|
||||||
playSE("hold")
|
|
||||||
end
|
|
||||||
|
|
||||||
function GameMode:onSoftDrop(dropped_row_count)
|
function GameMode:onSoftDrop(dropped_row_count)
|
||||||
self.drop_bonus = self.drop_bonus + 1 * dropped_row_count
|
self.drop_bonus = self.drop_bonus + 1 * dropped_row_count
|
||||||
@@ -223,30 +248,66 @@ function GameMode:onGameOver()
|
|||||||
switchBGM(nil)
|
switchBGM(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:chargeDAS(inputs)
|
-- DAS functions
|
||||||
if inputs[self.das.direction] == true then
|
|
||||||
local das_frames = self.das.frames + 1
|
function GameMode:startRightDAS()
|
||||||
if das_frames >= self:getDasLimit() then
|
self.move = "right"
|
||||||
if self.das.direction == "left" then
|
self.das = { direction = "right", frames = 0 }
|
||||||
self.move = (self:getARR() == 0 and "speed" or "") .. "left"
|
if self:getDasLimit() == 0 then
|
||||||
self.das.frames = self:getDasLimit() - self:getARR()
|
self:continueDAS()
|
||||||
elseif self.das.direction == "right" then
|
end
|
||||||
self.move = (self:getARR() == 0 and "speed" or "") .. "right"
|
end
|
||||||
self.das.frames = self:getDasLimit() - self:getARR()
|
|
||||||
end
|
function GameMode:startLeftDAS()
|
||||||
else
|
self.move = "left"
|
||||||
self.move = "none"
|
self.das = { direction = "left", frames = 0 }
|
||||||
self.das.frames = das_frames
|
if self:getDasLimit() == 0 then
|
||||||
|
self:continueDAS()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameMode:continueDAS()
|
||||||
|
local das_frames = self.das.frames + 1
|
||||||
|
if das_frames >= self:getDasLimit() then
|
||||||
|
if self.das.direction == "left" then
|
||||||
|
self.move = (self:getARR() == 0 and "speed" or "") .. "left"
|
||||||
|
self.das.frames = self:getDasLimit() - self:getARR()
|
||||||
|
elseif self.das.direction == "right" then
|
||||||
|
self.move = (self:getARR() == 0 and "speed" or "") .. "right"
|
||||||
|
self.das.frames = self:getDasLimit() - self:getARR()
|
||||||
end
|
end
|
||||||
elseif inputs["right"] == true then
|
|
||||||
self.move = "right"
|
|
||||||
self.das = { direction = "right", frames = 0 }
|
|
||||||
elseif inputs["left"] == true then
|
|
||||||
self.move = "left"
|
|
||||||
self.das = { direction = "left", frames = 0 }
|
|
||||||
else
|
else
|
||||||
self.move = "none"
|
self.move = "none"
|
||||||
self.das = { direction = "none", frames = -1 }
|
self.das.frames = das_frames
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameMode:stopDAS()
|
||||||
|
self.move = "none"
|
||||||
|
self.das = { direction = "none", frames = -1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameMode:chargeDAS(inputs)
|
||||||
|
if config["das_last_key"] then
|
||||||
|
if inputs["right"] == true and self.das.direction ~= "right" and not self.prev_inputs["right"] then
|
||||||
|
self:startRightDAS()
|
||||||
|
elseif inputs["left"] == true and self.das.direction ~= "left" and not self.prev_inputs["left"] then
|
||||||
|
self:startLeftDAS()
|
||||||
|
elseif inputs[self.das.direction] == true then
|
||||||
|
self:continueDAS()
|
||||||
|
else
|
||||||
|
self:stopDAS()
|
||||||
|
end
|
||||||
|
else -- default behaviour, das first key pressed
|
||||||
|
if inputs[self.das.direction] == true then
|
||||||
|
self:continueDAS()
|
||||||
|
elseif inputs["right"] == true then
|
||||||
|
self:startRightDAS()
|
||||||
|
elseif inputs["left"] == true then
|
||||||
|
self:startLeftDAS()
|
||||||
|
else
|
||||||
|
self:stopDAS()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -270,6 +331,18 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
end
|
end
|
||||||
elseif self.lcd > 0 then
|
elseif self.lcd > 0 then
|
||||||
self.lcd = self.lcd - 1
|
self.lcd = self.lcd - 1
|
||||||
|
if ruleset.are_cancel and
|
||||||
|
(self.move == "none" and not self.prev_inputs["up"] and
|
||||||
|
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
|
||||||
|
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
|
||||||
|
not self.prev_inputs["rotate_180"]) and
|
||||||
|
(inputs["left"] or inputs["right"] or inputs["up"] or
|
||||||
|
inputs["rotate_left"] or inputs["rotate_left2"] or
|
||||||
|
inputs["rotate_right"] or inputs["rotate_right2"] or
|
||||||
|
inputs["rotate_180"]) then
|
||||||
|
self.lcd = 0
|
||||||
|
self.are = 0
|
||||||
|
end
|
||||||
if self.lcd == 0 then
|
if self.lcd == 0 then
|
||||||
self.grid:clearClearedRows()
|
self.grid:clearClearedRows()
|
||||||
playSE("fall")
|
playSE("fall")
|
||||||
@@ -280,7 +353,11 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
elseif self.are > 0 then
|
elseif self.are > 0 then
|
||||||
self.are = self.are - 1
|
self.are = self.are - 1
|
||||||
if ruleset.are_cancel and
|
if ruleset.are_cancel and
|
||||||
(inputs["left"] or inputs["right"] or
|
(self.move == "none" and not self.prev_inputs["up"] and
|
||||||
|
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
|
||||||
|
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
|
||||||
|
not self.prev_inputs["rotate_180"]) and
|
||||||
|
(inputs["left"] or inputs["right"] or inputs["up"] or
|
||||||
inputs["rotate_left"] or inputs["rotate_left2"] or
|
inputs["rotate_left"] or inputs["rotate_left2"] or
|
||||||
inputs["rotate_right"] or inputs["rotate_right2"] or
|
inputs["rotate_right"] or inputs["rotate_right2"] or
|
||||||
inputs["rotate_180"]) then
|
inputs["rotate_180"]) then
|
||||||
@@ -294,7 +371,7 @@ end
|
|||||||
|
|
||||||
function GameMode:initializeOrHold(inputs, ruleset)
|
function GameMode:initializeOrHold(inputs, ruleset)
|
||||||
if self.ihs and self.enable_hold and inputs["hold"] == true then
|
if self.ihs and self.enable_hold and inputs["hold"] == true then
|
||||||
self:hold(inputs, ruleset)
|
self:hold(inputs, ruleset, true)
|
||||||
else
|
else
|
||||||
self:initializeNextPiece(inputs, ruleset, self.next_queue[1])
|
self:initializeNextPiece(inputs, ruleset, self.next_queue[1])
|
||||||
end
|
end
|
||||||
@@ -305,7 +382,7 @@ function GameMode:initializeOrHold(inputs, ruleset)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:hold(inputs, ruleset)
|
function GameMode:hold(inputs, ruleset, ihs)
|
||||||
local data = copy(self.hold_queue)
|
local data = copy(self.hold_queue)
|
||||||
if self.piece == nil then
|
if self.piece == nil then
|
||||||
self.hold_queue = self.next_queue[1]
|
self.hold_queue = self.next_queue[1]
|
||||||
@@ -324,6 +401,8 @@ function GameMode:hold(inputs, ruleset)
|
|||||||
self:initializeNextPiece(inputs, ruleset, data, false)
|
self:initializeNextPiece(inputs, ruleset, data, false)
|
||||||
end
|
end
|
||||||
self.held = true
|
self.held = true
|
||||||
|
if ihs then playSE("ihs")
|
||||||
|
else playSE("hold") end
|
||||||
self:onHold()
|
self:onHold()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -346,7 +425,7 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
|||||||
table.remove(self.next_queue, 1)
|
table.remove(self.next_queue, 1)
|
||||||
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
||||||
end
|
end
|
||||||
self:playNextSound()
|
if config.gamesettings.next_se == 1 then self:playNextSound() end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:playNextSound()
|
function GameMode:playNextSound()
|
||||||
@@ -398,7 +477,7 @@ function GameMode:drawNextQueue(ruleset)
|
|||||||
drawPiece(next_piece, skin, ruleset.block_offsets[next_piece][rotation], -16+i*80, -32)
|
drawPiece(next_piece, skin, ruleset.block_offsets[next_piece][rotation], -16+i*80, -32)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self.hold_queue ~= nil then
|
if self.hold_queue ~= nil and self.enable_hold then
|
||||||
local hold_color = self.held and 0.6 or 1
|
local hold_color = self.held and 0.6 or 1
|
||||||
self:setHoldOpacity(1, hold_color)
|
self:setHoldOpacity(1, hold_color)
|
||||||
drawPiece(
|
drawPiece(
|
||||||
@@ -455,6 +534,10 @@ function GameMode:drawSectionTimes(current_section)
|
|||||||
love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left")
|
love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function GameMode:sectionColourFunction(section)
|
||||||
|
return { 1, 1, 1, 1 }
|
||||||
|
end
|
||||||
|
|
||||||
function GameMode:drawSectionTimesWithSecondary(current_section)
|
function GameMode:drawSectionTimesWithSecondary(current_section)
|
||||||
local section_x = 530
|
local section_x = 530
|
||||||
local section_secondary_x = 440
|
local section_secondary_x = 440
|
||||||
@@ -466,9 +549,11 @@ function GameMode:drawSectionTimesWithSecondary(current_section)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for section, time in pairs(self.secondary_section_times) do
|
for section, time in pairs(self.secondary_section_times) do
|
||||||
|
love.graphics.setColor(self:sectionColourFunction(section))
|
||||||
if section > 0 then
|
if section > 0 then
|
||||||
love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left")
|
love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left")
|
||||||
end
|
end
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local current_x
|
local current_x
|
||||||
|
|||||||
@@ -327,10 +327,10 @@ function Marathon2020Game:checkClear(level)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
||||||
function sectionCool()
|
function sectionCool(section)
|
||||||
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")
|
if section < 10 then table.insert(self.section_status, "cool") end
|
||||||
self.cool_timer = 300
|
self.cool_timer = 300
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ function Marathon2020Game: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
|
||||||
|
|
||||||
if section > 4 then self.delay_level = math.min(20, self.delay_level + 1) end
|
if section > 5 then self.delay_level = math.min(20, self.delay_level + 1) end
|
||||||
self:checkTorikan(section)
|
self:checkTorikan(section)
|
||||||
self:checkClear(new_level)
|
self:checkClear(new_level)
|
||||||
|
|
||||||
@@ -357,11 +357,11 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
|||||||
self.secondary_section_times[section] < self.secondary_section_times[section - 1] + 120 and
|
self.secondary_section_times[section] < self.secondary_section_times[section - 1] + 120 and
|
||||||
self.secondary_section_times[section] < cool_cutoffs[section]
|
self.secondary_section_times[section] < cool_cutoffs[section]
|
||||||
) then
|
) then
|
||||||
sectionCool()
|
sectionCool(section)
|
||||||
elseif self.section_status[section - 1] == "cool" then
|
elseif self.section_status[section - 1] == "cool" then
|
||||||
table.insert(self.section_status, "none")
|
table.insert(self.section_status, "none")
|
||||||
elseif section <= 19 and self.secondary_section_times[section] < cool_cutoffs[section] then
|
elseif section <= 19 and self.secondary_section_times[section] < cool_cutoffs[section] then
|
||||||
sectionCool()
|
sectionCool(section)
|
||||||
else
|
else
|
||||||
table.insert(self.section_status, "none")
|
table.insert(self.section_status, "none")
|
||||||
end
|
end
|
||||||
@@ -423,6 +423,14 @@ function Marathon2020Game:drawGrid()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Marathon2020Game:sectionColourFunction(section)
|
||||||
|
if self.section_status[section] == "cool" then
|
||||||
|
return { 0, 1, 0, 1 }
|
||||||
|
else
|
||||||
|
return { 1, 1, 1, 1 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Marathon2020Game:drawScoringInfo()
|
function Marathon2020Game:drawScoringInfo()
|
||||||
Marathon2020Game.super.drawScoringInfo(self)
|
Marathon2020Game.super.drawScoringInfo(self)
|
||||||
|
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ 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)
|
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
|
elseif self.level >= 999 and 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.setColor(1, 1, 1, 1)
|
||||||
love.graphics.printf(self.level, 240, 340, 40, "right")
|
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ function MarathonAX4Game: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 self.lines < 150 then love.graphics.printf("TIME LEFT", 240, 250, 80, "left") end
|
||||||
love.graphics.printf("LINES", 240, 320, 40, "left")
|
love.graphics.printf("LINES", 240, 320, 40, "left")
|
||||||
|
|
||||||
local current_section = math.floor(self.lines / 10) + 1
|
local current_section = math.floor(self.lines / 10) + 1
|
||||||
@@ -161,7 +161,7 @@ function MarathonAX4Game:drawScoringInfo()
|
|||||||
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 not self.clear 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 self.lines < 150 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)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ PhantomMania2Game.garbageOpacityFunction = function(age)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function PhantomMania2Game:drawGrid()
|
function PhantomMania2Game:drawGrid()
|
||||||
if not (self.game_over or (self.clear and self.level < 1300)) then
|
if not (self.game_over) then
|
||||||
self.grid:drawInvisible(self.rollOpacityFunction, self.garbageOpacityFunction)
|
self.grid:drawInvisible(self.rollOpacityFunction, self.garbageOpacityFunction)
|
||||||
else
|
else
|
||||||
self.grid:draw()
|
self.grid:draw()
|
||||||
@@ -291,7 +291,7 @@ function PhantomMania2Game:setHoldOpacity()
|
|||||||
if self.level > 1000 and self.level < 1300 then
|
if self.level > 1000 and self.level < 1300 then
|
||||||
love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15))
|
love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15))
|
||||||
else
|
else
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
self.super:setHoldOpacity(1, self.held and 0.6 or 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -159,8 +159,9 @@ 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)
|
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
|
elseif self.level >= 999 and 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.setColor(1, 1, 1, 1)
|
||||||
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")
|
||||||
if sg >= 5 then
|
if sg >= 5 then
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ function SurvivalA3Game:drawScoringInfo()
|
|||||||
|
|
||||||
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)
|
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
|
elseif self.level >= 1300 and 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.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")
|
||||||
|
|||||||
@@ -97,11 +97,11 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
|
|
||||||
-- kick right, kick left
|
-- kick right, kick left
|
||||||
if (grid:canPlacePiece(new_piece:withOffset({x=1, y=0}))) then
|
if (grid:canPlacePiece(new_piece:withOffset({x=1, y=0}))) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif (grid:canPlacePiece(new_piece:withOffset({x=-1, y=0}))) then
|
elseif (grid:canPlacePiece(new_piece:withOffset({x=-1, y=0}))) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
local Ruleset = require 'tetris.rulesets.arika_ti'
|
||||||
|
|
||||||
local ARS = Ruleset:extend()
|
local ARS = Ruleset:extend()
|
||||||
|
|
||||||
@@ -39,137 +39,16 @@ ARS.big_spawn_positions = {
|
|||||||
Z = { x=2, y=1 },
|
Z = { x=2, y=1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
ARS.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=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} },
|
|
||||||
},
|
|
||||||
J={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
},
|
|
||||||
L={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
O={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
},
|
|
||||||
S={
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
T={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
|
|
||||||
},
|
|
||||||
Z={
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-- Component functions.
|
|
||||||
|
|
||||||
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|
||||||
|
|
||||||
-- O doesn't kick
|
|
||||||
if (piece.shape == "O") then return end
|
|
||||||
|
|
||||||
-- center column rule
|
|
||||||
if (
|
|
||||||
piece.shape == "J" or piece.shape == "T" or piece.shape == "L"
|
|
||||||
) and (
|
|
||||||
piece.rotation == 0 or piece.rotation == 2
|
|
||||||
) then
|
|
||||||
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
|
|
||||||
if offset.x == 0 then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if piece.shape == "I" then
|
|
||||||
-- special kick rules for I
|
|
||||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
|
||||||
-- kick right, right2, left
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
end
|
|
||||||
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
|
|
||||||
-- kick up, up2
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece.floorkick = 1
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece.floorkick = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- kick right, kick left
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
elseif piece.shape == "T"
|
|
||||||
and new_piece.rotation == 0
|
|
||||||
and piece.floorkick == 0
|
|
||||||
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
|
||||||
then
|
|
||||||
-- T floorkick
|
|
||||||
piece.floorkick = piece.floorkick + 1
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function ARS:onPieceCreate(piece, grid)
|
function ARS:onPieceCreate(piece, grid)
|
||||||
piece.floorkick = 0
|
piece.floorkick = 0
|
||||||
piece.manipulations = 0
|
piece.manipulations = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:onPieceDrop(piece, grid)
|
|
||||||
piece.lock_delay = 0 -- step reset
|
|
||||||
end
|
|
||||||
|
|
||||||
function ARS:onPieceMove(piece, grid)
|
function ARS: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 >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -179,20 +58,13 @@ function ARS:onPieceRotate(piece, grid)
|
|||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if piece.floorkick >= 1 then
|
||||||
|
piece.floorkick = piece.floorkick + 1
|
||||||
|
end
|
||||||
end
|
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
|
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
local Ruleset = require 'tetris.rulesets.arika_ti'
|
||||||
|
|
||||||
local ARS = Ruleset:extend()
|
local ARS = Ruleset:extend()
|
||||||
|
|
||||||
@@ -26,137 +26,16 @@ ARS.big_spawn_positions = {
|
|||||||
Z = { x=2, y=1 },
|
Z = { x=2, y=1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
ARS.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=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} },
|
|
||||||
},
|
|
||||||
J={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
},
|
|
||||||
L={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
O={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
},
|
|
||||||
S={
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
T={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
|
|
||||||
},
|
|
||||||
Z={
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-- Component functions.
|
|
||||||
|
|
||||||
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|
||||||
|
|
||||||
-- O doesn't kick
|
|
||||||
if (piece.shape == "O") then return end
|
|
||||||
|
|
||||||
-- center column rule
|
|
||||||
if (
|
|
||||||
piece.shape == "J" or piece.shape == "T" or piece.shape == "L"
|
|
||||||
) and (
|
|
||||||
piece.rotation == 0 or piece.rotation == 2
|
|
||||||
) then
|
|
||||||
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
|
|
||||||
if offset.x == 0 then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if piece.shape == "I" then
|
|
||||||
-- special kick rules for I
|
|
||||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
|
||||||
-- kick right, right2, left
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
end
|
|
||||||
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
|
|
||||||
-- kick up, up2
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece.floorkick = 1
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece.floorkick = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- kick right, kick left
|
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
elseif piece.shape == "T"
|
|
||||||
and new_piece.rotation == 0
|
|
||||||
and piece.floorkick == 0
|
|
||||||
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
|
||||||
then
|
|
||||||
-- T floorkick
|
|
||||||
piece.floorkick = piece.floorkick + 1
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function ARS:onPieceCreate(piece, grid)
|
function ARS:onPieceCreate(piece, grid)
|
||||||
piece.floorkick = 0
|
piece.floorkick = 0
|
||||||
piece.manipulations = 0
|
piece.manipulations = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:onPieceDrop(piece, grid)
|
|
||||||
piece.lock_delay = 0 -- step reset
|
|
||||||
end
|
|
||||||
|
|
||||||
function ARS:onPieceMove(piece, grid)
|
function ARS: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 >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -166,20 +45,13 @@ function ARS:onPieceRotate(piece, grid)
|
|||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if piece.floorkick >= 1 then
|
||||||
|
piece.floorkick = piece.floorkick + 1
|
||||||
|
end
|
||||||
end
|
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
|
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
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 = "ACE Standard"
|
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.spawn_positions = {
|
SRS.spawn_positions = {
|
||||||
I = { x=5, y=2 },
|
I = { x=5, y=2 },
|
||||||
@@ -38,137 +26,11 @@ SRS.big_spawn_positions = {
|
|||||||
Z = { x=2, y=1 },
|
Z = { x=2, y=1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
SRS.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} },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SRS.wallkicks_3x3 = {
|
|
||||||
[0]={
|
|
||||||
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
|
||||||
[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}},
|
|
||||||
},
|
|
||||||
[1]={
|
|
||||||
[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}},
|
|
||||||
[3]={{x=0, y=1}, {x=0, y=-1}},
|
|
||||||
},
|
|
||||||
[2]={
|
|
||||||
[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}},
|
|
||||||
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
|
||||||
},
|
|
||||||
[3]={
|
|
||||||
[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=-1}},
|
|
||||||
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
SRS.wallkicks_line = {
|
|
||||||
[0]={
|
|
||||||
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
|
||||||
[2]={},
|
|
||||||
[3]={{x= 2, y= 0}, {x=-1, 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]={},
|
|
||||||
},
|
|
||||||
[2]={
|
|
||||||
[0]={},
|
|
||||||
[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]={
|
|
||||||
[0]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 2}},
|
|
||||||
[1]={},
|
|
||||||
[2]={{x= 1, y= 0}, {x=-2, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
-- Component functions.
|
|
||||||
|
|
||||||
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:onPieceCreate(piece, grid)
|
|
||||||
piece.manipulations = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function SRS:onPieceDrop(piece, grid)
|
|
||||||
piece.lock_delay = 0 -- step reset
|
|
||||||
end
|
|
||||||
|
|
||||||
function SRS:onPieceMove(piece, grid)
|
function SRS:onPieceMove(piece, grid)
|
||||||
piece.lock_delay = 0 -- move reset
|
piece.lock_delay = 0 -- move reset
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -178,18 +40,10 @@ function SRS:onPieceRotate(piece, grid)
|
|||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
if piece:isDropBlocked(grid) then
|
if piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= 127 then
|
if piece.manipulations >= 128 then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:get180RotationValue()
|
|
||||||
if config.gamesettings.world_reverse == 1 then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||
@@ -1,77 +1,11 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
local Ruleset = require 'tetris.rulesets.arika'
|
||||||
|
|
||||||
local ARS = Ruleset:extend()
|
local ARS = Ruleset:extend()
|
||||||
|
|
||||||
ARS.name = "Ti-ARS"
|
ARS.name = "Ti-ARS"
|
||||||
ARS.hash = "ArikaTI"
|
ARS.hash = "ArikaTI"
|
||||||
|
|
||||||
ARS.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 },
|
|
||||||
}
|
|
||||||
|
|
||||||
ARS.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 },
|
|
||||||
}
|
|
||||||
|
|
||||||
ARS.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=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} },
|
|
||||||
},
|
|
||||||
J={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
},
|
|
||||||
L={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
O={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
|
||||||
},
|
|
||||||
S={
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
|
||||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
|
||||||
},
|
|
||||||
T={
|
|
||||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
|
|
||||||
},
|
|
||||||
Z={
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
|
||||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-- Component functions.
|
-- Component functions.
|
||||||
|
|
||||||
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
@@ -100,43 +34,48 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
|
|
||||||
if piece.shape == "I" then
|
if piece.shape == "I" then
|
||||||
-- special kick rules for I
|
-- special kick rules for I
|
||||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
if (new_piece.rotation == 0 or new_piece.rotation == 2) and
|
||||||
|
(piece:isMoveBlocked(grid, {x=-1, y=0}) or piece:isMoveBlocked(grid, {x=1, y=0})) then
|
||||||
-- kick right, right2, left
|
-- kick right, right2, left
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
||||||
end
|
end
|
||||||
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
|
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
|
||||||
-- kick up, up2
|
-- kick up, up2
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
piece.floorkick = 1
|
piece.floorkick = 1
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
||||||
piece.floorkick = 1
|
piece.floorkick = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- kick right, kick left
|
-- kick right, kick left
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
||||||
elseif piece.shape == "T"
|
elseif piece.shape == "T"
|
||||||
and new_piece.rotation == 0
|
and new_piece.rotation == 0
|
||||||
and piece.floorkick == 0
|
and piece.floorkick == 0
|
||||||
|
and piece:isDropBlocked(grid)
|
||||||
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
||||||
then
|
then
|
||||||
-- T floorkick
|
-- T floorkick
|
||||||
piece.floorkick = piece.floorkick + 1
|
piece.floorkick = piece.floorkick + 1
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -149,16 +88,15 @@ end
|
|||||||
|
|
||||||
function ARS:onPieceDrop(piece, grid)
|
function ARS:onPieceDrop(piece, grid)
|
||||||
piece.lock_delay = 0 -- step reset
|
piece.lock_delay = 0 -- step reset
|
||||||
end
|
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
|
||||||
|
piece.locked = true
|
||||||
function ARS:get180RotationValue()
|
|
||||||
if config.gamesettings.world_reverse == 3 then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 3
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
|
function ARS:onPieceRotate(piece, grid)
|
||||||
|
if piece.floorkick >= 1 then
|
||||||
|
piece.floorkick = piece.floorkick + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return ARS
|
return ARS
|
||||||
|
|||||||
@@ -384,9 +384,9 @@ function CRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
for idx, offset in pairs(kicks) do
|
for idx, offset in pairs(kicks) do
|
||||||
kicked_piece = new_piece:withOffset(offset)
|
kicked_piece = new_piece:withOffset(offset)
|
||||||
if grid:canPlacePiece(kicked_piece) then
|
if grid:canPlacePiece(kicked_piece) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir)
|
piece:setRelativeRotation(rot_dir)
|
||||||
piece:setOffset(offset)
|
piece:setOffset(offset)
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ function Ruleset:attemptRotate(new_inputs, piece, grid, initial)
|
|||||||
local new_piece = piece:withRelativeRotation(rot_dir)
|
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||||
|
|
||||||
if (grid:canPlacePiece(new_piece)) then
|
if (grid:canPlacePiece(new_piece)) then
|
||||||
piece:setRelativeRotation(rot_dir)
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir)
|
||||||
else
|
else
|
||||||
if not(initial and self.enable_IRS_wallkicks == false) then
|
if not(initial and self.enable_IRS_wallkicks == false) then
|
||||||
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
@@ -128,16 +128,16 @@ function Ruleset:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
-- do nothing in default ruleset
|
-- do nothing in default ruleset
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:movePiece(piece, grid, move)
|
function Ruleset:movePiece(piece, grid, move, instant)
|
||||||
local x = piece.position.x
|
local x = piece.position.x
|
||||||
if move == "left" then
|
if move == "left" then
|
||||||
piece:moveInGrid({x=-1, y=0}, 1, grid)
|
piece:moveInGrid({x=-1, y=0}, 1, grid, false)
|
||||||
elseif move == "speedleft" then
|
|
||||||
piece:moveInGrid({x=-1, y=0}, 10, grid)
|
|
||||||
elseif move == "right" then
|
elseif move == "right" then
|
||||||
piece:moveInGrid({x=1, y=0}, 1, grid)
|
piece:moveInGrid({x=1, y=0}, 1, grid, false)
|
||||||
|
elseif move == "speedleft" then
|
||||||
|
piece:moveInGrid({x=-1, y=0}, 10, grid, instant)
|
||||||
elseif move == "speedright" then
|
elseif move == "speedright" then
|
||||||
piece:moveInGrid({x=1, y=0}, 10, grid)
|
piece:moveInGrid({x=1, y=0}, 10, grid, instant)
|
||||||
end
|
end
|
||||||
if piece.position.x ~= x then
|
if piece.position.x ~= x then
|
||||||
self:onPieceMove(piece, grid)
|
self:onPieceMove(piece, grid)
|
||||||
@@ -197,7 +197,14 @@ function Ruleset:initializePiece(
|
|||||||
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
|
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
|
||||||
|
|
||||||
self:onPieceCreate(piece)
|
self:onPieceCreate(piece)
|
||||||
if irs then self:rotatePiece(inputs, piece, grid, {}, true) end
|
if irs then
|
||||||
|
if inputs.rotate_left or inputs.rotate_left2 or
|
||||||
|
inputs.rotate_right or inputs.rotate_right2 or
|
||||||
|
inputs.rotate_180 then
|
||||||
|
playSE("irs")
|
||||||
|
end
|
||||||
|
self:rotatePiece(inputs, piece, grid, {}, true)
|
||||||
|
end
|
||||||
self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked)
|
self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked)
|
||||||
return piece
|
return piece
|
||||||
end
|
end
|
||||||
@@ -211,8 +218,16 @@ function Ruleset:processPiece(
|
|||||||
drop_locked, hard_drop_locked,
|
drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity
|
hard_drop_enabled, additive_gravity
|
||||||
)
|
)
|
||||||
self:rotatePiece(inputs, piece, grid, prev_inputs, false)
|
|
||||||
self:movePiece(piece, grid, move)
|
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
|
||||||
|
|
||||||
|
if synchroes_allowed then
|
||||||
|
self:rotatePiece(inputs, piece, grid, prev_inputs, false)
|
||||||
|
self:movePiece(piece, grid, move, gravity >= 20)
|
||||||
|
else
|
||||||
|
self:movePiece(piece, grid, move, gravity >= 20)
|
||||||
|
self:rotatePiece(inputs, piece, grid, prev_inputs, false)
|
||||||
|
end
|
||||||
self:dropPiece(
|
self:dropPiece(
|
||||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity
|
hard_drop_enabled, additive_gravity
|
||||||
|
|||||||
@@ -1,112 +1,22 @@
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
local Ruleset = require 'tetris.rulesets.arika_srs'
|
||||||
|
|
||||||
local SRS = Ruleset:extend()
|
local SRS = Ruleset:extend()
|
||||||
|
|
||||||
SRS.name = "Guideline SRS"
|
SRS.name = "Guideline SRS"
|
||||||
SRS.hash = "Standard"
|
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 = false
|
|
||||||
SRS.harddrop_lock = true
|
|
||||||
|
|
||||||
SRS.enable_IRS_wallkicks = true
|
SRS.enable_IRS_wallkicks = true
|
||||||
|
|
||||||
SRS.spawn_positions = {
|
function SRS:check_new_low(piece)
|
||||||
I = { x=5, y=2 },
|
for _, block in pairs(piece:getBlockOffsets()) do
|
||||||
J = { x=4, y=3 },
|
local y = piece.position.y + block.y
|
||||||
L = { x=4, y=3 },
|
if y > piece.lowest_y then
|
||||||
O = { x=5, y=3 },
|
piece.manipulations = 0
|
||||||
S = { x=4, y=3 },
|
piece.lowest_y = y
|
||||||
T = { x=4, y=3 },
|
end
|
||||||
Z = { x=4, y=3 },
|
end
|
||||||
}
|
end
|
||||||
|
|
||||||
SRS.big_spawn_positions = {
|
|
||||||
I = { x=3, y=0 },
|
|
||||||
J = { x=2, y=1 },
|
|
||||||
L = { x=2, y=1 },
|
|
||||||
O = { x=3, y=1 },
|
|
||||||
S = { x=2, y=1 },
|
|
||||||
T = { x=2, y=1 },
|
|
||||||
Z = { x=2, y=1 },
|
|
||||||
}
|
|
||||||
|
|
||||||
SRS.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} },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SRS.wallkicks_3x3 = {
|
|
||||||
[0]={
|
|
||||||
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
|
|
||||||
[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}},
|
|
||||||
},
|
|
||||||
[1]={
|
|
||||||
[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}},
|
|
||||||
[3]={{x=0, y=1}, {x=0, y=-1}},
|
|
||||||
},
|
|
||||||
[2]={
|
|
||||||
[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}},
|
|
||||||
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
|
|
||||||
},
|
|
||||||
[3]={
|
|
||||||
[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=-1}},
|
|
||||||
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
SRS.wallkicks_line = {
|
SRS.wallkicks_line = {
|
||||||
[0]={
|
[0]={
|
||||||
@@ -131,16 +41,6 @@ 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)
|
||||||
@@ -203,4 +103,6 @@ function SRS:onPieceRotate(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SRS:get180RotationValue() return 2 end
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||
@@ -147,9 +147,9 @@ function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
for idx, offset in pairs(kicks) do
|
for idx, offset in pairs(kicks) do
|
||||||
kicked_piece = new_piece:withOffset(offset)
|
kicked_piece = new_piece:withOffset(offset)
|
||||||
if grid:canPlacePiece(kicked_piece) then
|
if grid:canPlacePiece(kicked_piece) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
piece:setRelativeRotation(rot_dir)
|
piece:setRelativeRotation(rot_dir)
|
||||||
piece:setOffset(offset)
|
piece:setOffset(offset)
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||