Compare commits

..

11 Commits

Author SHA1 Message Date
Hailey
e42e0225cf cleanup before pr 2021-11-14 17:49:27 +10:00
Hailey
d937ce8507 added information on haileyjunk in case people wonder what it is 2021-11-14 17:41:40 +10:00
Hailey
f994d768ef Added freeplay mode details and challenge details!! 2021-11-14 15:07:07 +10:00
Hailey
9f5f9bc336 Implemented challenges!!!!! 2021-11-14 14:18:55 +10:00
Hailey
23b42a534e Merge branch 'master' into haileyjunk 2021-11-09 14:58:14 +10:00
hailey
6a465f8441 changed version for screenshots 2021-10-22 20:37:49 +10:00
hailey
8c5564f196 debug keys and splash text i guess 2021-10-22 15:39:39 +10:00
hailey
035a3aa2f2 Merge branch 'master' into haileyjunk 2021-10-22 15:09:03 +10:00
hailey
9f88faa0a7 wip bs 2021-10-22 15:08:14 +10:00
hailey
63e9531b28 h 2021-09-30 12:46:38 +10:00
hailey
174c45e7eb new branch where i practice getting back into the coding groove while testing and experimenting with new and interesing ideas and concepts 2021-09-30 11:38:20 +10:00
17 changed files with 475 additions and 30 deletions

View File

@@ -57,13 +57,13 @@ Coding conventions
Use tabs to indent, spaces to align. Use tabs to indent, spaces to align.
* Specifically, spaces should not appear at the beginning of a line, and tabs should not appear _except_ at the beginning of a line. * Specifically, spaces should not appear at the beginning of a line, and tabs should not appear _except_ at the beginning of a line.
* If you're aligning multiline if-statements, the initial "if", "elseif" or "else" should be flush left with the indentation level, with spaces padding the gap to the next word as necessary. For example: * The sole exception is in a multiline `if` statement; the initial `if` should have four spaces before it to align it with an `elseif` on the next line. For example:
```lua ```lua
if self.level < 900 then return 12 ---- 4 spaces
elseif self.level < 1200 then return 8 if self.level < 900 then return 12
else return 6 elseif self.level < 1200 then return 8
end else return 6 end
``` ```
Comments at the end of lines of code must be one line long. Multi-line comments must appear in their own block. Comments at the end of lines of code must be one line long. Multi-line comments must appear in their own block.

View File

@@ -40,6 +40,14 @@ Alternatively, if you're on a 32-bit system, run this instead:
Then, check the mod pack section at the bottom of this page. Then, check the mod pack section at the bottom of this page.
#### Other branches/haileyjunk
The Cambridge repository has multiple public and private branches for working on and testing out major new features over the course of many commits.
If you're looking to test even newer features that aren't even in the master branch, the closest you're going to get is probably the haileyjunk branch, which you can download [here](https://github.com/MillaBasset/cambridge/archive/master.zip).
> WARNING: This branch can be very buggy and broken at times. Use with care.
### 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, because it won't work with earlier versions!**

View File

@@ -5,6 +5,8 @@ bgm = {
pacer_test = love.audio.newSource("res/bgm/pacer_test.mp3", "stream"), pacer_test = love.audio.newSource("res/bgm/pacer_test.mp3", "stream"),
} }
local frames = 0
local current_bgm = nil local current_bgm = nil
local bgm_locked = false local bgm_locked = false
local unfocused = false local unfocused = false

View File

@@ -118,7 +118,8 @@ misc_graphics = {
ready = love.graphics.newImage("res/img/ready.png"), ready = love.graphics.newImage("res/img/ready.png"),
go = love.graphics.newImage("res/img/go.png"), go = love.graphics.newImage("res/img/go.png"),
select_mode = love.graphics.newImage("res/img/select_mode.png"), select_mode = love.graphics.newImage("res/img/select_mode.png"),
select_challenge = love.graphics.newImage("res/img/select_challenge_placeholder.png"),
strike = love.graphics.newImage("res/img/strike.png"), strike = love.graphics.newImage("res/img/strike.png"),
santa = love.graphics.newImage("res/img/santa.png"), santa = love.graphics.newImage("res/img/santa.png"),
icon = love.graphics.newImage("res/img/cambridge_transparent.png") icon = love.graphics.newImage("res/img/cambridge_transparent.png")
} }

