Compare commits

...

19 Commits

Author SHA1 Message Date
Joe Zeng
323c457809 Reorganized the ruleset names and added ARS-X.
Also, the ruleset inheritance was a little wonky, so I changed that too.
In particular, I made SRS-X always spawn in-frame since that was always
supposed to be how it worked.
2022-10-24 20:09:08 -04:00
Joe Zeng
decc1f563f Changed cool/regret cutoffs.
They're all the same past 500 now - I've been meaning to tweak that for quite some time now.
2022-09-28 00:18:44 -04:00
nightmareci
e5892c0fae Rename shell scripts and implement better frame timing 2022-04-28 11:47:31 -07:00
--global
23a8c400ba Revert "made the experience feel closer to arcade stackers"
Happy April Fools!
This reverts commit bfbba75f17.
2022-04-01 18:43:35 -04:00
--global
bfbba75f17 made the experience feel closer to arcade stackers 2022-03-31 23:27:22 -04:00
--global
27e699841e Fixed a graphical issue in Survival A2 when getting torikanned 2022-03-31 23:00:39 -04:00
--global
fac8c6584e Added batch scripts to start the game on Windows 2022-03-10 22:36:21 -05:00
Oshisaure
9e447d51a7 Merge pull request #57 from jjdelvalle/master
Include complete path when printing screenshot info
2022-03-03 19:29:48 +00:00
JDV
4dfa234bc3 Include complete path when printing screenshot info 2022-03-03 20:27:41 +01:00
Ishaan Bhardwaj
92d67968f5 Tiny UI feature added to the title screen.
If you load a custom block skin, the title screen will use your skin to draw the logo.
2022-02-07 20:39:26 -05:00
Ishaan Bhardwaj
d68bd13d2a LOVE 11.3 notice
Reminder that Windows is unaffected by this, because Windows releases come bundled with the correct version, and the bleeding edge source includes the correct version of LOVE for Windows
2022-01-28 22:22:05 -05:00
Ishaan Bhardwaj
a84335646d Fix two bugs with Marathon A3 grading
S4 now correctly has 3 internal grades instead of 4
You can get a green-line GM
2022-01-28 20:51:25 -05:00
Ishaan Bhardwaj
d46973f12d Fixed color scheme setting not applying to active piece 2021-12-18 21:30:19 -05:00
Ishaan Bhardwaj
d4360b3662 Fixed the replay system's interaction with secret inputs 2021-12-09 23:00:20 -05:00
Ishaan Bhardwaj
06225bd35a Fixed an issue where replays played in the menu could save a duplicate copy 2021-12-09 22:21:48 -05:00
Ishaan Bhardwaj
e68238cbce Fixed disabling saving replays 2021-12-09 22:00:13 -05:00
Ishaan Bhardwaj
83e197b5d6 Slight RPC change to the selection menus 2021-12-09 21:51:41 -05:00
Ishaan Bhardwaj
1c0b73987d Rearrange sliders on the game settings menu 2021-12-09 21:48:39 -05:00
Ishaan Bhardwaj
afe6a43dab Rearrange game settings, add toggle for replay saving 2021-12-09 21:44:18 -05:00
24 changed files with 164 additions and 61 deletions

View File

