Compare commits

...

52 Commits

Author SHA1 Message Date
Ishaan Bhardwaj
f31beffab8 Update release script 2020-12-16 22:47:56 -05:00
Ishaan Bhardwaj
2ff8fb5edc Modpack README update 2020-12-16 22:33:48 -05:00
Boshi
1bf8f91ef2 Displays current gamemode in game (toggle) 2020-12-16 22:21:26 -05:00
Ishaan Bhardwaj
ba5f78d5f1 Merge branch 'master' of https://github.com/sashlilac/cambridge 2020-12-14 22:44:16 -05:00
Ishaan Bhardwaj
f7c4908062 Added an option to disable diagonal input 2020-12-14 22:43:50 -05:00
Ishaan Bhardwaj
3aa5bae7be Tetra Online notice and stuff 2020-12-10 21:22:16 -05:00
Ishaan Bhardwaj
40a2e78280 Marathon 2020 section colour function fixed 2020-12-06 11:38:45 -05:00
Ishaan Bhardwaj
696da3fa3f Marathon 2020 colour function removed 2020-12-06 11:27:44 -05:00
Ishaan Bhardwaj
4afe9f2bd4 Major sound effect update (closes #7?)
Sound effects can still be changed, and #7 can still be reopened.
2020-12-05 20:30:59 -05:00
Ishaan Bhardwaj
1f686fb5d4 Ti-ARS: T can no longer floorkick the air 2020-12-05 18:32:06 -05:00
Ishaan Bhardwaj
f4779c9847 Added the ability to toggle next piece SFX 2020-12-05 17:32:15 -05:00
Ishaan Bhardwaj
06cbec4bc8 Guideline SRS kicks fixed 2020-12-05 17:15:28 -05:00
Ishaan Bhardwaj
668564ffb0 Revert "big a3! (but its buggy??)"
This reverts commit 513cd6ba90.
Hailey, please do not add modes.
2020-12-05 16:56:12 -05:00
Hailey
e6edeea3d1 Merge branch 'master' of https://github.com/SashLilac/cambridge 2020-12-05 12:50:45 +10:00
Hailey
513cd6ba90 big a3! (but its buggy??) 2020-12-05 12:49:57 +10:00
Ishaan Bhardwaj
1beef8f157 Guideline SRS has 180s now 2020-12-04 21:36:25 -05:00
Ishaan Bhardwaj
d3b2b4c2d9 Ruleset refactoring! 2020-12-04 20:36:11 -05:00
Ishaan Bhardwaj
2b8b9d5084 Reduced the sound volume a little bit. 2020-12-04 20:12:36 -05:00
Ishaan Bhardwaj
2728780c45 Raised the piece sound volume by a factor of 10. 2020-12-04 19:42:33 -05:00
Ishaan Bhardwaj
ca592a3bcf Changed piece sounds, added sound sources 2020-12-04 19:27:02 -05:00
Ishaan Bhardwaj
b6f4158d70 Fixed SRS infinity bug! 2020-12-04 16:51:53 -05:00
Ishaan Bhardwaj
e43f5c470a Renaming backgrounds 2020-12-04 16:32:29 -05:00
Ishaan Bhardwaj
7bcdc517c0 Revert "Merge pull request #11 from Rexxt/master"
Reverting this pull request for a few reasons:
The piece sounds were too quiet.
The piece landing sound was distasteful.
2020-12-04 16:22:22 -05:00
Ishaan Bhardwaj
1d30987f9a Merge pull request #11 from Rexxt/master
Uncopyrightening and making the game slightly friendlier to mod
2020-12-04 16:13:38 -05:00
Ishaan Bhardwaj
1dd46a11ef Fixed torikans giving you a green line 2020-12-04 15:41:44 -05:00
Ishaan Bhardwaj
935c7aa14c Default secret grade names 2020-12-04 15:16:13 -05:00
Ishaan Bhardwaj
aea115d953 ACE-SRS has correct number of resets 2020-12-04 11:22:32 -05:00
Ishaan Bhardwaj
3d5b33f41a Added ability to enable/disable synchroes
On by default in anything but world rulesets.
Gamemodes / rulesets can override this setting.
2020-12-04 10:57:43 -05:00
Mizu
29f07bb6ab Update piece sounds 2020-12-04 15:38:34 +01:00
Ishaan Bhardwaj
891f96e814 I broke the DAS switch functionality 2020-12-03 14:10:46 -05:00
Ishaan Bhardwaj
36837a3af5 Update main.lua 2020-12-03 13:45:23 -05:00
Ishaan Bhardwaj
01b0f9f618 DAS switch behavior implemented 2020-12-02 21:09:52 -05:00
Ishaan Bhardwaj
7c8c5bb11d Hide hold queue when hold is disabled 2020-12-02 13:41:47 -05:00
Ishaan Bhardwaj
acaa6bdbbf whoops forgot to not require socket 2020-12-01 11:58:29 -05:00
Ishaan Bhardwaj
c37757f592 Implement an axis timer (fixes #12) 2020-12-01 11:57:09 -05:00
Ishaan Bhardwaj
905e4bcc77 drawSectionTimesWithSecondary update 2020-12-01 11:56:44 -05:00
Ishaan Bhardwaj
d956647678 Core mode rebalancing 2020-12-01 11:56:28 -05:00
Ishaan Bhardwaj
10f032b49b Added more functionality to advanceOneFrame 2020-11-30 12:34:21 -05:00
Ishaan Bhardwaj
5590e6c89b Small DAS changes 2020-11-29 11:11:47 -05:00
Joe Z
0393396d74 Made instant DAS respect instant gravity. 2020-11-29 09:19:17 -05:00
Joe Zeng
8c1eaec1aa DAS priority reversal (#25)
* Reversed the priority of key presses when charging DAS.
* Made it an actual config option.
* Config should be false by default.
2020-11-28 23:29:46 -05:00
Ishaan Bhardwaj
957802a78e Fixed a minor bug in the scope of SA2's line 2020-11-27 23:21:59 -05:00
Ishaan Bhardwaj
169a4e4d2f AX4 no longer shows timer in the roll 2020-11-22 10:39:42 -05:00
Ishaan Bhardwaj
48aee18340 Fix I wallkicks in ARS rules 2020-11-21 23:29:06 -05:00
Ishaan Bhardwaj
7b496d9412 Ti and ACE floorkick fix 2020-11-21 21:48:45 -05:00
Ishaan Bhardwaj
7abb861446 Hard drop can ARE cancel now 2020-11-21 16:29:24 -05:00
Ishaan Bhardwaj
21f8769228 Made ARE canceling also cancel LCD 2020-11-20 11:29:46 -05:00
Ishaan Bhardwaj
44423fd2e8 Made ARE canceling less slippery (again) 2020-11-19 22:22:43 -05:00
Mizu
6d326a142c Update some sounds (not the pieces 2020-11-11 18:38:45 +01:00
Mizu
b6f1072587 Merge branch 'master' of https://github.com/Rexxt/cambridge 2020-11-11 17:43:53 +01:00
Mizu
eef04ebf05 Update graphic names and SOURCES.md 2020-11-11 17:42:48 +01:00
Mizu
e24737a3b8 Merge pull request #1 from SashLilac/master
Update fork
2020-11-11 17:17:22 +01:00
62 changed files with 285 additions and 699 deletions

View File

@@ -1,5 +1,11 @@
![Cambridge Banner](https://cdn.discordapp.com/attachments/764432435802013709/767724895076614154/cambridge_logo_lt.png)
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
=========
@@ -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.
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:
@@ -74,9 +80,9 @@ It should run automatically!
## 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
-------

View File

@@ -8,7 +8,7 @@ Some of the assets are used without proper licenses. We aim to have fully licens
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/
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.
Sounds
------
All piece sounds are (c) 2020 Damian Yerrick.
Other sounds from:
- NullpoMino
- DTET, (c) 2003 Mihys.
Music
-----

View File

@@ -1,27 +1,27 @@
backgrounds = {
[0] = love.graphics.newImage("res/backgrounds/0-quantum-foam.png"),
love.graphics.newImage("res/backgrounds/100-big-bang.png"),
love.graphics.newImage("res/backgrounds/200-spiral-galaxy.png"),
love.graphics.newImage("res/backgrounds/300-sun-and-dust.png"),
love.graphics.newImage("res/backgrounds/400-earth-and-moon.png"),
love.graphics.newImage("res/backgrounds/500-cambrian-explosion.png"),
love.graphics.newImage("res/backgrounds/600-dinosaurs.png"),
love.graphics.newImage("res/backgrounds/700-asteroid.png"),
love.graphics.newImage("res/backgrounds/800-human-fire.png"),
love.graphics.newImage("res/backgrounds/900-early-civilization.png"),
love.graphics.newImage("res/backgrounds/1000-vikings.png"),
love.graphics.newImage("res/backgrounds/1100-crusades.png"),
love.graphics.newImage("res/backgrounds/1200-genghis-khan.png"),
love.graphics.newImage("res/backgrounds/1300-black-death.png"),
love.graphics.newImage("res/backgrounds/1400-columbus-discovery.png"),
love.graphics.newImage("res/backgrounds/1500-aztecas.png"),
love.graphics.newImage("res/backgrounds/1600-telescope.png"),
love.graphics.newImage("res/backgrounds/1700-american-revolution.png"),
love.graphics.newImage("res/backgrounds/1800-railways.png"),
love.graphics.newImage("res/backgrounds/1900-world-wide-web.png"),
title = love.graphics.newImage("res/backgrounds/title_v0.1.png"),
input_config = love.graphics.newImage("res/backgrounds/options-pcb.png"),
game_config = love.graphics.newImage("res/backgrounds/options-gears.png"),
[0] = love.graphics.newImage("res/backgrounds/0.png"),
love.graphics.newImage("res/backgrounds/100.png"),
love.graphics.newImage("res/backgrounds/200.png"),
love.graphics.newImage("res/backgrounds/300.png"),
love.graphics.newImage("res/backgrounds/400.png"),
love.graphics.newImage("res/backgrounds/500.png"),
love.graphics.newImage("res/backgrounds/600.png"),
love.graphics.newImage("res/backgrounds/700.png"),
love.graphics.newImage("res/backgrounds/800.png"),
love.graphics.newImage("res/backgrounds/900.png"),
love.graphics.newImage("res/backgrounds/1000.png"),
love.graphics.newImage("res/backgrounds/1100.png"),
love.graphics.newImage("res/backgrounds/1200.png"),
love.graphics.newImage("res/backgrounds/1300.png"),
love.graphics.newImage("res/backgrounds/1400.png"),
love.graphics.newImage("res/backgrounds/1500.png"),
love.graphics.newImage("res/backgrounds/1600.png"),
love.graphics.newImage("res/backgrounds/1700.png"),
love.graphics.newImage("res/backgrounds/1800.png"),
love.graphics.newImage("res/backgrounds/1900.png"),
title = love.graphics.newImage("res/backgrounds/title.png"),
input_config = love.graphics.newImage("res/backgrounds/options-input.png"),
game_config = love.graphics.newImage("res/backgrounds/options-game.png"),
}
blocks = {

View File

@@ -20,6 +20,8 @@ sounds = {
fall = love.audio.newSource("res/se/fall.wav", "static"),
ready = love.audio.newSource("res/se/ready.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)
@@ -30,7 +32,7 @@ function playSE(sound, subsound)
end
sounds[sound]:play()
else
sounds[sound][subsound]:setVolume(0.1)
sounds[sound][subsound]:setVolume(0.6)
if sounds[sound][subsound]:isPlaying() then
sounds[sound][subsound]:stop()
end

View File

@@ -15,7 +15,12 @@ function love.load()
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
if not config.gamesettings[option[1]] then
config.gamesettings[option[1]] = 1

View File

@@ -4,6 +4,6 @@ mkdir dist/windows
mkdir dist/win32
cp cambridge.love dist/
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
zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE
zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE.md

View File

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 3.6 MiB

View File

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

Before

Width:  |  Height:  |  Size: 3.0 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Binary file not shown.

BIN
res/se/ihs.wav Normal file

Binary file not shown.

BIN
res/se/irs.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -68,6 +68,10 @@ function GameScene:render()
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
function GameScene:onInputPress(e)

View File

@@ -9,6 +9,11 @@ ConfigScene.options = {
{"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}},
{"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}},
{"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
@@ -24,6 +29,7 @@ function ConfigScene:new()
end
function ConfigScene:update()
config["das_last_key"] = config.gamesettings.das_last_key == 2
end
function ConfigScene:render()

View File

@@ -32,6 +32,7 @@ function ConfigScene:new()
self.input_state = 1
self.set_inputs = newSetInputs()
self.new_input = {}
self.axis_timer = 0
DiscordRPC:update({
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("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
end
self.axis_timer = self.axis_timer + 1
end
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.input_state = self.input_state + 1
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)
if not self.new_input.joysticks[e.name].axes then
self.new_input.joysticks[e.name].axes = {}
@@ -128,10 +131,12 @@ function ConfigScene:onInputPress(e)
end
self.set_inputs[configurable_inputs[self.input_state]] =
"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 "")
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.last_axis = e.axis
self.axis_timer = 0
end
elseif e.type == "joyhat" then
if e.direction ~= "c" then

View File

@@ -78,12 +78,15 @@ function Piece:setRelativeRotation(rot)
return self
end
function Piece:moveInGrid(step, squares, grid)
function Piece:moveInGrid(step, squares, grid, instant)
local moved = false
for x = 1, squares do
if grid:canPlacePiece(self:withOffset(step)) then
moved = true
self:setOffset(step)
if instant then
self:dropToBottom(grid)
end
else
break
end

View File

@@ -46,6 +46,11 @@ function GameMode:new()
self.irs = true
self.ihs = true
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
self.drop_locked = false
self.hard_drop_locked = false
@@ -95,11 +100,31 @@ function GameMode:update(inputs, ruleset)
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
if self:advanceOneFrame(inputs) == false then return end
if self:advanceOneFrame(inputs, ruleset) == false then return end
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
self:processDelays(inputs, ruleset)
else
@@ -200,6 +225,8 @@ end
-- event functions
function GameMode:whilePieceActive() end
function GameMode:onAttemptPieceMove(piece) end
function GameMode:onAttemptPieceRotate(piece) end
function GameMode:onPieceLock(piece, cleared_row_count)
playSE("lock")
end
@@ -207,9 +234,7 @@ end
function GameMode:onLineClear(cleared_row_count) end
function GameMode:onPieceEnter() end
function GameMode:onHold()
playSE("hold")
end
function GameMode:onHold() end
function GameMode:onSoftDrop(dropped_row_count)
self.drop_bonus = self.drop_bonus + 1 * dropped_row_count
@@ -223,8 +248,25 @@ function GameMode:onGameOver()
switchBGM(nil)
end
function GameMode:chargeDAS(inputs)
if inputs[self.das.direction] == true then
-- DAS functions
function GameMode:startRightDAS()
self.move = "right"
self.das = { direction = "right", frames = 0 }
if self:getDasLimit() == 0 then
self:continueDAS()
end
end
function GameMode:startLeftDAS()
self.move = "left"
self.das = { direction = "left", frames = 0 }
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
@@ -238,16 +280,35 @@ function GameMode:chargeDAS(inputs)
self.move = "none"
self.das.frames = das_frames
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
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
function GameMode:processDelays(inputs, ruleset, drop_speed)
@@ -270,6 +331,18 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
end
elseif self.lcd > 0 then
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
self.grid:clearClearedRows()
playSE("fall")
@@ -280,7 +353,11 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
elseif self.are > 0 then
self.are = self.are - 1
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_right"] or inputs["rotate_right2"] or
inputs["rotate_180"]) then
@@ -294,7 +371,7 @@ end
function GameMode:initializeOrHold(inputs, ruleset)
if self.ihs and self.enable_hold and inputs["hold"] == true then
self:hold(inputs, ruleset)
self:hold(inputs, ruleset, true)
else
self:initializeNextPiece(inputs, ruleset, self.next_queue[1])
end
@@ -305,7 +382,7 @@ function GameMode:initializeOrHold(inputs, ruleset)
end
end
function GameMode:hold(inputs, ruleset)
function GameMode:hold(inputs, ruleset, ihs)
local data = copy(self.hold_queue)
if self.piece == nil then
self.hold_queue = self.next_queue[1]
@@ -324,6 +401,8 @@ function GameMode:hold(inputs, ruleset)
self:initializeNextPiece(inputs, ruleset, data, false)
end
self.held = true
if ihs then playSE("ihs")
else playSE("hold") end
self:onHold()
end
@@ -346,7 +425,7 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
table.remove(self.next_queue, 1)
table.insert(self.next_queue, self:getNextPiece(ruleset))
end
self:playNextSound()
if config.gamesettings.next_se == 1 then self:playNextSound() end
end
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)
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
self:setHoldOpacity(1, hold_color)
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")
end
function GameMode:sectionColourFunction(section)
return { 1, 1, 1, 1 }
end
function GameMode:drawSectionTimesWithSecondary(current_section)
local section_x = 530
local section_secondary_x = 440
@@ -466,9 +549,11 @@ function GameMode:drawSectionTimesWithSecondary(current_section)
end
for section, time in pairs(self.secondary_section_times) do
love.graphics.setColor(self:sectionColourFunction(section))
if section > 0 then
love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left")
end
love.graphics.setColor(1, 1, 1, 1)
end
local current_x

View File

@@ -327,10 +327,10 @@ function Marathon2020Game:checkClear(level)
end
function Marathon2020Game:updateSectionTimes(old_level, new_level)
function sectionCool()
function sectionCool(section)
self.section_cool_count = self.section_cool_count + 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
end
@@ -348,7 +348,7 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
table.insert(self.section_times, section_time)
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: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] < cool_cutoffs[section]
) then
sectionCool()
sectionCool(section)
elseif self.section_status[section - 1] == "cool" then
table.insert(self.section_status, "none")
elseif section <= 19 and self.secondary_section_times[section] < cool_cutoffs[section] then
sectionCool()
sectionCool(section)
else
table.insert(self.section_status, "none")
end
@@ -423,6 +423,14 @@ function Marathon2020Game:drawGrid()
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()
Marathon2020Game.super.drawScoringInfo(self)

View File

@@ -448,7 +448,7 @@ function MarathonA3Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, 240, 220, 90, "left")
if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
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.setColor(1, 1, 1, 1)
love.graphics.printf(self.level, 240, 340, 40, "right")

View File

@@ -146,7 +146,7 @@ function MarathonAX4Game:drawScoringInfo()
strTrueValues(self.prev_inputs)
)
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")
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
love.graphics.setColor(1, 0.3, 0.3, 1)
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)
end

View File

@@ -255,7 +255,7 @@ PhantomMania2Game.garbageOpacityFunction = function(age)
end
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)
else
self.grid:draw()
@@ -291,7 +291,7 @@ function PhantomMania2Game:setHoldOpacity()
if self.level > 1000 and self.level < 1300 then
love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15))
else
love.graphics.setColor(1, 1, 1, 1)
self.super:setHoldOpacity(1, self.held and 0.6 or 1)
end
end

View File

@@ -159,8 +159,9 @@ function SurvivalA2Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, text_x, 220, 90, "left")
if self.roll_frames > 2968 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
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
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.level, text_x, 340, 40, "right")
love.graphics.printf(self:getSectionEndLevel(), text_x, 370, 40, "right")
if sg >= 5 then

View File

@@ -243,7 +243,7 @@ function SurvivalA3Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3)
if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end
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.setColor(1, 1, 1, 1)
love.graphics.printf(self.score, text_x, 220, 90, "left")

View File

@@ -97,11 +97,11 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
-- kick right, kick left
if (grid:canPlacePiece(new_piece:withOffset({x=1, y=0}))) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=1, 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)
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
end
end

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local Ruleset = require 'tetris.rulesets.arika_ti'
local ARS = Ruleset:extend()
@@ -39,137 +39,16 @@ ARS.big_spawn_positions = {
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)
piece.floorkick = 0
piece.manipulations = 0
end
function ARS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
end
function ARS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
@@ -179,20 +58,13 @@ function ARS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
if piece.floorkick >= 1 then
piece.floorkick = piece.floorkick + 1
end
end
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
return ARS

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local Ruleset = require 'tetris.rulesets.arika_ti'
local ARS = Ruleset:extend()
@@ -26,137 +26,16 @@ ARS.big_spawn_positions = {
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)
piece.floorkick = 0
piece.manipulations = 0
end
function ARS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
end
function ARS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
@@ -166,20 +45,13 @@ function ARS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
if piece.floorkick >= 1 then
piece.floorkick = piece.floorkick + 1
end
end
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
return ARS

