mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
23 Commits
v0.3-beta1
...
v0.3-pre1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f22424d671 | ||
|
|
dd6baf1fe6 | ||
|
|
11cf5a9d55 | ||
|
|
5642ed1326 | ||
|
|
c0888c484f | ||
|
|
3ef3b193fd | ||
|
|
0c2e3efd1a | ||
|
|
5076adf022 | ||
|
|
1a75d983dc | ||
|
|
5b8e9586bd | ||
|
|
7d7dd8c3c2 | ||
|
|
29afdcecfc | ||
|
|
8b09833ae6 | ||
|
|
64047eaf9c | ||
|
|
125488b4d9 | ||
|
|
1fdd091456 | ||
|
|
ced40297cc | ||
|
|
32f2a0b3e7 | ||
|
|
dd5347ad8d | ||
|
|
b732ebb213 | ||
|
|
84634d6933 | ||
|
|
0d13a9f236 | ||
|
|
45120bc9f7 |
15
README.md
15
README.md
@@ -1,10 +1,5 @@
|
|||||||

|

|
||||||
|
|
||||||
Important notice
|
|
||||||
================
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Cambridge
|
Cambridge
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@@ -65,6 +60,14 @@ Then, check the mod pack section at the bottom of this page.
|
|||||||
|
|
||||||
If you haven't already, install `love` with your favourite package manager (Homebrew on macOS, your system's default on Linux). **Make sure you're using LÖVE 11, because it won't work with earlier versions!**
|
If you haven't already, install `love` with your favourite package manager (Homebrew on macOS, your system's default on Linux). **Make sure you're using LÖVE 11, because it won't work with earlier versions!**
|
||||||
|
|
||||||
|
#### Downloading a release
|
||||||
|
|
||||||
|
You can download the .love file in the latest release, and run it with:
|
||||||
|
|
||||||
|
love cambridge.love
|
||||||
|
|
||||||
|
#### Installing from source
|
||||||
|
|
||||||
Clone the repository in git:
|
Clone the repository in git:
|
||||||
|
|
||||||
git clone https://github.com/SashLilac/cambridge
|
git clone https://github.com/SashLilac/cambridge
|
||||||
@@ -81,6 +84,8 @@ It should run 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.
|
Simply drag your mode, ruleset, and randomizer Lua files into their respective [directory](https://love2d.org/wiki/love.filesystem), and they should appear automatically.
|
||||||
|
|
||||||
|
You can also load custom assets through this way, assuming you preserve the directory structure.
|
||||||
|
|
||||||
**WARNING:** The .exe / .love files and the bleeding edge releases have different save directories. Read the above link carefully!
|
**WARNING:** The .exe / .love files and the bleeding edge releases have different save directories. Read the above link carefully!
|
||||||
|
|
||||||
For more detailed instructions, 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.
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ function CreditsScene:new()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function CreditsScene:update()
|
function CreditsScene:update()
|
||||||
self.frames = self.frames + 1
|
if love.window.hasFocus() then
|
||||||
|
self.frames = self.frames + 1
|
||||||
|
end
|
||||||
if self.frames >= 4200 then
|
if self.frames >= 4200 then
|
||||||
playSE("mode_decide")
|
playSE("mode_decide")
|
||||||
scene = TitleScene()
|
scene = TitleScene()
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ GameScene.title = "Game"
|
|||||||
|
|
||||||
require 'load.save'
|
require 'load.save'
|
||||||
|
|
||||||
function GameScene:new(game_mode, ruleset)
|
function GameScene:new(game_mode, ruleset, inputs)
|
||||||
self.retry_mode = game_mode
|
self.retry_mode = game_mode
|
||||||
self.retry_ruleset = ruleset
|
self.retry_ruleset = ruleset
|
||||||
self.game = game_mode()
|
self.secret_inputs = copy(inputs)
|
||||||
|
self.game = game_mode(self.secret_inputs)
|
||||||
self.ruleset = ruleset()
|
self.ruleset = ruleset()
|
||||||
self.game:initialize(self.ruleset)
|
self.game:initialize(self.ruleset, self.secret_inputs)
|
||||||
self.inputs = {
|
self.inputs = {
|
||||||
left=false,
|
left=false,
|
||||||
right=false,
|
right=false,
|
||||||
@@ -82,9 +83,9 @@ function GameScene:onInputPress(e)
|
|||||||
highscore_entry = self.game:getHighscoreData()
|
highscore_entry = self.game:getHighscoreData()
|
||||||
highscore_hash = self.game.hash .. "-" .. self.ruleset.hash
|
highscore_hash = self.game.hash .. "-" .. self.ruleset.hash
|
||||||
submitHighscore(highscore_hash, highscore_entry)
|
submitHighscore(highscore_hash, highscore_entry)
|
||||||
scene = e.input == "retry" and GameScene(self.retry_mode, self.retry_ruleset) or ModeSelectScene()
|
scene = e.input == "retry" and GameScene(self.retry_mode, self.retry_ruleset, self.secret_inputs) or ModeSelectScene()
|
||||||
elseif e.input == "retry" then
|
elseif e.input == "retry" then
|
||||||
scene = GameScene(self.retry_mode, self.retry_ruleset)
|
scene = GameScene(self.retry_mode, self.retry_ruleset, self.secret_inputs)
|
||||||
elseif e.input == "pause" and not (self.game.game_over or self.game.completed) then
|
elseif e.input == "pause" and not (self.game.game_over or self.game.completed) then
|
||||||
self.paused = not self.paused
|
self.paused = not self.paused
|
||||||
if self.paused then pauseBGM()
|
if self.paused then pauseBGM()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ ConfigScene.options = {
|
|||||||
{"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}},
|
{"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}},
|
||||||
{"synchroes_allowed", "Synchroes", false, {"Per ruleset", "On", "Off"}},
|
{"synchroes_allowed", "Synchroes", false, {"Per ruleset", "On", "Off"}},
|
||||||
{"diagonal_input", "Diagonal Input", false, {"On", "Off"}},
|
{"diagonal_input", "Diagonal Input", false, {"On", "Off"}},
|
||||||
|
{"buffer_lock", "Buffer Lock Inputs", false, {"On", "Off"}},
|
||||||
{"sfx_volume", "SFX", true, "sfxSlider"},
|
{"sfx_volume", "SFX", true, "sfxSlider"},
|
||||||
{"bgm_volume", "BGM", true, "bgmSlider"},
|
{"bgm_volume", "BGM", true, "bgmSlider"},
|
||||||
}
|
}
|
||||||
@@ -55,7 +56,7 @@ function ConfigScene:render()
|
|||||||
--Lazy check to see if we're on the SFX or BGM slider. Probably will need to be rewritten if more options get added.
|
--Lazy check to see if we're on the SFX or BGM slider. Probably will need to be rewritten if more options get added.
|
||||||
love.graphics.setColor(1, 1, 1, 0.5)
|
love.graphics.setColor(1, 1, 1, 0.5)
|
||||||
if not ConfigScene.options[self.highlight][3] then
|
if not ConfigScene.options[self.highlight][3] then
|
||||||
love.graphics.rectangle("fill", 20, 98 + self.highlight * 20, 170, 22)
|
love.graphics.rectangle("fill", 25, 98 + self.highlight * 20, 170, 22)
|
||||||
else
|
else
|
||||||
love.graphics.rectangle("fill", 65 + (1+self.highlight-#self.options) * 300, 322, 215, 33)
|
love.graphics.rectangle("fill", 65 + (1+self.highlight-#self.options) * 300, 322, 215, 33)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ function ModeSelectScene:new()
|
|||||||
ruleset = current_ruleset,
|
ruleset = current_ruleset,
|
||||||
select = "mode",
|
select = "mode",
|
||||||
}
|
}
|
||||||
|
self.secret_inputs = {
|
||||||
|
rotate_left = false,
|
||||||
|
rotate_left2 = false,
|
||||||
|
rotate_right = false,
|
||||||
|
rotate_right2 = false,
|
||||||
|
rotate_180 = false,
|
||||||
|
hold = false,
|
||||||
|
}
|
||||||
DiscordRPC:update({
|
DiscordRPC:update({
|
||||||
details = "In menus",
|
details = "In menus",
|
||||||
state = "Choosing a mode",
|
state = "Choosing a mode",
|
||||||
@@ -67,7 +75,7 @@ function ModeSelectScene:onInputPress(e)
|
|||||||
config.current_ruleset = current_ruleset
|
config.current_ruleset = current_ruleset
|
||||||
playSE("mode_decide")
|
playSE("mode_decide")
|
||||||
saveConfig()
|
saveConfig()
|
||||||
scene = GameScene(game_modes[self.menu_state.mode], rulesets[self.menu_state.ruleset])
|
scene = GameScene(game_modes[self.menu_state.mode], rulesets[self.menu_state.ruleset], self.secret_inputs)
|
||||||
elseif e.input == "up" or e.scancode == "up" then
|
elseif e.input == "up" or e.scancode == "up" then
|
||||||
self:changeOption(-1)
|
self:changeOption(-1)
|
||||||
playSE("cursor")
|
playSE("cursor")
|
||||||
@@ -79,6 +87,14 @@ function ModeSelectScene:onInputPress(e)
|
|||||||
playSE("cursor_lr")
|
playSE("cursor_lr")
|
||||||
elseif e.input == "menu_back" or e.scancode == "delete" or e.scancode == "backspace" then
|
elseif e.input == "menu_back" or e.scancode == "delete" or e.scancode == "backspace" then
|
||||||
scene = TitleScene()
|
scene = TitleScene()
|
||||||
|
elseif e.input then
|
||||||
|
self.secret_inputs[e.input] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ModeSelectScene:onInputRelease(e)
|
||||||
|
if e.input == "hold" or (e.input and string.sub(e.input, 1, 7) == "rotate_") then
|
||||||
|
self.secret_inputs[e.input] = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ function TitleScene:render()
|
|||||||
)
|
)
|
||||||
love.graphics.print("Happy Holidays!", 320, -100 + self.y_offset)
|
love.graphics.print("Happy Holidays!", 320, -100 + self.y_offset)
|
||||||
|
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.print(self.restart_message and "Restart Cambridge..." or "", 0, 0)
|
love.graphics.print(self.restart_message and "Restart Cambridge..." or "", 0, 0)
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 0.5)
|
love.graphics.setColor(1, 1, 1, 0.5)
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ function Grid:markClearedRows()
|
|||||||
skin = self.grid[row][x].skin,
|
skin = self.grid[row][x].skin,
|
||||||
colour = "X"
|
colour = "X"
|
||||||
}
|
}
|
||||||
|
self.grid_age[row][x] = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -330,18 +331,21 @@ function Grid:draw()
|
|||||||
else
|
else
|
||||||
if self.grid[y][x].skin == "bone" then
|
if self.grid[y][x].skin == "bone" then
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
else
|
elseif self.grid[y][x].colour == "X" then
|
||||||
|
love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
||||||
|
else
|
||||||
love.graphics.setColor(0.5, 0.5, 0.5, 1)
|
love.graphics.setColor(0.5, 0.5, 0.5, 1)
|
||||||
end
|
end
|
||||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||||
end
|
end
|
||||||
if self.grid[y][x].skin ~= "bone" then
|
if self.grid[y][x].skin ~= "bone" and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 1 and self.grid[y-1][x] == empty then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < 24 and self.grid[y+1][x] == empty then
|
if y < 24 and self.grid[y+1][x] == empty or
|
||||||
|
(y + 1 > 24 or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -359,13 +363,18 @@ end
|
|||||||
function Grid:drawOutline()
|
function Grid:drawOutline()
|
||||||
for y = 5, 24 do
|
for y = 5, 24 do
|
||||||
for x = 1, 10 do
|
for x = 1, 10 do
|
||||||
if self.grid[y][x] ~= empty then
|
if self.grid[y][x].colour == "X" then
|
||||||
|
love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
||||||
|
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||||
|
end
|
||||||
|
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 1 and self.grid[y-1][x] == empty then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < 24 and self.grid[y+1][x] == empty then
|
if y < 24 and self.grid[y+1][x] == empty or
|
||||||
|
(y + 1 > 24 or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -386,7 +395,7 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_fla
|
|||||||
for x = 1, 10 do
|
for x = 1, 10 do
|
||||||
if self.grid[y][x] ~= empty then
|
if self.grid[y][x] ~= empty then
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
opacity = 1
|
opacity = 1 - self.grid_age[y][x] / 15
|
||||||
elseif garbage_opacity_function and self.grid[y][x].colour == "A" then
|
elseif garbage_opacity_function and self.grid[y][x].colour == "A" then
|
||||||
opacity = garbage_opacity_function(self.grid_age[y][x])
|
opacity = garbage_opacity_function(self.grid_age[y][x])
|
||||||
else
|
else
|
||||||
@@ -398,10 +407,11 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_fla
|
|||||||
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.64, 0.64, 0.64)
|
love.graphics.setColor(0.64, 0.64, 0.64)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 1 and self.grid[y-1][x] == empty then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < 24 and self.grid[y+1][x] == empty then
|
if y < 24 and self.grid[y+1][x] == empty or
|
||||||
|
(y + 1 > 24 or self.grid[y+1][x].colour == "X") then
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
end
|
end
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
@@ -432,25 +442,26 @@ function Grid:drawCustom(colour_function, gamestate)
|
|||||||
if block ~= empty then
|
if block ~= empty then
|
||||||
local R, G, B, A, outline = colour_function(gamestate, block, x, y, self.grid_age[y][x])
|
local R, G, B, A, outline = colour_function(gamestate, block, x, y, self.grid_age[y][x])
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
A = 1
|
A = 1 - self.grid_age[y][x] / 15
|
||||||
end
|
end
|
||||||
love.graphics.setColor(R, G, B, A)
|
love.graphics.setColor(R, G, B, A)
|
||||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||||
if outline > 0 and self.grid[y][x].colour ~= "X" then
|
if outline > 0 and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.64, 0.64, 0.64, outline)
|
love.graphics.setColor(0.64, 0.64, 0.64, outline)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
if y > 1 and self.grid[y-1][x] == empty then
|
if y > 1 and self.grid[y-1][x] == empty or self.grid[y-1][x].colour == "X" then
|
||||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||||
end
|
end
|
||||||
if y < 24 and self.grid[y+1][x] == empty then
|
if y < 24 and self.grid[y+1][x] == empty or
|
||||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
(y + 1 > 24 or self.grid[y+1][x].colour == "X") then
|
||||||
end
|
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||||
if x > 1 and self.grid[y][x-1] == empty then
|
end
|
||||||
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
|
if x > 1 and self.grid[y][x-1] == empty then
|
||||||
end
|
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
|
||||||
if x < 10 and self.grid[y][x+1] == empty then
|
end
|
||||||
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
|
if x < 10 and self.grid[y][x+1] == empty then
|
||||||
end
|
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ local playedReadySE = false
|
|||||||
local playedGoSE = false
|
local playedGoSE = false
|
||||||
|
|
||||||
local Grid = require 'tetris.components.grid'
|
local Grid = require 'tetris.components.grid'
|
||||||
local Randomizer = require 'tetris.randomizers.randomizer'
|
local Randomizer = require 'tetris.randomizers.bag7'
|
||||||
|
local BagRandomizer = require 'tetris.randomizers.bag'
|
||||||
|
|
||||||
local GameMode = Object:extend()
|
local GameMode = Object:extend()
|
||||||
|
|
||||||
GameMode.rollOpacityFunction = function(age) return 0 end
|
GameMode.rollOpacityFunction = function(age) return 0 end
|
||||||
|
|
||||||
function GameMode:new()
|
function GameMode:new(secret_inputs)
|
||||||
self.grid = Grid()
|
self.grid = Grid()
|
||||||
self.randomizer = Randomizer()
|
self.randomizer = Randomizer()
|
||||||
self.piece = nil
|
self.piece = nil
|
||||||
@@ -56,6 +57,7 @@ function GameMode:new()
|
|||||||
self.hard_drop_locked = false
|
self.hard_drop_locked = false
|
||||||
self.lock_on_soft_drop = false
|
self.lock_on_soft_drop = false
|
||||||
self.lock_on_hard_drop = false
|
self.lock_on_hard_drop = false
|
||||||
|
self.used_randomizer = nil
|
||||||
self.hold_queue = nil
|
self.hold_queue = nil
|
||||||
self.held = false
|
self.held = false
|
||||||
self.section_start_time = 0
|
self.section_start_time = 0
|
||||||
@@ -72,17 +74,29 @@ function GameMode:getLineClearDelay() return 40 end
|
|||||||
function GameMode:getDasLimit() return 15 end
|
function GameMode:getDasLimit() return 15 end
|
||||||
|
|
||||||
function GameMode:getNextPiece(ruleset)
|
function GameMode:getNextPiece(ruleset)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
skin = "2tie",
|
skin = self:getSkin(),
|
||||||
shape = self.randomizer:nextPiece(),
|
shape = self.used_randomizer:nextPiece(),
|
||||||
orientation = ruleset:getDefaultOrientation(),
|
orientation = ruleset:getDefaultOrientation(),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:initialize(ruleset)
|
function GameMode:getSkin()
|
||||||
|
return "2tie"
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameMode:initialize(ruleset, secret_inputs)
|
||||||
-- generate next queue
|
-- generate next queue
|
||||||
self:new()
|
self:new(secret_inputs)
|
||||||
|
self.used_randomizer = (
|
||||||
|
ruleset.pieces == self.randomizer.possible_pieces and
|
||||||
|
self.randomizer or
|
||||||
|
(
|
||||||
|
ruleset.pieces == 7 and
|
||||||
|
Randomizer() or
|
||||||
|
BagRandomizer(ruleset.pieces)
|
||||||
|
)
|
||||||
|
)
|
||||||
for i = 1, self.next_queue_length do
|
for i = 1, self.next_queue_length do
|
||||||
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
table.insert(self.next_queue, self:getNextPiece(ruleset))
|
||||||
end
|
end
|
||||||
@@ -194,7 +208,9 @@ function GameMode:update(inputs, ruleset)
|
|||||||
if cleared_row_count > 0 then
|
if cleared_row_count > 0 then
|
||||||
playSE("erase")
|
playSE("erase")
|
||||||
self.lcd = self:getLineClearDelay()
|
self.lcd = self:getLineClearDelay()
|
||||||
self.are = self:getLineARE()
|
self.are = (
|
||||||
|
ruleset.are and self:getLineARE() or 0
|
||||||
|
)
|
||||||
if self.lcd == 0 then
|
if self.lcd == 0 then
|
||||||
self.grid:clearClearedRows()
|
self.grid:clearClearedRows()
|
||||||
if self.are == 0 then
|
if self.are == 0 then
|
||||||
@@ -203,7 +219,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
end
|
end
|
||||||
self:onLineClear(cleared_row_count)
|
self:onLineClear(cleared_row_count)
|
||||||
else
|
else
|
||||||
if self:getARE() == 0 then
|
if self:getARE() == 0 or not ruleset.are then
|
||||||
self:initializeOrHold(inputs, ruleset)
|
self:initializeOrHold(inputs, ruleset)
|
||||||
else
|
else
|
||||||
self.are = self:getARE()
|
self.are = self:getARE()
|
||||||
@@ -327,6 +343,12 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
playedGoSE = false
|
playedGoSE = false
|
||||||
end
|
end
|
||||||
if self.ready_frames > 0 then
|
if self.ready_frames > 0 then
|
||||||
|
if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then
|
||||||
|
self.buffer_hard_drop = true
|
||||||
|
end
|
||||||
|
if not self.prev_inputs["down"] and inputs["down"] then
|
||||||
|
self.buffer_soft_drop = true
|
||||||
|
end
|
||||||
if not playedReadySE then
|
if not playedReadySE then
|
||||||
playedReadySE = true
|
playedReadySE = true
|
||||||
playSEOnce("ready")
|
playSEOnce("ready")
|
||||||
@@ -340,6 +362,12 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
self:initializeOrHold(inputs, ruleset)
|
self:initializeOrHold(inputs, ruleset)
|
||||||
end
|
end
|
||||||
elseif self.lcd > 0 then
|
elseif self.lcd > 0 then
|
||||||
|
if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then
|
||||||
|
self.buffer_hard_drop = true
|
||||||
|
end
|
||||||
|
if not self.prev_inputs["down"] and inputs["down"] then
|
||||||
|
self.buffer_soft_drop = true
|
||||||
|
end
|
||||||
self.lcd = self.lcd - 1
|
self.lcd = self.lcd - 1
|
||||||
self:areCancel(inputs, ruleset)
|
self:areCancel(inputs, ruleset)
|
||||||
if self.lcd == 0 then
|
if self.lcd == 0 then
|
||||||
@@ -350,6 +378,12 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif self.are > 0 then
|
elseif self.are > 0 then
|
||||||
|
if not self.prev_inputs["up"] and inputs["up"] and self.enable_hard_drop then
|
||||||
|
self.buffer_hard_drop = true
|
||||||
|
end
|
||||||
|
if not self.prev_inputs["down"] and inputs["down"] then
|
||||||
|
self.buffer_soft_drop = true
|
||||||
|
end
|
||||||
self.are = self.are - 1
|
self.are = self.are - 1
|
||||||
self:areCancel(inputs, ruleset)
|
self:areCancel(inputs, ruleset)
|
||||||
if self.are == 0 then
|
if self.are == 0 then
|
||||||
@@ -403,8 +437,24 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
|||||||
self.prev_inputs, self.move,
|
self.prev_inputs, self.move,
|
||||||
self:getLockDelay(), self:getDropSpeed(),
|
self:getLockDelay(), self:getDropSpeed(),
|
||||||
self.lock_drop, self.lock_hard_drop, self.big_mode,
|
self.lock_drop, self.lock_hard_drop, self.big_mode,
|
||||||
self.irs
|
self.irs, self.buffer_hard_drop, self.buffer_soft_drop,
|
||||||
|
self.lock_on_hard_drop, self.lock_on_soft_drop
|
||||||
)
|
)
|
||||||
|
if self.piece:isDropBlocked(self.grid) and
|
||||||
|
self.grid:canPlacePiece(self.piece) then
|
||||||
|
playSE("bottom")
|
||||||
|
end
|
||||||
|
if self.buffer_hard_drop then
|
||||||
|
self.buffer_hard_drop = false
|
||||||
|
self:onHardDrop(self.piece.position.y - (
|
||||||
|
self.big_mode and
|
||||||
|
ruleset.big_spawn_positions[self.piece.shape].y or
|
||||||
|
ruleset.spawn_positions[self.piece.shape].y)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if self.buffer_soft_drop then
|
||||||
|
self.buffer_soft_drop = false
|
||||||
|
end
|
||||||
if self.lock_drop then
|
if self.lock_drop then
|
||||||
self.drop_locked = true
|
self.drop_locked = true
|
||||||
end
|
end
|
||||||
@@ -415,11 +465,11 @@ 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()
|
self:playNextSound(ruleset)
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:playNextSound()
|
function GameMode:playNextSound(ruleset)
|
||||||
playSE("blocks", self.next_queue[1].shape)
|
playSE("blocks", ruleset.next_sounds[self.next_queue[1].shape])
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:getHighScoreData()
|
function GameMode:getHighScoreData()
|
||||||
|
|||||||
@@ -86,12 +86,8 @@ function PhantomMania2Game:getGarbageLimit()
|
|||||||
else return 8 end
|
else return 8 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function PhantomMania2Game:getNextPiece(ruleset)
|
function PhantomMania2Game:getSkin()
|
||||||
return {
|
return self.level >= 1000 and "bone" or "2tie"
|
||||||
skin = self.level >= 1000 and "bone" or "2tie",
|
|
||||||
shape = self.randomizer:nextPiece(),
|
|
||||||
orientation = ruleset:getDefaultOrientation(),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function PhantomMania2Game:hitTorikan(old_level, new_level)
|
function PhantomMania2Game:hitTorikan(old_level, new_level)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local GameMode = require 'tetris.modes.gamemode'
|
|||||||
local Piece = require 'tetris.components.piece'
|
local Piece = require 'tetris.components.piece'
|
||||||
|
|
||||||
local SakuraRandomizer = require 'tetris.randomizers.sakura'
|
local SakuraRandomizer = require 'tetris.randomizers.sakura'
|
||||||
|
local History6RollsRandomizer = require 'tetris.randomizers.history_6rolls_35bag'
|
||||||
|
|
||||||
local SakuraGame = GameMode:extend()
|
local SakuraGame = GameMode:extend()
|
||||||
|
|
||||||
@@ -264,10 +265,14 @@ local maps = {
|
|||||||
|
|
||||||
local STAGE_TRANSITION_TIME = 300
|
local STAGE_TRANSITION_TIME = 300
|
||||||
|
|
||||||
function SakuraGame:new()
|
function SakuraGame:new(secret_inputs)
|
||||||
self.super:new()
|
self.super:new()
|
||||||
|
|
||||||
self.randomizer = SakuraRandomizer()
|
self.randomizer = (
|
||||||
|
(
|
||||||
|
secret_inputs.rotate_left and secret_inputs.rotate_right
|
||||||
|
) and History6RollsRandomizer() or SakuraRandomizer()
|
||||||
|
)
|
||||||
|
|
||||||
self.current_map = 1
|
self.current_map = 1
|
||||||
self.time_limit = 10800
|
self.time_limit = 10800
|
||||||
@@ -403,18 +408,24 @@ function SakuraGame:advanceOneFrame(inputs, ruleset)
|
|||||||
|
|
||||||
self.frames = self.frames + 1
|
self.frames = self.frames + 1
|
||||||
self.stage_frames = self.stage_frames + 1
|
self.stage_frames = self.stage_frames + 1
|
||||||
self.time_limit = self.time_limit - 1
|
self.time_limit = math.max(self.time_limit - 1, 0)
|
||||||
if self.time_limit <= 0 then self.game_over = true end
|
if self.time_limit <= 0 and self.piece == nil then
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
|
|
||||||
if self.piece ~= nil and self.frames % 30 == 0 and
|
if self.piece ~= nil and
|
||||||
effects[self.current_map] == "roll"
|
effects[self.current_map] == "roll" and
|
||||||
|
self.stage_pieces % 4 == 0
|
||||||
then
|
then
|
||||||
ruleset:attemptRotate(
|
self.piece.colour = "F"
|
||||||
{[config.gamesettings.world_reverse == 3 or
|
if self.stage_frames % 30 == 0 then
|
||||||
(ruleset.world and config.gamesettings.world_reverse == 2)
|
ruleset:attemptRotate(
|
||||||
and "rotate_left" or "rotate_right"] = true},
|
{[config.gamesettings.world_reverse == 3 or
|
||||||
self.piece, self.grid, false
|
(ruleset.world and config.gamesettings.world_reverse == 2)
|
||||||
)
|
and "rotate_left" or "rotate_right"] = true},
|
||||||
|
self.piece, self.grid, false
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.cleared_frames = STAGE_TRANSITION_TIME
|
self.cleared_frames = STAGE_TRANSITION_TIME
|
||||||
@@ -482,13 +493,17 @@ function SakuraGame:drawScoringInfo()
|
|||||||
if effects[self.current_map] then
|
if effects[self.current_map] then
|
||||||
love.graphics.printf("EFFECT: " .. effects[self.current_map], 240, 300, 160, "left")
|
love.graphics.printf("EFFECT: " .. effects[self.current_map], 240, 300, 160, "left")
|
||||||
end
|
end
|
||||||
|
if self.randomizer.history then
|
||||||
|
love.graphics.printf("RANDOM PIECES ACTIVE!", 240, 150, 200, "left")
|
||||||
|
end
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.setColor(
|
love.graphics.setColor(
|
||||||
(self.time_limit % 4 < 2 and
|
(self.time_limit % 4 < 2 and
|
||||||
self.time_limit <= frameTime(0,10) and
|
self.time_limit <= frameTime(0,10) and
|
||||||
self.grid:hasGemBlocks() and
|
self.grid:hasGemBlocks() and
|
||||||
self.time_limit ~= 0) and
|
self.time_limit ~= 0 and
|
||||||
|
self.ready_frames == 0) and
|
||||||
{ 1, 0.3, 0.3, 1 } or
|
{ 1, 0.3, 0.3, 1 } or
|
||||||
{ 1, 1, 1, 1 }
|
{ 1, 1, 1, 1 }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,12 +92,8 @@ function SurvivalA3Game:getGarbageLimit()
|
|||||||
else return 8 end
|
else return 8 end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA3Game:getNextPiece(ruleset)
|
function SurvivalA3Game:getSkin()
|
||||||
return {
|
return self.level >= 1000 and "bone" or "2tie"
|
||||||
skin = self.level >= 1000 and "bone" or "2tie",
|
|
||||||
shape = self.randomizer:nextPiece(),
|
|
||||||
orientation = ruleset:getDefaultOrientation(),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA3Game:hitTorikan(old_level, new_level)
|
function SurvivalA3Game:hitTorikan(old_level, new_level)
|
||||||
|
|||||||
23
tetris/randomizers/bag.lua
Normal file
23
tetris/randomizers/bag.lua
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
local Randomizer = require 'tetris.randomizers.randomizer'
|
||||||
|
|
||||||
|
local BagRandomizer = Randomizer:extend()
|
||||||
|
|
||||||
|
function BagRandomizer:new(pieces)
|
||||||
|
self.bag = {}
|
||||||
|
self.pieces = pieces
|
||||||
|
for i = 1, self.pieces do
|
||||||
|
table.insert(self.bag, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function BagRandomizer:generatePiece()
|
||||||
|
if next(self.bag) == nil then
|
||||||
|
for i = 1, self.pieces do
|
||||||
|
table.insert(self.bag, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local x = math.random(table.getn(self.bag))
|
||||||
|
return table.remove(self.bag, x)
|
||||||
|
end
|
||||||
|
|
||||||
|
return BagRandomizer
|
||||||
@@ -3,6 +3,7 @@ local Object = require 'libs.classic'
|
|||||||
local Randomizer = Object:extend()
|
local Randomizer = Object:extend()
|
||||||
|
|
||||||
function Randomizer:new()
|
function Randomizer:new()
|
||||||
|
self.possible_pieces = 7
|
||||||
self:initialize()
|
self:initialize()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
254
tetris/rulesets/pairs.lua
Normal file
254
tetris/rulesets/pairs.lua
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||||
|
|
||||||
|
local PAIRS = Ruleset:extend()
|
||||||
|
|
||||||
|
PAIRS.name = "PAIRS"
|
||||||
|
PAIRS.hash = "PAIRS"
|
||||||
|
PAIRS.world = true
|
||||||
|
|
||||||
|
PAIRS.spawn_positions = {
|
||||||
|
[1] = { x=4, y=4 },
|
||||||
|
[2] = { x=4, y=5 },
|
||||||
|
[3] = { x=4, y=5 },
|
||||||
|
[4] = { x=4, y=5 },
|
||||||
|
[5] = { x=5, y=5 },
|
||||||
|
[6] = { x=5, y=5 },
|
||||||
|
[7] = { x=5, y=5 },
|
||||||
|
[8] = { x=5, y=5 },
|
||||||
|
[9] = { x=5, y=5 },
|
||||||
|
[10] = { x=5, y=5 },
|
||||||
|
[11] = { x=4, y=5 },
|
||||||
|
[12] = { x=4, y=5 },
|
||||||
|
[13] = { x=4, y=5 },
|
||||||
|
[14] = { x=4, y=5 },
|
||||||
|
[15] = { x=4, y=5 },
|
||||||
|
[16] = { x=4, y=5 },
|
||||||
|
[17] = { x=4, y=5 },
|
||||||
|
[18] = { x=4, y=5 },
|
||||||
|
}
|
||||||
|
|
||||||
|
PAIRS.big_spawn_positions = {
|
||||||
|
[1] = { x=2, y=2 },
|
||||||
|
[2] = { x=2, y=3 },
|
||||||
|
[3] = { x=2, y=3 },
|
||||||
|
[4] = { x=2, y=3 },
|
||||||
|
[5] = { x=3, y=3 },
|
||||||
|
[6] = { x=3, y=3 },
|
||||||
|
[7] = { x=3, y=3 },
|
||||||
|
[8] = { x=3, y=3 },
|
||||||
|
[9] = { x=3, y=3 },
|
||||||
|
[10] = { x=3, y=3 },
|
||||||
|
[11] = { x=2, y=3 },
|
||||||
|
[12] = { x=2, y=3 },
|
||||||
|
[13] = { x=2, y=3 },
|
||||||
|
[14] = { x=2, y=3 },
|
||||||
|
[15] = { x=2, y=3 },
|
||||||
|
[16] = { x=2, y=3 },
|
||||||
|
[17] = { x=2, y=3 },
|
||||||
|
[18] = { x=2, y=3 },
|
||||||
|
}
|
||||||
|
|
||||||
|
PAIRS.next_sounds = {
|
||||||
|
[1] = "I",
|
||||||
|
[2] = "O",
|
||||||
|
[3] = "S",
|
||||||
|
[4] = "Z",
|
||||||
|
[5] = "L",
|
||||||
|
[6] = "J",
|
||||||
|
[7] = "Z",
|
||||||
|
[8] = "S",
|
||||||
|
[9] = "J",
|
||||||
|
[10] = "L",
|
||||||
|
[11] = "O",
|
||||||
|
[12] = "O",
|
||||||
|
[13] = "T",
|
||||||
|
[14] = "L",
|
||||||
|
[15] = "J",
|
||||||
|
[16] = "T",
|
||||||
|
[17] = "J",
|
||||||
|
[18] = "I"
|
||||||
|
}
|
||||||
|
|
||||||
|
PAIRS.colourscheme = {
|
||||||
|
[1] = "R",
|
||||||
|
[2] = "C",
|
||||||
|
[3] = "G",
|
||||||
|
[4] = "M",
|
||||||
|
[5] = "O",
|
||||||
|
[6] = "C",
|
||||||
|
[7] = "G",
|
||||||
|
[8] = "M",
|
||||||
|
[9] = "G",
|
||||||
|
[10] = "M",
|
||||||
|
[11] = "Y",
|
||||||
|
[12] = "B",
|
||||||
|
[13] = "M",
|
||||||
|
[14] = "O",
|
||||||
|
[15] = "B",
|
||||||
|
[16] = "G",
|
||||||
|
[17] = "C",
|
||||||
|
[18] = "R"
|
||||||
|
}
|
||||||
|
|
||||||
|
PAIRS.pieces = 18
|
||||||
|
|
||||||
|
PAIRS.block_offsets = {
|
||||||
|
[1]={
|
||||||
|
{ {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0}, {x=2, y=0} },
|
||||||
|
{ {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||||
|
{ {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0}, {x=2, y=0} },
|
||||||
|
{ {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||||
|
},
|
||||||
|
[2]={
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-1}, {x=-1, y=-1} },
|
||||||
|
},
|
||||||
|
[3]={
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-2}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-2}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0}, {x=-1, y=-2} },
|
||||||
|
},
|
||||||
|
[4]={
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=0}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0}, {x=1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=0}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0}, {x=1, y=-2} },
|
||||||
|
},
|
||||||
|
[5]={
|
||||||
|
{ {x=1, y=-1}, {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=-1, y=-3}, {x=-1, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=-2, y=0}, {x=-2, y=-1}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=-1, y=-3}, {x=0, y=-3}, {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
[6]={
|
||||||
|
{ {x=-2, y=-1}, {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-3}, {x=-1, y=-3}, {x=-1, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=1, y=0}, {x=-2, y=-1}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=-1, y=0}, {x=0, y=-3}, {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
[7]={
|
||||||
|
{ {x=-2, y=-1}, {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-3}, {x=0, y=-2}, {x=-1, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=-2, y=-1}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=-1, y=0}, {x=0, y=-3}, {x=0, y=-2}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
},
|
||||||
|
[8]={
|
||||||
|
{ {x=1, y=-1}, {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=-1, y=-3}, {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1} },
|
||||||
|
{ {x=-2, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=-1, y=-3}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
[9]={
|
||||||
|
{ {x=-1, y=-1}, {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-2}, {x=-1, y=-3}, {x=-1, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=-2, y=-1}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=-1, y=-1}, {x=0, y=-3}, {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
[10]={
|
||||||
|
{ {x=0, y=-1}, {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-3}, {x=-1, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=-1, y=0}, {x=-2, y=-1}, {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=-1, y=-2}, {x=0, y=-3}, {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
[11]={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2}, {x=1, y=-1}, {x=1, y=-2} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=-1}, {x=1, y=0}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2}, {x=-1, y=-1}, {x=-1, y=0} },
|
||||||
|
},
|
||||||
|
[12]={
|
||||||
|
{ {x=0, y=0}, {x=1, y=-1}, {x=1, y=0}, {x=0, y=-1}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2}, {x=1, y=-1}, {x=1, y=0} },
|
||||||
|
{ {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=0, y=-1}, {x=0, y=-2}, {x=-1, y=-1}, {x=-1, y=-2} },
|
||||||
|
},
|
||||||
|
[13]={
|
||||||
|
{ {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=-2}, {x=1, y=0}, {x=1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {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=-2}, {x=-1, y=0}, {x=-1, y=-2} },
|
||||||
|
},
|
||||||
|
[14]={
|
||||||
|
{ {x=0, y=-1}, {x=0, y=0}, {x=0, y=-2}, {x=-1, y=-1}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=-2}, {x=-1, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-1}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-1}, {x=1, y=-1}, {x=-1, y=-1}, {x=0, y=0}, {x=1, y=-2} },
|
||||||
|
},
|
||||||
|
[15]={
|
||||||
|
{ {x=0, y=-1}, {x=0, y=0}, {x=0, y=-2}, {x=-1, y=0}, {x=1, y=-1} },
|
||||||
|
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=-2}, {x=0, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=1, y=-2}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=-1}, {x=1, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=-2} },
|
||||||
|
},
|
||||||
|
[16]={
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2}, {x=-1, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=-1, y=0}, {x=0, y=-1}, {x=-1, y=-2}, {x=-1, y=-1}, {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=-2}, {x=-1, y=-2}, {x=1, y=-2} },
|
||||||
|
{ {x=1, y=0}, {x=0, y=-1}, {x=1, y=-2}, {x=-1, y=-1}, {x=1, y=-1} },
|
||||||
|
},
|
||||||
|
[17]={
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-2}, {x=1, y=-2}, {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=-2} },
|
||||||
|
{ {x=0, y=-2}, {x=1, y=0}, {x=-1, y=-2}, {x=1, y=-1}, {x=1, y=-2} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=-1}, {x=1, y=-2} },
|
||||||
|
},
|
||||||
|
[18]={
|
||||||
|
{ {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1}, {x=-1, y=-2} },
|
||||||
|
{ {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=-2}, {x=1, y=-2} },
|
||||||
|
{ {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=-1}, {x=1, y=-1}, {x=1, y=0} },
|
||||||
|
{ {x=1, y=-2}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
PAIRS.wallkicks = {
|
||||||
|
{x=1, y=0}, {x=-1, y=0}, {x=2, y=0}, {x=-2, y=0}, {x=0, y=-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
function PAIRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
if (piece.shape == 2) then return end
|
||||||
|
|
||||||
|
local kicks = PAIRS.wallkicks
|
||||||
|
|
||||||
|
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
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir)
|
||||||
|
piece:setOffset(offset)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function PAIRS:checkNewLow(piece)
|
||||||
|
for _, block in pairs(piece:getBlockOffsets()) do
|
||||||
|
local y = piece.position.y + block.y
|
||||||
|
if y > piece.lowest_y then
|
||||||
|
piece.lock_delay = 0
|
||||||
|
piece.lowest_y = y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function PAIRS:onPieceCreate(piece, grid)
|
||||||
|
piece.lowest_y = -math.huge
|
||||||
|
end
|
||||||
|
|
||||||
|
function PAIRS:onPieceDrop(piece, grid)
|
||||||
|
self:checkNewLow(piece)
|
||||||
|
end
|
||||||
|
|
||||||
|
function PAIRS:get180RotationValue()
|
||||||
|
if config.gamesettings.world_reverse == 1 then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return PAIRS
|
||||||
@@ -22,10 +22,24 @@ Ruleset.harddrop_lock = false
|
|||||||
|
|
||||||
Ruleset.enable_IRS_wallkicks = false
|
Ruleset.enable_IRS_wallkicks = false
|
||||||
Ruleset.are_cancel = false
|
Ruleset.are_cancel = false
|
||||||
|
Ruleset.are = true
|
||||||
|
|
||||||
|
Ruleset.next_sounds = {
|
||||||
|
I = "I",
|
||||||
|
L = "L",
|
||||||
|
J = "J",
|
||||||
|
S = "S",
|
||||||
|
Z = "Z",
|
||||||
|
O = "O",
|
||||||
|
T = "T"
|
||||||
|
}
|
||||||
|
|
||||||
|
Ruleset.pieces = 7
|
||||||
|
|
||||||
-- Component functions.
|
-- Component functions.
|
||||||
|
|
||||||
function Ruleset:new()
|
function Ruleset:new()
|
||||||
|
|
||||||
if config.gamesettings.piece_colour == 1 then
|
if config.gamesettings.piece_colour == 1 then
|
||||||
blocks["bone"] = (not self.world) and
|
blocks["bone"] = (not self.world) and
|
||||||
{
|
{
|
||||||
@@ -181,7 +195,9 @@ function Ruleset:getDefaultOrientation() return 1 end
|
|||||||
function Ruleset:initializePiece(
|
function Ruleset:initializePiece(
|
||||||
inputs, data, grid, gravity, prev_inputs,
|
inputs, data, grid, gravity, prev_inputs,
|
||||||
move, lock_delay, drop_speed,
|
move, lock_delay, drop_speed,
|
||||||
drop_locked, hard_drop_locked, big, irs
|
drop_locked, hard_drop_locked, big, irs,
|
||||||
|
buffer_hard_drop, buffer_soft_drop,
|
||||||
|
lock_on_hard_drop, lock_on_soft_drop
|
||||||
)
|
)
|
||||||
local spawn_positions
|
local spawn_positions
|
||||||
if big then
|
if big then
|
||||||
@@ -206,6 +222,13 @@ function Ruleset:initializePiece(
|
|||||||
self:rotatePiece(inputs, piece, grid, {}, true)
|
self:rotatePiece(inputs, piece, grid, {}, true)
|
||||||
end
|
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)
|
||||||
|
if (buffer_hard_drop and config.gamesettings.buffer_lock == 1) then
|
||||||
|
piece:dropToBottom(grid)
|
||||||
|
if lock_on_hard_drop then piece.locked = true end
|
||||||
|
end
|
||||||
|
if (buffer_soft_drop and lock_on_soft_drop and piece:isDropBlocked(grid) and config.gamesettings.buffer_lock == 1) then
|
||||||
|
piece.locked = true
|
||||||
|
end
|
||||||
return piece
|
return piece
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ SRS.enable_IRS_wallkicks = true
|
|||||||
|
|
||||||
SRS.MANIPULATIONS_MAX = 15
|
SRS.MANIPULATIONS_MAX = 15
|
||||||
|
|
||||||
function SRS:check_new_low(piece)
|
function SRS:checkNewLow(piece)
|
||||||
for _, block in pairs(piece:getBlockOffsets()) do
|
for _, block in pairs(piece:getBlockOffsets()) do
|
||||||
local y = piece.position.y + block.y
|
local y = piece.position.y + block.y
|
||||||
if y > piece.lowest_y then
|
if y > piece.lowest_y then
|
||||||
@@ -76,7 +76,7 @@ function SRS:onPieceCreate(piece, grid)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SRS:onPieceDrop(piece, grid)
|
function SRS:onPieceDrop(piece, grid)
|
||||||
self:check_new_low(piece)
|
self:checkNewLow(piece)
|
||||||
if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
|
if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
else
|
else
|
||||||
@@ -96,7 +96,7 @@ end
|
|||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
self:check_new_low(piece)
|
self:checkNewLow(piece)
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
||||||
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
||||||
|
|||||||
Reference in New Issue
Block a user