Compare commits

..

33 Commits

Author SHA1 Message Date
Ishaan Bhardwaj
f31beffab8 Update release script 2020-12-16 22:47:56 -05:00
Ishaan Bhardwaj
2ff8fb5edc Modpack README update 2020-12-16 22:33:48 -05:00
Boshi
1bf8f91ef2 Displays current gamemode in game (toggle) 2020-12-16 22:21:26 -05:00
Ishaan Bhardwaj
ba5f78d5f1 Merge branch 'master' of https://github.com/sashlilac/cambridge 2020-12-14 22:44:16 -05:00
Ishaan Bhardwaj
f7c4908062 Added an option to disable diagonal input 2020-12-14 22:43:50 -05:00
Ishaan Bhardwaj
3aa5bae7be Tetra Online notice and stuff 2020-12-10 21:22:16 -05:00
Ishaan Bhardwaj
40a2e78280 Marathon 2020 section colour function fixed 2020-12-06 11:38:45 -05:00
Ishaan Bhardwaj
696da3fa3f Marathon 2020 colour function removed 2020-12-06 11:27:44 -05:00
Ishaan Bhardwaj
4afe9f2bd4 Major sound effect update (closes #7?)
Sound effects can still be changed, and #7 can still be reopened.
2020-12-05 20:30:59 -05:00
Ishaan Bhardwaj
1f686fb5d4 Ti-ARS: T can no longer floorkick the air 2020-12-05 18:32:06 -05:00
Ishaan Bhardwaj
f4779c9847 Added the ability to toggle next piece SFX 2020-12-05 17:32:15 -05:00
Ishaan Bhardwaj
06cbec4bc8 Guideline SRS kicks fixed 2020-12-05 17:15:28 -05:00
Ishaan Bhardwaj
668564ffb0 Revert "big a3! (but its buggy??)"
This reverts commit 513cd6ba90.
Hailey, please do not add modes.
2020-12-05 16:56:12 -05:00
Hailey
e6edeea3d1 Merge branch 'master' of https://github.com/SashLilac/cambridge 2020-12-05 12:50:45 +10:00
Hailey
513cd6ba90 big a3! (but its buggy??) 2020-12-05 12:49:57 +10:00
Ishaan Bhardwaj
1beef8f157 Guideline SRS has 180s now 2020-12-04 21:36:25 -05:00
Ishaan Bhardwaj
d3b2b4c2d9 Ruleset refactoring! 2020-12-04 20:36:11 -05:00
Ishaan Bhardwaj
2b8b9d5084 Reduced the sound volume a little bit. 2020-12-04 20:12:36 -05:00
Ishaan Bhardwaj
2728780c45 Raised the piece sound volume by a factor of 10. 2020-12-04 19:42:33 -05:00
Ishaan Bhardwaj
ca592a3bcf Changed piece sounds, added sound sources 2020-12-04 19:27:02 -05:00
Ishaan Bhardwaj
b6f4158d70 Fixed SRS infinity bug! 2020-12-04 16:51:53 -05:00
Ishaan Bhardwaj
e43f5c470a Renaming backgrounds 2020-12-04 16:32:29 -05:00
Ishaan Bhardwaj
7bcdc517c0 Revert "Merge pull request #11 from Rexxt/master"
Reverting this pull request for a few reasons:
The piece sounds were too quiet.
The piece landing sound was distasteful.
2020-12-04 16:22:22 -05:00
Ishaan Bhardwaj
1d30987f9a Merge pull request #11 from Rexxt/master
Uncopyrightening and making the game slightly friendlier to mod
2020-12-04 16:13:38 -05:00
Ishaan Bhardwaj
1dd46a11ef Fixed torikans giving you a green line 2020-12-04 15:41:44 -05:00
Ishaan Bhardwaj
935c7aa14c Default secret grade names 2020-12-04 15:16:13 -05:00
Ishaan Bhardwaj
aea115d953 ACE-SRS has correct number of resets 2020-12-04 11:22:32 -05:00
Ishaan Bhardwaj
3d5b33f41a Added ability to enable/disable synchroes
On by default in anything but world rulesets.
Gamemodes / rulesets can override this setting.
2020-12-04 10:57:43 -05:00
Mizu
29f07bb6ab Update piece sounds 2020-12-04 15:38:34 +01:00
Mizu
6d326a142c Update some sounds (not the pieces 2020-11-11 18:38:45 +01:00
Mizu
b6f1072587 Merge branch 'master' of https://github.com/Rexxt/cambridge 2020-11-11 17:43:53 +01:00
Mizu
eef04ebf05 Update graphic names and SOURCES.md 2020-11-11 17:42:48 +01:00
Mizu
e24737a3b8 Merge pull request #1 from SashLilac/master
Update fork
2020-11-11 17:17:22 +01:00
58 changed files with 138 additions and 667 deletions

View File

@@ -1,5 +1,11 @@
![Cambridge Banner](https://cdn.discordapp.com/attachments/764432435802013709/767724895076614154/cambridge_logo_lt.png) ![Cambridge Banner](https://cdn.discordapp.com/attachments/764432435802013709/767724895076614154/cambridge_logo_lt.png)
Important notice
================
Tetra Online was recently struck by an illegal DMCA claim from the Tetris Company.
Please, spread awareness of this, and use the hashtag #DMCAgaming in your posts.
Cambridge Cambridge
========= =========
@@ -42,7 +48,7 @@ You do not need LÖVE on Windows, as it comes bundled with the program.
To get the stable release, simply download the ZIP in the latest release. All assets needed are bundled with the executable. To get the stable release, simply download the ZIP in the latest release. All assets needed are bundled with the executable.
If you want the bleeding edge version, or want mod pack support, download [this](https://github.com/SashLilac/cambridge/archive/master.zip). If you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command: Extract the ZIP, open a Command Prompt at the folder you extracted Cambridge to, then run this command:
@@ -74,9 +80,9 @@ It should run automatically!
## Installing modpacks ## Installing modpacks
Simply drag your mode, ruleset, and randomizer Lua files into their respective directory, and they should appear automatically. Simply drag your mode, ruleset, and randomizer Lua files into their respective [directory](https://love2d.org/wiki/love.filesystem), and they should appear automatically.
Alternatively, install [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential. For more detailed instructions, install [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
License License
------- -------

View File

@@ -8,7 +8,7 @@ Some of the assets are used without proper licenses. We aim to have fully licens
Backgrounds Backgrounds
----------- -----------
1. Title: "Motus Glacies." Contributed by Daniel "Explo" McCarthy. 1. Title: Original picrute found on the Wikipedia article for Cambridge
1. *Gameplay level 0: "Quantum foam." Alex Sukontsev. https://www.flickr.com/photos/control9/14957509814/ 1. *Gameplay level 0: "Quantum foam." Alex Sukontsev. https://www.flickr.com/photos/control9/14957509814/
2. *Gameplay level 1: No name. http://www.onekind.tv/univision-mqb/q5mqh5brlvuuj2nhdx7ch7eum183uu 2. *Gameplay level 1: No name. http://www.onekind.tv/univision-mqb/q5mqh5brlvuuj2nhdx7ch7eum183uu
@@ -34,6 +34,14 @@ Backgrounds
Backgrounds marked with a * are placeholders that will be replaced in later versions due to incompatible licenses. We are generally aiming for public domain background images, but will also accept backgrounds given proper licenses to be included within Cambridge. Backgrounds marked with a * are placeholders that will be replaced in later versions due to incompatible licenses. We are generally aiming for public domain background images, but will also accept backgrounds given proper licenses to be included within Cambridge.
Sounds
------
All piece sounds are (c) 2020 Damian Yerrick.
Other sounds from:
- NullpoMino
- DTET, (c) 2003 Mihys.
Music Music
----- -----

View File

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

View File

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

View File

@@ -4,6 +4,6 @@ mkdir dist/windows
mkdir dist/win32 mkdir dist/win32
cp cambridge.love dist/ cp cambridge.love dist/
cat dist/windows/love.exe cambridge.love > dist/windows/cambridge.exe cat dist/windows/love.exe cambridge.love > dist/windows/cambridge.exe
zip dist/cambridge-windows.zip dist/windows/* SOURCES.md LICENSE zip dist/cambridge-windows.zip dist/windows/* SOURCES.md LICENSE.md
cat dist/win32/love.exe cambridge.love > dist/win32/cambridge.exe cat dist/win32/love.exe cambridge.love > dist/win32/cambridge.exe
zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE zip dist/cambridge-win32.zip dist/win32/* SOURCES.md LICENSE.md

View File

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 3.6 MiB

View File

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

Before

Width:  |  Height:  |  Size: 3.0 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Binary file not shown.

BIN
res/se/ihs.wav Normal file

Binary file not shown.

BIN
res/se/irs.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -68,6 +68,10 @@ function GameScene:render()
self.game:drawCustom() self.game:drawCustom()
love.graphics.setFont(font_3x5_2)
if config.gamesettings.display_gamemode == 1 then
love.graphics.printf(self.game.name .. " - " .. self.ruleset.name, 0, 460, 640, "left")
end
end end
function GameScene:onInputPress(e) function GameScene:onInputPress(e)

View File

@@ -9,7 +9,11 @@ ConfigScene.options = {
{"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}}, {"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}},
{"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}}, {"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}},
{"world_reverse","A Button Rotation", {"Left" ,"Auto" ,"Right"}}, {"world_reverse","A Button Rotation", {"Left" ,"Auto" ,"Right"}},
{"das_last_key", "DAS Switch", {"Default", "Instant"}} {"display_gamemode", "Display Gamemode", {"On", "Off"}},
{"next_se", "Next Piece SFX", {"On", "Off"}},
{"das_last_key", "DAS Switch", {"Default", "Instant"}},
{"synchroes_allowed", "Synchroes", {"Per ruleset", "On", "Off"}},
{"diagonal_input", "Diagonal Input", {"On", "Off"}}
} }
local optioncount = #ConfigScene.options local optioncount = #ConfigScene.options

View File

@@ -46,6 +46,11 @@ function GameMode:new()
self.irs = true self.irs = true
self.ihs = true self.ihs = true
self.rpc_details = "In game" self.rpc_details = "In game"
self.SGnames = {
"9", "8", "7", "6", "5", "4", "3", "2", "1",
"S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9",
"GM"
}
-- variables related to configurable parameters -- variables related to configurable parameters
self.drop_locked = false self.drop_locked = false
self.hard_drop_locked = false self.hard_drop_locked = false
@@ -95,6 +100,16 @@ function GameMode:update(inputs, ruleset)
end end
if self.completed then return end if self.completed then return end
if config.gamesettings.diagonal_input == 2 then
if inputs["left"] or inputs["right"] then
inputs["up"] = false
inputs["down"] = false
elseif inputs["up"] or inputs["down"] then
inputs["left"] = false
inputs["right"] = false
end
end
-- advance one frame -- advance one frame
if self:advanceOneFrame(inputs, ruleset) == false then return end if self:advanceOneFrame(inputs, ruleset) == false then return end
@@ -219,9 +234,7 @@ end
function GameMode:onLineClear(cleared_row_count) end function GameMode:onLineClear(cleared_row_count) end
function GameMode:onPieceEnter() end function GameMode:onPieceEnter() end
function GameMode:onHold() function GameMode:onHold() end
playSE("hold")
end
function GameMode:onSoftDrop(dropped_row_count) function GameMode:onSoftDrop(dropped_row_count)
self.drop_bonus = self.drop_bonus + 1 * dropped_row_count self.drop_bonus = self.drop_bonus + 1 * dropped_row_count
@@ -358,7 +371,7 @@ end
function GameMode:initializeOrHold(inputs, ruleset) function GameMode:initializeOrHold(inputs, ruleset)
if self.ihs and self.enable_hold and inputs["hold"] == true then if self.ihs and self.enable_hold and inputs["hold"] == true then
self:hold(inputs, ruleset) self:hold(inputs, ruleset, true)
else else
self:initializeNextPiece(inputs, ruleset, self.next_queue[1]) self:initializeNextPiece(inputs, ruleset, self.next_queue[1])
end end
@@ -369,7 +382,7 @@ function GameMode:initializeOrHold(inputs, ruleset)
end end
end end
function GameMode:hold(inputs, ruleset) function GameMode:hold(inputs, ruleset, ihs)
local data = copy(self.hold_queue) local data = copy(self.hold_queue)
if self.piece == nil then if self.piece == nil then
self.hold_queue = self.next_queue[1] self.hold_queue = self.next_queue[1]
@@ -388,6 +401,8 @@ function GameMode:hold(inputs, ruleset)
self:initializeNextPiece(inputs, ruleset, data, false) self:initializeNextPiece(inputs, ruleset, data, false)
end end
self.held = true self.held = true
if ihs then playSE("ihs")
else playSE("hold") end
self:onHold() self:onHold()
end end
@@ -410,7 +425,7 @@ 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() if config.gamesettings.next_se == 1 then self:playNextSound() end
end end
function GameMode:playNextSound() function GameMode:playNextSound()
@@ -519,7 +534,11 @@ function GameMode:drawSectionTimes(current_section)
love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left") love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left")
end end
function GameMode:drawSectionTimesWithSecondary(current_section, section_colour_function) function GameMode:sectionColourFunction(section)
return { 1, 1, 1, 1 }
end
function GameMode:drawSectionTimesWithSecondary(current_section)
local section_x = 530 local section_x = 530
local section_secondary_x = 440 local section_secondary_x = 440
@@ -530,12 +549,11 @@ function GameMode:drawSectionTimesWithSecondary(current_section, section_colour_
end end
for section, time in pairs(self.secondary_section_times) do for section, time in pairs(self.secondary_section_times) do
if self.section_colour_function then love.graphics.setColor(self:sectionColourFunction(section))
love.graphics.setColor(self:section_colour_function(section))
end
if section > 0 then if section > 0 then
love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left") love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left")
end end
love.graphics.setColor(1, 1, 1, 1)
end end
local current_x local current_x

View File

@@ -442,7 +442,7 @@ function Marathon2020Game:drawScoringInfo()
love.graphics.printf("GRADE PTS.", text_x, 200, 90, "left") love.graphics.printf("GRADE PTS.", text_x, 200, 90, "left")
love.graphics.printf("LEVEL", text_x, 320, 40, "left") love.graphics.printf("LEVEL", text_x, 320, 40, "left")
self:drawSectionTimesWithSecondary(current_section, self.sectionColourFunction) self:drawSectionTimesWithSecondary(current_section)
if (self.cool_timer > 0) then if (self.cool_timer > 0) then
love.graphics.printf("COOL!!", 64, 400, 160, "center") love.graphics.printf("COOL!!", 64, 400, 160, "center")

View File

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

View File

@@ -291,7 +291,7 @@ function PhantomMania2Game:setHoldOpacity()
if self.level > 1000 and self.level < 1300 then if self.level > 1000 and self.level < 1300 then
love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15)) love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15))
else else
love.graphics.setColor(1, 1, 1, 1) self.super:setHoldOpacity(1, self.held and 0.6 or 1)
end end
end end

View File

@@ -159,7 +159,7 @@ function SurvivalA2Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
love.graphics.printf(self.score, text_x, 220, 90, "left") love.graphics.printf(self.score, text_x, 220, 90, "left")
if self.roll_frames > 2968 then love.graphics.setColor(1, 0.5, 0, 1) if self.roll_frames > 2968 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end elseif self.level >= 999 and self.clear then love.graphics.setColor(0, 1, 0, 1) end
if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.level, text_x, 340, 40, "right") love.graphics.printf(self.level, text_x, 340, 40, "right")

View File

@@ -243,7 +243,7 @@ function SurvivalA3Game:drawScoringInfo()
love.graphics.setFont(font_3x5_3) love.graphics.setFont(font_3x5_3)
if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1) if self.roll_frames > 3238 then love.graphics.setColor(1, 0.5, 0, 1)
elseif self.clear then love.graphics.setColor(0, 1, 0, 1) end elseif self.level >= 1300 and self.clear then love.graphics.setColor(0, 1, 0, 1) end
love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left") love.graphics.printf(getLetterGrade(math.floor(self.grade)), text_x, 140, 90, "left")
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(self.score, text_x, 220, 90, "left") love.graphics.printf(self.score, text_x, 220, 90, "left")

View File

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

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset' local Ruleset = require 'tetris.rulesets.arika_ti'
local ARS = Ruleset:extend() local ARS = Ruleset:extend()
@@ -39,136 +39,11 @@ ARS.big_spawn_positions = {
Z = { x=2, y=1 }, Z = { x=2, y=1 },
} }
ARS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
},
Z={
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
}
}
-- Component functions.
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
-- O doesn't kick
if (piece.shape == "O") then return end
-- center column rule
if (
piece.shape == "J" or piece.shape == "T" or piece.shape == "L"
) and (
piece.rotation == 0 or piece.rotation == 2
) then
local offsets = new_piece:getBlockOffsets()
table.sort(offsets, function(A, B) return A.y < B.y or A.y == B.y and A.x < B.y end)
for index, offset in pairs(offsets) do
if grid:isOccupied(piece.position.x + offset.x, piece.position.y + offset.y) then
if offset.x == 0 then
return
else
break
end
end
end
end
if piece.shape == "I" then
-- special kick rules for I
if new_piece.rotation == 0 or new_piece.rotation == 2 and
(piece:isMoveBlocked(grid, {x=-1, y=0}) or piece:isMoveBlocked(grid, {x=1, y=0})) then
-- kick right, right2, left
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
self:onPieceRotate(piece, grid)
end
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
-- kick up, up2
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
self:onPieceRotate(piece, grid)
piece.floorkick = 1
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
self:onPieceRotate(piece, grid)
piece.floorkick = 1
end
end
else
-- kick right, kick left
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
elseif piece.shape == "T"
and new_piece.rotation == 0
and piece.floorkick == 0
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
then
-- T floorkick
piece.floorkick = piece.floorkick + 1
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
end
end
end
function ARS:onPieceCreate(piece, grid) function ARS:onPieceCreate(piece, grid)
piece.floorkick = 0 piece.floorkick = 0
piece.manipulations = 0 piece.manipulations = 0
end end
function ARS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
piece.locked = true
end
end
function ARS:onPieceMove(piece, grid) function ARS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
@@ -192,14 +67,4 @@ function ARS:onPieceRotate(piece, grid)
end end
end end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
end
end
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
return ARS return ARS

View File

@@ -1,5 +1,5 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset' local Ruleset = require 'tetris.rulesets.arika_ti'
local ARS = Ruleset:extend() local ARS = Ruleset:extend()
@@ -26,136 +26,11 @@ ARS.big_spawn_positions = {
Z = { x=2, y=1 }, Z = { x=2, y=1 },
} }
ARS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
},
Z={
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
}
}
-- Component functions.
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
-- O doesn't kick
if (piece.shape == "O") then return end
-- center column rule
if (
piece.shape == "J" or piece.shape == "T" or piece.shape == "L"
) and (
piece.rotation == 0 or piece.rotation == 2
) then
local offsets = new_piece:getBlockOffsets()
table.sort(offsets, function(A, B) return A.y < B.y or A.y == B.y and A.x < B.y end)
for index, offset in pairs(offsets) do
if grid:isOccupied(piece.position.x + offset.x, piece.position.y + offset.y) then
if offset.x == 0 then
return
else
break
end
end
end
end
if piece.shape == "I" then
-- special kick rules for I
if new_piece.rotation == 0 or new_piece.rotation == 2 and
(piece:isMoveBlocked(grid, {x=-1, y=0}) or piece:isMoveBlocked(grid, {x=1, y=0})) then
-- kick right, right2, left
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=2, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=2, y=0})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
self:onPieceRotate(piece, grid)
end
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then
-- kick up, up2
if grid:canPlacePiece(new_piece:withOffset({x=0, y=-1})) then
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
self:onPieceRotate(piece, grid)
piece.floorkick = 1
elseif grid:canPlacePiece(new_piece:withOffset({x=0, y=-2})) then
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
self:onPieceRotate(piece, grid)
piece.floorkick = 1
end
end
else
-- kick right, kick left
if grid:canPlacePiece(new_piece:withOffset({x=1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=1, y=0})
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
elseif piece.shape == "T"
and new_piece.rotation == 0
and piece.floorkick == 0
and grid:canPlacePiece(new_piece:withOffset({x=0, y=-1}))
then
-- T floorkick
piece.floorkick = piece.floorkick + 1
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
end
end
end
function ARS:onPieceCreate(piece, grid) function ARS:onPieceCreate(piece, grid)
piece.floorkick = 0 piece.floorkick = 0
piece.manipulations = 0 piece.manipulations = 0
end end
function ARS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
if piece.floorkick >= 2 and piece:isDropBlocked(grid) then
piece.locked = true
end
end
function ARS:onPieceMove(piece, grid) function ARS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
@@ -179,14 +54,4 @@ function ARS:onPieceRotate(piece, grid)
end end
end end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
end
end
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
return ARS return ARS

View File

@@ -1,22 +1,10 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset' local Ruleset = require 'tetris.rulesets.ti_srs'
local SRS = Ruleset:extend() local SRS = Ruleset:extend()
SRS.name = "ACE-SRS" SRS.name = "ACE-SRS"
SRS.hash = "ACE Standard" SRS.hash = "ACE Standard"
SRS.world = true
SRS.colourscheme = {
I = "C",
L = "O",
J = "B",
S = "G",
Z = "R",
O = "Y",
T = "M",
}
SRS.softdrop_lock = false
SRS.harddrop_lock = true
SRS.spawn_positions = { SRS.spawn_positions = {
I = { x=5, y=2 }, I = { x=5, y=2 },
@@ -38,137 +26,11 @@ SRS.big_spawn_positions = {
Z = { x=2, y=1 }, Z = { x=2, y=1 },
} }
SRS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1} },
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1} },
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0} },
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0} },
},
Z={
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1} },
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
}
}
SRS.wallkicks_3x3 = {
[0]={
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
[2]={{x=0, y=1}, {x=0, y=-1}},
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
},
[1]={
[0]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
[2]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
[3]={{x=0, y=1}, {x=0, y=-1}},
},
[2]={
[0]={{x=0, y=1}, {x=0, y=-1}},
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
},
[3]={
[0]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
[1]={{x=0, y=1}, {x=0, y=-1}},
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
},
};
SRS.wallkicks_line = {
[0]={
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
[2]={},
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
},
[1]={
[0]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 2}},
[2]={{x=-1, y= 0}, {x= 2, y= 0}, {x=-1, y=-2}, {x= 2, y= 1}},
[3]={},
},
[2]={
[0]={},
[1]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 1}},
[3]={{x= 2, y= 0}, {x=-1, y= 0}, {x= 2, y=-1}, {x=-1, y= 1}},
},
[3]={
[0]={{x=-2, y= 0}, {x= 1, y= 0}, {x=-2, y=-1}, {x= 1, y= 2}},
[1]={},
[2]={{x= 1, y= 0}, {x=-2, y= 0}, {x= 1, y=-2}, {x=-2, y= 1}},
},
};
-- Component functions.
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
local kicks
if piece.shape == "O" then
return
elseif piece.shape == "I" then
kicks = SRS.wallkicks_line[piece.rotation][new_piece.rotation]
else
kicks = SRS.wallkicks_3x3[piece.rotation][new_piece.rotation]
end
assert(piece.rotation ~= new_piece.rotation)
for idx, offset in pairs(kicks) do
kicked_piece = new_piece:withOffset(offset)
if grid:canPlacePiece(kicked_piece) then
piece:setRelativeRotation(rot_dir)
piece:setOffset(offset)
self:onPieceRotate(piece, grid)
return
end
end
end
function SRS:onPieceCreate(piece, grid)
piece.manipulations = 0
end
function SRS:onPieceDrop(piece, grid)
piece.lock_delay = 0 -- step reset
end
function SRS:onPieceMove(piece, grid) function SRS:onPieceMove(piece, grid)
piece.lock_delay = 0 -- move reset piece.lock_delay = 0 -- move reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then if piece.manipulations >= 128 then
piece.locked = true piece.locked = true
end end
end end
@@ -178,18 +40,10 @@ function SRS:onPieceRotate(piece, grid)
piece.lock_delay = 0 -- rotate reset piece.lock_delay = 0 -- rotate reset
if piece:isDropBlocked(grid) then if piece:isDropBlocked(grid) then
piece.manipulations = piece.manipulations + 1 piece.manipulations = piece.manipulations + 1
if piece.manipulations >= 127 then if piece.manipulations >= 128 then
piece.locked = true piece.locked = true
end end
end end
end end
function SRS:get180RotationValue()
if config.gamesettings.world_reverse == 1 then
return 1
else
return 3
end
end
return SRS return SRS

View File

@@ -1,77 +1,11 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset' local Ruleset = require 'tetris.rulesets.arika'
local ARS = Ruleset:extend() local ARS = Ruleset:extend()
ARS.name = "Ti-ARS" ARS.name = "Ti-ARS"
ARS.hash = "ArikaTI" ARS.hash = "ArikaTI"
ARS.spawn_positions = {
I = { x=5, y=4 },
J = { x=4, y=5 },
L = { x=4, y=5 },
O = { x=5, y=5 },
S = { x=4, y=5 },
T = { x=4, y=5 },
Z = { x=4, y=5 },
}
ARS.big_spawn_positions = {
I = { x=3, y=2 },
J = { x=2, y=3 },
L = { x=2, y=3 },
O = { x=3, y=3 },
S = { x=2, y=3 },
T = { x=2, y=3 },
Z = { x=2, y=3 },
}
ARS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} },
{ {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} },
{ {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=-2}, {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} },
},
Z={
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
{ {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=0}, {x=0, y=0} },
{ {x=0, y=-1}, {x=0, y=0}, {x=1, y=-2}, {x=1, y=-1} },
}
}
-- Component functions. -- Component functions.
function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid) function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
@@ -104,40 +38,44 @@ 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})
self:onPieceRotate(piece, grid)
elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then elseif grid:canPlacePiece(new_piece:withOffset({x=-1, y=0})) then
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
self:onPieceRotate(piece, grid) self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=-1, y=0})
end end
elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 then elseif piece:isDropBlocked(grid) and (new_piece.rotation == 1 or new_piece.rotation == 3) and piece.floorkick == 0 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
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
self:onPieceRotate(piece, grid) self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
piece.floorkick = 1 piece.floorkick = 1
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})
self:onPieceRotate(piece, grid) self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-2})
piece.floorkick = 1 piece.floorkick = 1
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 elseif 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 piece.shape == "T" elseif piece.shape == "T"
and new_piece.rotation == 0 and new_piece.rotation == 0
and piece.floorkick == 0 and piece.floorkick == 0
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
piece.floorkick = piece.floorkick + 1 piece.floorkick = piece.floorkick + 1
self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1}) piece:setRelativeRotation(rot_dir):setOffset({x=0, y=-1})
end end
end end
@@ -161,14 +99,4 @@ function ARS:onPieceRotate(piece, grid)
end end
end end
function ARS:get180RotationValue()
if config.gamesettings.world_reverse == 3 then
return 1
else
return 3
end
end
function ARS:getDefaultOrientation() return 3 end -- downward facing pieces by default
return ARS return ARS

View File

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

View File

@@ -115,8 +115,8 @@ function Ruleset:attemptRotate(new_inputs, piece, grid, initial)
local new_piece = piece:withRelativeRotation(rot_dir) local new_piece = piece:withRelativeRotation(rot_dir)
if (grid:canPlacePiece(new_piece)) then if (grid:canPlacePiece(new_piece)) then
piece:setRelativeRotation(rot_dir)
self:onPieceRotate(piece, grid) self:onPieceRotate(piece, grid)
piece:setRelativeRotation(rot_dir)
else else
if not(initial and self.enable_IRS_wallkicks == false) then if not(initial and self.enable_IRS_wallkicks == false) then
self:attemptWallkicks(piece, new_piece, rot_dir, grid) self:attemptWallkicks(piece, new_piece, rot_dir, grid)
@@ -197,7 +197,14 @@ function Ruleset:initializePiece(
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big) }, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
self:onPieceCreate(piece) self:onPieceCreate(piece)
if irs then self:rotatePiece(inputs, piece, grid, {}, true) end if irs then
if inputs.rotate_left or inputs.rotate_left2 or
inputs.rotate_right or inputs.rotate_right2 or
inputs.rotate_180 then
playSE("irs")
end
self:rotatePiece(inputs, piece, grid, {}, true)
end
self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked) self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked)
return piece return piece
end end
@@ -211,8 +218,16 @@ function Ruleset:processPiece(
drop_locked, hard_drop_locked, drop_locked, hard_drop_locked,
hard_drop_enabled, additive_gravity hard_drop_enabled, additive_gravity
) )
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
if synchroes_allowed then
self:rotatePiece(inputs, piece, grid, prev_inputs, false) self:rotatePiece(inputs, piece, grid, prev_inputs, false)
self:movePiece(piece, grid, move, gravity >= 20) self:movePiece(piece, grid, move, gravity >= 20)
else
self:movePiece(piece, grid, move, gravity >= 20)
self:rotatePiece(inputs, piece, grid, prev_inputs, false)
end
self:dropPiece( self:dropPiece(
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked, inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
hard_drop_enabled, additive_gravity hard_drop_enabled, additive_gravity

View File

@@ -1,112 +1,22 @@
local Piece = require 'tetris.components.piece' local Piece = require 'tetris.components.piece'
local Ruleset = require 'tetris.rulesets.ruleset' local Ruleset = require 'tetris.rulesets.arika_srs'
local SRS = Ruleset:extend() local SRS = Ruleset:extend()
SRS.name = "Guideline SRS" SRS.name = "Guideline SRS"
SRS.hash = "Standard" SRS.hash = "Standard"
SRS.world = true
SRS.colourscheme = {
I = "C",
L = "O",
J = "B",
S = "G",
Z = "R",
O = "Y",
T = "M",
}
SRS.softdrop_lock = false
SRS.harddrop_lock = true
SRS.enable_IRS_wallkicks = true SRS.enable_IRS_wallkicks = true
SRS.spawn_positions = { function SRS:check_new_low(piece)
I = { x=5, y=2 }, for _, block in pairs(piece:getBlockOffsets()) do
J = { x=4, y=3 }, local y = piece.position.y + block.y
L = { x=4, y=3 }, if y > piece.lowest_y then
O = { x=5, y=3 }, piece.manipulations = 0
S = { x=4, y=3 }, piece.lowest_y = y
T = { x=4, y=3 }, end
Z = { x=4, y=3 }, end
} end
SRS.big_spawn_positions = {
I = { x=3, y=0 },
J = { x=2, y=1 },
L = { x=2, y=1 },
O = { x=3, y=1 },
S = { x=2, y=1 },
T = { x=2, y=1 },
Z = { x=2, y=1 },
}
SRS.block_offsets = {
I={
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=0, y=2} },
{ {x=0, y=1}, {x=-1, y=1}, {x=-2, y=1}, {x=1, y=1} },
{ {x=-1, y=0}, {x=-1, y=-1}, {x=-1, y=1}, {x=-1, y=2} },
},
J={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1} },
},
L={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1} },
},
O={
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
{ {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} },
},
S={
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1} },
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0} },
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1} },
},
T={
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0} },
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1} },
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0} },
},
Z={
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1} },
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0} },
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
}
}
SRS.wallkicks_3x3 = {
[0]={
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
[2]={{x=0, y=1}, {x=0, y=-1}},
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
},
[1]={
[0]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
[2]={{x=1, y=0}, {x=1, y=1}, {x=0, y=-2}, {x=1, y=-2}},
[3]={{x=0, y=1}, {x=0, y=-1}},
},
[2]={
[0]={{x=0, y=1}, {x=0, y=-1}},
[1]={{x=-1, y=0}, {x=-1, y=-1}, {x=0, y=2}, {x=-1, y=2}},
[3]={{x=1, y=0}, {x=1, y=-1}, {x=0, y=2}, {x=1, y=2}},
},
[3]={
[0]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
[1]={{x=0, y=1}, {x=0, y=-1}},
[2]={{x=-1, y=0}, {x=-1, y=1}, {x=0, y=-2}, {x=-1, y=-2}},
},
};
SRS.wallkicks_line = { SRS.wallkicks_line = {
[0]={ [0]={
@@ -131,16 +41,6 @@ SRS.wallkicks_line = {
}, },
}; };
function SRS:check_new_low(piece)
for _, block in pairs(piece:getBlockOffsets()) do
local y = piece.position.y + block.y
if y > piece.lowest_y then
piece.manipulations = 0
piece.lowest_y = y
end
end
end
-- Component functions. -- Component functions.
function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid) function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
@@ -203,4 +103,6 @@ function SRS:onPieceRotate(piece, grid)
end end
end end
function SRS:get180RotationValue() return 2 end
return SRS return SRS

View File

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