mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
18 Commits
v0.3-beta5
...
366ac1d552
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
366ac1d552 | ||
| 302353f716 | |||
|
|
e1741440f2 | ||
|
|
c56f290921 | ||
|
|
86e975f929 | ||
|
|
9f8e9a9778 | ||
|
|
62f9475fa9 | ||
|
|
99d3732d00 | ||
|
|
f5121b62e5 | ||
|
|
cbdbfa6633 | ||
|
|
1b1abc9792 | ||
|
|
894e99e677 | ||
|
|
d4b619da89 | ||
|
|
3766149cb7 | ||
|
|
449ca16bc4 | ||
|
|
71d76e8a6b | ||
|
|
3bdc6e1b2d | ||
|
|
d9b6c85704 |
10
README.md
10
README.md
@@ -5,7 +5,7 @@ Cambridge
|
|||||||
|
|
||||||
Welcome to Cambridge, the next open-source falling-block game engine!
|
Welcome to Cambridge, the next open-source falling-block game engine!
|
||||||
|
|
||||||
The project is written and maintained exclusively by [SashLilac](https://github.com/SashLilac), [joezeng](https://github.com/joezeng) and [Oshisaure](https://github.com/oshisaure)!
|
The project is written and maintained exclusively by [Milla](https://github.com/MillaBasset), [joezeng](https://github.com/joezeng) and [Oshisaure](https://github.com/oshisaure)!
|
||||||
|
|
||||||
The Discord server has been reopened! https://discord.gg/AADZUmgsph
|
The Discord server has been reopened! https://discord.gg/AADZUmgsph
|
||||||
|
|
||||||
@@ -32,13 +32,13 @@ You do not need LÖVE on Windows, as it comes bundled with the program.
|
|||||||
|
|
||||||
#### Stable release
|
#### Stable release
|
||||||
|
|
||||||
To get the stable release, simply download either `cambridge-win32.zip` (32-bit) or `cambridge-windows.zip` (64-bit) in the [latest release](https://github.com/sashlilac/cambridge/releases/latest).
|
To get the stable release, simply download either `cambridge-win32.zip` (32-bit) or `cambridge-windows.zip` (64-bit) in the [latest release](https://github.com/MillaBasset/cambridge/releases/latest).
|
||||||
|
|
||||||
All assets needed are bundled with the executable.
|
All assets needed are bundled with the executable.
|
||||||
|
|
||||||
#### Bleeding edge
|
#### Bleeding edge
|
||||||
|
|
||||||
If you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
If you want the bleeding edge version, download [this](https://github.com/MillaBasset/cambridge/archive/master.zip).
|
||||||
|
|
||||||
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
|
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ You can download the .love file in the latest release, and run it with:
|
|||||||
|
|
||||||
Clone the repository in git:
|
Clone the repository in git:
|
||||||
|
|
||||||
git clone https://github.com/SashLilac/cambridge
|
git clone https://github.com/MillaBasset/cambridge
|
||||||
|
|
||||||
Alternatively, download the source code ZIP in the latest release.
|
Alternatively, download the source code ZIP in the latest release.
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ It should run automatically!
|
|||||||
|
|
||||||
## Installing modpacks
|
## Installing modpacks
|
||||||
|
|
||||||
For instructions on how to install modpacks, go to [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
|
For instructions on how to install modpacks, go to [this](https://github.com/MillaBasset/cambridge-modpack) mod pack to get a taste of the mod potential.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
1
conf.lua
1
conf.lua
@@ -6,5 +6,6 @@ function love.conf(t)
|
|||||||
t.window.title = "Cambridge"
|
t.window.title = "Cambridge"
|
||||||
t.window.width = 640
|
t.window.width = 640
|
||||||
t.window.height = 480
|
t.window.height = 480
|
||||||
|
t.window.icon = "res/img/cambridge_icon.png"
|
||||||
t.window.vsync = false
|
t.window.vsync = false
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ local mt = {
|
|||||||
end,
|
end,
|
||||||
__tostring = function()
|
__tostring = function()
|
||||||
return bigint.unserialize(self, "s")
|
return bigint.unserialize(self, "s")
|
||||||
|
end,
|
||||||
|
__eq = function(lhs, rhs)
|
||||||
|
return bigint.compare(lhs, rhs, "==")
|
||||||
|
end,
|
||||||
|
__lt = function(lhs, rhs)
|
||||||
|
return bigint.compare(lhs, rhs, "<")
|
||||||
|
end,
|
||||||
|
__le = function(lhs, rhs)
|
||||||
|
return bigint.compare(lhs, rhs, "<=")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
local binser = require 'libs.binser'
|
local binser = require 'libs.binser'
|
||||||
|
|
||||||
function loadSave()
|
function loadSave()
|
||||||
config = loadFromFile('config.sav')
|
local info = love.filesystem.getInfo(love.filesystem.getSaveDirectory())
|
||||||
highscores = loadFromFile('highscores.sav')
|
if not info or info.type ~= "directory" then
|
||||||
|
love.filesystem.remove(love.filesystem.getSaveDirectory())
|
||||||
|
love.filesystem.createDirectory(love.filesystem.getSaveDirectory())
|
||||||
|
end
|
||||||
|
config = loadFromFile(
|
||||||
|
love.filesystem.getSaveDirectory() .. '/config.sav'
|
||||||
|
)
|
||||||
|
highscores = loadFromFile(
|
||||||
|
love.filesystem.getSaveDirectory() .. '/highscores.sav'
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function loadFromFile(filename)
|
function loadFromFile(filename)
|
||||||
@@ -31,7 +40,7 @@ function initConfig()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not config.input then
|
if not config.input then
|
||||||
scene = KeyConfigScene()
|
scene = InputConfigScene()
|
||||||
else
|
else
|
||||||
if config.current_mode then current_mode = config.current_mode end
|
if config.current_mode then current_mode = config.current_mode end
|
||||||
if config.current_ruleset then current_ruleset = config.current_ruleset end
|
if config.current_ruleset then current_ruleset = config.current_ruleset end
|
||||||
@@ -40,9 +49,13 @@ function initConfig()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function saveConfig()
|
function saveConfig()
|
||||||
binser.writeFile('config.sav', config)
|
binser.writeFile(
|
||||||
|
love.filesystem.getSaveDirectory() .. '/config.sav', config
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function saveHighscores()
|
function saveHighscores()
|
||||||
binser.writeFile('highscores.sav', highscores)
|
binser.writeFile(
|
||||||
|
love.filesystem.getSaveDirectory() .. '/highscores.sav', highscores
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
version = "v0.3-beta5"
|
version = "v0.3-beta5.2"
|
||||||
BIN
res/img/cambridge_icon.png
Normal file
BIN
res/img/cambridge_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
@@ -30,30 +30,35 @@ function CreditsScene:render()
|
|||||||
|
|
||||||
love.graphics.setFont(font_3x5_4)
|
love.graphics.setFont(font_3x5_4)
|
||||||
love.graphics.print("Cambridge Credits", 320, 500 - self.frames / 2)
|
love.graphics.print("Cambridge Credits", 320, 500 - self.frames / 2)
|
||||||
love.graphics.print("THANK YOU\nFOR PLAYING!", 320, math.max(1750 - self.frames / 2, 240))
|
love.graphics.print("THANK YOU\nFOR PLAYING!", 320, math.max(1770 - self.frames / 2, 240))
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_3)
|
love.graphics.setFont(font_3x5_3)
|
||||||
love.graphics.print("Game Developers", 320, 550 - self.frames / 2)
|
love.graphics.print("Game Developers", 320, 550 - self.frames / 2)
|
||||||
love.graphics.print("Project Heads", 320, 640 - self.frames / 2)
|
love.graphics.print("Project Heads", 320, 640 - self.frames / 2)
|
||||||
love.graphics.print("Other Game Developers", 320, 730 - self.frames / 2)
|
love.graphics.print("Other Game Developers", 320, 730 - self.frames / 2)
|
||||||
love.graphics.print("Special Thanks", 320, 900 - self.frames / 2)
|
love.graphics.print("Special Thanks", 320, 950 - self.frames / 2)
|
||||||
love.graphics.print("- SashLilac / SpinTriple", 320, math.max(2000 - self.frames / 2, 320))
|
love.graphics.print("- Milla", 320, math.max(1850 - self.frames / 2, 320))
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_2)
|
love.graphics.setFont(font_3x5_2)
|
||||||
love.graphics.print("Oshisaure\nJoe Zeng", 320, 590 - self.frames / 2)
|
love.graphics.print("Oshisaure\nJoe Zeng", 320, 590 - self.frames / 2)
|
||||||
love.graphics.print("Mizu\nHailey", 320, 680 - self.frames / 2)
|
love.graphics.print("Mizu\nHailey", 320, 680 - self.frames / 2)
|
||||||
love.graphics.print("Axel Fox - Multimino\nMine - Tetra Online\nDr Ocelot - Tetra Legends\nFelicity / nightmareci - Shiromino\n2Tie - TGMsim\nPhoenix Flare - Master of Blocks", 320, 770 - self.frames / 2)
|
love.graphics.print(
|
||||||
|
"Axel Fox - Multimino\nMine - Tetra Online\nDr Ocelot - Tetra Legends\n" ..
|
||||||
|
"Felicity / nightmareci - Shiromino\n2Tie - TGMsim\nPhoenix Flare - Master of Blocks\n" ..
|
||||||
|
"RayRay26 - Spirit Drop\nosk - TETR.IO\nMarkGamed7794 - Picoris 2",
|
||||||
|
320, 770 - self.frames / 2
|
||||||
|
)
|
||||||
love.graphics.print(
|
love.graphics.print(
|
||||||
"RocketLanterns\nCylinderKnot\nHammrTime\nKirby703\nMattMayuga\nMyPasswordIsWeak\n" ..
|
"RocketLanterns\nCylinderKnot\nHammrTime\nKirby703\nMattMayuga\nMyPasswordIsWeak\n" ..
|
||||||
"Nikki Karissa\noffwo\nsinefuse\nTetro48\nTimmSkiller\nuser74003\nAgentBasey\n" ..
|
"Nikki Karissa\noffwo\nsinefuse\nTetro48\nTimmSkiller\nuser74003\nAgentBasey\n" ..
|
||||||
"CheeZed_Fish\neightsixfivezero\nEricICX\ngizmo4487\nM1ssing0\nMarkGamed7794\n" ..
|
"CheeZed_Fish\neightsixfivezero\nEricICX\ngizmo4487\nM1ssing0\n" ..
|
||||||
"pokemonfan1937\nSimon\nstratus\nZaptorZap\nArchina\nOliver\ncolour_thief\n" ..
|
"pokemonfan1937\nSimon\nstratus\nZaptorZap\nArchina\nOliver\ncolour_thief\n" ..
|
||||||
"Caithness\nkdex\nzid\nsaphie\nSuper302\nAurora\nswitchpalacecorner\nKitaru\n" ..
|
"Caithness\nkdex\nzid\nsaphie\nSuper302\nAurora\nswitchpalacecorner\nKitaru\n" ..
|
||||||
"JBroms\nMany more I definitely missed!\n" ..
|
"JBroms\nMany more I definitely missed!\n" ..
|
||||||
"The Absolute PLUS Discord\nTetra Legends Discord\nTetra Online Discord\n" ..
|
"The Absolute PLUS Discord\nTetra Legends Discord\nTetra Online Discord\n" ..
|
||||||
"Multimino Discord\nHard Drop Discord\nCambridge Discord (R.I.P.)\n" ..
|
"Multimino Discord\nHard Drop Discord\nCambridge Discord\n" ..
|
||||||
"And to you, the player!",
|
"And to you, the player!",
|
||||||
320, 940 - self.frames / 2
|
320, 990 - self.frames / 2
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function ConfigScene:render()
|
|||||||
love.graphics.print("INPUT CONFIG", 80, 40)
|
love.graphics.print("INPUT CONFIG", 80, 40)
|
||||||
|
|
||||||
love.graphics.setFont(font_3x5_2)
|
love.graphics.setFont(font_3x5_2)
|
||||||
love.graphics.print("Which controls do you want to change?", 80, 90)
|
love.graphics.print("Which controls do you want to configure?", 80, 90)
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1, 0.5)
|
love.graphics.setColor(1, 1, 1, 0.5)
|
||||||
love.graphics.rectangle("fill", 75, 118 + 50 * self.menu_state, 200, 33)
|
love.graphics.rectangle("fill", 75, 118 + 50 * self.menu_state, 200, 33)
|
||||||
@@ -56,7 +56,9 @@ function ConfigScene:onInputPress(e)
|
|||||||
elseif e.input == "down" or e.scancode == "down" then
|
elseif e.input == "down" or e.scancode == "down" then
|
||||||
self:changeOption(1)
|
self:changeOption(1)
|
||||||
playSE("cursor")
|
playSE("cursor")
|
||||||
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
|
elseif config.input and (
|
||||||
|
e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete"
|
||||||
|
) then
|
||||||
scene = SettingsScene()
|
scene = SettingsScene()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function KeyConfigScene:render()
|
|||||||
if self.input_state > table.getn(configurable_inputs) then
|
if self.input_state > table.getn(configurable_inputs) then
|
||||||
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
||||||
else
|
else
|
||||||
love.graphics.print("press key input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0)
|
love.graphics.print("press key input for " .. configurable_inputs[self.input_state] .. ", tab to skip, escape to cancel", 0, 0)
|
||||||
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -69,8 +69,7 @@ end
|
|||||||
function KeyConfigScene:onInputPress(e)
|
function KeyConfigScene:onInputPress(e)
|
||||||
if e.type == "key" then
|
if e.type == "key" then
|
||||||
-- function keys, escape, and tab are reserved and can't be remapped
|
-- function keys, escape, and tab are reserved and can't be remapped
|
||||||
if e.scancode == "escape" and config.input then
|
if e.scancode == "escape" then
|
||||||
-- cancel only if there was an input config already
|
|
||||||
scene = InputConfigScene()
|
scene = InputConfigScene()
|
||||||
elseif self.input_state > table.getn(configurable_inputs) then
|
elseif self.input_state > table.getn(configurable_inputs) then
|
||||||
if e.scancode == "return" then
|
if e.scancode == "return" then
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ function StickConfigScene:render()
|
|||||||
if self.input_state > table.getn(configurable_inputs) then
|
if self.input_state > table.getn(configurable_inputs) then
|
||||||
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
||||||
else
|
else
|
||||||
love.graphics.print("press joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0)
|
love.graphics.print("press joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip, escape to cancel", 0, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.axis_timer = self.axis_timer + 1
|
self.axis_timer = self.axis_timer + 1
|
||||||
@@ -82,9 +82,11 @@ function StickConfigScene:onInputPress(e)
|
|||||||
elseif self.input_state > table.getn(configurable_inputs) then
|
elseif self.input_state > table.getn(configurable_inputs) then
|
||||||
if e.scancode == "return" then
|
if e.scancode == "return" then
|
||||||
-- save new input, then load next scene
|
-- save new input, then load next scene
|
||||||
|
local had_config = config.input ~= nil
|
||||||
|
if not config.input then config.input = {} end
|
||||||
config.input.joysticks = self.new_input
|
config.input.joysticks = self.new_input
|
||||||
saveConfig()
|
saveConfig()
|
||||||
scene = InputConfigScene()
|
scene = had_config and InputConfigScene() or TitleScene()
|
||||||
elseif e.scancode == "delete" or e.scancode == "backspace" then
|
elseif e.scancode == "delete" or e.scancode == "backspace" then
|
||||||
-- retry
|
-- retry
|
||||||
self.input_state = 1
|
self.input_state = 1
|
||||||
|
|||||||
@@ -206,14 +206,14 @@ function GameMode:update(inputs, ruleset)
|
|||||||
self.piece.last_rotated = false
|
self.piece.last_rotated = false
|
||||||
self:onPieceMove(self.piece, self.grid, piece_dx)
|
self:onPieceMove(self.piece, self.grid, piece_dx)
|
||||||
end
|
end
|
||||||
if (piece_drot ~= 0) then
|
|
||||||
self.piece.last_rotated = true
|
|
||||||
self:onPieceRotate(self.piece, self.grid, piece_drot)
|
|
||||||
end
|
|
||||||
if (piece_dy ~= 0) then
|
if (piece_dy ~= 0) then
|
||||||
self.piece.last_rotated = false
|
self.piece.last_rotated = false
|
||||||
self:onPieceDrop(self.piece, self.grid, piece_dy)
|
self:onPieceDrop(self.piece, self.grid, piece_dy)
|
||||||
end
|
end
|
||||||
|
if (piece_drot ~= 0) then
|
||||||
|
self.piece.last_rotated = true
|
||||||
|
self:onPieceRotate(self.piece, self.grid, piece_drot)
|
||||||
|
end
|
||||||
|
|
||||||
if inputs["up"] == true and
|
if inputs["up"] == true and
|
||||||
self.piece:isDropBlocked(self.grid) and
|
self.piece:isDropBlocked(self.grid) and
|
||||||
@@ -242,7 +242,8 @@ function GameMode:update(inputs, ruleset)
|
|||||||
|
|
||||||
if self.piece.locked == true then
|
if self.piece.locked == true then
|
||||||
-- spin detection, immobile only for now
|
-- spin detection, immobile only for now
|
||||||
if self.immobile_spin_bonus and (
|
if self.immobile_spin_bonus and
|
||||||
|
self.piece.last_rotated and (
|
||||||
self.piece:isDropBlocked(self.grid) and
|
self.piece:isDropBlocked(self.grid) and
|
||||||
self.piece:isMoveBlocked(self.grid, { x=-1, y=0 }) and
|
self.piece:isMoveBlocked(self.grid, { x=-1, y=0 }) and
|
||||||
self.piece:isMoveBlocked(self.grid, { x=1, y=0 }) and
|
self.piece:isMoveBlocked(self.grid, { x=1, y=0 }) and
|
||||||
@@ -529,16 +530,13 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
|||||||
self.lock_drop, self.lock_hard_drop, self.big_mode,
|
self.lock_drop, self.lock_hard_drop, self.big_mode,
|
||||||
(
|
(
|
||||||
self.frames == 0 or (ruleset.are and self:getARE() ~= 0)
|
self.frames == 0 or (ruleset.are and self:getARE() ~= 0)
|
||||||
) and self.irs or false,
|
) and self.irs or false
|
||||||
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
|
if self.buffer_hard_drop then
|
||||||
self.buffer_hard_drop = false
|
if config.gamesettings.buffer_lock == 1 then
|
||||||
|
self.piece:dropToBottom(self.grid)
|
||||||
|
if self.lock_on_hard_drop then self.piece.locked = true end
|
||||||
|
end
|
||||||
local above_field = (
|
local above_field = (
|
||||||
(config.gamesettings.spawn_positions == 1 and
|
(config.gamesettings.spawn_positions == 1 and
|
||||||
ruleset.spawn_above_field) or
|
ruleset.spawn_above_field) or
|
||||||
@@ -552,10 +550,22 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
|||||||
piece_data.shape, piece_data.orientation
|
piece_data.shape, piece_data.orientation
|
||||||
) or 0)
|
) or 0)
|
||||||
)
|
)
|
||||||
|
self.buffer_hard_drop = false
|
||||||
end
|
end
|
||||||
if self.buffer_soft_drop then
|
if self.buffer_soft_drop then
|
||||||
|
if (
|
||||||
|
self.lock_on_soft_drop and
|
||||||
|
self.piece:isDropBlocked(self.grid) and
|
||||||
|
config.gamesettings.buffer_lock == 1
|
||||||
|
) then
|
||||||
|
self.piece.locked = true
|
||||||
|
end
|
||||||
self.buffer_soft_drop = false
|
self.buffer_soft_drop = false
|
||||||
end
|
end
|
||||||
|
if self.piece:isDropBlocked(self.grid) and
|
||||||
|
self.grid:canPlacePiece(self.piece) then
|
||||||
|
playSE("bottom")
|
||||||
|
end
|
||||||
if self.lock_drop or (
|
if self.lock_drop or (
|
||||||
not ruleset.are or self:getARE() == 0
|
not ruleset.are or self:getARE() == 0
|
||||||
) then
|
) then
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ function MarathonA1Game:new()
|
|||||||
|
|
||||||
self.randomizer = History4RollsRandomizer()
|
self.randomizer = History4RollsRandomizer()
|
||||||
|
|
||||||
|
self.additive_gravity = false
|
||||||
self.lock_drop = false
|
self.lock_drop = false
|
||||||
self.enable_hard_drop = false
|
self.enable_hard_drop = false
|
||||||
self.enable_hold = false
|
self.enable_hold = false
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ function MarathonA2Game:new()
|
|||||||
"GM"
|
"GM"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.additive_gravity = false
|
||||||
self.lock_drop = false
|
self.lock_drop = false
|
||||||
self.lock_hard_drop = false
|
self.lock_hard_drop = false
|
||||||
self.enable_hold = false
|
self.enable_hold = false
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ self.SGnames = {
|
|||||||
"GM"
|
"GM"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.additive_gravity = false
|
||||||
self.lock_drop = true
|
self.lock_drop = true
|
||||||
self.lock_hard_drop = true
|
self.lock_hard_drop = true
|
||||||
self.enable_hold = true
|
self.enable_hold = true
|
||||||
|
|||||||
@@ -111,9 +111,8 @@ function SurvivalA1Game:onLineClear(cleared_row_count)
|
|||||||
local new_level = math.min(self.level + cleared_row_count, 999)
|
local new_level = math.min(self.level + cleared_row_count, 999)
|
||||||
if new_level == 999 then
|
if new_level == 999 then
|
||||||
self.clear = true
|
self.clear = true
|
||||||
else
|
|
||||||
self.level = new_level
|
|
||||||
end
|
end
|
||||||
|
self.level = new_level
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ function SurvivalA2Game:new()
|
|||||||
self.lock_hard_drop = true
|
self.lock_hard_drop = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:initialize(ruleset)
|
|
||||||
SurvivalA2Game.super.initialize(self, ruleset)
|
|
||||||
self.world = ruleset.world
|
|
||||||
end
|
|
||||||
|
|
||||||
function SurvivalA2Game:getARE()
|
function SurvivalA2Game:getARE()
|
||||||
if self.level < 100 then return 18
|
if self.level < 100 then return 18
|
||||||
elseif self.level < 300 then return 14
|
elseif self.level < 300 then return 14
|
||||||
@@ -74,8 +69,7 @@ function SurvivalA2Game:getGravity()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:hitTorikan(old_level, new_level)
|
function SurvivalA2Game:hitTorikan(old_level, new_level)
|
||||||
local torikan_time = self.world and frameTime(3,55) or frameTime(3,25)
|
if old_level < 500 and new_level >= 500 and self.frames > frameTime(3,25) then
|
||||||
if old_level < 500 and new_level >= 500 and self.frames > torikan_time then
|
|
||||||
self.level = 500
|
self.level = 500
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -37,41 +37,41 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
(piece:isMoveBlocked(grid, {x=-1, y=0}) or piece:isMoveBlocked(grid, {x=1, y=0})) then
|
(piece:isMoveBlocked(grid, {x=-1, y=0}) or piece:isMoveBlocked(grid, {x=1, y=0})) then
|
||||||
-- kick right, right2, left
|
-- kick right, right2, left
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
end
|
end
|
||||||
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) then
|
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) then
|
||||||
-- kick up, up2
|
-- kick up, up2
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- kick right, kick left
|
-- kick right, kick left
|
||||||
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid)
|
||||||
|
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
elseif piece.shape == "T"
|
elseif piece.shape == "T"
|
||||||
and new_piece.rotation == 0
|
and new_piece.rotation == 0
|
||||||
and piece:isDropBlocked(grid)
|
and piece:isDropBlocked(grid)
|
||||||
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
|
||||||
then
|
then
|
||||||
-- T floorkick
|
-- T floorkick
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
piece.floorkick = 1
|
piece.floorkick = 1
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid, true)
|
||||||
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
|
||||||
piece.floorkick = 1
|
piece.floorkick = 1
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -76,7 +76,7 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
-- T floorkick
|
-- T floorkick
|
||||||
piece.floorkick = piece.floorkick + 1
|
piece.floorkick = piece.floorkick + 1
|
||||||
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -93,10 +93,10 @@ function ARS:onPieceDrop(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ARS:onPieceRotate(piece, grid)
|
function ARS:onPieceRotate(piece, grid, floorkick)
|
||||||
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
|
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
elseif piece.floorkick >= 1 then
|
elseif piece.floorkick >= 1 and not floorkick then
|
||||||
piece.floorkick = piece.floorkick + 1
|
piece.floorkick = piece.floorkick + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ function Ruleset:movePiece(piece, grid, move, instant)
|
|||||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||||
local offset = ({x=0, y=0})
|
local offset = ({x=0, y=0})
|
||||||
local moves = 0
|
local moves = 0
|
||||||
|
local y = piece.position.y
|
||||||
if move == "left" then
|
if move == "left" then
|
||||||
offset.x = -1
|
offset.x = -1
|
||||||
moves = 1
|
moves = 1
|
||||||
@@ -151,6 +152,9 @@ function Ruleset:movePiece(piece, grid, move, instant)
|
|||||||
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
||||||
playSE("bottom")
|
playSE("bottom")
|
||||||
end
|
end
|
||||||
|
if instant and piece.position.y ~= y then
|
||||||
|
self:onPieceDrop(piece, grid)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:dropPiece(
|
function Ruleset:dropPiece(
|
||||||
@@ -206,9 +210,7 @@ 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
|
||||||
@@ -261,13 +263,6 @@ function Ruleset:initializePiece(
|
|||||||
end
|
end
|
||||||
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
|
||||||
|
|
||||||
@@ -280,6 +275,7 @@ function Ruleset:processPiece(
|
|||||||
drop_locked, hard_drop_locked,
|
drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity, classic_lock
|
hard_drop_enabled, additive_gravity, classic_lock
|
||||||
)
|
)
|
||||||
|
if piece.locked then return end
|
||||||
|
|
||||||
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
|
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user