View File

@@ -1 +1 @@
version = "v0.3" version = "v0.3.1"

View File

@@ -13,14 +13,14 @@ function love.load()
loadSave() loadSave()
require "funcs" require "funcs"
require "scene" require "scene"
--config["side_next"] = false --config["side_next"] = false
--config["reverse_rotate"] = true --config["reverse_rotate"] = true
--config["das_last_key"] = false --config["das_last_key"] = false
--config["fullscreen"] = false --config["fullscreen"] = false
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true}); love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
-- used for screenshots -- used for screenshots
GLOBAL_CANVAS = love.graphics.newCanvas() GLOBAL_CANVAS = love.graphics.newCanvas()
@@ -42,6 +42,13 @@ function initModules()
game_modes[#game_modes+1] = require ("tetris.modes."..string.sub(mode_list[i],1,-5)) game_modes[#game_modes+1] = require ("tetris.modes."..string.sub(mode_list[i],1,-5))
end end
end end
challenges = {}
challenge_list = love.filesystem.getDirectoryItems("tetris/challenges")
for i=1,#challenge_list do
if(challenge_list[i] ~= "challenge.lua" and string.sub(challenge_list[i], -4) == ".lua") then
challenges[#challenges+1] = require ("tetris.challenges."..string.sub(challenge_list[i],1,-5))
end
end
rulesets = {} rulesets = {}
rule_list = love.filesystem.getDirectoryItems("tetris/rulesets") rule_list = love.filesystem.getDirectoryItems("tetris/rulesets")
for i=1,#rule_list do for i=1,#rule_list do
@@ -72,7 +79,7 @@ function love.draw()
(height - scale_factor * 480) / 2 (height - scale_factor * 480) / 2
) )
love.graphics.scale(scale_factor) love.graphics.scale(scale_factor)
scene:render() scene:render()
if config.gamesettings.display_gamemode == 1 or scene.title == "Title" then if config.gamesettings.display_gamemode == 1 or scene.title == "Title" then
@@ -83,9 +90,9 @@ function love.draw()
"fps - " .. version, 0, 460, 635, "right" "fps - " .. version, 0, 460, 635, "right"
) )
end end
love.graphics.pop() love.graphics.pop()
love.graphics.setCanvas() love.graphics.setCanvas()
love.graphics.setColor(1,1,1,1) love.graphics.setColor(1,1,1,1)
love.graphics.draw(GLOBAL_CANVAS) love.graphics.draw(GLOBAL_CANVAS)
@@ -120,7 +127,7 @@ function love.keypressed(key, scancode)
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
return return
-- escape is reserved for menu_back -- escape is reserved for menu_back
elseif scancode == "escape" then elseif scancode == "escape" then
scene:onInputPress({input="menu_back", type="key", key=key, scancode=scancode}) scene:onInputPress({input="menu_back", type="key", key=key, scancode=scancode})
@@ -140,7 +147,7 @@ function love.keyreleased(key, scancode)
scene:onInputRelease({input="menu_back", type="key", key=key, scancode=scancode}) scene:onInputRelease({input="menu_back", type="key", key=key, scancode=scancode})
-- 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
return return
-- handle all other keys; tab is reserved, but the input config scene keeps it from getting configured as a game input, so pass tab to the scene here -- handle all other keys; tab is reserved, but the input config scene keeps it from getting configured as a game input, so pass tab to the scene here
else else
local input_released = nil local input_released = nil
@@ -186,7 +193,7 @@ function love.joystickaxis(joystick, axis, value)
config.input.joysticks and config.input.joysticks and
config.input.joysticks[joystick:getName()] and config.input.joysticks[joystick:getName()] and
config.input.joysticks[joystick:getName()].axes and config.input.joysticks[joystick:getName()].axes and
config.input.joysticks[joystick:getName()].axes[axis] config.input.joysticks[joystick:getName()].axes[axis]
then then
if math.abs(value) >= 1 then if math.abs(value) >= 1 then
input_pressed = config.input.joysticks[joystick:getName()].axes[axis][value >= 1 and "positive" or "negative"] input_pressed = config.input.joysticks[joystick:getName()].axes[axis][value >= 1 and "positive" or "negative"]
@@ -314,10 +321,10 @@ function love.run()
if love.timer then if love.timer then
processBGMFadeout(love.timer.step()) processBGMFadeout(love.timer.step())
end end
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 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -10,7 +10,9 @@ function Scene:onInputRelease() end
ExitScene = require "scene.exit" ExitScene = require "scene.exit"
GameScene = require "scene.game" GameScene = require "scene.game"
ChallengeScene = require "scene.challenge"
ModeSelectScene = require "scene.mode_select" ModeSelectScene = require "scene.mode_select"
ChallengeSelectScene = require "scene.challenge_select"
KeyConfigScene = require "scene.key_config" KeyConfigScene = require "scene.key_config"
StickConfigScene = require "scene.stick_config" StickConfigScene = require "scene.stick_config"
InputConfigScene = require "scene.input_config" InputConfigScene = require "scene.input_config"

