mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
27 Commits
v0.3-beta2
...
v0.3-beta3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ac60cbb5e | ||
|
|
cdd846c3e6 | ||
|
|
33d260b753 | ||
|
|
1644fcdf8e | ||
|
|
f3c1cf6e1f | ||
|
|
06a8a2ebf7 | ||
|
|
15354ce004 | ||
|
|
af02cd3467 | ||
|
|
acb05918c1 | ||
|
|
b644c8e457 | ||
|
|
288961e12a | ||
|
|
a047e51681 | ||
|
|
77f24f5ee5 | ||
|
|
32c2274bef | ||
|
|
4920e5de1c | ||
|
|
8418fc8ab7 | ||
|
|
711a5120f1 | ||
|
|
e7c3c9446a | ||
|
|
3ac39acd7a | ||
|
|
d0505251b3 | ||
|
|
bb0fe2ac20 | ||
|
|
986ebac47f | ||
|
|
9799147f96 | ||
|
|
1dda12e4be | ||
|
|
38947e00c0 | ||
|
|
035f6dd7b4 | ||
|
|
aa3eadc93d |
20
README.md
20
README.md
@@ -1,11 +1,11 @@
|
|||||||

|

|
||||||
|
|
||||||
Cambridge
|
Cambridge
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Welcome to Cambridge, the next open-source falling-block game engine!
|
Welcome to Cambridge, the next open-source falling-block game engine!
|
||||||
|
|
||||||
This fork is written and maintained exclusively by [SashLilac](https://github.com/SashLilac), [joezeng](https://github.com/joezeng) and [Oshisaure](https://github.com/oshisaure)!
|
The project is written and maintained exclusively by [SashLilac](https://github.com/SashLilac), [joezeng](https://github.com/joezeng) and [Oshisaure](https://github.com/oshisaure)!
|
||||||
|
|
||||||
Join our Discord server for help and a welcoming community! https://discord.gg/mteMJw4
|
Join our Discord server for help and a welcoming community! https://discord.gg/mteMJw4
|
||||||
|
|
||||||
@@ -40,7 +40,13 @@ Playing the game
|
|||||||
|
|
||||||
You do not need LÖVE on Windows, as it comes bundled with the program.
|
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.
|
#### Stable release
|
||||||
|
|
||||||
|
To get the stable release, simply download either `cambridge-win32.zip` (32-bit) or `cambridge-windows.zip` (64-bit) in the [latest release](https://github.com/sashlilac/cambridge/releases/latest).
|
||||||
|
|
||||||
|
All assets needed are bundled with the executable.
|
||||||
|
|
||||||
|
#### Bleeding edge
|
||||||
|
|
||||||
If you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
If you want the bleeding edge version, download [this](https://github.com/SashLilac/cambridge/archive/master.zip).
|
||||||
|
|
||||||
@@ -82,13 +88,7 @@ It should run automatically!
|
|||||||
|
|
||||||
## Installing modpacks
|
## Installing modpacks
|
||||||
|
|
||||||
Simply drag your mode, ruleset, and randomizer Lua files into their respective [directory](https://love2d.org/wiki/love.filesystem), and they should appear automatically.
|
For instructions on how to install modpacks, go to [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
|
||||||
|
|
||||||
You can also load custom assets through this way, assuming you preserve the directory structure.
|
|
||||||
|
|
||||||
**WARNING:** The .exe / .love files and the bleeding edge releases have different save directories. Read the above link carefully!
|
|
||||||
|
|
||||||
For more detailed instructions, install [this](https://github.com/SashLilac/cambridge-modpack) mod pack to get a taste of the mod potential.
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -55,14 +55,8 @@ function bigint.new(num)
|
|||||||
__pow = function(lhs, rhs)
|
__pow = function(lhs, rhs)
|
||||||
return bigint.exponentiate(lhs, rhs)
|
return bigint.exponentiate(lhs, rhs)
|
||||||
end,
|
end,
|
||||||
__eq = function(lhs, rhs)
|
__tostring = function()
|
||||||
return bigint.compare(lhs, rhs, "==")
|
return bigint.unserialize(self, "s")
|
||||||
end,
|
|
||||||
__lt = function(lhs, rhs)
|
|
||||||
return bigint.compare(lhs, rhs, "<")
|
|
||||||
end,
|
|
||||||
__le = function(lhs, rhs)
|
|
||||||
return bigint.compare(lhs, rhs, "<=")
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -88,7 +82,8 @@ function bigint.check(big, force)
|
|||||||
assert(type(big.sign) == "string", "bigint is unsigned")
|
assert(type(big.sign) == "string", "bigint is unsigned")
|
||||||
for _, digit in pairs(big.digits) do
|
for _, digit in pairs(big.digits) do
|
||||||
assert(type(digit) == "number", digit .. " is not a number")
|
assert(type(digit) == "number", digit .. " is not a number")
|
||||||
assert(digit < 10, digit .. " is greater than or equal to 10")
|
assert(digit <= 9 and digit >= 0, digit .. " is not between 0 and 9")
|
||||||
|
assert(math.floor(digit) == digit, digit .. " is not an integer")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@@ -103,6 +98,12 @@ function bigint.abs(big)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return the number of digits in the big
|
||||||
|
function bigint.digits(big)
|
||||||
|
bigint.check(big)
|
||||||
|
return #big.digits
|
||||||
|
end
|
||||||
|
|
||||||
-- Convert a big to a number or string
|
-- Convert a big to a number or string
|
||||||
function bigint.unserialize(big, output_type, precision)
|
function bigint.unserialize(big, output_type, precision)
|
||||||
bigint.check(big)
|
bigint.check(big)
|
||||||
@@ -137,7 +138,7 @@ function bigint.unserialize(big, output_type, precision)
|
|||||||
-- Unserialization to human-readable form or scientific notation only
|
-- Unserialization to human-readable form or scientific notation only
|
||||||
-- requires reading the first few digits
|
-- requires reading the first few digits
|
||||||
if (precision == nil) then
|
if (precision == nil) then
|
||||||
precision = 3
|
precision = math.min(#big.digits, 3)
|
||||||
else
|
else
|
||||||
assert(precision > 0, "Precision cannot be less than 1")
|
assert(precision > 0, "Precision cannot be less than 1")
|
||||||
assert(math.floor(precision) == precision,
|
assert(math.floor(precision) == precision,
|
||||||
@@ -146,17 +147,18 @@ function bigint.unserialize(big, output_type, precision)
|
|||||||
|
|
||||||
-- num is the first (precision + 1) digits, the first being separated by
|
-- num is the first (precision + 1) digits, the first being separated by
|
||||||
-- a decimal point from the others
|
-- a decimal point from the others
|
||||||
num = num .. big.digits[1]
|
num = num .. math.floor(big.digits[1])
|
||||||
if (precision > 1) then
|
if (precision > 1) then
|
||||||
num = num .. "."
|
num = num .. "."
|
||||||
for i = 1, (precision - 1) do
|
for i = 1, (precision - 1) do
|
||||||
num = num .. big.digits[i + 1]
|
num = num .. math.floor(big.digits[i + 1])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ((output_type == "human-readable")
|
if ((output_type == "human-readable")
|
||||||
or (output_type == "human")
|
or (output_type == "human")
|
||||||
or (output_type == "h")) then
|
or (output_type == "h"))
|
||||||
|
and (#big.digits >= 3 and #big.digits <= 10002) then
|
||||||
-- Human-readable output contributed by 123eee555
|
-- Human-readable output contributed by 123eee555
|
||||||
|
|
||||||
local name
|
local name
|
||||||
@@ -435,7 +437,6 @@ function bigint.multiply(big1, big2)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Raise a big to a positive integer or big power (TODO: negative integer power)
|
-- Raise a big to a positive integer or big power (TODO: negative integer power)
|
||||||
function bigint.exponentiate(big, power)
|
function bigint.exponentiate(big, power)
|
||||||
-- Type checking for big done by bigint.multiply
|
-- Type checking for big done by bigint.multiply
|
||||||
@@ -446,13 +447,23 @@ function bigint.exponentiate(big, power)
|
|||||||
if (bigint.compare(exp, bigint.new(0), "==")) then
|
if (bigint.compare(exp, bigint.new(0), "==")) then
|
||||||
return bigint.new(1)
|
return bigint.new(1)
|
||||||
elseif (bigint.compare(exp, bigint.new(1), "==")) then
|
elseif (bigint.compare(exp, bigint.new(1), "==")) then
|
||||||
return big
|
return big:clone()
|
||||||
else
|
else
|
||||||
local result = big:clone()
|
local result = bigint.new(1)
|
||||||
|
local base = big:clone()
|
||||||
|
|
||||||
while (bigint.compare(exp, bigint.new(1), ">")) do
|
while (true) do
|
||||||
result = bigint.multiply(result, big)
|
if (bigint.compare(
|
||||||
exp = bigint.subtract(exp, bigint.new(1))
|
bigint.modulus(exp, bigint.new(2)), bigint.new(1), "=="
|
||||||
|
)) then
|
||||||
|
result = bigint.multiply(result, base)
|
||||||
|
end
|
||||||
|
if (bigint.compare(exp, bigint.new(1), "==")) then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
exp = bigint.divide(exp, bigint.new(2))
|
||||||
|
base = bigint.multiply(base, base)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -468,7 +479,7 @@ function bigint.divide_raw(big1, big2)
|
|||||||
if (bigint.compare(big1, big2, "==")) then
|
if (bigint.compare(big1, big2, "==")) then
|
||||||
return bigint.new(1), bigint.new(0)
|
return bigint.new(1), bigint.new(0)
|
||||||
elseif (bigint.compare(big1, big2, "<")) then
|
elseif (bigint.compare(big1, big2, "<")) then
|
||||||
return bigint.new(0), bigint.new(0)
|
return bigint.new(0), big1:clone()
|
||||||
else
|
else
|
||||||
assert(bigint.compare(big2, bigint.new(0), "!="), "error: divide by zero")
|
assert(bigint.compare(big2, bigint.new(0), "!="), "error: divide by zero")
|
||||||
assert(big1.sign == "+", "error: big1 is not positive")
|
assert(big1.sign == "+", "error: big1 is not positive")
|
||||||
@@ -476,54 +487,35 @@ function bigint.divide_raw(big1, big2)
|
|||||||
|
|
||||||
local result = bigint.new()
|
local result = bigint.new()
|
||||||
|
|
||||||
local dividend = bigint.new() -- Dividend of a single operation, not the
|
local dividend = bigint.new() -- Dividend of a single operation
|
||||||
-- dividend of the overall function
|
|
||||||
local divisor = big2:clone()
|
|
||||||
local factor = 1
|
|
||||||
|
|
||||||
-- Walk left to right among digits in the dividend, like in long
|
local neg_zero = bigint.new(0)
|
||||||
-- division
|
neg_zero.sign = "-"
|
||||||
for _, digit in pairs(big1.digits) do
|
|
||||||
dividend.digits[#dividend.digits + 1] = digit
|
|
||||||
|
|
||||||
-- The dividend is smaller than the divisor, so a zero is appended
|
for i = 1, #big1.digits do
|
||||||
-- to the result and the loop ends
|
-- Fixes a negative zero bug
|
||||||
if (bigint.compare(dividend, divisor, "<")) then
|
if (#dividend.digits ~= 0) and (bigint.compare(dividend, neg_zero, "==")) then
|
||||||
if (#result.digits > 0) then -- Don't add leading zeroes
|
dividend = bigint.new()
|
||||||
result.digits[#result.digits + 1] = 0
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Find the maximum number of divisors that fit into the
|
|
||||||
-- dividend
|
|
||||||
factor = 0
|
|
||||||
while (bigint.compare(divisor, dividend, "<=")) do
|
|
||||||
divisor = bigint.add(divisor, big2)
|
|
||||||
factor = factor + 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Append the factor to the result
|
table.insert(dividend.digits, big1.digits[i])
|
||||||
if (factor == 10) then
|
|
||||||
-- Fixes a weird bug that introduces a new bug if fixed by
|
local factor = bigint.new(0)
|
||||||
-- changing the comparison in the while loop to "<="
|
while bigint.compare(dividend, big2, ">=") do
|
||||||
result.digits[#result.digits] = 1
|
dividend = bigint.subtract(dividend, big2)
|
||||||
result.digits[#result.digits + 1] = 0
|
factor = bigint.add(factor, bigint.new(1))
|
||||||
else
|
|
||||||
result.digits[#result.digits + 1] = factor
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Subtract the divisor from the dividend to obtain the
|
for i = 0, #factor.digits - 1 do
|
||||||
-- remainder, which is the new dividend for the next loop
|
result.digits[#result.digits + 1 - i] = factor.digits[i + 1]
|
||||||
dividend = bigint.subtract(dividend,
|
end
|
||||||
bigint.subtract(divisor, big2))
|
|
||||||
|
|
||||||
-- Reset the divisor
|
|
||||||
divisor = big2:clone()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remove leading zeros from result
|
||||||
|
while (result.digits[1] == 0) do
|
||||||
|
table.remove(result.digits, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The remainder of the final loop is returned as the function's
|
|
||||||
-- overall remainder
|
|
||||||
return result, dividend
|
return result, dividend
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ function GameScene:render()
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.game:drawGrid()
|
self.game:drawGrid()
|
||||||
|
if self.game.lcd > 0 then self.game:drawLineClearAnimation() end
|
||||||
self.game:drawPiece()
|
self.game:drawPiece()
|
||||||
self.game:drawNextQueue(self.ruleset)
|
self.game:drawNextQueue(self.ruleset)
|
||||||
self.game:drawScoringInfo()
|
self.game:drawScoringInfo()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ ConfigScene.options = {
|
|||||||
{"manlock", "Manual Locking", false, {"Per ruleset", "Per gamemode", "Harddrop", "Softdrop"}},
|
{"manlock", "Manual Locking", false, {"Per ruleset", "Per gamemode", "Harddrop", "Softdrop"}},
|
||||||
{"piece_colour", "Piece Colours", false, {"Per ruleset", "Arika", "TTC"}},
|
{"piece_colour", "Piece Colours", false, {"Per ruleset", "Arika", "TTC"}},
|
||||||
{"world_reverse", "A Button Rotation", false, {"Left", "Auto", "Right"}},
|
{"world_reverse", "A Button Rotation", false, {"Left", "Auto", "Right"}},
|
||||||
{"spawn_positions", "Spawn Positions", false, {"In field", "Out of field"}},
|
{"spawn_positions", "Spawn Positions", false, {"Per ruleset", "In field", "Out of field"}},
|
||||||
{"display_gamemode", "Display Gamemode", false, {"On", "Off"}},
|
{"display_gamemode", "Display Gamemode", false, {"On", "Off"}},
|
||||||
{"das_last_key", "DAS Switch", false, {"Default", "Instant"}},
|
{"das_last_key", "DAS Switch", false, {"Default", "Instant"}},
|
||||||
{"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}},
|
{"smooth_movement", "Smooth Piece Drop", false, {"On", "Off"}},
|
||||||
@@ -103,7 +103,7 @@ function ConfigScene:onInputPress(e)
|
|||||||
else
|
else
|
||||||
playSE("cursor")
|
playSE("cursor")
|
||||||
sld = self[self.options[self.highlight][4]]
|
sld = self[self.options[self.highlight][4]]
|
||||||
sld.value = math.max(sld.min, math.min(sld.max, (sld:getValue() - 3) / (sld.max - sld.min)))
|
sld.value = math.max(sld.min, math.min(sld.max, (sld:getValue() - 5) / (sld.max - sld.min)))
|
||||||
end
|
end
|
||||||
elseif e.input == "right" or e.scancode == "right" then
|
elseif e.input == "right" or e.scancode == "right" then
|
||||||
if not self.options[self.highlight][3] then
|
if not self.options[self.highlight][3] then
|
||||||
@@ -113,7 +113,7 @@ function ConfigScene:onInputPress(e)
|
|||||||
else
|
else
|
||||||
playSE("cursor")
|
playSE("cursor")
|
||||||
sld = self[self.options[self.highlight][4]]
|
sld = self[self.options[self.highlight][4]]
|
||||||
sld.value = math.max(sld.min, math.min(sld.max, (sld:getValue() + 3) / (sld.max - sld.min)))--math.max(0, (math.floor(sld:getValue())+2)/(sld.max-sld.min))
|
sld.value = math.max(sld.min, math.min(sld.max, (sld:getValue() + 5) / (sld.max - sld.min)))--math.max(0, (math.floor(sld:getValue())+2)/(sld.max-sld.min))
|
||||||
end
|
end
|
||||||
elseif e.input == "menu_back" or e.scancode == "delete" or e.scancode == "backspace" then
|
elseif e.input == "menu_back" or e.scancode == "delete" or e.scancode == "backspace" then
|
||||||
loadSave()
|
loadSave()
|
||||||
|
|||||||
@@ -111,18 +111,24 @@ function Grid:getClearedRowCount()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Grid:markClearedRows()
|
function Grid:markClearedRows()
|
||||||
|
local block_table = {}
|
||||||
for row = 1, self.height do
|
for row = 1, self.height do
|
||||||
if self:isRowFull(row) then
|
if self:isRowFull(row) then
|
||||||
|
block_table[row] = {}
|
||||||
for x = 1, self.width do
|
for x = 1, self.width do
|
||||||
|
block_table[row][x] = {
|
||||||
|
skin = self.grid[row][x].skin,
|
||||||
|
colour = self.grid[row][x].colour,
|
||||||
|
}
|
||||||
self.grid[row][x] = {
|
self.grid[row][x] = {
|
||||||
skin = self.grid[row][x].skin,
|
skin = self.grid[row][x].skin,
|
||||||
colour = "X"
|
colour = "X"
|
||||||
}
|
}
|
||||||
self.grid_age[row][x] = 0
|
--self.grid_age[row][x] = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return block_table
|
||||||
end
|
end
|
||||||
|
|
||||||
function Grid:clearClearedRows()
|
function Grid:clearClearedRows()
|
||||||
@@ -388,7 +394,8 @@ end
|
|||||||
function Grid:draw()
|
function Grid:draw()
|
||||||
for y = 5, self.height do
|
for y = 5, self.height do
|
||||||
for x = 1, self.width do
|
for x = 1, self.width do
|
||||||
if self.grid[y][x] ~= empty then
|
if blocks[self.grid[y][x].skin] and
|
||||||
|
blocks[self.grid[y][x].skin][self.grid[y][x].colour] then
|
||||||
if self.grid_age[y][x] < 2 then
|
if self.grid_age[y][x] < 2 then
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.draw(blocks[self.grid[y][x].skin]["F"], 48+x*16, y*16)
|
love.graphics.draw(blocks[self.grid[y][x].skin]["F"], 48+x*16, y*16)
|
||||||
@@ -396,7 +403,8 @@ function Grid:draw()
|
|||||||
if self.grid[y][x].skin == "bone" then
|
if self.grid[y][x].skin == "bone" then
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
elseif self.grid[y][x].colour == "X" then
|
elseif self.grid[y][x].colour == "X" then
|
||||||
love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
love.graphics.setColor(0, 0, 0, 0)
|
||||||
|
--love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
||||||
else
|
else
|
||||||
love.graphics.setColor(0.5, 0.5, 0.5, 1)
|
love.graphics.setColor(0.5, 0.5, 0.5, 1)
|
||||||
end
|
end
|
||||||
@@ -427,10 +435,12 @@ end
|
|||||||
function Grid:drawOutline()
|
function Grid:drawOutline()
|
||||||
for y = 5, self.height do
|
for y = 5, self.height do
|
||||||
for x = 1, self.width do
|
for x = 1, self.width do
|
||||||
|
--[[
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
love.graphics.setColor(0.5, 0.5, 0.5, 1 - self.grid_age[y][x] / 15)
|
||||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||||
end
|
end
|
||||||
|
]]
|
||||||
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= "X" then
|
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= "X" then
|
||||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||||
love.graphics.setLineWidth(1)
|
love.graphics.setLineWidth(1)
|
||||||
@@ -459,7 +469,8 @@ function Grid:drawInvisible(opacity_function, garbage_opacity_function, lock_fla
|
|||||||
for x = 1, self.width do
|
for x = 1, self.width do
|
||||||
if self.grid[y][x] ~= empty then
|
if self.grid[y][x] ~= empty then
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
opacity = 1 - self.grid_age[y][x] / 15
|
opacity = 0
|
||||||
|
--opacity = 1 - self.grid_age[y][x] / 15
|
||||||
elseif garbage_opacity_function and self.grid[y][x].colour == "A" then
|
elseif garbage_opacity_function and self.grid[y][x].colour == "A" then
|
||||||
opacity = garbage_opacity_function(self.grid_age[y][x])
|
opacity = garbage_opacity_function(self.grid_age[y][x])
|
||||||
else
|
else
|
||||||
@@ -506,7 +517,8 @@ function Grid:drawCustom(colour_function, gamestate)
|
|||||||
if block ~= empty then
|
if block ~= empty then
|
||||||
local R, G, B, A, outline = colour_function(gamestate, block, x, y, self.grid_age[y][x])
|
local R, G, B, A, outline = colour_function(gamestate, block, x, y, self.grid_age[y][x])
|
||||||
if self.grid[y][x].colour == "X" then
|
if self.grid[y][x].colour == "X" then
|
||||||
A = 1 - self.grid_age[y][x] / 15
|
A = 0
|
||||||
|
--A = 1 - self.grid_age[y][x] / 15
|
||||||
end
|
end
|
||||||
love.graphics.setColor(R, G, B, A)
|
love.graphics.setColor(R, G, B, A)
|
||||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||||
|
|||||||
@@ -104,9 +104,8 @@ function Piece:dropToBottom(grid)
|
|||||||
self:dropSquares(math.huge, grid)
|
self:dropSquares(math.huge, grid)
|
||||||
self.gravity = 0
|
self.gravity = 0
|
||||||
if self.position.y > piece_y then
|
if self.position.y > piece_y then
|
||||||
-- if it got dropped any, also reset lock delay
|
|
||||||
if self.ghost == false then playSE("bottom") end
|
if self.ghost == false then playSE("bottom") end
|
||||||
self.lock_delay = 0
|
-- self.lock_delay = 0
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ function GameMode:new(secret_inputs)
|
|||||||
self.enable_hard_drop = true
|
self.enable_hard_drop = true
|
||||||
self.next_queue_length = 1
|
self.next_queue_length = 1
|
||||||
self.additive_gravity = true
|
self.additive_gravity = true
|
||||||
|
self.classic_lock = false
|
||||||
self.draw_section_times = false
|
self.draw_section_times = false
|
||||||
self.draw_secondary_section_times = false
|
self.draw_secondary_section_times = false
|
||||||
self.big_mode = false
|
self.big_mode = false
|
||||||
@@ -63,6 +64,7 @@ function GameMode:new(secret_inputs)
|
|||||||
self.hard_drop_locked = false
|
self.hard_drop_locked = false
|
||||||
self.lock_on_soft_drop = false
|
self.lock_on_soft_drop = false
|
||||||
self.lock_on_hard_drop = false
|
self.lock_on_hard_drop = false
|
||||||
|
self.cleared_block_table = {}
|
||||||
self.used_randomizer = nil
|
self.used_randomizer = nil
|
||||||
self.hold_queue = nil
|
self.hold_queue = nil
|
||||||
self.held = false
|
self.held = false
|
||||||
@@ -177,11 +179,15 @@ function GameMode:update(inputs, ruleset)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.lock_drop and inputs["down"] ~= true then
|
if (self.lock_drop or (
|
||||||
|
not ruleset.are or self:getARE() == 0
|
||||||
|
)) and inputs["down"] ~= true then
|
||||||
self.drop_locked = false
|
self.drop_locked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.lock_hard_drop and inputs["up"] ~= true then
|
if (self.lock_hard_drop or (
|
||||||
|
not ruleset.are or self:getARE() == 0
|
||||||
|
)) and inputs["up"] ~= true then
|
||||||
self.hard_drop_locked = false
|
self.hard_drop_locked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -193,7 +199,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
inputs, self.piece, self.grid, self:getGravity(), self.prev_inputs,
|
inputs, self.piece, self.grid, self:getGravity(), self.prev_inputs,
|
||||||
self.move, self:getLockDelay(), self:getDropSpeed(),
|
self.move, self:getLockDelay(), self:getDropSpeed(),
|
||||||
self.drop_locked, self.hard_drop_locked,
|
self.drop_locked, self.hard_drop_locked,
|
||||||
self.enable_hard_drop, self.additive_gravity
|
self.enable_hard_drop, self.additive_gravity, self.classic_lock
|
||||||
)
|
)
|
||||||
|
|
||||||
local piece_dy = self.piece.position.y - piece_y
|
local piece_dy = self.piece.position.y - piece_y
|
||||||
@@ -244,7 +250,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
self:onPieceLock(self.piece, cleared_row_count)
|
self:onPieceLock(self.piece, cleared_row_count)
|
||||||
self:updateScore(self.level, self.drop_bonus, cleared_row_count)
|
self:updateScore(self.level, self.drop_bonus, cleared_row_count)
|
||||||
|
|
||||||
self.grid:markClearedRows()
|
self.cleared_block_table = self.grid:markClearedRows()
|
||||||
self.piece = nil
|
self.piece = nil
|
||||||
if self.enable_hold then
|
if self.enable_hold then
|
||||||
self.held = false
|
self.held = false
|
||||||
@@ -258,6 +264,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
)
|
)
|
||||||
if self.lcd == 0 then
|
if self.lcd == 0 then
|
||||||
self.grid:clearClearedRows()
|
self.grid:clearClearedRows()
|
||||||
|
self:afterLineClear(cleared_row_count)
|
||||||
if self.are == 0 then
|
if self.are == 0 then
|
||||||
self:initializeOrHold(inputs, ruleset)
|
self:initializeOrHold(inputs, ruleset)
|
||||||
end
|
end
|
||||||
@@ -294,6 +301,7 @@ function GameMode:onPieceLock(piece, cleared_row_count)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:onLineClear(cleared_row_count) end
|
function GameMode:onLineClear(cleared_row_count) end
|
||||||
|
function GameMode:afterLineClear(cleared_row_count) end
|
||||||
|
|
||||||
function GameMode:onPieceEnter() end
|
function GameMode:onPieceEnter() end
|
||||||
function GameMode:onHold() end
|
function GameMode:onHold() end
|
||||||
@@ -425,7 +433,9 @@ function GameMode:processDelays(inputs, ruleset, drop_speed)
|
|||||||
self.lcd = self.lcd - 1
|
self.lcd = self.lcd - 1
|
||||||
self:areCancel(inputs, ruleset)
|
self:areCancel(inputs, ruleset)
|
||||||
if self.lcd == 0 then
|
if self.lcd == 0 then
|
||||||
|
local cleared_row_count = self.grid:getClearedRowCount()
|
||||||
self.grid:clearClearedRows()
|
self.grid:clearClearedRows()
|
||||||
|
self:afterLineClear(cleared_row_count)
|
||||||
playSE("fall")
|
playSE("fall")
|
||||||
if self.are == 0 then
|
if self.are == 0 then
|
||||||
self:initializeOrHold(inputs, ruleset)
|
self:initializeOrHold(inputs, ruleset)
|
||||||
@@ -513,10 +523,14 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
|||||||
if self.buffer_soft_drop then
|
if self.buffer_soft_drop then
|
||||||
self.buffer_soft_drop = false
|
self.buffer_soft_drop = false
|
||||||
end
|
end
|
||||||
if self.lock_drop then
|
if self.lock_drop or (
|
||||||
|
not ruleset.are or self:getARE() == 0
|
||||||
|
) then
|
||||||
self.drop_locked = true
|
self.drop_locked = true
|
||||||
end
|
end
|
||||||
if self.lock_hard_drop then
|
if self.lock_hard_drop or (
|
||||||
|
not ruleset.are or self:getARE() == 0
|
||||||
|
) then
|
||||||
self.hard_drop_locked = true
|
self.hard_drop_locked = true
|
||||||
end
|
end
|
||||||
if generate_next_piece == nil then
|
if generate_next_piece == nil then
|
||||||
@@ -536,14 +550,87 @@ function GameMode:getHighScoreData()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function GameMode:animation(x, y, skin, colour)
|
||||||
|
return {
|
||||||
|
1, 1, 1,
|
||||||
|
-0.25 + 1.25 * (self.lcd / self:getLineClearDelay()),
|
||||||
|
skin, colour,
|
||||||
|
48 + x * 16, y * 16
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function GameMode:drawLineClearAnimation()
|
||||||
|
-- animation function
|
||||||
|
-- params: block x, y, skin, colour
|
||||||
|
-- returns: table with RGBA, skin, colour, x, y
|
||||||
|
|
||||||
|
-- Fadeout (default)
|
||||||
|
--[[
|
||||||
|
function animation(x, y, skin, colour)
|
||||||
|
return {
|
||||||
|
1, 1, 1,
|
||||||
|
-0.25 + 1.25 * (self.lcd / self:getLineClearDelay()),
|
||||||
|
skin, colour,
|
||||||
|
48 + x * 16, y * 16
|
||||||
|
}
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
-- Flash
|
||||||
|
--[[
|
||||||
|
function animation(x, y, skin, colour)
|
||||||
|
return {
|
||||||
|
1, 1, 1,
|
||||||
|
self.lcd % 6 < 3 and 1 or 0.25,
|
||||||
|
skin, colour,
|
||||||
|
48 + x * 16, y * 16
|
||||||
|
}
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
-- TGM1 pop-out
|
||||||
|
--[[
|
||||||
|
function animation(x, y, skin, colour)
|
||||||
|
local p = 0.5
|
||||||
|
local l = (
|
||||||
|
(self:getLineClearDelay() - self.lcd) / self:getLineClearDelay()
|
||||||
|
)
|
||||||
|
local dx = l * (x - (1 + self.grid.width) / 2)
|
||||||
|
local dy = l * (y - (1 + self.grid.height) / 2)
|
||||||
|
return {
|
||||||
|
1, 1, 1, 1, skin, colour,
|
||||||
|
48 + (x + dx) * 16,
|
||||||
|
(y + dy) * 16 + (464 / (p - 1)) * l * (p - l)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
for y, row in pairs(self.cleared_block_table) do
|
||||||
|
for x, block in pairs(row) do
|
||||||
|
local animation_table = self:animation(x, y, block.skin, block.colour)
|
||||||
|
love.graphics.setColor(
|
||||||
|
animation_table[1], animation_table[2],
|
||||||
|
animation_table[3], animation_table[4]
|
||||||
|
)
|
||||||
|
love.graphics.draw(
|
||||||
|
blocks[animation_table[5]][animation_table[6]],
|
||||||
|
animation_table[7], animation_table[8]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function GameMode:drawPiece()
|
function GameMode:drawPiece()
|
||||||
if self.piece ~= nil then
|
if self.piece ~= nil then
|
||||||
self.piece:draw(
|
local b = (
|
||||||
1,
|
self.classic_lock and
|
||||||
self:getLockDelay() == 0 and 1 or
|
(
|
||||||
(0.25 + 0.75 * math.max(1 - self.piece.gravity, 1 - (self.piece.lock_delay / self:getLockDelay()))),
|
self.piece:isDropBlocked(self.grid) and
|
||||||
self.grid
|
1 - self.piece.gravity or 1
|
||||||
|
) or
|
||||||
|
1 - (self.piece.lock_delay / self:getLockDelay())
|
||||||
)
|
)
|
||||||
|
self.piece:draw(1, 0.25 + 0.75 * b, self.grid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -676,7 +763,9 @@ function GameMode:drawSectionTimesWithSecondary(current_section, section_limit)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GameMode:drawSectionTimesWithSplits(current_section)
|
function GameMode:drawSectionTimesWithSplits(current_section, section_limit)
|
||||||
|
section_limit = section_limit or math.huge
|
||||||
|
|
||||||
local section_x = 440
|
local section_x = 440
|
||||||
local split_x = 530
|
local split_x = 530
|
||||||
|
|
||||||
@@ -690,9 +779,12 @@ function GameMode:drawSectionTimesWithSplits(current_section)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (current_section <= section_limit) then
|
||||||
|
love.graphics.setColor(self:sectionColourFunction(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")
|
||||||
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")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function GameMode:drawCustom() end
|
function GameMode:drawCustom() end
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ function MarathonA2Game:updateSectionTimes(old_level, new_level)
|
|||||||
self.section_start_time = self.frames
|
self.section_start_time = self.frames
|
||||||
self.section_tetrises[math.floor(old_level / 100)] = self.tetris_count
|
self.section_tetrises[math.floor(old_level / 100)] = self.tetris_count
|
||||||
self.tetris_count = 0
|
self.tetris_count = 0
|
||||||
print(self.section_tetrises[math.floor(old_level / 100)])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ ARS.colourscheme = {
|
|||||||
|
|
||||||
ARS.softdrop_lock = false
|
ARS.softdrop_lock = false
|
||||||
ARS.harddrop_lock = true
|
ARS.harddrop_lock = true
|
||||||
|
ARS.spawn_above_field = true
|
||||||
|
|
||||||
function ARS:onPieceCreate(piece, grid)
|
function ARS:onPieceCreate(piece, grid)
|
||||||
piece.floorkick = 0
|
piece.floorkick = 0
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ local ARS = Ruleset:extend()
|
|||||||
|
|
||||||
ARS.name = "ACE-ARS2"
|
ARS.name = "ACE-ARS2"
|
||||||
ARS.hash = "ArikaACE2"
|
ARS.hash = "ArikaACE2"
|
||||||
|
ARS.spawn_above_field = true
|
||||||
|
|
||||||
function ARS:onPieceCreate(piece, grid)
|
function ARS:onPieceCreate(piece, grid)
|
||||||
piece.floorkick = 0
|
piece.floorkick = 0
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ SRS.colourscheme = {
|
|||||||
}
|
}
|
||||||
SRS.softdrop_lock = false
|
SRS.softdrop_lock = false
|
||||||
SRS.harddrop_lock = true
|
SRS.harddrop_lock = true
|
||||||
|
SRS.spawn_above_field = true
|
||||||
|
|
||||||
SRS.MANIPULATIONS_MAX = 128
|
SRS.MANIPULATIONS_MAX = 128
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Ruleset.harddrop_lock = false
|
|||||||
Ruleset.enable_IRS_wallkicks = false
|
Ruleset.enable_IRS_wallkicks = false
|
||||||
Ruleset.are_cancel = false
|
Ruleset.are_cancel = false
|
||||||
Ruleset.are = true
|
Ruleset.are = true
|
||||||
|
Ruleset.spawn_above_field = false
|
||||||
|
|
||||||
Ruleset.next_sounds = {
|
Ruleset.next_sounds = {
|
||||||
I = "I",
|
I = "I",
|
||||||
@@ -208,8 +209,11 @@ function Ruleset:dropPiece(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:lockPiece(piece, grid, lock_delay)
|
function Ruleset:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||||
if piece:isDropBlocked(grid) and piece.gravity >= 1 and piece.lock_delay >= lock_delay then
|
if piece:isDropBlocked(grid) and (
|
||||||
|
(classic_lock and piece.gravity >= 1) or
|
||||||
|
(not classic_lock and piece.lock_delay >= lock_delay)
|
||||||
|
) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -243,10 +247,17 @@ function Ruleset:initializePiece(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local spawn_dy = (
|
local spawn_dy
|
||||||
config.gamesettings.spawn_positions == 2 and
|
if (config.gamesettings.spawn_positions == 1) then
|
||||||
|
spawn_dy = (
|
||||||
|
self.spawn_above_field and 2 or 0
|
||||||
|
)
|
||||||
|
else
|
||||||
|
spawn_dy = (
|
||||||
|
config.gamesettings.spawn_positions == 3 and
|
||||||
2 or 0
|
2 or 0
|
||||||
)
|
)
|
||||||
|
end
|
||||||
|
|
||||||
local piece = Piece(data.shape, data.orientation - 1, {
|
local piece = Piece(data.shape, data.orientation - 1, {
|
||||||
x = spawn_x and spawn_x or spawn_positions[data.shape].x,
|
x = spawn_x and spawn_x or spawn_positions[data.shape].x,
|
||||||
@@ -278,7 +289,7 @@ function Ruleset:processPiece(
|
|||||||
inputs, piece, grid, gravity, prev_inputs,
|
inputs, piece, grid, gravity, prev_inputs,
|
||||||
move, lock_delay, drop_speed,
|
move, lock_delay, drop_speed,
|
||||||
drop_locked, hard_drop_locked,
|
drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity
|
hard_drop_enabled, additive_gravity, classic_lock
|
||||||
)
|
)
|
||||||
|
|
||||||
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
|
local synchroes_allowed = ({not self.world, true, false})[config.gamesettings.synchroes_allowed]
|
||||||
@@ -294,7 +305,7 @@ function Ruleset:processPiece(
|
|||||||
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
|
||||||
)
|
)
|
||||||
self:lockPiece(piece, grid, lock_delay)
|
self:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:onPieceMove(piece) end
|
function Ruleset:onPieceMove(piece) end
|
||||||
|
|||||||
Reference in New Issue
Block a user