View File

@@ -1,22 +1,10 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local Ruleset = require 'tetris.rulesets.ti_srs'
local SRS = Ruleset:extend()
SRS.name = "ACE-SRS"
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 = {
I = { x=5, y=2 },
@@ -38,137 +26,11 @@ SRS.big_spawn_positions = {
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)
piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
@@ -178,18 +40,10 @@ function SRS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then
if piece.manipulations >= 128 then
piece.locked = true
end
end
end
function SRS:get180RotationValue()
if config.gamesettings.world_reverse == 1 then
return 1
else
return 3
end
end
return SRS

View File

@@ -1,77 +1,11 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local Ruleset = require 'tetris.rulesets.arika'
local ARS = Ruleset:extend()
ARS.name = "Ti-ARS"
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.
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
-- 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
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
self:onPieceRotate(piece, grid)
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)
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
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:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
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:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
piece.floorkick = 1
end
end
else
-- kick right, kick left
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
elseif piece.shape == "T"
and new_piece.rotation == 0
and piece.floorkick == 0
and piece:isDropBlocked(grid)
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
then
-- T floorkick
piece.floorkick = piece.floorkick + 1
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
end
end
@@ -149,16 +88,15 @@ end
function ARS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
piece.locked = true
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

View File

@@ -384,9 +384,9 @@ function CRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
for idx, offset in pairs(kicks) do
kicked_piece = new_piece:withOffset(offset)
if grid:canPlacePiece(kicked_piece) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir)
piece:setOffset(offset)
self:onPieceRotate(piece, grid)
return
end
end