93
scene/challenge.lua Normal file
View File

@@ -0,0 +1,93 @@
local ChallengeScene = Scene:extend()
ChallengeScene.title = "Challenge"
require 'load.save'
function ChallengeScene:new(game_mode, ruleset, inputs)
self.retry_mode = game_mode
self.retry_ruleset = ruleset
self.secret_inputs = inputs
self.game = game_mode(self.secret_inputs)
self.ruleset = ruleset(self.game)
self.game:initialize(self.ruleset)
self.inputs = {
left=false,
right=false,
up=false,
down=false,
rotate_left=false,
rotate_left2=false,
rotate_right=false,
rotate_right2=false,
rotate_180=false,
hold=false,
}
self.paused = false
DiscordRPC:update({
details = "In challenge",
state = self.game.name,
largeImageKey = "ingame-"..self.game:getBackground().."00"
})
end
function ChallengeScene:update()
if love.window.hasFocus() and not self.paused then
local inputs = {}
for input, value in pairs(self.inputs) do
inputs[input] = value
end
self.game:update(inputs, self.ruleset)
self.game.grid:update()
DiscordRPC:update({
largeImageKey = "ingame-"..self.game:getBackground().."00"
})
end
end
function ChallengeScene:render()
self.game:draw(self.paused)
end
function ChallengeScene:onInputPress(e)
if (
self.game.game_over or self.game.completed
) and (
e.input == "menu_decide" or
e.input == "menu_back" or
e.input == "retry"
) then
highscore_entry = self.game:getHighscoreData()
highscore_hash = self.game.hash .. "-" .. self.ruleset.hash
submitHighscore(highscore_hash, highscore_entry)
self.game:onExit()
scene = e.input == "retry" and ChallengeScene(self.retry_mode, self.retry_ruleset, self.secret_inputs) or ModeSelectScene()
elseif e.input == "retry" then
switchBGM(nil)
self.game:onExit()
scene = ChallengeScene(self.retry_mode, self.retry_ruleset, self.secret_inputs)
elseif e.input == "pause" and not (self.game.game_over or self.game.completed) then
self.paused = not self.paused
if self.paused then pauseBGM()
else resumeBGM() end
elseif e.input == "menu_back" then
self.game:onExit()
scene = ChallengeSelectScene()
elseif e.input and string.sub(e.input, 1, 5) ~= "menu_" then
self.inputs[e.input] = true
end
end
function ChallengeScene:onInputRelease(e)
if e.input and string.sub(e.input, 1, 5) ~= "menu_" then
self.inputs[e.input] = false
end
end
function submitHighscore(hash, data)
if not highscores[hash] then highscores[hash] = {} end
table.insert(highscores[hash], data)
saveHighscores()
end
return ChallengeScene

186
scene/challenge_select.lua Normal file
View File

