mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52da36bf7 | ||
|
|
76142c1dff | ||
|
|
a3458e2413 | ||
|
|
7eba9c012f | ||
|
|
4d2868b7b6 | ||
|
|
2e6fcd232b | ||
|
|
10833f2ec1 | ||
|
|
abb2b9491e |
58
README.md
58
README.md
@@ -12,41 +12,24 @@ Join our Discord server for help and a welcoming community! https://discord.gg/m
|
||||
Credits
|
||||
-------
|
||||
|
||||
- [Lilla Oshisaure](https://www.youtube.com/user/LeSpyroshisaure) for their amazing contributions to my life in general!
|
||||
- [Lilla Oshisaure](https://www.youtube.com/user/LeSpyroshisaure) for being my co-dev!
|
||||
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
|
||||
- [The Absolute Plus](https://discord.gg/6Gf2awJ) for being another source of motivation!
|
||||
- [joezeng](https://github.com/joezeng) for the original project.
|
||||
- [Hailey](https://github.com/haileylgbt) for some miscellaneous assets.
|
||||
- CylinderKnot for an amazing gamemode.
|
||||
- MarkGamed7794 for some miscellaneous contributions.
|
||||
- Mizu for the Cambridge logo and the [Cambridge launcher](https://github.com/rexxt/cambridge-launcher).
|
||||
- MattMayuga for the Cambridge banner.
|
||||
|
||||
The following people in no particular order also helped with the project:
|
||||
- [Hailey](https://github.com/haileylgbt)
|
||||
- CylinderKnot
|
||||
- MarkGamed7794
|
||||
- [Mizu](https://github.com/rexxt)
|
||||
- MattMayuga
|
||||
- Kitaru
|
||||
- switchpalacecorner
|
||||
|
||||

|
||||
|
||||
Installation instructions
|
||||
-------------------------
|
||||
|
||||
Pre-built releases are available on the releases page.
|
||||
|
||||
### Windows
|
||||
|
||||
Unzip the exe file and run it directly. All assets are currently bundled inside the executable.
|
||||
|
||||
### macOS
|
||||
|
||||
For the time being, the file `cambridge.love` only works on the command line. Install `love` with [Homebrew](https://brew.sh), and run:
|
||||
|
||||
$ love cambridge.love
|
||||
|
||||
### Linux
|
||||
|
||||
Same as macOS, except install `love` with your favourite package manager.
|
||||
|
||||
|
||||
Running from source
|
||||
-------------------
|
||||
|
||||
If you want the bleeding-edge release, you can also clone the code straight from this repository.
|
||||
Playing the game
|
||||
----------------
|
||||
|
||||
### macOS, Linux
|
||||
|
||||
@@ -56,12 +39,27 @@ Clone the repository in git:
|
||||
|
||||
git clone https://github.com/SashLilac/cambridge
|
||||
|
||||
Alternatively, download the source code ZIP in the latest release.
|
||||
|
||||
Then, navigate to the root directory that you just cloned, and type:
|
||||
|
||||
love .
|
||||
|
||||
It should run automatically!
|
||||
|
||||
## Windows
|
||||
|
||||
You do not need LÖVE on Windows, as it comes bundled with the program. Download the source code ZIP in the latest release, or if you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
||||
|
||||
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
|
||||
|
||||
dist\windows\love.exe .
|
||||
|
||||
Alternatively, if you're on a 32-bit system, run this instead:
|
||||
|
||||
dist\win32\love.exe .
|
||||
|
||||
32-bit systems do not support rich presence integration.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
@@ -98,7 +98,7 @@ end
|
||||
|
||||
function Piece:dropToBottom(grid)
|
||||
local piece_y = self.position.y
|
||||
self:dropSquares(24, grid)
|
||||
self:dropSquares(math.huge, grid)
|
||||
self.gravity = 0
|
||||
if self.position.y > piece_y then
|
||||
-- if it got dropped any, also reset lock delay
|
||||
|
||||
@@ -107,7 +107,7 @@ function IntervalTrainingGame:updateSectionTimes(old_level, new_level)
|
||||
end
|
||||
end
|
||||
|
||||
function IntervalTrainingGame:drawGrid(ruleset)
|
||||
function IntervalTrainingGame:drawGrid()
|
||||
self.grid:draw()
|
||||
end
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ MarathonA3Game.tagline = "The game gets faster way more quickly! Can you get all
|
||||
|
||||
function MarathonA3Game:new()
|
||||
MarathonA3Game.super:new()
|
||||
|
||||
self.speed_level = 0
|
||||
|
||||
self.speed_level = 0
|
||||
self.roll_frames = 0
|
||||
self.combo = 1
|
||||
self.grade = 0
|
||||
@@ -29,6 +29,7 @@ function MarathonA3Game:new()
|
||||
self.section_start_time = 0
|
||||
self.section_70_times = { [0] = 0 }
|
||||
self.section_times = { [0] = 0 }
|
||||
self.section_cool = false
|
||||
|
||||
self.randomizer = History6RollsRandomizer()
|
||||
|
||||
@@ -151,6 +152,7 @@ function MarathonA3Game:onPieceEnter()
|
||||
self:updateSectionTimes(self.level, self.level + 1)
|
||||
self.level = self.level + 1
|
||||
self.speed_level = self.speed_level + 1
|
||||
self.torikan_passed = self.level >= 500 and true or false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -171,7 +173,7 @@ function MarathonA3Game:onLineClear(cleared_row_count)
|
||||
if not self.torikan_passed and self.level >= 500 and self.frames >= 25200 then
|
||||
self.level = 500
|
||||
self.game_over = true
|
||||
elseif self.level >= 500 then self.torikan_passed = true end
|
||||
end
|
||||
end
|
||||
|
||||
local cool_cutoffs = {
|
||||
@@ -194,33 +196,37 @@ function MarathonA3Game:updateSectionTimes(old_level, new_level)
|
||||
table.insert(self.section_times, section_time)
|
||||
self.section_start_time = self.frames
|
||||
|
||||
self.speed_level = self.section_cool and self.speed_level + 100 or self.speed_level
|
||||
|
||||
if section_time > regret_cutoffs[section] then
|
||||
self.section_cool_grade = self.section_cool_grade - 1
|
||||
table.insert(self.section_status, "regret")
|
||||
self.coolregret_message = "REGRET!!"
|
||||
self.coolregret_timer = 300
|
||||
elseif section <= 9 and self.section_status[section - 1] == "cool" and
|
||||
self.section_70_times[section] < self.section_70_times[section - 1] + 120 then
|
||||
elseif self.section_cool then
|
||||
self.section_cool_grade = self.section_cool_grade + 1
|
||||
self.speed_level = self.speed_level + 100
|
||||
table.insert(self.section_status, "cool")
|
||||
self.coolregret_message = "COOL!!"
|
||||
self.coolregret_timer = 300
|
||||
elseif self.section_status[section - 1] == "cool" then
|
||||
table.insert(self.section_status, "none")
|
||||
elseif section <= 9 and self.section_70_times[section] < cool_cutoffs[section] then
|
||||
self.section_cool_grade = self.section_cool_grade + 1
|
||||
self.speed_level = self.speed_level + 100
|
||||
table.insert(self.section_status, "cool")
|
||||
self.coolregret_message = "COOL!!"
|
||||
self.coolregret_timer = 300
|
||||
else
|
||||
table.insert(self.section_status, "none")
|
||||
end
|
||||
elseif section <= 9 and old_level % 100 < 70 and new_level % 100 >= 70 then
|
||||
|
||||
self.section_cool = false
|
||||
elseif old_level % 100 < 70 and new_level % 100 >= 70 then
|
||||
-- record section 70 time
|
||||
section_70_time = self.frames - self.section_start_time
|
||||
table.insert(self.section_70_times, section_70_time)
|
||||
|
||||
if section <= 9 and self.section_status[section - 1] == "cool" and
|
||||
self.section_70_times[section] < self.section_70_times[section - 1] + 120 then
|
||||
self.section_cool = true
|
||||
self.coolregret_message = "COOL!!"
|
||||
self.coolregret_timer = 300
|
||||
elseif self.section_status[section - 1] == "cool" then self.section_cool = false
|
||||
elseif section <= 9 and self.section_70_times[section] < cool_cutoffs[section] then
|
||||
self.section_cool = true
|
||||
self.coolregret_message = "COOL!!"
|
||||
self.coolregret_timer = 300
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -430,7 +436,7 @@ function MarathonA3Game:drawScoringInfo()
|
||||
current_x = section_70_x
|
||||
end
|
||||
|
||||
love.graphics.printf(formatTime(self.frames - self.section_start_time), current_x, 40 + 20 * current_section, 90, "left")
|
||||
if not self.clear then love.graphics.printf(formatTime(self.frames - self.section_start_time), current_x, 40 + 20 * current_section, 90, "left") end
|
||||
|
||||
if(self.coolregret_timer > 0) then
|
||||
love.graphics.printf(self.coolregret_message, 64, 400, 160, "center")
|
||||
@@ -439,7 +445,10 @@ 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
|
||||
love.graphics.printf(self:getLetterGrade(), 240, 140, 90, "left")
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.printf(self.level, 240, 340, 40, "right")
|
||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 40, "right")
|
||||
if sg >= 5 then
|
||||
|
||||
189
tetris/modes/scoredrain.lua
Normal file
189
tetris/modes/scoredrain.lua
Normal file
@@ -0,0 +1,189 @@
|
||||
require 'funcs'
|
||||
|
||||
local GameMode = require 'tetris.modes.gamemode'
|
||||
local Piece = require 'tetris.components.piece'
|
||||
|
||||
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
||||
|
||||
local ScoreDrainGame = GameMode:extend()
|
||||
|
||||
ScoreDrainGame.name = "Score Drain"
|
||||
ScoreDrainGame.hash = "ScoreDrain"
|
||||
ScoreDrainGame.tagline = "Your score goes down over time! Avoid hitting 0 points, or your game is over!"
|
||||
|
||||
function ScoreDrainGame:new()
|
||||
self.super:new()
|
||||
|
||||
self.score = 2500
|
||||
self.drain_rate = 50
|
||||
self.combo = 1
|
||||
self.randomizer = History6RollsRandomizer()
|
||||
|
||||
self.lock_drop = true
|
||||
self.lock_hard_drop = true
|
||||
self.enable_hold = true
|
||||
self.next_queue_length = 3
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getARE()
|
||||
if self.level < 700 then return 27
|
||||
elseif self.level < 800 then return 18
|
||||
elseif self.level < 1000 then return 14
|
||||
elseif self.level < 1100 then return 8
|
||||
elseif self.level < 1200 then return 7
|
||||
else return 6 end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getLineARE()
|
||||
if self.level < 600 then return 27
|
||||
elseif self.level < 700 then return 18
|
||||
elseif self.level < 800 then return 14
|
||||
elseif self.level < 1100 then return 8
|
||||
elseif self.level < 1200 then return 7
|
||||
else return 6 end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getDasLimit()
|
||||
if self.level < 500 then return 15
|
||||
elseif self.level < 900 then return 9
|
||||
else return 7 end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getLineClearDelay()
|
||||
if self.level < 500 then return 40
|
||||
elseif self.level < 600 then return 25
|
||||
elseif self.level < 700 then return 16
|
||||
elseif self.level < 800 then return 12
|
||||
elseif self.level < 1100 then return 6
|
||||
elseif self.level < 1200 then return 5
|
||||
else return 4 end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getLockDelay()
|
||||
if self.level < 900 then return 30
|
||||
elseif self.level < 1100 then return 17
|
||||
else return 15 end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getGravity()
|
||||
if (self.level < 30) then return 4/256
|
||||
elseif (self.level < 35) then return 6/256
|
||||
elseif (self.level < 40) then return 8/256
|
||||
elseif (self.level < 50) then return 10/256
|
||||
elseif (self.level < 60) then return 12/256
|
||||
elseif (self.level < 70) then return 16/256
|
||||
elseif (self.level < 80) then return 32/256
|
||||
elseif (self.level < 90) then return 48/256
|
||||
elseif (self.level < 100) then return 64/256
|
||||
elseif (self.level < 120) then return 80/256
|
||||
elseif (self.level < 140) then return 96/256
|
||||
elseif (self.level < 160) then return 112/256
|
||||
elseif (self.level < 170) then return 128/256
|
||||
elseif (self.level < 200) then return 144/256
|
||||
elseif (self.level < 220) then return 4/256
|
||||
elseif (self.level < 230) then return 32/256
|
||||
elseif (self.level < 233) then return 64/256
|
||||
elseif (self.level < 236) then return 96/256
|
||||
elseif (self.level < 239) then return 128/256
|
||||
elseif (self.level < 243) then return 160/256
|
||||
elseif (self.level < 247) then return 192/256
|
||||
elseif (self.level < 251) then return 224/256
|
||||
elseif (self.level < 300) then return 1
|
||||
elseif (self.level < 330) then return 2
|
||||
elseif (self.level < 360) then return 3
|
||||
elseif (self.level < 400) then return 4
|
||||
elseif (self.level < 420) then return 5
|
||||
elseif (self.level < 450) then return 4
|
||||
elseif (self.level < 500) then return 3
|
||||
else return 20
|
||||
end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:advanceOneFrame()
|
||||
if self.ready_frames == 0 then
|
||||
self.frames = self.frames + 1
|
||||
self.score = math.max(0, self.score - self.drain_rate / 60)
|
||||
self.game_over = self.score <= 0 and true or false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function ScoreDrainGame:onPieceEnter()
|
||||
if (self.level % 100 ~= 99) and self.frames ~= 0 then
|
||||
self.level = self.level + 1
|
||||
end
|
||||
end
|
||||
|
||||
local cleared_row_levels = {1, 2, 4, 6}
|
||||
|
||||
function ScoreDrainGame:onLineClear(cleared_row_count)
|
||||
local new_level = self.level + cleared_row_levels[cleared_row_count]
|
||||
self.drain_rate = math.floor(self.level / 100) < math.floor(new_level / 100) and self.drain_rate * 1.5 or self.drain_rate
|
||||
self.level = new_level
|
||||
end
|
||||
|
||||
function ScoreDrainGame:updateScore(level, drop_bonus, cleared_lines)
|
||||
if cleared_lines > 0 then
|
||||
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||
self.score = self.score + (
|
||||
(math.ceil((level + cleared_lines) / 4) + drop_bonus) *
|
||||
cleared_lines * self.combo
|
||||
)
|
||||
else
|
||||
self.combo = 1
|
||||
end
|
||||
self.drop_bonus = 0
|
||||
end
|
||||
|
||||
function ScoreDrainGame:drawGrid()
|
||||
self.grid:draw()
|
||||
if self.piece ~= nil and self.level < 100 then
|
||||
self:drawGhostPiece(ruleset)
|
||||
end
|
||||
end
|
||||
|
||||
function ScoreDrainGame:drawScoringInfo()
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
|
||||
love.graphics.setFont(font_3x5_2)
|
||||
love.graphics.print(
|
||||
self.das.direction .. " " ..
|
||||
self.das.frames .. " " ..
|
||||
strTrueValues(self.prev_inputs)
|
||||
)
|
||||
love.graphics.printf("NEXT", 64, 40, 40, "left")
|
||||
love.graphics.printf("DRAIN RATE", 240, 90, 80, "left")
|
||||
love.graphics.printf("SCORE", 240, 170, 40, "left")
|
||||
love.graphics.printf("TIME LEFT", 240, 250, 80, "left")
|
||||
love.graphics.printf("LEVEL", 240, 320, 40, "left")
|
||||
|
||||
love.graphics.setFont(font_3x5_3)
|
||||
love.graphics.printf(math.floor(self.drain_rate).."/s", 240, 110, 120, "left")
|
||||
local frames_left = self.score / self.drain_rate * 60
|
||||
if frames_left <= 600 and frames_left % 4 < 2 and not self.game_over then love.graphics.setColor(1, 0.3, 0.3, 1) end
|
||||
love.graphics.printf(formatTime(frames_left), 240, 270, 120, "left")
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.printf(math.floor(self.score), 240, 190, 90, "left")
|
||||
love.graphics.printf(self.level, 240, 340, 50, "right")
|
||||
love.graphics.printf(self:getSectionEndLevel(), 240, 370, 50, "right")
|
||||
|
||||
love.graphics.setFont(font_8x11)
|
||||
love.graphics.printf(formatTime(self.frames), 64, 420, 160, "center")
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getHighscoreData()
|
||||
return {
|
||||
level = self.level,
|
||||
frames = self.frames,
|
||||
}
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getSectionEndLevel()
|
||||
return math.floor(self.level / 100 + 1) * 100
|
||||
end
|
||||
|
||||
function ScoreDrainGame:getBackground()
|
||||
return math.floor(self.level / 100)
|
||||
end
|
||||
|
||||
return ScoreDrainGame
|
||||
@@ -157,6 +157,8 @@ 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
|
||||
if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end
|
||||
love.graphics.printf(self.level, text_x, 340, 40, "right")
|
||||
love.graphics.printf(self:getSectionEndLevel(), text_x, 370, 40, "right")
|
||||
|
||||
@@ -18,8 +18,6 @@ SRS.colourscheme = {
|
||||
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 },
|
||||
|
||||
173
tetris/rulesets/crap.lua
Normal file
173
tetris/rulesets/crap.lua
Normal file
@@ -0,0 +1,173 @@
|
||||
local Piece = require 'tetris.components.piece'
|
||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||
|
||||
local CRAP = Ruleset:extend()
|
||||
|
||||
CRAP.name = "C.R.A.P."
|
||||
CRAP.hash = "Completely Random Auto-Positioner"
|
||||
CRAP.world = true
|
||||
CRAP.colors={"C","O","M","R","G","Y","B"}
|
||||
CRAP.colourscheme = {
|
||||
I = CRAP.colors[math.ceil(math.random(7))],
|
||||
L = CRAP.colors[math.ceil(math.random(7))],
|
||||
J = CRAP.colors[math.ceil(math.random(7))],
|
||||
S = CRAP.colors[math.ceil(math.random(7))],
|
||||
Z = CRAP.colors[math.ceil(math.random(7))],
|
||||
O = CRAP.colors[math.ceil(math.random(7))],
|
||||
T = CRAP.colors[math.ceil(math.random(7))],
|
||||
}
|
||||
CRAP.softdrop_lock = true
|
||||
CRAP.harddrop_lock = false
|
||||
|
||||
CRAP.enable_IRS_wallkicks = true
|
||||
|
||||
CRAP.spawn_positions = {
|
||||
I = { x=5, y=4 },
|
||||
J = { x=4, y=5 },
|
||||
L = { x=4, y=5 },
|
||||
O = { x=5, y=5 },
|
||||
S = { x=4, y=5 },
|
||||
T = { x=4, y=5 },
|
||||
Z = { x=4, y=5 },
|
||||
}
|
||||
|
||||
CRAP.big_spawn_positions = {
|
||||
I = { x=3, y=2 },
|
||||
J = { x=2, y=3 },
|
||||
L = { x=2, y=3 },
|
||||
O = { x=3, y=3 },
|
||||
S = { x=2, y=3 },
|
||||
T = { x=2, y=3 },
|
||||
Z = { x=2, y=3 },
|
||||
}
|
||||
|
||||
CRAP.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
|
||||
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1} },
|
||||
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2} },
|
||||
},
|
||||
J={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1} },
|
||||
},
|
||||
L={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||
},
|
||||
O={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
},
|
||||
S={
|
||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
||||
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0} },
|
||||
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||
},
|
||||
T={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0} },
|
||||
},
|
||||
Z={
|
||||
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
|
||||
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0} },
|
||||
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||
}
|
||||
}
|
||||
|
||||
-- Component functions.
|
||||
|
||||
function CRAP:attemptRotate(new_inputs, piece, grid, initial)
|
||||
local rot_dir = 0
|
||||
|
||||
if (new_inputs["rotate_left"] or new_inputs["rotate_left2"]) then
|
||||
rot_dir = 3
|
||||
elseif (new_inputs["rotate_right"] or new_inputs["rotate_right2"]) then
|
||||
rot_dir = 1
|
||||
elseif (new_inputs["rotate_180"]) then
|
||||
rot_dir = self:get180RotationValue()
|
||||
end
|
||||
|
||||
if rot_dir == 0 then return end
|
||||
if self.world and config.gamesettings.world_reverse == 2 then
|
||||
rot_dir = 4 - rot_dir
|
||||
end
|
||||
|
||||
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||
|
||||
self:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
end
|
||||
|
||||
function CRAP:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
for i=1,20 do
|
||||
dx=math.floor(math.random(11))-5
|
||||
dy=math.floor(math.random(11))-5
|
||||
if grid:canPlacePiece(new_piece:withOffset({x=dx, y=dy})) then
|
||||
piece:setRelativeRotation(rot_dir):setOffset({x=dx, y=dy})
|
||||
self:onPieceRotate(piece, grid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function CRAP:onPieceCreate(piece, grid)
|
||||
CRAP:randomizeColours()
|
||||
piece.manipulations = 0
|
||||
piece.rotations = 0
|
||||
end
|
||||
|
||||
function CRAP:onPieceDrop(piece, grid)
|
||||
CRAP:randomizeColours()
|
||||
piece.lock_delay = 0 -- step reset
|
||||
end
|
||||
|
||||
function CRAP:onPieceMove(piece, grid)
|
||||
CRAP:randomizeColours()
|
||||
piece.lock_delay = 0 -- move reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.manipulations = piece.manipulations + 1
|
||||
if piece.manipulations >= 10 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CRAP:onPieceRotate(piece, grid)
|
||||
CRAP:randomizeColours()
|
||||
piece.lock_delay = 0 -- rotate reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.rotations = piece.rotations + 1
|
||||
if piece.rotations >= 8 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CRAP:get180RotationValue() return 2 end
|
||||
|
||||
function CRAP:randomizeColours()
|
||||
CRAP.colourscheme = {
|
||||
I = CRAP.colors[math.ceil(math.random(7))],
|
||||
L = CRAP.colors[math.ceil(math.random(7))],
|
||||
J = CRAP.colors[math.ceil(math.random(7))],
|
||||
S = CRAP.colors[math.ceil(math.random(7))],
|
||||
Z = CRAP.colors[math.ceil(math.random(7))],
|
||||
O = CRAP.colors[math.ceil(math.random(7))],
|
||||
T = CRAP.colors[math.ceil(math.random(7))],
|
||||
}
|
||||
end
|
||||
|
||||
return CRAP
|
||||
153
tetris/rulesets/dtet.lua
Normal file
153
tetris/rulesets/dtet.lua
Normal file
@@ -0,0 +1,153 @@
|
||||
local Piece = require 'tetris.components.piece'
|
||||
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||
|
||||
local DTET = Ruleset:extend()
|
||||
|
||||
DTET.name = "D.R.S."
|
||||
DTET.hash = "DTET"
|
||||
|
||||
DTET.spawn_positions = {
|
||||
I = { x=5, y=4 },
|
||||
J = { x=4, y=5 },
|
||||
L = { x=4, y=5 },
|
||||
O = { x=5, y=5 },
|
||||
S = { x=4, y=5 },
|
||||
T = { x=4, y=5 },
|
||||
Z = { x=4, y=5 },
|
||||
}
|
||||
|
||||
DTET.big_spawn_positions = {
|
||||
I = { x=3, y=2 },
|
||||
J = { x=2, y=3 },
|
||||
L = { x=2, y=3 },
|
||||
O = { x=3, y=3 },
|
||||
S = { x=2, y=3 },
|
||||
T = { x=2, y=3 },
|
||||
Z = { x=2, y=3 },
|
||||
}
|
||||
|
||||
DTET.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
{ {x=-1, y=-1}, {x=-1, y=-2}, {x=-1, y=0}, {x=-1, y=1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=0, y=1} },
|
||||
},
|
||||
J={
|
||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
|
||||
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
||||
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
||||
},
|
||||
L={
|
||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
|
||||
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
||||
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
|
||||
},
|
||||
O={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||
},
|
||||
S={
|
||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
||||
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
||||
{ {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=1, y=-1} },
|
||||
{ {x=1, y=0}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||
},
|
||||
T={
|
||||
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
|
||||
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
||||
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
|
||||
},
|
||||
Z={
|
||||
{ {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||
{ {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||
{ {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||
{ {x=1, y=-2}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
|
||||
}
|
||||
}
|
||||
|
||||
-- clockwise kicks: {{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
-- counterclockwise kicks: {{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
|
||||
DTET.wallkicks_3x3 = {
|
||||
[0]={
|
||||
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
[1]={
|
||||
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
[2]={
|
||||
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[3]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
},
|
||||
[3]={
|
||||
[0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
};
|
||||
|
||||
DTET.wallkicks_line = {
|
||||
[0]={
|
||||
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
[1]={
|
||||
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
[2]={
|
||||
[0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
[3]={
|
||||
[0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}},
|
||||
[1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
[2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}},
|
||||
},
|
||||
};
|
||||
|
||||
function DTET:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
local kicks
|
||||
if piece.shape == "O" then
|
||||
return
|
||||
elseif piece.shape == "I" then
|
||||
kicks = DTET.wallkicks_line[piece.rotation][new_piece.rotation]
|
||||
else
|
||||
kicks = DTET.wallkicks_3x3[piece.rotation][new_piece.rotation]
|
||||
end
|
||||
|
||||
assert(piece.rotation ~= new_piece.rotation)
|
||||
|
||||
for idx, offset in pairs(kicks) do
|
||||
kicked_piece = new_piece:withOffset(offset)
|
||||
if grid:canPlacePiece(kicked_piece) then
|
||||
piece:setRelativeRotation(rot_dir)
|
||||
piece:setOffset(offset)
|
||||
self:onPieceRotate(piece, grid)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DTET:onPieceDrop(piece, grid)
|
||||
piece.lock_delay = 0 -- step reset
|
||||
end
|
||||
|
||||
function DTET:getDefaultOrientation() return 1 end
|
||||
|
||||
return DTET
|
||||
45
tetris/rulesets/eheart.lua
Normal file
45
tetris/rulesets/eheart.lua
Normal file
@@ -0,0 +1,45 @@
|
||||
local Piece = require 'tetris.components.piece'
|
||||
local ARS = require 'tetris.rulesets.arika'
|
||||
|
||||
local EHeart = ARS:extend()
|
||||
|
||||
EHeart.name = "E-Heart ARS"
|
||||
EHeart.hash = "EHeartARS"
|
||||
|
||||
function EHeart:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
-- I and O don't kick
|
||||
if (piece.shape == "I" or piece.shape == "O") then return end
|
||||
|
||||
-- center column rule (kicks)
|
||||
local offsets = new_piece:getBlockOffsets()
|
||||
table.sort(offsets, function(A, B) return A.y < B.y or A.y == B.y and A.x < B.y end)
|
||||
for index, offset in pairs(offsets) do
|
||||
if grid:isOccupied(piece.position.x + offset.x, piece.position.y + offset.y) then
|
||||
-- individual checks for all 9 cells, in the given order
|
||||
if offset.y < 0 then
|
||||
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||
elseif offset.x == 0 then return
|
||||
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||
elseif offset.y == 0 then
|
||||
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||
elseif offset.x == 0 then return
|
||||
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||
elseif offset.y > 0 then
|
||||
if offset.x < 0 then self:lateralKick(1, piece, new_piece, rot_dir, grid)
|
||||
elseif offset.x == 0 then return
|
||||
elseif offset.x > 0 then self:lateralKick(-1, piece, new_piece, rot_dir, grid) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function EHeart:lateralKick(dx, piece, new_piece, rot_dir, grid)
|
||||
if (grid:canPlacePiece(new_piece:withOffset({x=dx, y=0}))) then
|
||||
piece:setRelativeRotation(rot_dir):setOffset({x=dx, y=0})
|
||||
self:onPieceRotate(piece, grid)
|
||||
end
|
||||
end
|
||||
|
||||
return EHeart
|
||||
102
tetris/rulesets/pptprs.lua
Normal file
102
tetris/rulesets/pptprs.lua
Normal file
@@ -0,0 +1,102 @@
|
||||
local Piece = require 'tetris.components.piece'
|
||||
local SRS = require 'tetris.rulesets.standard_exp'
|
||||
|
||||
local PPTPRS = SRS:extend()
|
||||
|
||||
PPTPRS.name = "PPTPRS"
|
||||
PPTPRS.hash = "Puyo Tetris Pentos"
|
||||
|
||||
PPTPRS.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0}, {x=-3, y=0} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2}, {x=0, y=-2} },
|
||||
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1}, {x=2, y=1} },
|
||||
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2}, {x=-1, y=3} },
|
||||
},
|
||||
J={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1}, {x=0, y=1} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1}, {x=-1, y=0} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1}, {x=0, y=-1} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1}, {x=1, y=0} },
|
||||
},
|
||||
L={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1}, {x=-1, y=1} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=-1} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1}, {x=1, y=-1} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=1} },
|
||||
},
|
||||
O={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=-1, y=1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=-2, y=-1} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=-2} },
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=0} },
|
||||
},
|
||||
S={
|
||||
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0} },
|
||||
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2} },
|
||||
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0}, {x=2, y=0} },
|
||||
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||
},
|
||||
T={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1}, {x=0, y=-2} },
|
||||
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0}, {x=2, y=0} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0}, {x=-2, y=0} },
|
||||
},
|
||||
Z={
|
||||
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0}, {x=1, y=1} },
|
||||
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1}, {x=-1, y=1} },
|
||||
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1} },
|
||||
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=1, y=-1} },
|
||||
}
|
||||
}
|
||||
|
||||
PPTPRS.wallkicks_O = {
|
||||
[0]={
|
||||
[1]={{x=0, y=1}},
|
||||
[2]={{x=0, y=1}},
|
||||
[3]={{x=-1, y=0}},
|
||||
},
|
||||
[1]={
|
||||
[0]={{x=0, y=-1}},
|
||||
[2]={{x=-1, y=0}},
|
||||
[3]={{x=-1, y=0}},
|
||||
},
|
||||
[2]={
|
||||
[0]={{x=0, y=-1}},
|
||||
[1]={{x=1, y=0}},
|
||||
[3]={{x=0, y=-1}},
|
||||
},
|
||||
[3]={
|
||||
[0]={{x=1, y=0}},
|
||||
[1]={{x=1, y=0}},
|
||||
[2]={{x=0, y=1}},
|
||||
},
|
||||
}
|
||||
|
||||
function PPTPRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
local kicks
|
||||
|
||||
if piece.shape == "O" then
|
||||
kicks = PPTPRS.wallkicks_O[piece.rotation][new_piece.rotation]
|
||||
elseif piece.shape == "I" then
|
||||
kicks = SRS.wallkicks_line[piece.rotation][new_piece.rotation]
|
||||
else
|
||||
kicks = SRS.wallkicks_3x3[piece.rotation][new_piece.rotation]
|
||||
end
|
||||
|
||||
assert(piece.rotation ~= new_piece.rotation)
|
||||
|
||||
for idx, offset in pairs(kicks) do
|
||||
kicked_piece = new_piece:withOffset(offset)
|
||||
if grid:canPlacePiece(kicked_piece) then
|
||||
piece:setRelativeRotation(rot_dir)
|
||||
piece:setOffset(offset)
|
||||
self:onPieceRotate(piece, grid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return PPTPRS
|
||||
@@ -18,8 +18,6 @@ SRS.colourscheme = {
|
||||
SRS.softdrop_lock = false
|
||||
SRS.harddrop_lock = true
|
||||
|
||||
SRS.enable_IRS_wallkicks = true
|
||||
|
||||
SRS.spawn_positions = {
|
||||
I = { x=5, y=4 },
|
||||
J = { x=4, y=5 },
|
||||
|
||||
Reference in New Issue
Block a user