mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36837a3af5 | ||
|
|
01b0f9f618 | ||
|
|
7c8c5bb11d | ||
|
|
acaa6bdbbf | ||
|
|
c37757f592 | ||
|
|
905e4bcc77 | ||
|
|
d956647678 | ||
|
|
10f032b49b | ||
|
|
5590e6c89b | ||
|
|
0393396d74 | ||
|
|
8c1eaec1aa | ||
|
|
957802a78e | ||
|
|
169a4e4d2f | ||
|
|
48aee18340 | ||
|
|
7b496d9412 | ||
|
|
7abb861446 | ||
|
|
21f8769228 | ||
|
|
44423fd2e8 | ||
|
|
351fb4cfe9 | ||
|
|
103f04ceaa | ||
|
|
88d2f0d8d1 | ||
|
|
e100289c82 | ||
|
|
e38da49180 | ||
|
|
b03473d2fe | ||
|
|
cf6e0be4e7 | ||
|
|
2bc9dc179c | ||
|
|
d626926d5a | ||
|
|
721acefea0 | ||
|
|
b9b71e90bb | ||
|
|
9f61b139fd |
@@ -29,6 +29,7 @@ The following people in no particular order also helped with the project:
|
||||
- [2Tie](https://github.com/2Tie)
|
||||
- [nightmareci](https://github.com/nightmareci)
|
||||
- [MyPasswordIsWeak](https://github.com/MyPasswordIsWeak)
|
||||
- [Dr Ocelot](https://github.com/Dr-Ocelot)
|
||||
|
||||

|
||||
|
||||
|
||||
1
main.lua
1
main.lua
@@ -12,6 +12,7 @@ function love.load()
|
||||
config["side_next"] = false
|
||||
config["reverse_rotate"] = true
|
||||
config["fullscreen"] = false
|
||||
config["das_last_key"] = false
|
||||
|
||||
love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ ConfigScene.options = {
|
||||
{"manlock", "Manual locking",{"Per ruleset","Per gamemode","Harddrop", "Softdrop"}},
|
||||
{"piece_colour", "Piece Colours", {"Per ruleset","Arika" ,"TTC"}},
|
||||
{"world_reverse","A Button Rotation", {"Left" ,"Auto" ,"Right"}},
|
||||
{"das_last_key", "DAS Switch", {"Default", "Instant"}}
|
||||
}
|
||||
local optioncount = #ConfigScene.options
|
||||
|
||||
@@ -24,6 +25,7 @@ function ConfigScene:new()
|
||||
end
|
||||
|
||||
function ConfigScene:update()
|
||||
config["das_last_key"] = config.gamesettings.das_last_key == 2
|
||||
end
|
||||
|
||||
function ConfigScene:render()
|
||||
|
||||
@@ -32,6 +32,7 @@ function ConfigScene:new()
|
||||
self.input_state = 1
|
||||
self.set_inputs = newSetInputs()
|
||||
self.new_input = {}
|
||||
self.axis_timer = 0
|
||||
|
||||
DiscordRPC:update({
|
||||
details = "In menus",
|
||||
@@ -63,6 +64,8 @@ function ConfigScene:render()
|
||||
love.graphics.print("press key or joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0)
|
||||
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
||||
end
|
||||
|
||||
self.axis_timer = self.axis_timer + 1
|
||||
end
|
||||
|
||||
local function addJoystick(input, name)
|
||||
@@ -118,7 +121,7 @@ function ConfigScene:onInputPress(e)
|
||||
self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state]
|
||||
self.input_state = self.input_state + 1
|
||||
elseif e.type == "joyaxis" then
|
||||
if math.abs(e.value) >= 0.5 then
|
||||
if (e.axis ~= self.last_axis or self.axis_timer > 30) and math.abs(e.value) >= 1 then
|
||||
addJoystick(self.new_input, e.name)
|
||||
if not self.new_input.joysticks[e.name].axes then
|
||||
self.new_input.joysticks[e.name].axes = {}
|
||||
@@ -128,10 +131,12 @@ function ConfigScene:onInputPress(e)
|
||||
end
|
||||
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||
"jaxis " ..
|
||||
(e.value >= 0.5 and "+" or "-") .. e.axis ..
|
||||
(e.value >= 1 and "+" or "-") .. e.axis ..
|
||||
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
||||
self.new_input.joysticks[e.name].axes[e.axis][e.value >= 0.5 and "positive" or "negative"] = configurable_inputs[self.input_state]
|
||||
self.new_input.joysticks[e.name].axes[e.axis][e.value >= 1 and "positive" or "negative"] = configurable_inputs[self.input_state]
|
||||
self.input_state = self.input_state + 1
|
||||
self.last_axis = e.axis
|
||||
self.axis_timer = 0
|
||||
end
|
||||
elseif e.type == "joyhat" then
|
||||
if e.direction ~= "c" then
|
||||
|
||||
@@ -230,6 +230,15 @@ function Grid:checkForBravo(cleared_row_count)
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:checkStackHeight()
|
||||
for i = 0, 23 do
|
||||
for j = 0, 9 do
|
||||
if self:isOccupied(j, i) then return 24 - i end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function Grid:checkSecretGrade()
|
||||
local sgrade = 0
|
||||
for i=23,5,-1 do
|
||||
@@ -310,7 +319,32 @@ function Grid:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:drawInvisible(opacity_function, garbage_opacity_function)
|
||||
function Grid:drawOutline()
|
||||
for y = 5, 24 do
|
||||
for x = 1, 10 do
|
||||
if self.grid[y][x] ~= empty then
|
||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||
love.graphics.setLineWidth(1)
|
||||
if y > 1 and self.grid[y-1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||
end
|
||||
if y < 24 and self.grid[y+1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||
end
|
||||
if x > 1 and self.grid[y][x-1] == empty then
|
||||
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
|
||||
end
|
||||
if x < 10 and self.grid[y][x+1] == empty then
|
||||
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_flash, brightness)
|
||||
lock_flash = lock_flash == nil and true or lock_flash
|
||||
brightness = brightness == nil and 0.5 or brightness
|
||||
for y = 5, 24 do
|
||||
for x = 1, 10 do
|
||||
if self.grid[y][x] ~= empty then
|
||||
@@ -321,22 +355,24 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function)
|
||||
else
|
||||
opacity = opacity_function(self.grid_age[y][x])
|
||||
end
|
||||
love.graphics.setColor(0.5, 0.5, 0.5, opacity)
|
||||
love.graphics.setColor(brightness, brightness, brightness, opacity)
|
||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
||||
love.graphics.setColor(0.64, 0.64, 0.64)
|
||||
love.graphics.setLineWidth(1)
|
||||
if y > 1 and self.grid[y-1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||
end
|
||||
if y < 24 and self.grid[y+1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||
end
|
||||
if x > 1 and self.grid[y][x-1] == empty then
|
||||
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
|
||||
end
|
||||
if x < 10 and self.grid[y][x+1] == empty then
|
||||
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
|
||||
if lock_flash then
|
||||
if opacity > 0 and self.grid[y][x].colour ~= "X" then
|
||||
love.graphics.setColor(0.64, 0.64, 0.64)
|
||||
love.graphics.setLineWidth(1)
|
||||
if y > 1 and self.grid[y-1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, -0.5+y*16, 64.0+x*16, -0.5+y*16)
|
||||
end
|
||||
if y < 24 and self.grid[y+1][x] == empty then
|
||||
love.graphics.line(48.0+x*16, 16.5+y*16, 64.0+x*16, 16.5+y*16)
|
||||
end
|
||||
if x > 1 and self.grid[y][x-1] == empty then
|
||||
love.graphics.line(47.5+x*16, -0.0+y*16, 47.5+x*16, 16.0+y*16)
|
||||
end
|
||||
if x < 10 and self.grid[y][x+1] == empty then
|
||||
love.graphics.line(64.5+x*16, -0.0+y*16, 64.5+x*16, 16.0+y*16)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -78,12 +78,15 @@ function Piece:setRelativeRotation(rot)
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:moveInGrid(step, squares, grid)
|
||||
function Piece:moveInGrid(step, squares, grid, instant)
|
||||
local moved = false
|
||||
for x = 1, squares do
|
||||
if grid:canPlacePiece(self:withOffset(step)) then
|
||||
moved = true
|
||||
self:setOffset(step)
|
||||
if instant then
|
||||
self:dropToBottom(grid)
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
@@ -250,7 +250,7 @@ end
|
||||
|
||||
function MarathonA2Game:drawGrid(ruleset)
|
||||
if self.clear and not (self.completed or self.game_over) then
|
||||
self.grid:drawInvisible(self.rollOpacityFunction)
|
||||
self.grid:drawInvisible(self.rollOpacityFunction, nil, false)
|
||||
else
|
||||
self.grid:draw()
|
||||
if self.piece ~= nil and self.level < 100 then
|
||||
|
||||
@@ -43,6 +43,8 @@ function GameMode:new()
|
||||
self.draw_section_times = false
|
||||
self.draw_secondary_section_times = false
|
||||
self.big_mode = false
|
||||
self.irs = true
|
||||
self.ihs = true
|
||||
self.rpc_details = "In game"
|
||||
-- variables related to configurable parameters
|
||||
self.drop_locked = false
|
||||
@@ -94,10 +96,20 @@ function GameMode:update(inputs, ruleset)
|
||||
if self.completed then return end
|
||||
|
||||
-- advance one frame
|
||||
if self:advanceOneFrame(inputs) == false then return end
|
||||
if self:advanceOneFrame(inputs, ruleset) == false then return end
|
||||
|
||||
self:chargeDAS(inputs, self:getDasLimit(), self.getARR())
|
||||
|
||||
-- set attempt flags
|
||||
if inputs["left"] or inputs["right"] then self:onAttemptPieceMove(self.piece) end
|
||||
if
|
||||
inputs["rotate_left"] or inputs["rotate_right"] or
|
||||
inputs["rotate_left2"] or inputs["rotate_right2"] or
|
||||
inputs["rotate_180"]
|
||||
then
|
||||
self:onAttemptPieceRotate(self.piece)
|
||||
end
|
||||
|
||||
if self.piece == nil then
|
||||
self:processDelays(inputs, ruleset)
|
||||
else
|
||||
@@ -105,7 +117,7 @@ function GameMode:update(inputs, ruleset)
|
||||
self:whilePieceActive()
|
||||
local gravity = self:getGravity()
|
||||
|
||||
if self.enable_hold and inputs["hold"] == true and self.held == false then
|
||||
if self.enable_hold and inputs["hold"] == true and self.held == false and self.prev_inputs["hold"] == false then
|
||||
self:hold(inputs, ruleset)
|
||||
self.prev_inputs = inputs
|
||||
return
|
||||
@@ -198,6 +210,8 @@ end
|
||||
|
||||
-- event functions
|
||||
function GameMode:whilePieceActive() end
|
||||
function GameMode:onAttemptPieceMove(piece) end
|
||||
function GameMode:onAttemptPieceRotate(piece) end
|
||||
function GameMode:onPieceLock(piece, cleared_row_count)
|
||||
playSE("lock")
|
||||
end
|
||||
@@ -221,30 +235,66 @@ function GameMode:onGameOver()
|
||||
switchBGM(nil)
|
||||
end
|
||||
|
||||
function GameMode:chargeDAS(inputs)
|
||||
if inputs[self.das.direction] == true then
|
||||
local das_frames = self.das.frames + 1
|
||||
if das_frames >= self:getDasLimit() then
|
||||
if self.das.direction == "left" then
|
||||
self.move = (self:getARR() == 0 and "speed" or "") .. "left"
|
||||
self.das.frames = self:getDasLimit() - self:getARR()
|
||||
elseif self.das.direction == "right" then
|
||||
self.move = (self:getARR() == 0 and "speed" or "") .. "right"
|
||||
self.das.frames = self:getDasLimit() - self:getARR()
|
||||
end
|
||||
else
|
||||
self.move = "none"
|
||||
self.das.frames = das_frames
|
||||
-- DAS functions
|
||||
|
||||
function GameMode:startRightDAS()
|
||||
self.move = "right"
|
||||
self.das = { direction = "right", frames = 0 }
|
||||
if self:getDasLimit() == 0 then
|
||||
self:continueDAS()
|
||||
end
|
||||
end
|
||||
|
||||
function GameMode:startLeftDAS()
|
||||
self.move = "left"
|
||||
self.das = { direction = "left", frames = 0 }
|
||||
if self:getDasLimit() == 0 then
|
||||
self:continueDAS()
|
||||
end
|
||||
end
|
||||
|
||||
function GameMode:continueDAS()
|
||||
local das_frames = self.das.frames + 1
|
||||
if das_frames >= self:getDasLimit() then
|
||||
if self.das.direction == "left" then
|
||||
self.move = (self:getARR() == 0 and "speed" or "") .. "left"
|
||||
self.das.frames = self:getDasLimit() - self:getARR()
|
||||
elseif self.das.direction == "right" then
|
||||
self.move = (self:getARR() == 0 and "speed" or "") .. "right"
|
||||
self.das.frames = self:getDasLimit() - self:getARR()
|
||||
end
|
||||
elseif inputs["right"] == true then
|
||||
self.move = "right"
|
||||
self.das = { direction = "right", frames = 0 }
|
||||
elseif inputs["left"] == true then
|
||||
self.move = "left"
|
||||
self.das = { direction = "left", frames = 0 }
|
||||
else
|
||||
self.move = "none"
|
||||
self.das = { direction = "none", frames = -1 }
|
||||
self.das.frames = das_frames
|
||||
end
|
||||
end
|
||||
|
||||
function GameMode:stopDAS()
|
||||
self.move = "none"
|
||||
self.das = { direction = "none", frames = -1 }
|
||||
end
|
||||
|
||||
function GameMode:chargeDAS(inputs)
|
||||
if config["das_last_key"] then
|
||||
if inputs["right"] == true and self.das.direction ~= "right" and not self.prev_inputs["right"] then
|
||||
self:startRightDAS()
|
||||
elseif inputs["left"] == true and self.das.direction ~= "left" and not self.prev_inputs["left"] then
|
||||
self:startLeftDAS()
|
||||
elseif inputs[self.das.direction] == true then
|
||||
self:continueDAS()
|
||||
else
|
||||
self:stopDAS()
|
||||
end
|
||||
else -- default behaviour, das first key pressed
|
||||
if inputs[self.das.direction] == true then
|
||||
self:continueDAS()
|
||||
elseif inputs["right"] == true then
|
||||
self:startRightDAS()
|
||||
elseif inputs["left"] == true then
|
||||
self:startLeftDAS()
|
||||
else
|
||||
self:stopDAS()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -268,6 +318,18 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
||||
end
|
||||
elseif self.lcd > 0 then
|
||||
self.lcd = self.lcd - 1
|
||||
if ruleset.are_cancel and
|
||||
(self.move == "none" and not self.prev_inputs["up"] and
|
||||
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
|
||||
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
|
||||
not self.prev_inputs["rotate_180"]) and
|
||||
(inputs["left"] or inputs["right"] or inputs["up"] or
|
||||
inputs["rotate_left"] or inputs["rotate_left2"] or
|
||||
inputs["rotate_right"] or inputs["rotate_right2"] or
|
||||
inputs["rotate_180"]) then
|
||||
self.lcd = 0
|
||||
self.are = 0
|
||||
end
|
||||
if self.lcd == 0 then
|
||||
self.grid:clearClearedRows()
|
||||
playSE("fall")
|
||||
@@ -277,6 +339,17 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
||||
end
|
||||
elseif self.are > 0 then
|
||||
self.are = self.are - 1
|
||||
if ruleset.are_cancel and
|
||||
(self.move == "none" and not self.prev_inputs["up"] and
|
||||
not self.prev_inputs["rotate_left"] and not self.prev_inputs["rotate_left2"] and
|
||||
not self.prev_inputs["rotate_right"] and not self.prev_inputs["rotate_right2"] and
|
||||
not self.prev_inputs["rotate_180"]) and
|
||||
(inputs["left"] or inputs["right"] or inputs["up"] or
|
||||
inputs["rotate_left"] or inputs["rotate_left2"] or
|
||||
inputs["rotate_right"] or inputs["rotate_right2"] or
|
||||
inputs["rotate_180"]) then
|
||||
self.are = 0
|
||||
end
|
||||
if self.are == 0 then
|
||||
self:initializeOrHold(inputs, ruleset)
|
||||
end
|
||||
@@ -284,7 +357,7 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
||||
end
|
||||
|
||||
function GameMode:initializeOrHold(inputs, ruleset)
|
||||
if self.enable_hold and inputs["hold"] == true then
|
||||
if self.ihs and self.enable_hold and inputs["hold"] == true then
|
||||
self:hold(inputs, ruleset)
|
||||
else
|
||||
self:initializeNextPiece(inputs, ruleset, self.next_queue[1])
|
||||
@@ -324,7 +397,8 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
||||
inputs, piece_data, self.grid, gravity,
|
||||
self.prev_inputs, self.move,
|
||||
self:getLockDelay(), self:getDropSpeed(),
|
||||
self.lock_drop, self.lock_hard_drop, self.big_mode
|
||||
self.lock_drop, self.lock_hard_drop, self.big_mode,
|
||||
self.irs
|
||||
)
|
||||
if self.lock_drop then
|
||||
self.drop_locked = true
|
||||
@@ -388,7 +462,7 @@ function GameMode:drawNextQueue(ruleset)
|
||||
drawPiece(next_piece, skin, ruleset.block_offsets[next_piece][rotation], -16+i*80, -32)
|
||||
end
|
||||
end
|
||||
if self.hold_queue ~= nil then
|
||||
if self.hold_queue ~= nil and self.enable_hold then
|
||||
local hold_color = self.held and 0.6 or 1
|
||||
self:setHoldOpacity(1, hold_color)
|
||||
drawPiece(
|
||||
@@ -445,7 +519,7 @@ function GameMode:drawSectionTimes(current_section)
|
||||
love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left")
|
||||
end
|
||||
|
||||
function GameMode:drawSectionTimesWithSecondary(current_section)
|
||||
function GameMode:drawSectionTimesWithSecondary(current_section, section_colour_function)
|
||||
local section_x = 530
|
||||
local section_secondary_x = 440
|
||||
|
||||
@@ -456,6 +530,9 @@ function GameMode:drawSectionTimesWithSecondary(current_section)
|
||||
end
|
||||
|
||||
for section, time in pairs(self.secondary_section_times) do
|
||||
if self.section_colour_function then
|
||||
love.graphics.setColor(self:section_colour_function(section))
|
||||
end
|
||||
if section > 0 then
|
||||
love.graphics.printf(formatTime(time), section_secondary_x, 40 + 20 * section, 90, "left")
|
||||
end
|
||||
|
||||
@@ -144,6 +144,7 @@ function Marathon2020Game:advanceOneFrame()
|
||||
if self.roll_frames < 0 then
|
||||
return false
|
||||
elseif self.roll_frames > 4000 then
|
||||
if self.grade >= 30 and self.section_cool_count >= 20 then self.grade = 31 end
|
||||
self.completed = true
|
||||
end
|
||||
elseif self.ready_frames == 0 then
|
||||
@@ -248,6 +249,7 @@ function Marathon2020Game:updateGrade(cleared_lines)
|
||||
end
|
||||
|
||||
function Marathon2020Game:getTotalGrade()
|
||||
if self.grade + self.section_cool_count > 50 then return "GM" end
|
||||
return self.grade + self.section_cool_count
|
||||
end
|
||||
|
||||
@@ -325,10 +327,10 @@ function Marathon2020Game:checkClear(level)
|
||||
end
|
||||
|
||||
function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
||||
function sectionCool()
|
||||
function sectionCool(section)
|
||||
self.section_cool_count = self.section_cool_count + 1
|
||||
self.delay_level = math.min(20, self.delay_level + 1)
|
||||
table.insert(self.section_status, "cool")
|
||||
if section < 10 then table.insert(self.section_status, "cool") end
|
||||
self.cool_timer = 300
|
||||
end
|
||||
|
||||
@@ -346,7 +348,7 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
||||
table.insert(self.section_times, section_time)
|
||||
self.section_start_time = self.frames
|
||||
|
||||
if section > 4 then self.delay_level = math.min(20, self.delay_level + 1) end
|
||||
if section > 5 then self.delay_level = math.min(20, self.delay_level + 1) end
|
||||
self:checkTorikan(section)
|
||||
self:checkClear(new_level)
|
||||
|
||||
@@ -355,11 +357,11 @@ function Marathon2020Game:updateSectionTimes(old_level, new_level)
|
||||
self.secondary_section_times[section] < self.secondary_section_times[section - 1] + 120 and
|
||||
self.secondary_section_times[section] < cool_cutoffs[section]
|
||||
) then
|
||||
sectionCool()
|
||||
sectionCool(section)
|
||||
elseif self.section_status[section - 1] == "cool" then
|
||||
table.insert(self.section_status, "none")
|
||||
elseif section <= 19 and self.secondary_section_times[section] < cool_cutoffs[section] then
|
||||
sectionCool()
|
||||
sectionCool(section)
|
||||
else
|
||||
table.insert(self.section_status, "none")
|
||||
end
|
||||
@@ -392,7 +394,6 @@ Marathon2020Game.mRollOpacityFunction = function(age)
|
||||
end
|
||||
|
||||
function Marathon2020Game:qualifiesForMRoll()
|
||||
return false -- until I actually have grading working
|
||||
--[[
|
||||
|
||||
GM-roll requirements
|
||||
@@ -403,6 +404,8 @@ You qualify for the GM roll if you:
|
||||
- in less than 13:30.00 total.
|
||||
|
||||
]]--
|
||||
|
||||
return self.level >= 2020 and self:getTotalGrade() == 50 and self.frames <= frameTime(13,30)
|
||||
end
|
||||
|
||||
function Marathon2020Game:drawGrid()
|
||||
@@ -420,6 +423,14 @@ function Marathon2020Game:drawGrid()
|
||||
end
|
||||
end
|
||||
|
||||
function Marathon2020Game:sectionColourFunction(section)
|
||||
if self.section_status[section] == "cool" then
|
||||
return { 0, 1, 0, 1 }
|
||||
else
|
||||
return { 1, 1, 1, 1 }
|
||||
end
|
||||
end
|
||||
|
||||
function Marathon2020Game:drawScoringInfo()
|
||||
Marathon2020Game.super.drawScoringInfo(self)
|
||||
|
||||
@@ -431,7 +442,7 @@ function Marathon2020Game:drawScoringInfo()
|
||||
love.graphics.printf("GRADE PTS.", text_x, 200, 90, "left")
|
||||
love.graphics.printf("LEVEL", text_x, 320, 40, "left")
|
||||
|
||||
self:drawSectionTimesWithSecondary(current_section)
|
||||
self:drawSectionTimesWithSecondary(current_section, self.sectionColourFunction)
|
||||
|
||||
if (self.cool_timer > 0) then
|
||||
love.graphics.printf("COOL!!", 64, 400, 160, "center")
|
||||
|
||||
@@ -310,12 +310,12 @@ MarathonA2Game.mRollOpacityFunction = function(age)
|
||||
else return 1 - age / 4 end
|
||||
end
|
||||
|
||||
function MarathonA2Game:drawGrid(ruleset)
|
||||
function MarathonA2Game:drawGrid()
|
||||
if self.clear and not (self.completed or self.game_over) then
|
||||
if self:qualifiesForMRoll() then
|
||||
self.grid:drawInvisible(self.mRollOpacityFunction)
|
||||
self.grid:drawInvisible(self.mRollOpacityFunction, nil, false)
|
||||
else
|
||||
self.grid:drawInvisible(self.rollOpacityFunction)
|
||||
self.grid:drawInvisible(self.rollOpacityFunction, nil, false)
|
||||
end
|
||||
else
|
||||
self.grid:draw()
|
||||
|
||||
@@ -231,8 +231,8 @@ function MarathonA3Game:updateSectionTimes(old_level, new_level)
|
||||
end
|
||||
|
||||
function MarathonA3Game:updateScore(level, drop_bonus, cleared_lines)
|
||||
if not self.clear then
|
||||
self:updateGrade(cleared_lines)
|
||||
self:updateGrade(cleared_lines)
|
||||
if not self.clear then
|
||||
if cleared_lines > 0 then
|
||||
self.combo = self.combo + (cleared_lines - 1) * 2
|
||||
self.score = self.score + (
|
||||
|
||||
@@ -146,7 +146,7 @@ function MarathonAX4Game:drawScoringInfo()
|
||||
strTrueValues(self.prev_inputs)
|
||||
)
|
||||
love.graphics.printf("NEXT", 64, 40, 40, "left")
|
||||
love.graphics.printf("TIME LEFT", 240, 250, 80, "left")
|
||||
if self.lines < 150 then love.graphics.printf("TIME LEFT", 240, 250, 80, "left") end
|
||||
love.graphics.printf("LINES", 240, 320, 40, "left")
|
||||
|
||||
local current_section = math.floor(self.lines / 10) + 1
|
||||
@@ -161,7 +161,7 @@ function MarathonAX4Game:drawScoringInfo()
|
||||
if not self.game_over and not self.clear and time_left < frameTime(0,10) and time_left % 4 < 2 then
|
||||
love.graphics.setColor(1, 0.3, 0.3, 1)
|
||||
end
|
||||
love.graphics.printf(formatTime(time_left), 240, 270, 160, "left")
|
||||
if self.lines < 150 then love.graphics.printf(formatTime(time_left), 240, 270, 160, "left") end
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ end
|
||||
|
||||
function PhantomManiaGame:drawGrid()
|
||||
if not (self.game_over or self.clear) then
|
||||
self.grid:drawInvisible(self.rollOpacityFunction)
|
||||
self.grid:drawInvisible(self.rollOpacityFunction, nil, false)
|
||||
else
|
||||
self.grid:draw()
|
||||
end
|
||||
|
||||
@@ -255,7 +255,7 @@ PhantomMania2Game.garbageOpacityFunction = function(age)
|
||||
end
|
||||
|
||||
function PhantomMania2Game:drawGrid()
|
||||
if not (self.game_over or (self.clear and self.level < 1300)) then
|
||||
if not (self.game_over) then
|
||||
self.grid:drawInvisible(self.rollOpacityFunction, self.garbageOpacityFunction)
|
||||
else
|
||||
self.grid:draw()
|
||||
|
||||
22
tetris/modes/phantom_mania_n.lua
Normal file
22
tetris/modes/phantom_mania_n.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
local PhantomManiaGame = require 'tetris.modes.phantom_mania'
|
||||
|
||||
local PhantomManiaNGame = PhantomManiaGame:extend()
|
||||
|
||||
PhantomManiaNGame.name = "Phantom Mania N"
|
||||
PhantomManiaNGame.hash = "PhantomManiaN"
|
||||
PhantomManiaNGame.tagline = "The old mode from Nullpomino, for Ti-ARS and SRS support."
|
||||
|
||||
function PhantomManiaNGame:new()
|
||||
PhantomManiaNGame.super:new()
|
||||
|
||||
self.SGnames = {
|
||||
"M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9",
|
||||
"M10", "M11", "M12", "M13", "M14", "M15", "M16", "M17", "M18",
|
||||
"GM"
|
||||
}
|
||||
|
||||
self.next_queue_length = 3
|
||||
self.enable_hold = true
|
||||
end
|
||||
|
||||
return PhantomManiaNGame
|
||||
@@ -161,6 +161,7 @@ function SurvivalA2Game:drawScoringInfo()
|
||||
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
|
||||
if self:getLetterGrade() ~= "" then love.graphics.printf(self:getLetterGrade(), text_x, 140, 90, "left") end
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.printf(self.level, text_x, 340, 40, "right")
|
||||
love.graphics.printf(self:getSectionEndLevel(), text_x, 370, 40, "right")
|
||||
if sg >= 5 then
|
||||
|
||||
@@ -112,9 +112,9 @@ end
|
||||
|
||||
function ARS:get180RotationValue()
|
||||
if config.gamesettings.world_reverse == 3 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -113,7 +113,8 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
if piece.shape == "I" then
|
||||
-- special kick rules for I
|
||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
||||
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})
|
||||
@@ -163,13 +164,16 @@ 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)
|
||||
piece.lock_delay = 0 -- move reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.manipulations = piece.manipulations + 1
|
||||
if piece.manipulations >= 127 then
|
||||
if piece.manipulations >= 128 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
@@ -179,17 +183,20 @@ function ARS:onPieceRotate(piece, grid)
|
||||
piece.lock_delay = 0 -- rotate reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.manipulations = piece.manipulations + 1
|
||||
if piece.manipulations >= 127 then
|
||||
if piece.manipulations >= 128 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
if piece.floorkick >= 1 then
|
||||
piece.floorkick = piece.floorkick + 1
|
||||
end
|
||||
end
|
||||
|
||||
function ARS:get180RotationValue()
|
||||
if config.gamesettings.world_reverse == 3 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
if piece.shape == "I" then
|
||||
-- special kick rules for I
|
||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
||||
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})
|
||||
@@ -150,13 +151,16 @@ 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)
|
||||
piece.lock_delay = 0 -- move reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.manipulations = piece.manipulations + 1
|
||||
if piece.manipulations >= 127 then
|
||||
if piece.manipulations >= 128 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
@@ -166,17 +170,20 @@ function ARS:onPieceRotate(piece, grid)
|
||||
piece.lock_delay = 0 -- rotate reset
|
||||
if piece:isDropBlocked(grid) then
|
||||
piece.manipulations = piece.manipulations + 1
|
||||
if piece.manipulations >= 127 then
|
||||
if piece.manipulations >= 128 then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
if piece.floorkick >= 1 then
|
||||
piece.floorkick = piece.floorkick + 1
|
||||
end
|
||||
end
|
||||
|
||||
function ARS:get180RotationValue()
|
||||
if config.gamesettings.world_reverse == 3 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ function ARS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
|
||||
if piece.shape == "I" then
|
||||
-- special kick rules for I
|
||||
if new_piece.rotation == 0 or new_piece.rotation == 2 then
|
||||
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})
|
||||
@@ -149,13 +150,22 @@ 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:onPieceRotate(piece, grid)
|
||||
if piece.floorkick >= 1 then
|
||||
piece.floorkick = piece.floorkick + 1
|
||||
end
|
||||
end
|
||||
|
||||
function ARS:get180RotationValue()
|
||||
if config.gamesettings.world_reverse == 3 then
|
||||
return 3
|
||||
else
|
||||
return 1
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Ruleset.softdrop_lock = true
|
||||
Ruleset.harddrop_lock = false
|
||||
|
||||
Ruleset.enable_IRS_wallkicks = false
|
||||
Ruleset.are_cancel = false
|
||||
|
||||
-- Component functions.
|
||||
|
||||
@@ -127,16 +128,16 @@ function Ruleset:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||
-- do nothing in default ruleset
|
||||
end
|
||||
|
||||
function Ruleset:movePiece(piece, grid, move)
|
||||
function Ruleset:movePiece(piece, grid, move, instant)
|
||||
local x = piece.position.x
|
||||
if move == "left" then
|
||||
piece:moveInGrid({x=-1, y=0}, 1, grid)
|
||||
elseif move == "speedleft" then
|
||||
piece:moveInGrid({x=-1, y=0}, 10, grid)
|
||||
piece:moveInGrid({x=-1, y=0}, 1, grid, false)
|
||||
elseif move == "right" then
|
||||
piece:moveInGrid({x=1, y=0}, 1, grid)
|
||||
piece:moveInGrid({x=1, y=0}, 1, grid, false)
|
||||
elseif move == "speedleft" then
|
||||
piece:moveInGrid({x=-1, y=0}, 10, grid, instant)
|
||||
elseif move == "speedright" then
|
||||
piece:moveInGrid({x=1, y=0}, 10, grid)
|
||||
piece:moveInGrid({x=1, y=0}, 10, grid, instant)
|
||||
end
|
||||
if piece.position.x ~= x then
|
||||
self:onPieceMove(piece, grid)
|
||||
@@ -180,7 +181,7 @@ function Ruleset:getDefaultOrientation() return 1 end
|
||||
function Ruleset:initializePiece(
|
||||
inputs, data, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked, big
|
||||
drop_locked, hard_drop_locked, big, irs
|
||||
)
|
||||
local spawn_positions
|
||||
if big then
|
||||
@@ -196,7 +197,7 @@ function Ruleset:initializePiece(
|
||||
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
|
||||
|
||||
self:onPieceCreate(piece)
|
||||
self:rotatePiece(inputs, piece, grid, {}, true)
|
||||
if irs then self:rotatePiece(inputs, piece, grid, {}, true) end
|
||||
self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked)
|
||||
return piece
|
||||
end
|
||||
@@ -211,7 +212,7 @@ function Ruleset:processPiece(
|
||||
hard_drop_enabled, additive_gravity
|
||||
)
|
||||
self:rotatePiece(inputs, piece, grid, prev_inputs, false)
|
||||
self:movePiece(piece, grid, move)
|
||||
self:movePiece(piece, grid, move, gravity >= 20)
|
||||
self:dropPiece(
|
||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity
|
||||
|
||||
Reference in New Issue
Block a user