@@ -0,0 +1,186 @@
local ChallengeSelectScene = Scene:extend()
ChallengeSelectScene.title = "Challenges"
current_challenge = 1
function indexOf(array, value)
for i, v in ipairs(array) do
if v == value then
return i
end
end
return nil
end
function ChallengeSelectScene:new()
-- reload custom modules
initModules()
if table.getn(challenges) == 0 then
self.display_warning = true
current_challenge = 1
else
self.display_warning = false
if current_challenge > table.getn(challenges) then
current_challenge = 1
end
end
self.menu_state = {
challenge = current_challenge,
select = "challenge",
}
self.secret_inputs = {}
self.das = 0
DiscordRPC:update({
details = "In menus",
state = "Choosing a challenge",
largeImageKey = "ingame-000"
})
end
function ChallengeSelectScene:update()
switchBGM(nil) -- experimental
if self.das_up or self.das_down then
self.das = self.das + 1
else
self.das = 0
end
if self.das >= 15 then
self:changeOption(self.das_up and -1 or 1)
self.das = self.das - 4
end
DiscordRPC:update({
details = "In menus",
state = "Choosing a challenge",
largeImageKey = "ingame-000"
})
end
function ChallengeSelectScene:render()
love.graphics.draw(
backgrounds[0],
0, 0, 0,
0.5, 0.5
)
love.graphics.draw(misc_graphics["select_challenge"], 20, 40)
if self.display_warning then
love.graphics.setFont(font_3x5_3)
love.graphics.printf(
"You have no challenges",
80, 200, 480, "center"
)
love.graphics.setFont(font_3x5_2)
love.graphics.printf(
"Come back to this menu after getting more challenges. " ..
"Press any button to return to the main menu.",
80, 250, 480, "center"
)
return
end
if self.menu_state.select == "challenge" then
love.graphics.setColor(1, 1, 1, 0.5)
end
love.graphics.rectangle("fill", 20, 258, 240, 22)
if self.menu_state.select == "challenge" then
love.graphics.setColor(1, 1, 1, 0.25)
end
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setFont(font_3x5_2)
for idx, challenge in pairs(challenges) do
if(idx >= self.menu_state.challenge-9 and idx <= self.menu_state.challenge+9) then
love.graphics.printf(challenge.name, 40, (260 - 20*(self.menu_state.challenge)) + 20 * idx, 200, "left")
end
end
-- challenge details
love.graphics.printf(challenges[self.menu_state.challenge].tagline, 340, 150, 200, "left")
love.graphics.printf(challenges[self.menu_state.challenge].description, 340, 250, 200, "left")
love.graphics.printf("Mode: "..challenges[self.menu_state.challenge].mode, 340, 350, 200, "left")
love.graphics.printf("Ruleset: "..challenges[self.menu_state.challenge].ruleset, 340, 380, 200, "left")
end
function ChallengeSelectScene:onInputPress(e)
if self.display_warning and e.input then
scene = TitleScene()
elseif e.type == "wheel" then
if e.x % 2 == 1 then
self:switchSelect()
end
if e.y ~= 0 then
self:changeOption(-e.y)
end
elseif e.input == "menu_decide" or e.scancode == "return" then
for idx, mode in pairs(game_modes) do
if mode.hash == challenges[self.menu_state.challenge].mode then
cur_mode = idx
break
end
end
for idx, ruleset in pairs(rulesets) do
if ruleset.hash == challenges[self.menu_state.challenge].ruleset then
cur_ruleset = idx
break
end
end
playSE("mode_decide")
saveConfig()
scene = ChallengeScene(
challenges[current_challenge],
rulesets[cur_ruleset]
)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
self.das_up = true
self.das_down = nil
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
self.das_down = true
self.das_up = nil
elseif e.input == "menu_back" or e.scancode == "delete" or e.scancode == "backspace" then
scene = TitleScene()
elseif e.input then
self.secret_inputs[e.input] = true
end
end
function ChallengeSelectScene:onInputRelease(e)
if e.input == "up" or e.scancode == "up" then
self.das_up = nil
elseif e.input == "down" or e.scancode == "down" then
self.das_down = nil
elseif e.input then
self.secret_inputs[e.input] = false
end
end
function ChallengeSelectScene:changeOption(rel)
self:changechallenge(rel)
playSE("cursor")
end
function ChallengeSelectScene:changechallenge(rel)
local len = table.getn(challenges)
self.menu_state.challenge = Mod1(self.menu_state.challenge + rel, len)
end
return ChallengeSelectScene

View File

