mirror of
https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile.git
synced 2025-01-08 17:33:09 +08:00
first commit
This commit is contained in:
1154
game/gamemode.lua
Normal file
1154
game/gamemode.lua
Normal file
File diff suppressed because it is too large
Load Diff
212
game/grid.lua
Normal file
212
game/grid.lua
Normal file
@@ -0,0 +1,212 @@
|
||||
local Object = require 'libs.classic'
|
||||
|
||||
local Grid = Object:extend()
|
||||
|
||||
local empty = { skin = "", colour = "", oob=false }
|
||||
local oob = { skin = "", colour = "", oob=true }
|
||||
local block = { skin = "2tie", colour = "A", oob=false }
|
||||
|
||||
function Grid:new(width, height)
|
||||
self.grid = {}
|
||||
self.grid_age = {}
|
||||
self.width = width
|
||||
self.height = height
|
||||
for y = 1, self.height do
|
||||
self.grid[y] = {}
|
||||
self.grid_age[y] = {}
|
||||
for x = 1, self.width do
|
||||
self.grid[y][x] = empty
|
||||
self.grid_age[y][x] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:clear()
|
||||
for y = 1, self.height do
|
||||
for x = 1, self.width do
|
||||
self.grid[y][x] = empty
|
||||
self.grid_age[y][x] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:getCell(x, y)
|
||||
if x < 1 or x > self.width or y > self.height then return oob
|
||||
elseif y < 1 then return oob
|
||||
else return self.grid[y][x]
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:isOccupied(x, y)
|
||||
return self:getCell(x+1, y+1) ~= empty
|
||||
end
|
||||
|
||||
function Grid:isRowFull(row)
|
||||
for index, square in pairs(self.grid[row]) do
|
||||
if square == empty then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:canPlacePiece(piece)
|
||||
local offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = piece.position.x + offset.x
|
||||
local y = piece.position.y + offset.y
|
||||
if self:isOccupied(x, y) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:canPlacePieceInVisibleGrid(piece)
|
||||
local offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = piece.position.x + offset.x
|
||||
local y = piece.position.y + offset.y
|
||||
if y < 1 or self:isOccupied(x, y) ~= empty then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:getClearedRowCount()
|
||||
local count = 0
|
||||
local cleared_row_table = {}
|
||||
for row = 1, self.height do
|
||||
if self:isRowFull(row) then
|
||||
count = count + 1
|
||||
table.insert(cleared_row_table, row)
|
||||
end
|
||||
end
|
||||
return count, cleared_row_table
|
||||
end
|
||||
|
||||
function Grid:markClearedRows()
|
||||
local block_table = {}
|
||||
for row = 1, self.height do
|
||||
if self:isRowFull(row) then
|
||||
block_table[row] = {}
|
||||
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] = {
|
||||
skin = self.grid[row][x].skin,
|
||||
colour = "X"
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
return block_table
|
||||
end
|
||||
|
||||
function Grid:clearClearedRows()
|
||||
for row = 1, self.height do
|
||||
if self:isRowFull(row) then
|
||||
for above_row = row, 2, -1 do
|
||||
self.grid[above_row] = self.grid[above_row - 1]
|
||||
self.grid_age[above_row] = self.grid_age[above_row - 1]
|
||||
end
|
||||
self.grid[1] = {}
|
||||
self.grid_age[1] = {}
|
||||
for i = 1, self.width do
|
||||
self.grid[1][i] = empty
|
||||
self.grid_age[1][i] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:clearSpecificRow(row)
|
||||
for col = 1, self.width do
|
||||
self.grid[row][col] = empty
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:applyPiece(piece)
|
||||
if piece.big then
|
||||
self:applyBigPiece(piece)
|
||||
return
|
||||
end
|
||||
offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
x = piece.position.x + offset.x
|
||||
y = piece.position.y + offset.y
|
||||
if y + 1 > 0 and y < self.height then
|
||||
self.grid[y+1][x+1] = {
|
||||
skin = piece.skin,
|
||||
colour = piece.colour,
|
||||
flash = 5
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:checkStackHeight()
|
||||
for i = 0, self.height - 1 do
|
||||
for j = 0, self.width - 1 do
|
||||
if self:isOccupied(j, i) then return self.height - i end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function Grid:applyMap(map)
|
||||
for y, row in pairs(map) do
|
||||
for x, block in pairs(row) do
|
||||
self.grid_age[y][x] = 0
|
||||
self.grid[y][x] = block
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:update()
|
||||
for y = 1, self.height do
|
||||
for x = 1, self.width do
|
||||
if self.grid[y][x] ~= empty then
|
||||
self.grid_age[y][x] = self.grid_age[y][x] + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:draw(greyscale, timer)
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.rectangle("fill", 256, 31, 80, 45, 0, 0)
|
||||
love.graphics.setColor(0.3, 0.3, 0.3, 1)
|
||||
love.graphics.line(256,31,256,31+45)
|
||||
love.graphics.line(256,31,256+80,31)
|
||||
love.graphics.line(256+80,31,256+80,31+45)
|
||||
love.graphics.line(256,31+45,256+80,31+45)
|
||||
for y = 1, self.height do
|
||||
for x = 1, self.width do
|
||||
if blocks[self.grid[y][x].skin] and
|
||||
blocks[self.grid[y][x].skin][self.grid[y][x].colour] then
|
||||
if self.grid[y][x].flash ~= nil then
|
||||
if self.grid[y][x].flash > 0 then
|
||||
love.graphics.setColor(0.4+(self.grid[y][x].flash*0.1), 0.4+(self.grid[y][x].flash*0.1), 0.4+(self.grid[y][x].flash*0.1), 1)
|
||||
love.graphics.draw(blocks[self.grid[y][x].skin]['W'], 200+x*16, 64+y*16)
|
||||
self.grid[y][x].flash = self.grid[y][x].flash - 1
|
||||
else
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour..'_d'], 200+x*16, 64+y*16)
|
||||
end
|
||||
end
|
||||
if greyscale then
|
||||
if timer > 1 then timer = 1 end
|
||||
love.graphics.setColor(0.7, 0.7, 0.7, 0+timer)
|
||||
if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= 'X' then
|
||||
love.graphics.draw(blocks[self.grid[y][x].skin]["A"], 200+x*16, 64+y*16)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Grid
|
||||
174
game/piece.lua
Normal file
174
game/piece.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
local Object = require 'libs.classic'
|
||||
|
||||
local Piece = Object:extend()
|
||||
|
||||
function Piece:new(shape, rotation, position, block_offsets, gravity, lock_delay, skin, colour, big)
|
||||
self.shape = shape
|
||||
self.rotation = rotation
|
||||
self.position = position
|
||||
self.block_offsets = block_offsets
|
||||
self.gravity = gravity
|
||||
self.lock_delay = lock_delay
|
||||
self.skin = skin
|
||||
self.colour = colour
|
||||
self.lowest_point = -1
|
||||
-- self.ghost = false
|
||||
self.locked = false
|
||||
-- self.big = big
|
||||
end
|
||||
|
||||
-- Functions that return a new piece to test in rotation systems.
|
||||
|
||||
function Piece:withOffset(offset)
|
||||
return Piece(
|
||||
self.shape, self.rotation,
|
||||
{x = self.position.x + offset.x, y = self.position.y + offset.y},
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin, self.colour
|
||||
)
|
||||
end
|
||||
|
||||
function Piece:withRelativeRotation(rot)
|
||||
local new_rot = self.rotation + rot
|
||||
while new_rot < 0 do new_rot = new_rot + 4 end
|
||||
while new_rot >= 4 do new_rot = new_rot - 4 end
|
||||
return Piece(
|
||||
self.shape, new_rot, self.position,
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin, self.colour
|
||||
)
|
||||
end
|
||||
|
||||
-- Functions that return predicates relative to a grid.
|
||||
|
||||
function Piece:getBlockOffsets()
|
||||
return self.block_offsets[self.shape][self.rotation + 1]
|
||||
end
|
||||
|
||||
function Piece:occupiesSquare(x, y)
|
||||
local offsets = self:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local new_offset = {x = self.position.x + offset.x, y = self.position.y + offset.y}
|
||||
if new_offset.x == x and new_offset.y == y then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Piece:isMoveBlocked(grid, offset)
|
||||
local moved_piece = self:withOffset(offset)
|
||||
return not grid:canPlacePiece(moved_piece)
|
||||
end
|
||||
|
||||
function Piece:isDropBlocked(grid)
|
||||
return self:isMoveBlocked(grid, { x=0, y=1 })
|
||||
end
|
||||
|
||||
-- Procedures to actually do stuff to pieces.
|
||||
|
||||
function Piece:setOffset(offset)
|
||||
self.position.x = self.position.x + offset.x
|
||||
self.position.y = self.position.y + offset.y
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:setRelativeRotation(rot)
|
||||
new_rot = self.rotation + rot
|
||||
while new_rot < 0 do new_rot = new_rot + 4 end
|
||||
while new_rot >= 4 do new_rot = new_rot - 4 end
|
||||
self.rotation = new_rot
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:moveInGrid(step, squares, grid, instant)
|
||||
local moved = false
|
||||
for x = 1, squares do
|
||||
if grid:canPlacePiece(self:withOffset(step)) then
|
||||
moved = true
|
||||
self:setOffset(step)
|
||||
if instant then
|
||||
self:dropToBottom(grid)
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:dropSquares(dropped_squares, grid)
|
||||
self:moveInGrid({ x = 0, y = 1 }, dropped_squares, grid)
|
||||
end
|
||||
|
||||
function Piece:dropToBottom(grid)
|
||||
local piece_y = self.position.y
|
||||
self:dropSquares(math.huge, grid)
|
||||
self.gravity = 0
|
||||
if self.position.y > piece_y then
|
||||
--self.lock_delay = 0
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:lockIfBottomed(grid)
|
||||
if self:isDropBlocked(grid) then
|
||||
self.locked = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Piece:addGravity(gravity, grid, classic_lock)
|
||||
gravity = gravity / (self.big and 2 or 1)
|
||||
local new_gravity = self.gravity + gravity
|
||||
if self:isDropBlocked(grid) then
|
||||
if classic_lock then
|
||||
self.gravity = new_gravity
|
||||
else
|
||||
self.gravity = 0
|
||||
self.lock_delay = self.lock_delay + 1
|
||||
end
|
||||
elseif not (
|
||||
self:isMoveBlocked(grid, { x=0, y=-1 }) and gravity < 0
|
||||
) then
|
||||
local dropped_squares = math.floor(math.abs(new_gravity))
|
||||
if gravity >= 0 then
|
||||
local new_frac_gravity = new_gravity - dropped_squares
|
||||
self.gravity = new_frac_gravity
|
||||
self:dropSquares(dropped_squares, grid)
|
||||
if self:isDropBlocked(grid) then
|
||||
playSE("bottom")
|
||||
end
|
||||
else
|
||||
local new_frac_gravity = new_gravity + dropped_squares
|
||||
self.gravity = new_frac_gravity
|
||||
self:moveInGrid({ x=0, y=-1 }, dropped_squares, grid)
|
||||
if self:isMoveBlocked(grid, { x=0, y=-1 }) then
|
||||
playSE("bottom")
|
||||
end
|
||||
end
|
||||
else
|
||||
self.gravity = 0
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
-- Procedures for drawing.
|
||||
|
||||
function Piece:draw(opacity, brightness, grid, partial_das)
|
||||
if opacity == nil then opacity = 1 end
|
||||
if brightness == nil then brightness = 1 end
|
||||
love.graphics.setColor(brightness, brightness, brightness, opacity)
|
||||
local offsets = self:getBlockOffsets()
|
||||
local gravity_offset = 0
|
||||
if partial_das == nil then partial_das = 0 end
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = self.position.x + offset.x
|
||||
local y = self.position.y + offset.y
|
||||
love.graphics.draw(
|
||||
blocks[self.skin][self.colour],
|
||||
216+x*16+partial_das, 80+y*16+gravity_offset
|
||||
)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return Piece
|
||||
148
game/randomizer.lua
Normal file
148
game/randomizer.lua
Normal file
@@ -0,0 +1,148 @@
|
||||
local Object = require 'libs.classic'
|
||||
|
||||
local Randomizer = Object:extend()
|
||||
|
||||
local highest_count = 0
|
||||
|
||||
function Randomizer:new(always, seed)
|
||||
self.always = always
|
||||
if seed ~= nil then
|
||||
self.seed = seed
|
||||
else
|
||||
self.seed = love.math.random(1, 9007199254740991)
|
||||
end
|
||||
self.drought = {
|
||||
I = 0,
|
||||
J = 0,
|
||||
L = 0,
|
||||
T = 0,
|
||||
S = 0,
|
||||
Z = 0,
|
||||
O = 0
|
||||
}
|
||||
self.droughted_deals = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||
self.piece_counts = {
|
||||
I = 0,
|
||||
J = 0,
|
||||
L = 0,
|
||||
T = 0,
|
||||
S = 0,
|
||||
Z = 0,
|
||||
O = 0
|
||||
}
|
||||
self.piece_round = 0
|
||||
self:initialize()
|
||||
end
|
||||
|
||||
function Randomizer:nextPiece()
|
||||
return self:generatePiece()
|
||||
end
|
||||
|
||||
function Randomizer:runTest()
|
||||
local i_distance = 0
|
||||
local highest_distance = 0
|
||||
local distance_total = 0
|
||||
local i_appearances = 0
|
||||
local dupe = 0
|
||||
local trip = 0
|
||||
local quad = 0
|
||||
local quin = 0
|
||||
local lastpiece = 0
|
||||
local lastpiece2 = 0
|
||||
local lastpiece3 = 0
|
||||
local lastpiece4 = 0
|
||||
local pieceseq_rep = 0
|
||||
local pieceseq = {}
|
||||
local last_pieceseq = {}
|
||||
local highest_discrepancy = 0
|
||||
local discrepancy = self.piece_counts[table.highest(self.piece_counts)] - self.piece_counts[table.lowest(self.piece_counts)]
|
||||
local total_chance = 0
|
||||
for i=0, 750000 do
|
||||
piece = self:generatePiece()
|
||||
if #pieceseq < 7 then
|
||||
table.insert(pieceseq, piece)
|
||||
else
|
||||
--print(table.concat(pieceseq))
|
||||
if table.concat(pieceseq) == table.concat(last_pieceseq) then
|
||||
pieceseq_rep = pieceseq_rep + 1
|
||||
end
|
||||
last_pieceseq = copy(pieceseq)
|
||||
pieceseq = {}
|
||||
end
|
||||
if piece == lastpiece then dupe = dupe + 1 end
|
||||
if piece == lastpiece and piece == lastpiece2 then trip = trip + 1 end
|
||||
if piece == lastpiece and piece == lastpiece2 and piece == lastpiece3 then quad = quad + 1 end
|
||||
if piece == lastpiece and piece == lastpiece2 and piece == lastpiece3 and piece == lastpiece4 then quin = quin + 1 end
|
||||
if piece == 'I' then
|
||||
distance_total = distance_total + i_distance
|
||||
i_appearances = i_appearances + 1
|
||||
i_distance = 0
|
||||
else i_distance = i_distance + 1 end
|
||||
if highest_distance < i_distance then highest_distance = i_distance end
|
||||
lastpiece4 = lastpiece3
|
||||
lastpiece3 = lastpiece2
|
||||
lastpiece2 = lastpiece
|
||||
lastpiece = piece
|
||||
--if self.piece_round <= 750 then print(discrepancy) end
|
||||
local new_discrepancy = self.piece_counts[table.highest(self.piece_counts)] - self.piece_counts[table.lowest(self.piece_counts)]
|
||||
if new_discrepancy > discrepancy then highest_discrepancy = new_discrepancy end
|
||||
discrepancy = new_discrepancy
|
||||
local chance = 0
|
||||
for piece,drought in pairs(self.drought) do
|
||||
local piece_chance = 0.14/( ((self.drought[table.highest(self.drought)]+1)-drought) / (self.drought[table.highest(self.drought)]) )
|
||||
chance = chance + piece_chance
|
||||
end
|
||||
chance = chance / 7
|
||||
total_chance = total_chance + chance
|
||||
end
|
||||
--something = something / 750000
|
||||
print(string.format('dupes: %d, trips: %s, quads: %s, quins: %s, highest i distance: %d, average i distance: %f, pieceseq reps: %d, highest discrepancy:%d, average chance:%f\ndrought lengths dealt: %s', dupe, trip, quad, quin, highest_distance, distance_total/i_appearances, pieceseq_rep, highest_discrepancy, total_chance/750000, table.concat(self.droughted_deals, '-')))
|
||||
for piece,count in pairs(self.piece_counts) do
|
||||
print(piece..' '..count)
|
||||
end
|
||||
end
|
||||
|
||||
function Randomizer:initialize()
|
||||
local start_pieces = {"I", "J", "L", "T"}
|
||||
local shapes = {"I", "J", "L", "T", "S", "Z", "O"}
|
||||
love.math.setRandomSeed(self.seed)
|
||||
self.drought[table.remove(shapes, love.math.random(1, 4))] = 10
|
||||
for i=4,9 do
|
||||
self.drought[table.remove(shapes, love.math.random(1, #shapes))] = i
|
||||
end
|
||||
|
||||
--self:runTest()
|
||||
end
|
||||
|
||||
function Randomizer:generatePiece(always)
|
||||
if self.always then
|
||||
return "I"
|
||||
end
|
||||
|
||||
local shapes = {"I", "J", "L", "T", "S", "Z", "O"}
|
||||
local new_piece = shapes[love.math.random(1,7)]
|
||||
local chance = love.math.random(0,self.drought[table.highest(self.drought)])
|
||||
while self.drought[new_piece] < chance do
|
||||
new_piece = shapes[love.math.random(1,7)]
|
||||
end
|
||||
for piece,drought in pairs(self.drought) do
|
||||
if drought >= 10 then
|
||||
new_piece = piece
|
||||
end
|
||||
end
|
||||
generated_piece = new_piece
|
||||
|
||||
for piece,drought in pairs(self.drought) do
|
||||
if new_piece ~= piece then self.drought[piece] = self.drought[piece] + 1
|
||||
else
|
||||
if drought < #self.droughted_deals then self.droughted_deals[drought+1] = self.droughted_deals[drought+1] + 1 end
|
||||
self.piece_counts[piece] = self.piece_counts[piece] + 1
|
||||
self.drought[piece] = 0
|
||||
end
|
||||
end
|
||||
self.piece_round = self.piece_round + 1
|
||||
|
||||
return generated_piece
|
||||
end
|
||||
|
||||
return Randomizer
|
||||
299
game/rotation.lua
Normal file
299
game/rotation.lua
Normal file
@@ -0,0 +1,299 @@
|
||||
local Object = require 'libs.classic'
|
||||
local Piece = require 'game.piece'
|
||||
|
||||
local Rotation = Object:extend()
|
||||
|
||||
Rotation.spawn_positions = {
|
||||
I = { x=3, y= -1 },
|
||||
J = { x=3, y= -1 },
|
||||
L = { x=3, y= -1 },
|
||||
O = { x=3, y= -1 },
|
||||
S = { x=3, y= -1 },
|
||||
T = { x=3, y= -1 },
|
||||
Z = { x=3, y= -1 },
|
||||
}
|
||||
|
||||
Rotation.colourscheme = {
|
||||
I = "R",
|
||||
L = "O",
|
||||
J = "B",
|
||||
S = "M",
|
||||
Z = "G",
|
||||
O = "Y",
|
||||
T = "C",
|
||||
}
|
||||
|
||||
Rotation.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=2, y=1}, {x=3, y=1} },
|
||||
{ {x=2, y=0}, {x=2, y=1}, {x=2, y=2}, {x=2, y=3} },
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=2, y=1}, {x=3, y=1} },
|
||||
{ {x=2, y=0}, {x=2, y=1}, {x=2, y=2}, {x=2, y=3} },
|
||||
},
|
||||
J={
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=2, y=1}, {x=2, y=2} },
|
||||
{ {x=1, y=0}, {x=1, y=1}, {x=1, y=2}, {x=0, y=2} },
|
||||
{ {x=0, y=1}, {x=0, y=2}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=1, y=0}, {x=2, y=0}, {x=1, y=1}, {x=1, y=2} },
|
||||
},
|
||||
L={
|
||||
{ {x=0, y=1}, {x=0, y=2}, {x=1, y=1}, {x=2, y=1} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=1, y=1}, {x=1, y=2} },
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=2, y=1}, {x=2, y=2} },
|
||||
{ {x=1, y=0}, {x=1, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
},
|
||||
O={
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
},
|
||||
S={
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=0, y=2}, {x=1, y=2} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=1, y=1}, {x=1, y=2} },
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=0, y=2}, {x=1, y=2} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=1, y=1}, {x=1, y=2} },
|
||||
},
|
||||
T={
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=1, y=2}, {x=2, y=1} },
|
||||
{ {x=0, y=1}, {x=1, y=0}, {x=1, y=1}, {x=1, y=2} },
|
||||
{ {x=0, y=2}, {x=1, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=1, y=0}, {x=1, y=1}, {x=2, y=1}, {x=1, y=2} },
|
||||
},
|
||||
Z={
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=2, y=0}, {x=1, y=1}, {x=2, y=1}, {x=1, y=2} },
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=1, y=2}, {x=2, y=2} },
|
||||
{ {x=2, y=0}, {x=1, y=1}, {x=2, y=1}, {x=1, y=2} },
|
||||
}
|
||||
}
|
||||
|
||||
Rotation.pieces = 7
|
||||
|
||||
-- Component functions.
|
||||
|
||||
function Rotation:new(game_mode)
|
||||
self.game = require 'game.gamemode'
|
||||
end
|
||||
|
||||
function Rotation:rotatePiece(inputs, piece, grid, prev_inputs, initial, lastdir)
|
||||
local new_inputs = {}
|
||||
|
||||
for input, value in pairs(inputs) do
|
||||
if value and not prev_inputs[input] then
|
||||
new_inputs[input] = true
|
||||
end
|
||||
end
|
||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||
|
||||
if self:canPieceRotate(piece, grid) then
|
||||
-- if not self.held_rotate then
|
||||
-- self:attemptRotate(inputs, piece, grid, initial)
|
||||
-- self.held_rotate = true
|
||||
-- else
|
||||
self:attemptRotate(new_inputs, piece, grid, initial, lastdir)
|
||||
-- end
|
||||
end
|
||||
|
||||
if not initial and not was_drop_blocked and piece:isDropBlocked(grid) then
|
||||
playSE("bottom")
|
||||
end
|
||||
|
||||
-- prev_inputs becomes the previous inputs
|
||||
for input, value in pairs(inputs) do
|
||||
prev_inputs[input] = inputs[input]
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:attemptRotate(new_inputs, piece, grid, initial, lastdir)
|
||||
local rot_dir = 0
|
||||
|
||||
if (new_inputs["rotate_left"] or new_inputs["rotate_left2"]) then
|
||||
rot_dir = 3
|
||||
if lastdir == 0 then lastdir = -1 end
|
||||
elseif (new_inputs["rotate_right"] or new_inputs["rotate_right2"]) then
|
||||
rot_dir = 1
|
||||
if lastdir == 0 then lastdir = 1 end
|
||||
end
|
||||
if rot_dir == 0 then return end
|
||||
|
||||
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||
self:attemptWallkicks(piece, new_piece, rot_dir, grid, lastdir)
|
||||
end
|
||||
|
||||
function Rotation:attemptWallkicks(piece, new_piece, rot_dir, grid, lastdir)
|
||||
-- wallkick routine designed to maximize flexibility while minimizing teleports
|
||||
|
||||
-- O doesn't kick
|
||||
if (piece.shape == "O") then return end
|
||||
|
||||
-- assess precisely what rows/columns would be blocked given the desired rotation
|
||||
local sides = {top=false,uright=false,lright=false,uleft=false,lleft=false,center=false,bottom=false}
|
||||
local left_exists = false
|
||||
local right_exists = false
|
||||
local kick = {x=0,y=0}
|
||||
for _,offset in pairs(new_piece:getBlockOffsets()) do
|
||||
local x = piece.position.x + offset.x
|
||||
local y = piece.position.y + offset.y
|
||||
if offset.x == 0 then left_exists = true end
|
||||
if offset.x == 2 or offset.x == 3 then right_exists = true end
|
||||
|
||||
if grid:isOccupied(x,y) then
|
||||
if offset.y == 0 then sides.top = true end
|
||||
if offset.y == 3 then sides.bottom = true end
|
||||
if offset.y == 1 and offset.x == 0 then sides.uleft = true end
|
||||
if offset.y == 2 and offset.x == 0 then sides.lleft = true end
|
||||
if offset.y == 1 and (offset.x == 2 or offset.x == 3) then sides.uright = true end
|
||||
if offset.y == 2 and (offset.x == 2 or offset.x == 3) then sides.lright = true end
|
||||
if offset.x == 1 then sides.center = true end
|
||||
end
|
||||
end
|
||||
|
||||
if sides.top then kick = {x=0,y=1}
|
||||
elseif (sides.uleft and sides.lright) or (sides.uright and sides.lleft) or (sides.uright and sides.uleft) then kick = {x=0,y=1}
|
||||
elseif (sides.lleft and sides.lright) then kick = {x=0,y=-1}
|
||||
elseif (sides.lleft or sides.uleft) then kick = {x=1,y=0}
|
||||
elseif (sides.lright or sides.uright) then kick = {x=-1,y=0}
|
||||
elseif sides.center and left_exists then kick = {x=1,y=0}
|
||||
elseif sides.center and right_exists then kick = {x=-1,y=0}
|
||||
elseif sides.bottom then kick = {x=0,y=-1}
|
||||
end
|
||||
|
||||
|
||||
if grid:canPlacePiece(new_piece:withOffset({x=0,y=0})) then
|
||||
self:onPieceRotate(piece, grid)
|
||||
piece:setRelativeRotation(rot_dir):setOffset({x=0,y=0})
|
||||
elseif grid:canPlacePiece(new_piece:withOffset(kick)) then
|
||||
self:onPieceRotate(piece, grid)
|
||||
piece:setRelativeRotation(rot_dir):setOffset(kick)
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:movePiece(piece, grid, move, instant)
|
||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||
local offset = ({x=0, y=0})
|
||||
local moves = 0
|
||||
local y = piece.position.y
|
||||
if move == "left" then
|
||||
offset.x = -1
|
||||
moves = 1
|
||||
elseif move == "right" then
|
||||
offset.x = 1
|
||||
moves = 1
|
||||
elseif move == "speedleft" then
|
||||
offset.x = -1
|
||||
moves = grid.width
|
||||
elseif move == "speedright" then
|
||||
offset.x = 1
|
||||
moves = grid.width
|
||||
end
|
||||
if not self:canPieceMove(piece, grid) then return end
|
||||
for i = 1, moves do
|
||||
local x = piece.position.x
|
||||
if moves ~= 1 then
|
||||
piece:moveInGrid(offset, 1, grid, instant)
|
||||
else
|
||||
piece:moveInGrid(offset, 1, grid, false)
|
||||
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
|
||||
|
||||
function Rotation:dropPiece(
|
||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock
|
||||
)
|
||||
local y = piece.position.y
|
||||
if inputs["down"] == true and drop_locked == false then
|
||||
piece:addGravity(math.max(gravity, drop_speed), grid, classic_lock)
|
||||
else
|
||||
piece:addGravity(gravity, grid, classic_lock)
|
||||
end
|
||||
if piece.position.y ~= y then
|
||||
self:onPieceDrop(piece, grid)
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||
if piece:isDropBlocked(grid) and piece.lock_delay >= lock_delay then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:get180RotationValue() return 3 end
|
||||
function Rotation:getDefaultOrientation() return 1 end
|
||||
function Rotation:getDrawOffset(shape, orientation) return { x=0, y=0 } end
|
||||
function Rotation:getAboveFieldOffset(shape, orientation)
|
||||
if shape == "I" then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:initializePiece(
|
||||
inputs, data, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked, big, irs, lastdir
|
||||
)
|
||||
local spawn_positions
|
||||
spawn_positions = self.spawn_positions
|
||||
|
||||
local colours
|
||||
colours = self.colourscheme
|
||||
self.last_dir = 0
|
||||
self.held_rotate = false
|
||||
if inputs['left'] then self.last_dir = -1
|
||||
elseif inputs['right'] then self.last_dir = 1 end
|
||||
local spawn_x = math.floor(spawn_positions[data.shape].x / 10 * grid.width)
|
||||
|
||||
local spawn_dy
|
||||
spawn_dy = 0
|
||||
|
||||
local piece = Piece(data.shape, data.orientation - 1, {
|
||||
x = spawn_x or spawn_positions[data.shape].x,
|
||||
y = spawn_positions[data.shape].y - spawn_dy
|
||||
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
|
||||
|
||||
self:onPieceCreate(piece)
|
||||
if irs then
|
||||
self:rotatePiece(inputs, piece, grid, {}, true, lastdir)
|
||||
end
|
||||
return piece
|
||||
end
|
||||
|
||||
function Rotation:onPieceCreate(piece) end
|
||||
|
||||
function Rotation:processPiece(
|
||||
inputs, piece, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock, lastdir
|
||||
)
|
||||
self:rotatePiece(inputs, piece, grid, prev_inputs, false, lastdir)
|
||||
self:movePiece(piece, grid, move, gravity >= grid.height)
|
||||
self:dropPiece(
|
||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock
|
||||
)
|
||||
self:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||
end
|
||||
|
||||
function Rotation:canPieceMove(piece, grid) return true end
|
||||
function Rotation:canPieceRotate(piece, grid) return true end
|
||||
function Rotation:onPieceMove(piece) end
|
||||
function Rotation:onPieceRotate(piece) end
|
||||
function Rotation:onPieceDrop(piece)
|
||||
if piece.position.y > piece.lowest_point then
|
||||
piece.lock_delay = 0
|
||||
piece.lowest_point = piece.position.y
|
||||
end
|
||||
end
|
||||
|
||||
return Rotation
|
||||
287
game/rotation_pent.lua
Normal file
287
game/rotation_pent.lua
Normal file
@@ -0,0 +1,287 @@
|
||||
local Object = require 'libs.classic'
|
||||
local Piece = require 'game.piece'
|
||||
|
||||
local Rotation = Object:extend()
|
||||
|
||||
Rotation.spawn_positions = {
|
||||
I = { x=3, y= -2 },
|
||||
J = { x=3, y= -2 },
|
||||
L = { x=3, y= -2 },
|
||||
O = { x=3, y= -2 },
|
||||
S = { x=3, y= -2 },
|
||||
T = { x=3, y= -2 },
|
||||
Z = { x=3, y= -2 },
|
||||
}
|
||||
|
||||
Rotation.colourscheme = {
|
||||
I = "R",
|
||||
L = "O",
|
||||
J = "B",
|
||||
S = "M",
|
||||
Z = "G",
|
||||
O = "Y",
|
||||
T = "C",
|
||||
}
|
||||
|
||||
Rotation.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=2, y=2}, {x=3, y=2}, {x=4, y=2} },
|
||||
{ {x=2, y=0}, {x=2, y=1}, {x=2, y=2}, {x=2, y=3}, {x=2, y=4} },
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=2, y=2}, {x=3, y=2}, {x=4, y=2} },
|
||||
{ {x=2, y=0}, {x=2, y=1}, {x=2, y=2}, {x=2, y=3}, {x=2, y=4} },
|
||||
},
|
||||
J={
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=2, y=2}, {x=2, y=3}, {x=3, y=2} },
|
||||
{ {x=1, y=0}, {x=1, y=1}, {x=1, y=2}, {x=0, y=2}, {x=1, y=3} },
|
||||
{ {x=1, y=2}, {x=1, y=3}, {x=2, y=3}, {x=3, y=3}, {x=0, y=3} },
|
||||
{ {x=1, y=1}, {x=2, y=1}, {x=1, y=2}, {x=1, y=3}, {x=1, y=0} },
|
||||
},
|
||||
L={
|
||||
{ {x=0, y=2}, {x=0, y=3}, {x=1, y=2}, {x=2, y=2}, {x=3, y=2} },
|
||||
{ {x=0, y=0}, {x=1, y=0}, {x=1, y=1}, {x=1, y=2}, {x=1, y=3} },
|
||||
{ {x=1, y=3}, {x=2, y=3}, {x=3, y=2}, {x=3, y=3}, {x=0, y=3} },
|
||||
{ {x=1, y=1}, {x=1, y=2}, {x=1, y=3}, {x=2, y=3}, {x=1, y=0} },
|
||||
},
|
||||
O={
|
||||
{ {x=0, y=2}, {x=0, y=3}, {x=1, y=2}, {x=2, y=2}, {x=1, y=3} },
|
||||
{ {x=0, y=1}, {x=1, y=1}, {x=1, y=2}, {x=1, y=3}, {x=0, y=2} },
|
||||
{ {x=0, y=3}, {x=1, y=3}, {x=2, y=2}, {x=2, y=3}, {x=1, y=2} },
|
||||
{ {x=1, y=1}, {x=1, y=2}, {x=1, y=3}, {x=2, y=3}, {x=2, y=2} },
|
||||
},
|
||||
S={
|
||||
{ {x=1, y=2}, {x=2, y=2}, {x=0, y=3}, {x=1, y=3}, {x=3, y=2} },
|
||||
{ {x=0, y=0}, {x=0, y=1}, {x=1, y=1}, {x=1, y=2}, {x=1, y=3} },
|
||||
{ {x=2, y=2}, {x=3, y=2}, {x=1, y=3}, {x=2, y=3}, {x=0, y=3} },
|
||||
{ {x=1, y=1}, {x=1, y=2}, {x=2, y=2}, {x=2, y=3}, {x=1, y=0} },
|
||||
},
|
||||
T={
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=1, y=3}, {x=2, y=2}, {x=3, y=2} },
|
||||
{ {x=0, y=1}, {x=1, y=0}, {x=1, y=1}, {x=1, y=2}, {x=1, y=3} },
|
||||
{ {x=1, y=3}, {x=2, y=2}, {x=2, y=3}, {x=3, y=3}, {x=0, y=3} },
|
||||
{ {x=2, y=1}, {x=2, y=2}, {x=3, y=2}, {x=2, y=3}, {x=2, y=0} },
|
||||
},
|
||||
Z={
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=1, y=3}, {x=2, y=3}, {x=2, y=2} },
|
||||
{ {x=1, y=1}, {x=0, y=2}, {x=1, y=2}, {x=0, y=3}, {x=1, y=3} },
|
||||
{ {x=0, y=2}, {x=1, y=2}, {x=1, y=3}, {x=2, y=3}, {x=0, y=3} },
|
||||
{ {x=2, y=1}, {x=1, y=2}, {x=2, y=2}, {x=1, y=3}, {x=1, y=1} },
|
||||
}
|
||||
}
|
||||
|
||||
Rotation.pieces = 7
|
||||
|
||||
-- Component functions.
|
||||
|
||||
function Rotation:new(game_mode)
|
||||
self.game = require 'game.gamemode'
|
||||
end
|
||||
|
||||
function Rotation:rotatePiece(inputs, piece, grid, prev_inputs, initial, lastdir)
|
||||
local new_inputs = {}
|
||||
|
||||
for input, value in pairs(inputs) do
|
||||
if value and not prev_inputs[input] then
|
||||
new_inputs[input] = true
|
||||
end
|
||||
end
|
||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||
|
||||
if self:canPieceRotate(piece, grid) then
|
||||
-- if not self.held_rotate then
|
||||
-- self:attemptRotate(inputs, piece, grid, initial)
|
||||
-- self.held_rotate = true
|
||||
-- else
|
||||
self:attemptRotate(new_inputs, piece, grid, initial, lastdir)
|
||||
-- end
|
||||
end
|
||||
|
||||
if not initial and not was_drop_blocked and piece:isDropBlocked(grid) then
|
||||
playSE("bottom")
|
||||
end
|
||||
|
||||
-- prev_inputs becomes the previous inputs
|
||||
for input, value in pairs(inputs) do
|
||||
prev_inputs[input] = inputs[input]
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:attemptRotate(new_inputs, piece, grid, initial, lastdir)
|
||||
local rot_dir = 0
|
||||
|
||||
if (new_inputs["rotate_left"] or new_inputs["rotate_left2"]) then
|
||||
rot_dir = 3
|
||||
if lastdir == 0 then lastdir = -1 end
|
||||
elseif (new_inputs["rotate_right"] or new_inputs["rotate_right2"]) then
|
||||
rot_dir = 1
|
||||
if lastdir == 0 then lastdir = 1 end
|
||||
end
|
||||
if rot_dir == 0 then return end
|
||||
|
||||
local new_piece = piece:withRelativeRotation(rot_dir)
|
||||
self:attemptWallkicks(piece, new_piece, rot_dir, grid, lastdir)
|
||||
end
|
||||
|
||||
function Rotation:attemptWallkicks(piece, new_piece, rot_dir, grid, lastdir)
|
||||
-- assess precisely what rows/columns would be blocked given the desired rotation
|
||||
local sides = {top=false,uright=false,lright=false,uleft=false,lleft=false,center=false,bottom=false}
|
||||
local left_exists = false
|
||||
local right_exists = false
|
||||
local kick = {x=0,y=0}
|
||||
for _,offset in pairs(new_piece:getBlockOffsets()) do
|
||||
local x = piece.position.x + offset.x
|
||||
local y = piece.position.y + offset.y
|
||||
|
||||
if grid:isOccupied(x,y) then
|
||||
if offset.y <= 1 then sides.top = true end
|
||||
if offset.y == 4 then sides.bottom = true end
|
||||
if offset.x <= 1 then sides.lleft = true end
|
||||
if offset.x >= 2 then sides.lright = true end
|
||||
end
|
||||
end
|
||||
|
||||
if sides.top then kick = {x=0,y=1}
|
||||
elseif sides.bottom then kick = {x=0,y=-1}
|
||||
elseif (sides.lleft or sides.uleft) then kick = {x=1,y=0}
|
||||
elseif (sides.lright or sides.uright) then kick = {x=-1,y=0}
|
||||
end
|
||||
|
||||
if grid:canPlacePiece(new_piece:withOffset({x=0,y=0})) then
|
||||
self:onPieceRotate(piece, grid)
|
||||
piece:setRelativeRotation(rot_dir):setOffset({x=0,y=0})
|
||||
elseif grid:canPlacePiece(new_piece:withOffset(kick)) then
|
||||
self:onPieceRotate(piece, grid)
|
||||
piece:setRelativeRotation(rot_dir):setOffset(kick)
|
||||
elseif grid:canPlacePiece(new_piece:withOffset({x=kick.x*2,y=kick.y*2})) then
|
||||
self:onPieceRotate(piece, grid)
|
||||
piece:setRelativeRotation(rot_dir):setOffset({x=kick.x*2,y=kick.y*2})
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:movePiece(piece, grid, move, instant)
|
||||
local was_drop_blocked = piece:isDropBlocked(grid)
|
||||
local offset = ({x=0, y=0})
|
||||
local moves = 0
|
||||
local y = piece.position.y
|
||||
if move == "left" then
|
||||
offset.x = -1
|
||||
moves = 1
|
||||
elseif move == "right" then
|
||||
offset.x = 1
|
||||
moves = 1
|
||||
elseif move == "speedleft" then
|
||||
offset.x = -1
|
||||
moves = grid.width
|
||||
elseif move == "speedright" then
|
||||
offset.x = 1
|
||||
moves = grid.width
|
||||
end
|
||||
if not self:canPieceMove(piece, grid) then return end
|
||||
for i = 1, moves do
|
||||
local x = piece.position.x
|
||||
if moves ~= 1 then
|
||||
piece:moveInGrid(offset, 1, grid, instant)
|
||||
else
|
||||
piece:moveInGrid(offset, 1, grid, false)
|
||||
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
|
||||
|
||||
function Rotation:dropPiece(
|
||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock
|
||||
)
|
||||
local y = piece.position.y
|
||||
if inputs["down"] == true and drop_locked == false then
|
||||
piece:addGravity(math.max(gravity, drop_speed), grid, classic_lock)
|
||||
else
|
||||
piece:addGravity(gravity, grid, classic_lock)
|
||||
end
|
||||
if piece.position.y ~= y then
|
||||
self:onPieceDrop(piece, grid)
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||
if piece:isDropBlocked(grid) and piece.lock_delay >= lock_delay then
|
||||
piece.locked = true
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:get180RotationValue() return 3 end
|
||||
function Rotation:getDefaultOrientation() return 1 end
|
||||
function Rotation:getDrawOffset(shape, orientation) return { x=0, y=0 } end
|
||||
function Rotation:getAboveFieldOffset(shape, orientation)
|
||||
if shape == "I" then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
|
||||
function Rotation:initializePiece(
|
||||
inputs, data, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked, big, irs, lastdir
|
||||
)
|
||||
local spawn_positions
|
||||
spawn_positions = self.spawn_positions
|
||||
|
||||
local colours
|
||||
colours = self.colourscheme
|
||||
self.last_dir = 0
|
||||
self.held_rotate = false
|
||||
if inputs['left'] then self.last_dir = -1
|
||||
elseif inputs['right'] then self.last_dir = 1 end
|
||||
local spawn_x = math.floor(spawn_positions[data.shape].x / 10 * grid.width)
|
||||
|
||||
local spawn_dy
|
||||
spawn_dy = 0
|
||||
|
||||
local piece = Piece(data.shape, data.orientation - 1, {
|
||||
x = spawn_x or spawn_positions[data.shape].x,
|
||||
y = spawn_positions[data.shape].y - spawn_dy
|
||||
}, self.block_offsets, 0, 0, data.skin, colours[data.shape], big)
|
||||
|
||||
self:onPieceCreate(piece)
|
||||
if irs then
|
||||
self:rotatePiece(inputs, piece, grid, {}, true, lastdir)
|
||||
end
|
||||
return piece
|
||||
end
|
||||
|
||||
function Rotation:onPieceCreate(piece) end
|
||||
|
||||
function Rotation:processPiece(
|
||||
inputs, piece, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock, lastdir
|
||||
)
|
||||
self:rotatePiece(inputs, piece, grid, prev_inputs, false, lastdir)
|
||||
self:movePiece(piece, grid, move, gravity >= grid.height)
|
||||
self:dropPiece(
|
||||
inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked,
|
||||
hard_drop_enabled, additive_gravity, classic_lock
|
||||
)
|
||||
self:lockPiece(piece, grid, lock_delay, classic_lock)
|
||||
end
|
||||
|
||||
function Rotation:canPieceMove(piece, grid) return true end
|
||||
function Rotation:canPieceRotate(piece, grid) return true end
|
||||
function Rotation:onPieceMove(piece) end
|
||||
function Rotation:onPieceRotate(piece) end
|
||||
function Rotation:onPieceDrop(piece)
|
||||
if piece.position.y > piece.lowest_point then
|
||||
piece.lock_delay = 0
|
||||
piece.lowest_point = piece.position.y
|
||||
end
|
||||
end
|
||||
|
||||
return Rotation
|
||||
Reference in New Issue
Block a user