@@ -26,13 +26,13 @@ All assets needed are bundled with the executable.
#### Bleeding edge #### Bleeding edge
If you want the bleeding edge version, download [this](https://github.com/MillaBasset/cambridge/archive/master.zip). If you want the bleeding edge version, download [this](https://github.com/MillaBasset/cambridge/archive/master.zip). Extract the ZIP to a folder of your choosing.
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command: Assuming you're on a 64-bit system, you can double-click `start_win64.bat` to run the game. If that doesn't work, open a Command Prompt where you extracted Cambridge and run:
dist\windows\love.exe . dist\windows\love.exe .
Alternatively, if you're on a 32-bit system, run this instead: If you're on a 32-bit system, you'll want to double-click `start_win32.bat`. If that doesn't work, run this instead:
dist\win32\love.exe . dist\win32\love.exe .
@@ -42,7 +42,7 @@ Then, check the mod pack section at the bottom of this page.
### macOS, Linux ### macOS, Linux
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.3, because it won't work with earlier or later versions!**
#### Downloading a release #### Downloading a release

View File

@@ -20,6 +20,7 @@ backgrounds = {
love.graphics.newImage("res/backgrounds/1800.png"), love.graphics.newImage("res/backgrounds/1800.png"),
love.graphics.newImage("res/backgrounds/1900.png"), love.graphics.newImage("res/backgrounds/1900.png"),
title = love.graphics.newImage("res/backgrounds/title.png"), title = love.graphics.newImage("res/backgrounds/title.png"),
title_no_icon = love.graphics.newImage("res/backgrounds/title-no-icon.jpg"),
title_night = love.graphics.newImage("res/backgrounds/title-night.jpg"), title_night = love.graphics.newImage("res/backgrounds/title-night.jpg"),
snow = love.graphics.newImage("res/backgrounds/snow.png"), snow = love.graphics.newImage("res/backgrounds/snow.png"),
input_config = love.graphics.newImage("res/backgrounds/options-input.png"), input_config = love.graphics.newImage("res/backgrounds/options-input.png"),

View File

@@ -81,7 +81,7 @@ function love.draw()
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf( love.graphics.printf(
string.format("%.2f", 1 / love.timer.getAverageDelta()) .. string.format("%.2f", 1.0 / love.timer.getAverageDelta()) ..
"fps - " .. version, 0, 460, 635, "right" "fps - " .. version, 0, 460, 635, "right"
) )
end end
@@ -118,7 +118,7 @@ function love.keypressed(key, scancode)
love.filesystem.remove("ss") love.filesystem.remove("ss")
love.filesystem.createDirectory("ss") love.filesystem.createDirectory("ss")
end end
print("Saving screenshot as "..ss_name) print("Saving screenshot as "..love.filesystem.getSaveDirectory().."/"..ss_name)
GLOBAL_CANVAS:newImageData():encode("png", ss_name) GLOBAL_CANVAS:newImageData():encode("png", ss_name)
-- function keys are reserved -- function keys are reserved
elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f[1-9][0-9]+$") then elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f[1-9][0-9]+$") then
@@ -290,6 +290,7 @@ function love.resize(w, h)
end end
local TARGET_FPS = 60 local TARGET_FPS = 60
local FRAME_DURATION = 1.0 / TARGET_FPS
function love.run() function love.run()
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
@@ -299,7 +300,7 @@ function love.run()
local dt = 0 local dt = 0
local last_time = love.timer.getTime() local last_time = love.timer.getTime()
local time_accumulator = 0 local time_accumulator = 0.0
return function() return function()
if love.event then if love.event then
love.event.pump() love.event.pump()
@@ -320,24 +321,39 @@ function love.run()
if scene and scene.update and love.timer then if scene and scene.update and love.timer then
scene:update() scene:update()
local frame_duration = 1.0 / TARGET_FPS if time_accumulator < FRAME_DURATION then
if time_accumulator < frame_duration then
if love.graphics and love.graphics.isActive() and love.draw then if love.graphics and love.graphics.isActive() and love.draw then
love.graphics.origin() love.graphics.origin()
love.graphics.clear(love.graphics.getBackgroundColor()) love.graphics.clear(love.graphics.getBackgroundColor())
love.draw() love.draw()
love.graphics.present() love.graphics.present()
end end
local end_time = last_time + frame_duration
local time = love.timer.getTime() -- request 1ms delays first but stop short of overshooting, then do "0ms" delays without overshooting (0ms requests generally do a delay of some nonzero amount of time, but maybe less than 1ms)
while time < end_time do for milliseconds=0.001,0.000,-0.001 do
love.timer.sleep(0.001) local max_delay = 0.0
time = love.timer.getTime() while max_delay < FRAME_DURATION do
local delay_start_time = love.timer.getTime()
if delay_start_time - last_time < FRAME_DURATION - max_delay then
love.timer.sleep(milliseconds)
local last_delay = love.timer.getTime() - delay_start_time
if last_delay > max_delay then
max_delay = last_delay
end end
time_accumulator = time_accumulator + time - last_time else
break
end end
time_accumulator = time_accumulator - frame_duration
end end
last_time = love.timer.getTime() end
while love.timer.getTime() - last_time < FRAME_DURATION do
-- busy loop, do nothing here until delay is finished; delays above stop short of finishing, so this part can finish it off precisely
end
end
local finish_delay_time = love.timer.getTime()
local real_frame_duration = finish_delay_time - last_time
time_accumulator = time_accumulator + real_frame_duration - FRAME_DURATION
last_time = finish_delay_time
end
end end
end end

View File

@@ -1 +1,3 @@
#!/bin/sh
zip -r cambridge.love libs load res scene tetris conf.lua main.lua scene.lua funcs.lua zip -r cambridge.love libs load res scene tetris conf.lua main.lua scene.lua funcs.lua

View File

@@ -1,4 +1,6 @@
./package #!/bin/sh
./package-love.sh
mkdir dist mkdir dist
mkdir dist/windows mkdir dist/windows
mkdir dist/win32 mkdir dist/win32

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

View File

@@ -5,7 +5,7 @@ CreditsScene.title = "Credits"
function CreditsScene:new() function CreditsScene:new()
self.frames = 0 self.frames = 0
-- higher = slower -- higher = slower
self.scroll_speed = 1.85 self.scroll_speed = 1.8
switchBGM("credit_roll", "gm3") switchBGM("credit_roll", "gm3")
DiscordRPC:update({ DiscordRPC:update({
@@ -40,14 +40,14 @@ function CreditsScene:render()
love.graphics.setFont(font_3x5_4) love.graphics.setFont(font_3x5_4)
love.graphics.print("Cambridge Credits", 320, 500 - offset) love.graphics.print("Cambridge Credits", 320, 500 - offset)
love.graphics.print("THANK YOU\nFOR PLAYING!", 320, math.max(2030 - offset, 240)) love.graphics.print("THANK YOU\nFOR PLAYING!", 320, math.max(2050 - offset, 240))
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.print("Game Developers", 320, 550 - offset) love.graphics.print("Game Developers", 320, 550 - offset)
love.graphics.print("Project Heads", 320, 640 - offset) love.graphics.print("Project Heads", 320, 640 - offset)
love.graphics.print("Notable Game Developers", 320, 750 - offset) love.graphics.print("Notable Game Developers", 320, 750 - offset)
love.graphics.print("Special Thanks", 320, 1000 - offset) love.graphics.print("Special Thanks", 320, 1000 - offset)
love.graphics.print("- Milla", 320, math.max(2110 - offset, 320)) love.graphics.print("- Milla", 320, math.max(2130 - offset, 320))
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
love.graphics.print("Oshisaure\nJoe Zeng", 320, 590 - offset) love.graphics.print("Oshisaure\nJoe Zeng", 320, 590 - offset)
@@ -66,7 +66,7 @@ function CreditsScene:render()
"CylinderKnot\neightsixfivezero\nEricICX\nGesomaru\n" .. "CylinderKnot\neightsixfivezero\nEricICX\nGesomaru\n" ..
"gizmo4487\nJBroms\nKirby703\nKitaru\n" .. "gizmo4487\nJBroms\nKirby703\nKitaru\n" ..
"M1ssing0\nMattMayuga\nMyPasswordIsWeak\n" .. "M1ssing0\nMattMayuga\nMyPasswordIsWeak\n" ..
"Nikki Karissa\noffwo\nOliver\nPineapple\npokemonfan1937\n" .. "Nikki Karissa\nnim\noffwo\nOliver\nPineapple\npokemonfan1937\n" ..
"Pyra Neoxi\nRDST64\nRocketLanterns\nRustyFoxxo\n" .. "Pyra Neoxi\nRDST64\nRocketLanterns\nRustyFoxxo\n" ..
"saphie\nShelleloch\nSimon\nstratus\nSuper302\n" .. "saphie\nShelleloch\nSimon\nstratus\nSuper302\n" ..
"switchpalacecorner\nterpyderp\nTetrian22\nTetro48\nThatCookie\n" .. "switchpalacecorner\nterpyderp\nTetrian22\nTetro48\nThatCookie\n" ..

View File

@@ -9,6 +9,7 @@ function GameScene:new(game_mode, ruleset, inputs)
self.retry_ruleset = ruleset self.retry_ruleset = ruleset
self.secret_inputs = inputs self.secret_inputs = inputs
self.game = game_mode(self.secret_inputs) self.game = game_mode(self.secret_inputs)
self.game.secret_inputs = inputs
self.ruleset = ruleset(self.game) self.ruleset = ruleset(self.game)
self.game:initialize(self.ruleset) self.game:initialize(self.ruleset)
self.inputs = { self.inputs = {
@@ -40,6 +41,8 @@ function GameScene:update()
self.game:update(inputs, self.ruleset) self.game:update(inputs, self.ruleset)
self.game.grid:update() self.game.grid:update()
DiscordRPC:update({ DiscordRPC:update({
details = self.game.rpc_details,
state = self.game.name,
largeImageKey = "ingame-"..self.game:getBackground().."00" largeImageKey = "ingame-"..self.game:getBackground().."00"
}) })
end end

View File

@@ -13,11 +13,12 @@ ConfigScene.options = {
{"world_reverse", "A Button Rotation", false, {"Left", "Auto", "Right"}}, {"world_reverse", "A Button Rotation", false, {"Left", "Auto", "Right"}},
{"spawn_positions", "Spawn Positions", false, {"Per ruleset", "In field", "Out of field"}}, {"spawn_positions", "Spawn Positions", false, {"Per ruleset", "In field", "Out of field"}},
{"display_gamemode", "Debug Info", false, {"On", "Off"}}, {"display_gamemode", "Debug Info", false, {"On", "Off"}},
{"das_last_key", "DAS Last Key", false, {"Off", "On"}}, {"save_replay", "Save Replays", false, {"On", "Off"}},
{"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}}, {"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}},
{"synchroes_allowed", "Synchroes", false, {"Per ruleset", "On", "Off"}},
{"diagonal_input", "Diagonal Input", false, {"On", "Off"}}, {"diagonal_input", "Diagonal Input", false, {"On", "Off"}},
{"das_last_key", "DAS Last Key", false, {"Off", "On"}},
{"buffer_lock", "Buffer Drop Type", false, {"Off", "Hold", "Tap"}}, {"buffer_lock", "Buffer Drop Type", false, {"Off", "Hold", "Tap"}},
{"synchroes_allowed", "Synchroes", false, {"Per ruleset", "On", "Off"}},
{"sfx_volume", "SFX", true, "sfxSlider"}, {"sfx_volume", "SFX", true, "sfxSlider"},
{"bgm_volume", "BGM", true, "bgmSlider"}, {"bgm_volume", "BGM", true, "bgmSlider"},
} }
@@ -33,8 +34,8 @@ function ConfigScene:new()
state = "Changing game settings", state = "Changing game settings",
}) })
self.sfxSlider = newSlider(165, 400, 225, config.sfx_volume * 100, 0, 100, function(v) config.sfx_volume = v / 100 end, {width=20, knob="circle", track="roundrect"}) self.sfxSlider = newSlider(165, 420, 225, config.sfx_volume * 100, 0, 100, function(v) config.sfx_volume = v / 100 end, {width=20, knob="circle", track="roundrect"})
self.bgmSlider = newSlider(465, 400, 225, config.bgm_volume * 100, 0, 100, function(v) config.bgm_volume = v / 100 end, {width=20, knob="circle", track="roundrect"}) self.bgmSlider = newSlider(465, 420, 225, config.bgm_volume * 100, 0, 100, function(v) config.bgm_volume = v / 100 end, {width=20, knob="circle", track="roundrect"})
end end
function ConfigScene:update() function ConfigScene:update()
@@ -58,7 +59,7 @@ function ConfigScene:render()
if not ConfigScene.options[self.highlight][3] then if not ConfigScene.options[self.highlight][3] then
love.graphics.rectangle("fill", 25, 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, 342, 215, 33) love.graphics.rectangle("fill", 65 + (1+self.highlight-#self.options) * 300, 362, 215, 33)
end end
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
@@ -75,8 +76,8 @@ function ConfigScene:render()
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.print("SFX Volume: " .. math.floor(self.sfxSlider:getValue()) .. "%", 75, 345) love.graphics.print("SFX Volume: " .. math.floor(self.sfxSlider:getValue()) .. "%", 75, 365)
love.graphics.print("BGM Volume: " .. math.floor(self.bgmSlider:getValue()) .. "%", 375, 345) love.graphics.print("BGM Volume: " .. math.floor(self.bgmSlider:getValue()) .. "%", 375, 365)
love.graphics.setColor(1, 1, 1, 0.75) love.graphics.setColor(1, 1, 1, 0.75)
self.sfxSlider:draw() self.sfxSlider:draw()

View File

@@ -4,17 +4,18 @@ local ReplayScene = Scene:extend()
ReplayScene.title = "Replay" ReplayScene.title = "Replay"
function ReplayScene:new(replay, game_mode, ruleset, inputs) function ReplayScene:new(replay, game_mode, ruleset)
config.gamesettings = replay["gamesettings"] config.gamesettings = replay["gamesettings"]
love.math.setRandomSeed(replay["random_low"], replay["random_high"]) love.math.setRandomSeed(replay["random_low"], replay["random_high"])
love.math.setRandomState(replay["random_state"]) love.math.setRandomState(replay["random_state"])
self.retry_replay = replay self.retry_replay = replay
self.retry_mode = game_mode self.retry_mode = game_mode
self.retry_ruleset = ruleset self.retry_ruleset = ruleset
self.secret_inputs = inputs self.secret_inputs = replay["secret_inputs"]
self.game = game_mode(self.secret_inputs) self.game = game_mode(self.secret_inputs)
self.game.save_replay = false
self.ruleset = ruleset(self.game) self.ruleset = ruleset(self.game)
self.game:initialize(self.ruleset, true) self.game:initialize(self.ruleset)
self.inputs = { self.inputs = {
left=false, left=false,
right=false, right=false,
@@ -51,6 +52,8 @@ function ReplayScene:update()
self.game:update(input_copy, self.ruleset) self.game:update(input_copy, self.ruleset)
self.game.grid:update() self.game.grid:update()
DiscordRPC:update({ DiscordRPC:update({
details = "Viewing a replay",
state = self.game.name,
largeImageKey = "ingame-"..self.game:getBackground().."00" largeImageKey = "ingame-"..self.game:getBackground().."00"
}) })
end end

View File

@@ -121,12 +121,15 @@ function ReplaySelectScene:render()
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
for idx, replay in ipairs(replays) do for idx, replay in ipairs(replays) do
if(idx >= self.menu_state.replay-9 and idx <= self.menu_state.replay+9) then if(idx >= self.menu_state.replay-9 and idx <= self.menu_state.replay+9) then
local display_string = os.date("%c", replay["timestamp"]).." "..replay["mode"].." "..replay["ruleset"] local display_string = os.date("%c", replay["timestamp"]).." - "..replay["mode"].." - "..replay["ruleset"]
if replay["level"] ~= nil then if replay["level"] ~= nil then
display_string = display_string.." Level: "..replay["level"] display_string = display_string.." - Level: "..replay["level"]
end end
if replay["timer"] ~= nil then if replay["timer"] ~= nil then
display_string = display_string.." Time: "..formatTime(replay["timer"]) display_string = display_string.." - Time: "..formatTime(replay["timer"])
end
if #display_string > 75 then
display_string = display_string:sub(1, 75) .. "..."
end end
love.graphics.printf(display_string, 6, (260 - 20*(self.menu_state.replay)) + 20 * idx, 640, "left") love.graphics.printf(display_string, 6, (260 - 20*(self.menu_state.replay)) + 20 * idx, 640, "left")
end end
@@ -167,8 +170,7 @@ function ReplaySelectScene:onInputPress(e)
scene = ReplayScene( scene = ReplayScene(
replays[self.menu_state.replay], replays[self.menu_state.replay],
mode, mode,
rules, rules
replays[self.menu_state.replay]["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)

View File

@@ -60,18 +60,38 @@ function TitleScene:update()
else self.y_offset = 310 - self.frames end else self.y_offset = 310 - self.frames end
end end
local block_offsets = {
{color = "M", x = 0, y = 0},
{color = "G", x = 32, y = 0},
{color = "Y", x = 64, y = 0},
{color = "B", x = 0, y = 32},
{color = "O", x = 0, y = 64},
{color = "C", x = 32, y = 64},
{color = "R", x = 64, y = 64}
}
function TitleScene:render() function TitleScene:render()
love.graphics.setFont(font_3x5_4) love.graphics.setFont(font_3x5_4)
love.graphics.setColor(1, 1, 1, 1 - self.snow_bg_opacity) love.graphics.setColor(1, 1, 1, 1 - self.snow_bg_opacity)
love.graphics.draw( love.graphics.draw(
backgrounds["title"], -- title_night backgrounds["title_no_icon"], -- title, title_night
0, 0, 0, 0, 0, 0,
0.5, 0.5 0.5, 0.5
) )
-- 490, 192
for _, b in ipairs(block_offsets) do
love.graphics.draw(
blocks["2tie"][b.color],
490 + b.x, 192 + b.y, 0,
2, 2
)
end
--[[ --[[
love.graphics.draw( love.graphics.draw(
misc_graphics["icon"], misc_graphics["icon"],
460, 170, 0, 490, 192, 0,
2, 2 2, 2
) )
]] ]]

1
start_win32.bat Normal file
View File

@@ -0,0 +1 @@
dist\win32\love.exe .

1
start_win64.bat Normal file
View File

@@ -0,0 +1 @@
dist\windows\love.exe .

View File

@@ -16,12 +16,11 @@ GameMode.hash = ""
GameMode.tagline = "" GameMode.tagline = ""
GameMode.rollOpacityFunction = function(age) return 0 end GameMode.rollOpacityFunction = function(age) return 0 end
function GameMode:new(secret_inputs) function GameMode:new()
self.replay_inputs = {} self.replay_inputs = {}
self.random_low, self.random_high = love.math.getRandomSeed() self.random_low, self.random_high = love.math.getRandomSeed()
self.random_state = love.math.getRandomState() self.random_state = love.math.getRandomState()
self.secret_inputs = secret_inputs self.save_replay = config.gamesettings.save_replay == 1
self.save_replay = true
self.grid = Grid(10, 24) self.grid = Grid(10, 24)
self.randomizer = Randomizer() self.randomizer = Randomizer()
@@ -104,7 +103,7 @@ function GameMode:getSkin()
return "2tie" return "2tie"
end end
function GameMode:initialize(ruleset, replay) function GameMode:initialize(ruleset)
-- generate next queue -- generate next queue
self.used_randomizer = ( self.used_randomizer = (
table.equalvalues( table.equalvalues(
@@ -114,11 +113,10 @@ function GameMode:initialize(ruleset, replay)
self.randomizer or BagRandomizer(table.keys(ruleset.colourscheme)) self.randomizer or BagRandomizer(table.keys(ruleset.colourscheme))
) )
self.ruleset = ruleset self.ruleset = ruleset
self.save_replay = not replay
for i = 1, math.max(self.next_queue_length, 1) do for i = 1, math.max(self.next_queue_length, 1) do
table.insert(self.next_queue, self:getNextPiece(ruleset)) table.insert(self.next_queue, self:getNextPiece(ruleset))
end end
self.lock_on_soft_drop = ({ruleset.softdrop_lock, self.instant_soft_drop, false, true})[config.gamesettings.manlock] self.lock_on_soft_drop = ({ruleset.softdrop_lock, self.instant_soft_drop, false, true })[config.gamesettings.manlock]
self.lock_on_hard_drop = ({ruleset.harddrop_lock, self.instant_hard_drop, true, false})[config.gamesettings.manlock] self.lock_on_hard_drop = ({ruleset.harddrop_lock, self.instant_hard_drop, true, false})[config.gamesettings.manlock]
end end

View File

@@ -309,7 +309,7 @@ local mroll_points = {10, 20, 30, 100}
local grade_conversion = { local grade_conversion = {
[0] = 0, [0] = 0,
1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7,
7, 8, 8, 8, 9, 9, 9, 10, 11, 12, 12, 7, 8, 8, 8, 9, 9, 9, 10, 11, 12,
12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
17 17
} }
@@ -354,8 +354,7 @@ function MarathonA3Game:getAggregateGrade()
return math.min( return math.min(
self.section_cool_grade + self.section_cool_grade +
math.floor(self.roll_points / 100) + math.floor(self.roll_points / 100) +
grade_conversion[self.grade], grade_conversion[self.grade]
self.roll_frames > 3238 and 32 or 31
) )
end end

View File

@@ -202,13 +202,13 @@ end
local cool_cutoffs = { local cool_cutoffs = {
frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36), frameTime(0,36),
frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30), frameTime(0,30),
frameTime(0,27), frameTime(0,27), frameTime(0,27), frameTime(0,30), frameTime(0,30), frameTime(0,30),
} }
local regret_cutoffs = { local regret_cutoffs = {
frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50), frameTime(0,50),
frameTime(0,40), frameTime(0,40), frameTime(0,40), frameTime(0,40), frameTime(0,40), frameTime(0,42), frameTime(0,42), frameTime(0,42), frameTime(0,42), frameTime(0,42),
frameTime(0,35), frameTime(0,35), frameTime(0,35), frameTime(0,42), frameTime(0,42), frameTime(0,42),
} }
function PhantomMania2Game:updateSectionTimes(old_level, new_level) function PhantomMania2Game:updateSectionTimes(old_level, new_level)

View File

@@ -101,6 +101,7 @@ function SurvivalA2Game:onLineClear(cleared_row_count)
self.clear = true self.clear = true
if new_level < 999 then if new_level < 999 then
self.game_over = true self.game_over = true
return
end end
end end
self.level = new_level self.level = new_level

View File

@@ -0,0 +1,49 @@
local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.arika_ace2'
local ARS = Ruleset:extend()
ARS.name = "ARS-X"
ARS.hash = "ArikaEXP"
ARS.MANIPULATIONS_MAX = 24
ARS.ROTATIONS_MAX = 12
function ARS:onPieceCreate(piece, grid)
piece.manipulations = 0
piece.rotations = 0
piece.lowest_y = -math.huge
end
function ARS:checkNewLow(piece)
for _, block in pairs(piece:getBlockOffsets()) do
local y = piece.position.y + block.y
if y > piece.lowest_y then
piece.manipulations = 0
piece.rotations = 0
piece.lowest_y = y
end
end
end
function ARS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1
if piece.manipulations >= ARS.MANIPULATIONS_MAX then
piece.locked = true
end
end
end
function ARS:onPieceRotate(piece, grid, upward)
piece.lock_delay = 0 -- rotate reset
if upward or piece:isDropBlocked(grid) then
piece.rotations = piece.rotations + 1
if piece.rotations >= ARS.ROTATIONS_MAX and piece:isDropBlocked(grid) then
piece.locked = true
end
end
end
return ARS

View File

@@ -209,7 +209,7 @@ function Ruleset:initializePiece(
local colours local colours
if table.equalvalues( if table.equalvalues(
self.colourscheme, {"I", "J", "L", "O", "S", "T", "Z"} table.keys(self.colourscheme), {"I", "J", "L", "O", "S", "T", "Z"}
) then ) then
colours = ({self.colourscheme, ColourSchemes.Arika, ColourSchemes.TTC})[config.gamesettings.piece_colour] colours = ({self.colourscheme, ColourSchemes.Arika, ColourSchemes.TTC})[config.gamesettings.piece_colour]
else else

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.standard_exp' local Ruleset = require 'tetris.rulesets.standard_ace'
local SRS = Ruleset:extend() local SRS = Ruleset:extend()
@@ -33,8 +33,8 @@ SRS.wallkicks_line = {
}, },
}; };
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
local kicks local kicks
if piece.shape == "O" then if piece.shape == "O" then
return return
@@ -69,6 +69,12 @@ function SRS:checkNewLow(piece)
end end
end end
function SRS:onPieceCreate(piece, grid)
piece.manipulations = 0
piece.rotations = 0
piece.lowest_y = -math.huge
end
function SRS:onPieceDrop(piece, grid) function SRS:onPieceDrop(piece, grid)
self:checkNewLow(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

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ti_srs' local Ruleset = require 'tetris.rulesets.standard_ti'
local SRS = Ruleset:extend() local SRS = Ruleset:extend()

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.arika_srs' local Ruleset = require 'tetris.rulesets.standard_ti'
local SRS = Ruleset:extend() local SRS = Ruleset:extend()
@@ -27,8 +27,6 @@ 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
--piece.manipulations = 0
--piece.rotations = 0
piece.lowest_y = y piece.lowest_y = y
end end
end end