@@ -1,6 +1,6 @@
local ModeSelectScene = Scene:extend() local ModeSelectScene = Scene:extend()
ModeSelectScene.title = "Game Start" ModeSelectScene.title = "Freeplay"
current_mode = 1 current_mode = 1
current_ruleset = 1 current_ruleset = 1
@@ -108,6 +108,7 @@ function ModeSelectScene:render()
love.graphics.printf(ruleset.name, 360, (260 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left") love.graphics.printf(ruleset.name, 360, (260 - 20*(self.menu_state.ruleset)) + 20 * idx, 160, "left")
end end
end end
love.graphics.printf(game_modes[self.menu_state.mode].tagline, 5, 5, 600, "left")
end end
function ModeSelectScene:onInputPress(e) function ModeSelectScene:onInputPress(e)

View File

@@ -5,6 +5,7 @@ TitleScene.restart_message = false
local main_menu_screens = { local main_menu_screens = {
ModeSelectScene, ModeSelectScene,
ChallengeSelectScene,
SettingsScene, SettingsScene,
CreditsScene, CreditsScene,
ExitScene, ExitScene,
@@ -34,6 +35,21 @@ local mainmenuidle = {
"This is probably the longest RPC string out of every possible RPC string that can be displayed." "This is probably the longest RPC string out of every possible RPC string that can be displayed."
} }
local menusplash = {
"Welcome to Cambridge!",
"Get ready to put the block!",
"Also try Master of Blocks!",
"Also try Shiromino!",
"1 year in the making!",
"haileyjunk!",
"WOOOOAAAAAHHH!!!!!"
}
local currentSplash = menusplash[math.random(#menusplash)]
local now = os.date("t")
showDebugKeys = false
function TitleScene:new() function TitleScene:new()
self.main_menu_state = 1 self.main_menu_state = 1
self.frames = 0 self.frames = 0
@@ -47,6 +63,12 @@ function TitleScene:new()
largeImageKey = "1year", largeImageKey = "1year",
largeImageText = version.." | Thanks for 1 year!" largeImageText = version.." | Thanks for 1 year!"
}) })
if now.month == 12 then
DiscordRPC:update({
largeImageKey = "snow"
})
end
end end
function TitleScene:update() function TitleScene:update()
@@ -79,7 +101,7 @@ function TitleScene:render()
460, 170, 0, 460, 170, 0,
2, 2 2, 2
) )
love.graphics.printf("Thanks for 1 year!", 430, 280, 160, "center") love.graphics.printf(currentSplash, 390, 280, 320, "center", 0, 0.75, 0.75)
love.graphics.setFont(font_3x5_2) love.graphics.setFont(font_3x5_2)
love.graphics.setColor(1, 1, 1, self.snow_bg_opacity) love.graphics.setColor(1, 1, 1, self.snow_bg_opacity)
@@ -106,6 +128,11 @@ function TitleScene:render()
for i, screen in pairs(main_menu_screens) do for i, screen in pairs(main_menu_screens) do
love.graphics.printf(screen.title, 40, 280 + 20 * i, 120, "left") love.graphics.printf(screen.title, 40, 280 + 20 * i, 120, "left")
end end
if showDebugKeys then
love.graphics.print("DEBUG KEYS\n\nF3+S: Get new splash message\nF3+R: Restart\nF3+I: Toggle this")
end
end end
function TitleScene:changeOption(rel) function TitleScene:changeOption(rel)
@@ -113,7 +140,10 @@ function TitleScene:changeOption(rel)
self.main_menu_state = (self.main_menu_state + len + rel - 1) % len + 1 self.main_menu_state = (self.main_menu_state + len + rel - 1) % len + 1
end end
function TitleScene:onInputPress(e) function TitleScene:onInputPress(e)
local debugkey = love.keyboard.isDown("f3")
if e.input == "menu_decide" or e.scancode == "return" then if e.input == "menu_decide" or e.scancode == "return" then
playSE("main_decide") playSE("main_decide")
scene = main_menu_screens[self.main_menu_state]() scene = main_menu_screens[self.main_menu_state]()
@@ -125,6 +155,25 @@ function TitleScene:onInputPress(e)
playSE("cursor") playSE("cursor")
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
love.event.quit() love.event.quit()
-- small debug feature, press f3+s to get a new splash message
elseif e.scancode == "s" then
if debugkey then
currentSplash = menusplash[math.random(#menusplash)]
playSE("main_decide")
end
elseif e.scancode == "r" then
if debugkey then
love.event.quit("restart")
end
elseif e.scancode == "i" then
if debugkey then
if showDebugKeys then
showDebugKeys = false
else
showDebugKeys = true
end
end
-- no winter easter egg for now -- no winter easter egg for now
--[[ --[[
else else

View File

@@ -0,0 +1,26 @@
require 'funcs'
local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece'
local Grid = require 'tetris.components.grid'
local Randomizer = require 'tetris.randomizers.randomizer'
local Bag7Randomizer = require 'tetris.randomizers.bag7noI'
local MarathonGF = require 'tetris.modes.marathon_gf'
local TetrsChallenge = MarathonGF:extend()
TetrsChallenge.name = "Tetrs"
TetrsChallenge.hash = "Tetrs"
TetrsChallenge.mode = "MarathonGF"
TetrsChallenge.ruleset = "Standard"
TetrsChallenge.tagline = "Where's the long bar? Seriously, I can't find it."
TetrsChallenge.description = "Complete a 150-line Marathon...without the I piece!"
function TetrsChallenge:new()
TetrsChallenge.super:new()
self.randomizer = Bag7Randomizer()
self.next_queue_length = 6
end
return TetrsChallenge

View File

@@ -0,0 +1,23 @@
-- currently you need to require and extend the gamemode you're making a challenge out of
require 'funcs'
local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece'
local Grid = require 'tetris.components.grid'
local Randomizer = require 'tetris.randomizers.randomizer'
local BagRandomizer = require 'tetris.randomizers.bag'
local MarathonGF = require 'tetris.modes.marathon_gf'
local Challenge = GameMode:extend()
Challenge.name = "A really cool challenge name"
Challenge.hash = ""
Challenge.mode = ""
Challenge.ruleset = ""
Challenge.tagline = "Are you up for this challenge?"
Challenge.description = "Complete a mode with a specific ruleset and idk they did some other stupid things too lol"
return Challenge

View File

@@ -0,0 +1,26 @@
require 'funcs'
local GameMode = require 'tetris.modes.gamemode'
local Piece = require 'tetris.components.piece'
local Grid = require 'tetris.components.grid'
local Randomizer = require 'tetris.randomizers.randomizer'
local Bag7Randomizer = require 'tetris.randomizers.bag7noI'
local MarathonGF = require 'tetris.modes.marathon_gf'
local TetrsChallenge = MarathonGF:extend()
TetrsChallenge.name = "Another mode"
TetrsChallenge.hash = "Tetrs2"
TetrsChallenge.mode = "MarathonGF"
TetrsChallenge.ruleset = "Standard"
TetrsChallenge.tagline = "Hey look! The feature works!"
TetrsChallenge.description = "This is just a clone of Tetrs to test out the challenge details feature."
function TetrsChallenge:new()
TetrsChallenge.super:new()
self.randomizer = Bag7Randomizer()
self.next_queue_length = 6
end
return TetrsChallenge

View File

@@ -143,7 +143,7 @@ function GameMode:update(inputs, ruleset)
) then ) then
self:onAttemptPieceRotate(self.piece, self.grid) self:onAttemptPieceRotate(self.piece, self.grid)
end end
if self.piece == nil then if self.piece == nil then
self:processDelays(inputs, ruleset) self:processDelays(inputs, ruleset)
else else
@@ -243,7 +243,7 @@ function GameMode:update(inputs, ruleset)
if self.immobile_spin_bonus and if self.immobile_spin_bonus and
self.piece.last_rotated 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
self.piece:isMoveBlocked(self.grid, { x=0, y=-1 }) self.piece:isMoveBlocked(self.grid, { x=0, y=-1 })
) then ) then
@@ -251,7 +251,7 @@ function GameMode:update(inputs, ruleset)
end end
self.grid:applyPiece(self.piece) self.grid:applyPiece(self.piece)
-- mark squares (can be overridden) -- mark squares (can be overridden)
if self.square_mode then if self.square_mode then
self.squares = self.squares + self.grid:markSquares() self.squares = self.squares + self.grid:markSquares()
@@ -312,7 +312,7 @@ function GameMode:onAttemptPieceRotate(piece, grid) end
function GameMode:onPieceMove(piece, grid, dx) end function GameMode:onPieceMove(piece, grid, dx) end
function GameMode:onPieceRotate(piece, grid, drot) end function GameMode:onPieceRotate(piece, grid, drot) end
function GameMode:onPieceDrop(piece, grid, dy) end function GameMode:onPieceDrop(piece, grid, dy) end
function GameMode:onPieceLock(piece, cleared_row_count) function GameMode:onPieceLock(piece, cleared_row_count)
playSE("lock") playSE("lock")
end end
@@ -530,8 +530,6 @@ function GameMode:onEnterOrHold(inputs, ruleset)
if not self.grid:canPlacePiece(self.piece) then if not self.grid:canPlacePiece(self.piece) then
self.game_over = true self.game_over = true
return return
elseif self.piece:isDropBlocked(self.grid) then
playSE("bottom")
end end
ruleset:dropPiece( ruleset:dropPiece(
inputs, self.piece, self.grid, self:getGravity(), inputs, self.piece, self.grid, self:getGravity(),
@@ -580,6 +578,10 @@ function GameMode:initializeNextPiece(
self.piece_soft_locked = false self.piece_soft_locked = false
self.buffer_hard_drop = false self.buffer_hard_drop = false
self.buffer_soft_drop = false self.buffer_soft_drop = false
if self.piece:isDropBlocked(self.grid) and
self.grid:canPlacePiece(self.piece) then
playSE("bottom")
end
if generate_next_piece == nil then if generate_next_piece == nil then
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))
@@ -614,7 +616,7 @@ function GameMode:drawLineClearAnimation()
-- animation function -- animation function
-- params: block x, y, skin, colour -- params: block x, y, skin, colour
-- returns: table with RGBA, skin, colour, x, y -- returns: table with RGBA, skin, colour, x, y
-- Fadeout (default) -- Fadeout (default)
--[[ --[[
function animation(x, y, skin, colour) function animation(x, y, skin, colour)
@@ -726,8 +728,8 @@ function GameMode:drawNextQueue(ruleset)
if self.hold_queue ~= nil and self.enable_hold then if self.hold_queue ~= nil and self.enable_hold then
self:setHoldOpacity() self:setHoldOpacity()
drawPiece( drawPiece(
self.hold_queue.shape, self.hold_queue.shape,
self.hold_queue.skin, self.hold_queue.skin,
ruleset.block_offsets[self.hold_queue.shape][self.hold_queue.orientation], ruleset.block_offsets[self.hold_queue.shape][self.hold_queue.orientation],
-16, -32 -16, -32
) )
@@ -826,7 +828,7 @@ end
function GameMode:drawSectionTimesWithSplits(current_section, section_limit) function GameMode:drawSectionTimesWithSplits(current_section, section_limit)
section_limit = section_limit or math.huge section_limit = section_limit or math.huge
local section_x = 440 local section_x = 440
local split_x = 530 local split_x = 530
@@ -841,7 +843,7 @@ function GameMode:drawSectionTimesWithSplits(current_section, section_limit)
love.graphics.printf(formatTime(split_time), split_x, 40 + 20 * section, 90, "left") love.graphics.printf(formatTime(split_time), split_x, 40 + 20 * section, 90, "left")
end end
end end
if (current_section <= section_limit) then if (current_section <= section_limit) then
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")
love.graphics.printf(formatTime(self.frames), split_x, 40 + 20 * current_section, 90, "left") love.graphics.printf(formatTime(self.frames), split_x, 40 + 20 * current_section, 90, "left")

View File

@@ -0,0 +1,19 @@
-- for the pre-packaged/example challenge tetrs
local Randomizer = require 'tetris.randomizers.randomizer'
local Bag7NoIRandomizer = Randomizer:extend()
function Bag7NoIRandomizer:initialize()
self.bag = {"J", "L", "O", "S", "T", "Z"}
end
function Bag7NoIRandomizer:generatePiece()
if next(self.bag) == nil then
self.bag = {"J", "L", "O", "S", "T", "Z"}
end
local x = math.random(table.getn(self.bag))
return table.remove(self.bag, x)
end
return Bag7NoIRandomizer