View File

@@ -115,8 +115,8 @@ function Ruleset:attemptRotate(new_inputs, piece, grid, initial)
local new_piece = piece:withRelativeRotation(rot_dir)
if (grid:canPlacePiece(new_piece)) then
piece:setRelativeRotation(rot_dir)
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir)
else
if not(initial and self.enable_IRS_wallkicks == false) then
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
end
function Ruleset:movePiece(piece, grid, move)
function Ruleset:movePiece(piece, grid, move, instant)
local x = piece.position.x
if move == "left" then
piece:moveInGrid({x=-1, y=0}, 1, grid)
elseif move == "speedleft" then
piece:moveInGrid({x=-1, y=0}, 10, grid)
piece:moveInGrid({x=-1, y=0}, 1, grid, false)
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
piece:moveInGrid({x=1, y=0}, 10, grid)
piece:moveInGrid({x=1, y=0}, 10, grid, instant)
end
if piece.position.x ~= x then
self:onPieceMove(piece, grid)
@@ -197,7 +197,14 @@ function Ruleset:initializePiece(
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
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)
return piece
end
@@ -211,8 +218,16 @@ function Ruleset:processPiece(
drop_locked, hard_drop_locked,
hard_drop_enabled, additive_gravity
)
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)
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(
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
hard_drop_enabled, additive_gravity

View File

@@ -1,112 +1,22 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset'
local Ruleset = require 'tetris.rulesets.arika_srs'
local SRS = Ruleset:extend()
SRS.name = "Guideline SRS"
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.spawn_positions = {
I = { x=5, y=2 },
J = { x=4, y=3 },
L = { x=4, y=3 },
O = { x=5, y=3 },
S = { x=4, y=3 },
T = { x=4, y=3 },
Z = { x=4, y=3 },
}
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}},
},
};
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
SRS.wallkicks_line = {
[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.
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
@@ -203,4 +103,6 @@ function SRS:onPieceRotate(piece, grid)
end
end
function SRS:get180RotationValue() return 2 end
return SRS

View File

@@ -147,9 +147,9 @@ function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
for idx, offset in pairs(kicks) do
kicked_piece = new_piece:withOffset(offset)
if grid:canPlacePiece(kicked_piece) then
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir)
piece:setOffset(offset)
self:onPieceRotate(piece, grid)
return
end
end