mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Compare commits
45 Commits
v0.3-beta2
...
v0.3-beta4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83e498534c | ||
|
|
8f19c73e2a | ||
|
|
e36b855ff7 | ||
|
|
23b58951cb | ||
|
|
1d73916b7c | ||
|
|
3947e9f02f | ||
|
|
99b15803ee | ||
|
|
d350b25726 | ||
|
|
44e4d00172 | ||
|
|
31e2529265 | ||
|
|
ea7c75f0b3 | ||
|
|
714c6b5e99 | ||
|
|
6a5d5a9c88 | ||
|
|
03491ba151 | ||
|
|
6e22e3d15b | ||
|
|
66ab5992ad | ||
|
|
2c07c2a58c | ||
|
|
a4d3f3bffc | ||
|
|
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 |
36
README.md
36
README.md
@@ -1,13 +1,13 @@
|
|||||||

|

|
||||||
|
|
||||||
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
|
The game also has a website now with more detail than seen on this README: https://t-sp.in/cambridge
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
-------
|
-------
|
||||||
@@ -17,19 +17,7 @@ Credits
|
|||||||
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
|
- [The Tetra Legends Discord](http://discord.com/invite/7hMx5r2) for supporting me and playtesting!
|
||||||
- [The Absolute Plus](https://discord.gg/6Gf2awJ) for being another source of motivation!
|
- [The Absolute Plus](https://discord.gg/6Gf2awJ) for being another source of motivation!
|
||||||
|
|
||||||
The following people in no particular order also helped with the project:
|
More special thanks can be found in-game, under the "Credits" menu.
|
||||||
- [Hailey](https://github.com/haileylgbt)
|
|
||||||
- CylinderKnot
|
|
||||||
- MarkGamed7794
|
|
||||||
- [Mizu](https://github.com/rexxt)
|
|
||||||
- MattMayuga
|
|
||||||
- Kitaru
|
|
||||||
- switchpalacecorner
|
|
||||||
- [sinefuse](https://github.com/sinefuse)
|
|
||||||
- [2Tie](https://github.com/2Tie)
|
|
||||||
- [nightmareci](https://github.com/nightmareci)
|
|
||||||
- [MyPasswordIsWeak](https://github.com/MyPasswordIsWeak)
|
|
||||||
- [Dr Ocelot](https://github.com/Dr-Ocelot)
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -40,7 +28,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 +76,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
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
-- If this variable is true, then strict type checking is performed for all
|
-- If this variable is true, then strict type checking is performed for all
|
||||||
-- operations. This may result in slower code, but it will allow you to catch
|
-- operations. This may result in slower code, but it will allow you to catch
|
||||||
-- errors and bugs earlier.
|
-- errors and bugs earlier.
|
||||||
local strict = true
|
local strict = false
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -33,12 +33,7 @@ function bigint.new(num)
|
|||||||
return bigint.add(lhs, rhs)
|
return bigint.add(lhs, rhs)
|
||||||
end,
|
end,
|
||||||
__unm = function()
|
__unm = function()
|
||||||
if (self.sign == "+") then
|
return bigint.negate(self)
|
||||||
self.sign = "-"
|
|
||||||
else
|
|
||||||
self.sign = "+"
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end,
|
end,
|
||||||
__sub = function(lhs, rhs)
|
__sub = function(lhs, rhs)
|
||||||
return bigint.subtract(lhs, rhs)
|
return bigint.subtract(lhs, rhs)
|
||||||
@@ -55,14 +50,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 +77,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 +93,24 @@ function bigint.abs(big)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return a new big with the same digits but the opposite sign (negation)
|
||||||
|
function bigint.negate(big)
|
||||||
|
bigint.check(big)
|
||||||
|
local result = big:clone()
|
||||||
|
if (result.sign == "+") then
|
||||||
|
result.sign = "-"
|
||||||
|
else
|
||||||
|
result.sign = "+"
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
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 +145,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 +154,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 +444,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 +454,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 +486,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 +494,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
|
|
||||||
|
|
||||||
-- Append the factor to the result
|
|
||||||
if (factor == 10) then
|
|
||||||
-- Fixes a weird bug that introduces a new bug if fixed by
|
|
||||||
-- changing the comparison in the while loop to "<="
|
|
||||||
result.digits[#result.digits] = 1
|
|
||||||
result.digits[#result.digits + 1] = 0
|
|
||||||
else
|
|
||||||
result.digits[#result.digits + 1] = factor
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Subtract the divisor from the dividend to obtain the
|
|
||||||
-- remainder, which is the new dividend for the next loop
|
|
||||||
dividend = bigint.subtract(dividend,
|
|
||||||
bigint.subtract(divisor, big2))
|
|
||||||
|
|
||||||
-- Reset the divisor
|
|
||||||
divisor = big2:clone()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
table.insert(dividend.digits, big1.digits[i])
|
||||||
|
|
||||||
|
local factor = bigint.new(0)
|
||||||
|
while bigint.compare(dividend, big2, ">=") do
|
||||||
|
dividend = bigint.subtract(dividend, big2)
|
||||||
|
factor = bigint.add(factor, bigint.new(1))
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 0, #factor.digits - 1 do
|
||||||
|
result.digits[#result.digits + 1 - i] = factor.digits[i + 1]
|
||||||
|
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()
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ end
|
|||||||
|
|
||||||
function ConfigScene:new()
|
function ConfigScene:new()
|
||||||
self.input_state = 1
|
self.input_state = 1
|
||||||
|
self.key = 1
|
||||||
self.set_inputs = newSetInputs()
|
self.set_inputs = newSetInputs()
|
||||||
self.new_input = {}
|
self.new_input = {}
|
||||||
self.axis_timer = 0
|
self.axis_timer = 0
|
||||||
@@ -62,7 +63,7 @@ function ConfigScene:render()
|
|||||||
if self.input_state > table.getn(configurable_inputs) then
|
if self.input_state > table.getn(configurable_inputs) then
|
||||||
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or ""))
|
||||||
else
|
else
|
||||||
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("press " .. (self.key == 2 and "joystick" or "key") .. " 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)
|
love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -97,18 +98,28 @@ function ConfigScene:onInputPress(e)
|
|||||||
self.new_input = {}
|
self.new_input = {}
|
||||||
end
|
end
|
||||||
elseif e.scancode == "tab" then
|
elseif e.scancode == "tab" then
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] = "skipped"
|
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||||
self.input_state = self.input_state + 1
|
(
|
||||||
elseif e.scancode ~= "escape" then
|
self.set_inputs[configurable_inputs[self.input_state]] == false
|
||||||
|
and "" or self.set_inputs[configurable_inputs[self.input_state]]
|
||||||
|
) ..
|
||||||
|
(self.key == 2 and " / " or "") .. "skipped"
|
||||||
|
if self.key == 2 then
|
||||||
|
self.input_state = self.input_state + 1
|
||||||
|
self.key = 1
|
||||||
|
else
|
||||||
|
self.key = 2
|
||||||
|
end
|
||||||
|
elseif e.scancode ~= "escape" and self.key == 1 then
|
||||||
-- all other keys can be configured
|
-- all other keys can be configured
|
||||||
if not self.new_input.keys then
|
if not self.new_input.keys then
|
||||||
self.new_input.keys = {}
|
self.new_input.keys = {}
|
||||||
end
|
end
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] = "key " .. love.keyboard.getKeyFromScancode(e.scancode) .. " (" .. e.scancode .. ")"
|
self.set_inputs[configurable_inputs[self.input_state]] = "key " .. love.keyboard.getKeyFromScancode(e.scancode) .. " (" .. e.scancode .. ")"
|
||||||
self.new_input.keys[e.scancode] = configurable_inputs[self.input_state]
|
self.new_input.keys[e.scancode] = configurable_inputs[self.input_state]
|
||||||
self.input_state = self.input_state + 1
|
self.key = 2
|
||||||
end
|
end
|
||||||
elseif string.sub(e.type, 1, 3) == "joy" then
|
elseif string.sub(e.type, 1, 3) == "joy" and self.key == 2 then
|
||||||
if self.input_state <= table.getn(configurable_inputs) then
|
if self.input_state <= table.getn(configurable_inputs) then
|
||||||
if e.type == "joybutton" then
|
if e.type == "joybutton" then
|
||||||
addJoystick(self.new_input, e.name)
|
addJoystick(self.new_input, e.name)
|
||||||
@@ -116,11 +127,13 @@ function ConfigScene:onInputPress(e)
|
|||||||
self.new_input.joysticks[e.name].buttons = {}
|
self.new_input.joysticks[e.name].buttons = {}
|
||||||
end
|
end
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] =
|
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||||
"jbtn " ..
|
self.set_inputs[configurable_inputs[self.input_state]] ..
|
||||||
|
" / jbtn " ..
|
||||||
e.button ..
|
e.button ..
|
||||||
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
||||||
self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state]
|
self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state]
|
||||||
self.input_state = self.input_state + 1
|
self.input_state = self.input_state + 1
|
||||||
|
self.key = 1
|
||||||
elseif e.type == "joyaxis" then
|
elseif e.type == "joyaxis" then
|
||||||
if (e.axis ~= self.last_axis or self.axis_timer > 30) and math.abs(e.value) >= 1 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)
|
addJoystick(self.new_input, e.name)
|
||||||
@@ -131,11 +144,13 @@ function ConfigScene:onInputPress(e)
|
|||||||
self.new_input.joysticks[e.name].axes[e.axis] = {}
|
self.new_input.joysticks[e.name].axes[e.axis] = {}
|
||||||
end
|
end
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] =
|
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||||
"jaxis " ..
|
self.set_inputs[configurable_inputs[self.input_state]] ..
|
||||||
|
" / jaxis " ..
|
||||||
(e.value >= 1 and "+" or "-") .. e.axis ..
|
(e.value >= 1 and "+" or "-") .. e.axis ..
|
||||||
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
||||||
self.new_input.joysticks[e.name].axes[e.axis][e.value >= 1 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.input_state = self.input_state + 1
|
||||||
|
self.key = 1
|
||||||
self.last_axis = e.axis
|
self.last_axis = e.axis
|
||||||
self.axis_timer = 0
|
self.axis_timer = 0
|
||||||
end
|
end
|
||||||
@@ -149,11 +164,13 @@ function ConfigScene:onInputPress(e)
|
|||||||
self.new_input.joysticks[e.name].hats[e.hat] = {}
|
self.new_input.joysticks[e.name].hats[e.hat] = {}
|
||||||
end
|
end
|
||||||
self.set_inputs[configurable_inputs[self.input_state]] =
|
self.set_inputs[configurable_inputs[self.input_state]] =
|
||||||
"jhat " ..
|
self.set_inputs[configurable_inputs[self.input_state]]
|
||||||
|
" / jhat " ..
|
||||||
e.hat .. " " .. e.direction ..
|
e.hat .. " " .. e.direction ..
|
||||||
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
" " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "")
|
||||||
self.new_input.joysticks[e.name].hats[e.hat][e.direction] = configurable_inputs[self.input_state]
|
self.new_input.joysticks[e.name].hats[e.hat][e.direction] = configurable_inputs[self.input_state]
|
||||||
self.input_state = self.input_state + 1
|
self.input_state = self.input_state + 1
|
||||||
|
self.key = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -118,11 +117,15 @@ function Piece:lockIfBottomed(grid)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function Piece:addGravity(gravity, grid)
|
function Piece:addGravity(gravity, grid, classic_lock)
|
||||||
local new_gravity = self.gravity + gravity
|
local new_gravity = self.gravity + gravity
|
||||||
if self:isDropBlocked(grid) then
|
if self:isDropBlocked(grid) then
|
||||||
self.gravity = math.min(1, new_gravity)
|
if classic_lock then
|
||||||
self.lock_delay = self.lock_delay + 1
|
self.gravity = math.min(1, new_gravity)
|
||||||
|
else
|
||||||
|
self.gravity = 0
|
||||||
|
self.lock_delay = self.lock_delay + 1
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local dropped_squares = math.floor(new_gravity)
|
local dropped_squares = math.floor(new_gravity)
|
||||||
local new_frac_gravity = new_gravity - dropped_squares
|
local new_frac_gravity = new_gravity - dropped_squares
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -135,7 +137,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
|
|
||||||
-- set attempt flags
|
-- set attempt flags
|
||||||
if inputs["left"] or inputs["right"] then
|
if inputs["left"] or inputs["right"] then
|
||||||
self:onAttemptPieceMove(self.piece)
|
self:onAttemptPieceMove(self.piece, self.grid)
|
||||||
if self.immobile_spin_bonus and self.piece ~= nil then
|
if self.immobile_spin_bonus and self.piece ~= nil then
|
||||||
if not self.piece:isMoveBlocked(self.grid, { x=-1, y=0 }) and
|
if not self.piece:isMoveBlocked(self.grid, { x=-1, y=0 }) and
|
||||||
not self.piece:isMoveBlocked(self.grid, { x=1, y=0 }) then
|
not self.piece:isMoveBlocked(self.grid, { x=1, y=0 }) then
|
||||||
@@ -148,7 +150,7 @@ function GameMode:update(inputs, ruleset)
|
|||||||
inputs["rotate_left2"] or inputs["rotate_right2"] or
|
inputs["rotate_left2"] or inputs["rotate_right2"] or
|
||||||
inputs["rotate_180"]
|
inputs["rotate_180"]
|
||||||
then
|
then
|
||||||
self:onAttemptPieceRotate(self.piece)
|
self:onAttemptPieceRotate(self.piece, self.grid)
|
||||||
if self.immobile_spin_bonus and self.piece ~= nil then
|
if self.immobile_spin_bonus and self.piece ~= nil then
|
||||||
if self.piece:isDropBlocked(self.grid) and
|
if 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
|
||||||
@@ -177,26 +179,32 @@ 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
|
||||||
|
|
||||||
-- diff vars to use in checks
|
-- diff vars to use in checks
|
||||||
local piece_y = self.piece.position.y
|
local piece_y = self.piece.position.y
|
||||||
|
local piece_x = self.piece.position.x
|
||||||
local piece_rot = self.piece.rotation
|
local piece_rot = self.piece.rotation
|
||||||
|
|
||||||
ruleset:processPiece(
|
ruleset:processPiece(
|
||||||
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
|
||||||
|
local piece_dx = self.piece.position.x - piece_x
|
||||||
local piece_drot = self.piece.rotation - piece_rot
|
local piece_drot = self.piece.rotation - piece_rot
|
||||||
|
|
||||||
-- das cut
|
-- das cut
|
||||||
@@ -208,12 +216,13 @@ function GameMode:update(inputs, ruleset)
|
|||||||
inputs.rotate_180
|
inputs.rotate_180
|
||||||
))
|
))
|
||||||
) then
|
) then
|
||||||
self.das.frames = math.max(
|
self:dasCut()
|
||||||
self.das.frames - self:getDasCutDelay(),
|
|
||||||
-(self:getDasCutDelay() + 1)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (piece_dx ~= 0) then self:onPieceMove(self.piece, self.grid) end
|
||||||
|
if (piece_drot ~= 0) then self:onPieceRotate(self.piece, self.grid) end
|
||||||
|
if (piece_dy ~= 0) then self:onPieceDrop(self.piece, self.grid) end
|
||||||
|
|
||||||
if inputs["up"] == true and
|
if inputs["up"] == true and
|
||||||
self.piece:isDropBlocked(self.grid) and
|
self.piece:isDropBlocked(self.grid) and
|
||||||
not self.hard_drop_locked then
|
not self.hard_drop_locked then
|
||||||
@@ -244,7 +253,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 +267,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
|
||||||
@@ -287,13 +297,17 @@ end
|
|||||||
|
|
||||||
-- event functions
|
-- event functions
|
||||||
function GameMode:whilePieceActive() end
|
function GameMode:whilePieceActive() end
|
||||||
function GameMode:onAttemptPieceMove(piece) end
|
function GameMode:onAttemptPieceMove(piece, grid) end
|
||||||
function GameMode:onAttemptPieceRotate(piece) end
|
function GameMode:onAttemptPieceRotate(piece, grid) end
|
||||||
|
function GameMode:onPieceMove(piece, grid) end
|
||||||
|
function GameMode:onPieceRotate(piece, grid) end
|
||||||
|
function GameMode:onPieceDrop(piece, grid) end
|
||||||
function GameMode:onPieceLock(piece, cleared_row_count)
|
function GameMode:onPieceLock(piece, cleared_row_count)
|
||||||
playSE("lock")
|
playSE("lock")
|
||||||
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
|
||||||
@@ -382,6 +396,13 @@ function GameMode:chargeDAS(inputs)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function GameMode:dasCut()
|
||||||
|
self.das.frames = math.max(
|
||||||
|
self.das.frames - self:getDasCutDelay(),
|
||||||
|
-(self:getDasCutDelay() + 1)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
function GameMode:areCancel(inputs, ruleset)
|
function GameMode:areCancel(inputs, ruleset)
|
||||||
if ruleset.are_cancel and self.piece_hard_dropped and
|
if ruleset.are_cancel and self.piece_hard_dropped and
|
||||||
not self.prev_inputs.up and
|
not self.prev_inputs.up and
|
||||||
@@ -425,7 +446,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 +536,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 +563,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 +776,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
|
||||||
|
|
||||||
@@ -684,14 +786,18 @@ function GameMode:drawSectionTimesWithSplits(current_section)
|
|||||||
|
|
||||||
for section, time in pairs(self.section_times) do
|
for section, time in pairs(self.section_times) do
|
||||||
if section > 0 then
|
if section > 0 then
|
||||||
|
love.graphics.setColor(self:sectionColourFunction(section))
|
||||||
love.graphics.printf(formatTime(time), section_x, 40 + 20 * section, 90, "left")
|
love.graphics.printf(formatTime(time), section_x, 40 + 20 * section, 90, "left")
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
split_time = split_time + time
|
split_time = split_time + time
|
||||||
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
|
||||||
|
|
||||||
love.graphics.printf(formatTime(self.frames - self.section_start_time), section_x, 40 + 20 * current_section, 90, "left")
|
if (current_section <= section_limit) then
|
||||||
love.graphics.printf(formatTime(self.frames), split_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")
|
||||||
|
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
|
||||||
|
|
||||||
|
|||||||
@@ -52,23 +52,14 @@ function StrategyGame:getLineClearDelay()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:getLockDelay()
|
function StrategyGame:getLockDelay()
|
||||||
if self.level < 500 then return 8
|
if self.level < 700 then return 8
|
||||||
elseif self.level < 700 then return 6
|
else return 6 end
|
||||||
else return 4 end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:getGravity()
|
function StrategyGame:getGravity()
|
||||||
return 20
|
return 20
|
||||||
end
|
end
|
||||||
|
|
||||||
function StrategyGame:getNextPiece(ruleset)
|
|
||||||
return {
|
|
||||||
skin = "2tie",
|
|
||||||
shape = self.randomizer:nextPiece(),
|
|
||||||
orientation = ruleset:getDefaultOrientation(),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function StrategyGame:advanceOneFrame()
|
function StrategyGame:advanceOneFrame()
|
||||||
if self.clear then
|
if self.clear then
|
||||||
self.roll_frames = self.roll_frames + 1
|
self.roll_frames = self.roll_frames + 1
|
||||||
|
|||||||
@@ -94,12 +94,8 @@ function Survival2020Game:getGravity()
|
|||||||
return 20
|
return 20
|
||||||
end
|
end
|
||||||
|
|
||||||
function Survival2020Game:getNextPiece(ruleset)
|
function Survival2020Game:getSkin()
|
||||||
return {
|
return self.level >= 1000 and "bone" or "2tie"
|
||||||
skin = self.level >= 1000 and "bone" or "2tie",
|
|
||||||
shape = self.randomizer:nextPiece(),
|
|
||||||
orientation = ruleset:getDefaultOrientation(),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Survival2020Game:hitTorikan(old_level, new_level)
|
function Survival2020Game:hitTorikan(old_level, new_level)
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ function SurvivalA2Game:new()
|
|||||||
self.lock_hard_drop = true
|
self.lock_hard_drop = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SurvivalA2Game:initialize(ruleset)
|
||||||
|
SurvivalA2Game.super.initialize(self, ruleset)
|
||||||
|
self.world = ruleset.world
|
||||||
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:getARE()
|
function SurvivalA2Game:getARE()
|
||||||
if self.level < 100 then return 18
|
if self.level < 100 then return 18
|
||||||
elseif self.level < 300 then return 14
|
elseif self.level < 300 then return 14
|
||||||
@@ -69,7 +74,8 @@ function SurvivalA2Game:getGravity()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SurvivalA2Game:hitTorikan(old_level, new_level)
|
function SurvivalA2Game:hitTorikan(old_level, new_level)
|
||||||
if old_level < 500 and new_level >= 500 and self.frames > frameTime(3,25) then
|
local torikan_time = self.world and frameTime(3,55) or frameTime(3,25)
|
||||||
|
if old_level < 500 and new_level >= 500 and self.frames > torikan_time then
|
||||||
self.level = 500
|
self.level = 500
|
||||||
return true
|
return true
|
||||||
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,17 +17,22 @@ 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
|
||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid, upward)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
if piece:isDropBlocked(grid) then
|
if upward or piece:isDropBlocked(grid) then
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SRS:canPieceRotate(piece)
|
||||||
|
return piece.manipulations < self.MANIPULATIONS_MAX
|
||||||
|
end
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ end
|
|||||||
function ARS:onPieceRotate(piece, grid)
|
function ARS:onPieceRotate(piece, grid)
|
||||||
if piece.floorkick >= 1 then
|
if piece.floorkick >= 1 then
|
||||||
piece.floorkick = piece.floorkick + 1
|
piece.floorkick = piece.floorkick + 1
|
||||||
|
if piece:isDropBlocked(grid) then
|
||||||
|
piece.locked = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
@@ -114,7 +115,9 @@ function Ruleset:rotatePiece(inputs, piece, grid, prev_inputs, initial)
|
|||||||
|
|
||||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||||
|
|
||||||
self:attemptRotate(new_inputs, piece, grid, initial)
|
if self:canPieceRotate(piece, grid) then
|
||||||
|
self:attemptRotate(new_inputs, piece, grid, initial)
|
||||||
|
end
|
||||||
|
|
||||||
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
||||||
playSE("bottom")
|
playSE("bottom")
|
||||||
@@ -159,28 +162,43 @@ function Ruleset:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:movePiece(piece, grid, move, instant)
|
function Ruleset:movePiece(piece, grid, move, instant)
|
||||||
local x = piece.position.x
|
if not self:canPieceMove(piece, grid) then return end
|
||||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||||
|
local offset = ({x=0, y=0})
|
||||||
|
local moves = 0
|
||||||
if move == "left" then
|
if move == "left" then
|
||||||
piece:moveInGrid({x=-1, y=0}, 1, grid, false)
|
offset.x = -1
|
||||||
|
moves = 1
|
||||||
elseif move == "right" then
|
elseif move == "right" then
|
||||||
piece:moveInGrid({x=1, y=0}, 1, grid, false)
|
offset.x = 1
|
||||||
|
moves = 1
|
||||||
elseif move == "speedleft" then
|
elseif move == "speedleft" then
|
||||||
piece:moveInGrid({x=-1, y=0}, grid.width, grid, instant)
|
offset.x = -1
|
||||||
|
moves = grid.width
|
||||||
elseif move == "speedright" then
|
elseif move == "speedright" then
|
||||||
piece:moveInGrid({x=1, y=0}, grid.width, grid, instant)
|
offset.x = 1
|
||||||
|
moves = grid.width
|
||||||
end
|
end
|
||||||
if piece.position.x ~= x then
|
for i = 1, moves do
|
||||||
self:onPieceMove(piece, grid)
|
local x = piece.position.x
|
||||||
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
if moves ~= 1 then
|
||||||
playSE("bottom")
|
piece:moveInGrid(offset, 1, grid, instant)
|
||||||
|
else
|
||||||
|
piece:moveInGrid(offset, 1, grid, false)
|
||||||
end
|
end
|
||||||
|
if piece.position.x ~= x then
|
||||||
|
self:onPieceMove(piece, grid)
|
||||||
|
if piece.locked then break end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not was_drop_blocked and piece:isDropBlocked(grid) then
|
||||||
|
playSE("bottom")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Ruleset:dropPiece(
|
function Ruleset:dropPiece(
|
||||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity
|
hard_drop_enabled, additive_gravity, classic_lock
|
||||||
)
|
)
|
||||||
if piece.big then
|
if piece.big then
|
||||||
gravity = gravity / 2
|
gravity = gravity / 2
|
||||||
@@ -190,26 +208,29 @@ function Ruleset:dropPiece(
|
|||||||
local y = piece.position.y
|
local y = piece.position.y
|
||||||
if inputs["down"] == true and drop_locked == false then
|
if inputs["down"] == true and drop_locked == false then
|
||||||
if additive_gravity then
|
if additive_gravity then
|
||||||
piece:addGravity(gravity + drop_speed, grid)
|
piece:addGravity(gravity + drop_speed, grid, classic_lock)
|
||||||
else
|
else
|
||||||
piece:addGravity(math.max(gravity, drop_speed), grid)
|
piece:addGravity(math.max(gravity, drop_speed), grid, classic_lock)
|
||||||
end
|
end
|
||||||
elseif inputs["up"] == true and hard_drop_enabled == true then
|
elseif inputs["up"] == true and hard_drop_enabled == true then
|
||||||
if hard_drop_locked == true or piece:isDropBlocked(grid) then
|
if hard_drop_locked == true or piece:isDropBlocked(grid) then
|
||||||
piece:addGravity(gravity, grid)
|
piece:addGravity(gravity, grid, classic_lock)
|
||||||
else
|
else
|
||||||
piece:dropToBottom(grid)
|
piece:dropToBottom(grid)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
piece:addGravity(gravity, grid)
|
piece:addGravity(gravity, grid, classic_lock)
|
||||||
end
|
end
|
||||||
if piece.position.y ~= y then
|
if piece.position.y ~= y then
|
||||||
self:onPieceDrop(piece, grid)
|
self:onPieceDrop(piece, grid)
|
||||||
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 +264,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
|
||||||
2 or 0
|
spawn_dy = (
|
||||||
)
|
self.spawn_above_field and 2 or 0
|
||||||
|
)
|
||||||
|
else
|
||||||
|
spawn_dy = (
|
||||||
|
config.gamesettings.spawn_positions == 3 and
|
||||||
|
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 +306,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]
|
||||||
@@ -292,11 +320,13 @@ function Ruleset:processPiece(
|
|||||||
end
|
end
|
||||||
self:dropPiece(
|
self:dropPiece(
|
||||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||||
hard_drop_enabled, additive_gravity
|
hard_drop_enabled, additive_gravity, classic_lock
|
||||||
)
|
)
|
||||||
self:lockPiece(piece, grid, lock_delay)
|
self:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Ruleset:canPieceMove(piece, grid) return true end
|
||||||
|
function Ruleset:canPieceRotate(piece, grid) return true end
|
||||||
function Ruleset:onPieceMove(piece) end
|
function Ruleset:onPieceMove(piece) end
|
||||||
function Ruleset:onPieceRotate(piece) end
|
function Ruleset:onPieceRotate(piece) end
|
||||||
function Ruleset:onPieceDrop(piece) end
|
function Ruleset:onPieceDrop(piece) end
|
||||||
|
|||||||
@@ -92,11 +92,14 @@ function SRS:onPieceRotate(piece, grid)
|
|||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
self:checkNewLow(piece)
|
self:checkNewLow(piece)
|
||||||
piece.manipulations = piece.manipulations + 1
|
piece.manipulations = piece.manipulations + 1
|
||||||
if piece:isDropBlocked(grid) then
|
if piece.manipulations >= self.MANIPULATIONS_MAX then
|
||||||
if piece.manipulations >= SRS.MANIPULATIONS_MAX then
|
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
||||||
piece.locked = true
|
if piece:isDropBlocked(grid) then
|
||||||
end
|
piece.locked = true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SRS:canPieceRotate() return true end
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
if grid:canPlacePiece(kicked_piece) then
|
if grid:canPlacePiece(kicked_piece) then
|
||||||
piece:setRelativeRotation(rot_dir)
|
piece:setRelativeRotation(rot_dir)
|
||||||
piece:setOffset(offset)
|
piece:setOffset(offset)
|
||||||
self:onPieceRotate(piece, grid)
|
self:onPieceRotate(piece, grid, offset.y < 0)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -69,7 +69,10 @@ end
|
|||||||
|
|
||||||
function SRS:onPieceDrop(piece, grid)
|
function SRS:onPieceDrop(piece, grid)
|
||||||
self:checkNewLow(piece)
|
self:checkNewLow(piece)
|
||||||
if piece.manipulations >= self.MANIPULATIONS_MAX and piece:isDropBlocked(grid) then
|
if (
|
||||||
|
piece.manipulations >= self.MANIPULATIONS_MAX or
|
||||||
|
piece.rotations >= self.ROTATIONS_MAX
|
||||||
|
) and piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
else
|
else
|
||||||
piece.lock_delay = 0 -- step reset
|
piece.lock_delay = 0 -- step reset
|
||||||
@@ -86,16 +89,18 @@ function SRS:onPieceMove(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid, upward)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
self:checkNewLow(piece)
|
if upward or piece:isDropBlocked(grid) then
|
||||||
if piece.rotations >= self.ROTATIONS_MAX then
|
piece.rotations = piece.rotations + 1
|
||||||
piece.rotations = piece.rotations + 1
|
if piece.rotations >= self.ROTATIONS_MAX and piece:isDropBlocked(grid) then
|
||||||
piece:moveInGrid({ x = 0, y = 1 }, 1, grid)
|
piece.locked = true
|
||||||
if piece:isDropBlocked(grid) then
|
end
|
||||||
piece.locked = true
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
function SRS:canPieceRotate(piece)
|
||||||
|
return piece.rotations < self.ROTATIONS_MAX
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:get180RotationValue() return 2 end
|
function SRS:get180RotationValue() return 2 end
|
||||||
|
|||||||
@@ -150,9 +150,9 @@ function SRS:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
|||||||
for idx, offset in pairs(kicks) do
|
for idx, offset in pairs(kicks) do
|
||||||
kicked_piece = new_piece:withOffset(offset)
|
kicked_piece = new_piece:withOffset(offset)
|
||||||
if grid:canPlacePiece(kicked_piece) then
|
if grid:canPlacePiece(kicked_piece) then
|
||||||
self:onPieceRotate(piece, grid)
|
|
||||||
piece:setRelativeRotation(rot_dir)
|
piece:setRelativeRotation(rot_dir)
|
||||||
piece:setOffset(offset)
|
piece:setOffset(offset)
|
||||||
|
self:onPieceRotate(piece, grid, offset.y < 0)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -182,16 +182,20 @@ function SRS:onPieceMove(piece, grid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SRS:onPieceRotate(piece, grid)
|
function SRS:onPieceRotate(piece, grid, upward)
|
||||||
piece.lock_delay = 0 -- rotate reset
|
piece.lock_delay = 0 -- rotate reset
|
||||||
if piece:isDropBlocked(grid) then
|
if upward or piece:isDropBlocked(grid) then
|
||||||
piece.rotations = piece.rotations + 1
|
piece.rotations = piece.rotations + 1
|
||||||
if piece.rotations >= self.ROTATIONS_MAX then
|
if piece.rotations >= self.ROTATIONS_MAX and piece:isDropBlocked(grid) then
|
||||||
piece.locked = true
|
piece.locked = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SRS:canPieceRotate(piece)
|
||||||
|
return piece.rotations < self.ROTATIONS_MAX
|
||||||
|
end
|
||||||
|
|
||||||
function SRS:get180RotationValue() return 3 end
|
function SRS:get180RotationValue() return 3 end
|
||||||
|
|
||||||
return SRS
|
return SRS
|
||||||
|
|||||||
Reference in New Issue
Block a user