Skip to content

Commit

Permalink
Added Cassette Block, Playback Billboard and Star Jump Block entities
Browse files Browse the repository at this point in the history
  • Loading branch information
Cruor committed Sep 8, 2021
1 parent d9bbfca commit 9c3bc06
Show file tree
Hide file tree
Showing 4 changed files with 500 additions and 1 deletion.
152 changes: 152 additions & 0 deletions src/entities/cassette_block.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
local fakeTilesHelper = require("fake_tiles_helper")
local utils = require("utils")
local matrixLib = require("matrix")
local drawableSprite = require("structs.drawable_sprite")
local connectedEntities = require("helpers.connected_entities")

local cassetteBlock = {}

local colors = {
{73 / 255, 170 / 255, 240 / 255},
{240 / 255, 73 / 255, 190 / 255},
{252 / 255, 220 / 255, 58 / 255},
{56 / 255, 224 / 255, 78 / 255},
}

local frames = {
"objects/cassetteblock/solid",
"objects/cassetteblock/solid",
"objects/cassetteblock/solid",
"objects/cassetteblock/solid"
}

local depths = {
-10,
-10,
-10,
-10
}

cassetteBlock.name = "cassetteBlock"
cassetteBlock.minimumSize = {16, 16}
cassetteBlock.placements = {}

for i, _ in ipairs(colors) do
cassetteBlock.placements[i] = {
name = string.format("cassette_block_%s", i - 1),
data = {
index = i - 1,
tempo = 1.0,
width = 8,
height = 8
}
}
end

-- Filter by cassette blocks sharing the same index
local function getSearchPredicate(entity)
return function(target)
return entity._name == target._name and entity.index == target.index
end
end

local function getTileSprite(entity, x, y, frame, color, depth, rectangles)
local hasAdjacent = connectedEntities.hasAdjacent

local drawX, drawY = (x - 1) * 8, (y - 1) * 8

local closedLeft = hasAdjacent(entity, drawX - 8, drawY, rectangles)
local closedRight = hasAdjacent(entity, drawX + 8, drawY, rectangles)
local closedUp = hasAdjacent(entity, drawX, drawY - 8, rectangles)
local closedDown = hasAdjacent(entity, drawX, drawY + 8, rectangles)
local completelyClosed = closedLeft and closedRight and closedUp and closedDown

local quadX, quadY = false, false

if completelyClosed then
if not hasAdjacent(entity, drawX + 8, drawY - 8, rectangles) then
quadX, quadY = 24, 0

elseif not hasAdjacent(entity, drawX - 8, drawY - 8, rectangles) then
quadX, quadY = 24, 8

elseif not hasAdjacent(entity, drawX + 8, drawY + 8, rectangles) then
quadX, quadY = 24, 16

elseif not hasAdjacent(entity, drawX - 8, drawY + 8, rectangles) then
quadX, quadY = 24, 24

else
quadX, quadY = 8, 8
end
else
if closedLeft and closedRight and not closedUp and closedDown then
quadX, quadY = 8, 0

elseif closedLeft and closedRight and closedUp and not closedDown then
quadX, quadY = 8, 16

elseif closedLeft and not closedRight and closedUp and closedDown then
quadX, quadY = 16, 8

elseif not closedLeft and closedRight and closedUp and closedDown then
quadX, quadY = 0, 8

elseif closedLeft and not closedRight and not closedUp and closedDown then
quadX, quadY = 16, 0

elseif not closedLeft and closedRight and not closedUp and closedDown then
quadX, quadY = 0, 0

elseif not closedLeft and closedRight and closedUp and not closedDown then
quadX, quadY = 0, 16

elseif closedLeft and not closedRight and closedUp and not closedDown then
quadX, quadY = 16, 16
end
end

if quadX and quadY then
local sprite = drawableSprite.fromTexture(frame, entity)

sprite:addPosition(drawX, drawY)
sprite:useRelativeQuad(quadX, quadY, 8, 8)
sprite:setColor(color)

sprite.depth = depth

return sprite
end
end

function cassetteBlock.sprite(room, entity)
local relevantBlocks = utils.filter(getSearchPredicate(entity), room.entities)

connectedEntities.appendIfMissing(relevantBlocks, entity)

local rectangles = connectedEntities.getEntityRectangles(relevantBlocks)

local sprites = {}

local width, height = entity.width or 32, entity.height or 32
local tileWidth, tileHeight = math.ceil(width / 8), math.ceil(height / 8)

local index = entity.index or 0
local color = colors[index + 1] or colors[1]
local frame = frames[index + 1] or frames[1]
local depth = depths[index + 1] or depths[1]

for x = 1, tileWidth do
for y = 1, tileHeight do
local sprite = getTileSprite(entity, x, y, frame, color, depth, rectangles)

if sprite then
table.insert(sprites, sprite)
end
end
end

return sprites
end

return cassetteBlock
131 changes: 131 additions & 0 deletions src/entities/playback_billboard.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
local utils = require("utils")
local drawableSprite = require("structs.drawable_sprite")
local drawableRectangle = require("structs.drawable_rectangle")
local connectedEntities = require("helpers.connected_entities")

local playbackBillboard = {}

playbackBillboard.name = "playbackBillboard"
playbackBillboard.depth = 9010
playbackBillboard.minimumSize = {8, 8}
playbackBillboard.placements = {
name = "playback_billboard",
data = {
width = 8,
height = 8
}
}

local fillColor = {0.17, 0.14, 0.33}
local borderTexture = "scenery/tvSlices"

local function getSearchPredicate(entity)
return function(target)
return entity._name == target._name
end
end

local function empty(entity, x, y, rectangles)
return not connectedEntities.hasAdjacent(entity, x * 8, y * 8, rectangles)
end

local function getTileSprite(entity, x, y, texture, rectangles)
if empty(entity, x, y, rectangles) then
local quadX, quadY = false, false

local centerLeft = not empty(entity, x - 1, y, rectangles)
local centerRight = not empty(entity, x + 1, y, rectangles)
local topCenter = not empty(entity, x, y - 1, rectangles)
local bottomCenter = not empty(entity, x, y + 1, rectangles)
local topLeft = not empty(entity, x - 1, y - 1, rectangles)
local topRight = not empty(entity, x + 1, y - 1, rectangles)
local bottomLeft = not empty(entity, x - 1, y + 1, rectangles)
local bottomRight = not empty(entity, x + 1, y + 1, rectangles)

if not centerRight and not bottomCenter and bottomRight then
quadX, quadY = 0, 0

elseif not centerLeft and not bottomCenter and bottomLeft then
quadX, quadY = 16, 0

elseif not topCenter and not centerRight and topRight then
quadX, quadY = 0, 16

elseif not topCenter and not centerLeft and topLeft then
quadX, quadY = 16, 16

elseif centerRight and bottomCenter then
quadX, quadY = 24, 0

elseif centerLeft and bottomCenter then
quadX, quadY = 32, 0

elseif centerRight and topCenter then
quadX, quadY = 24, 16

elseif centerLeft and topCenter then
quadX, quadY = 32, 16

elseif bottomCenter then
quadX, quadY = 8, 0

elseif centerRight then
quadX, quadY = 0, 8

elseif centerLeft then
quadX, quadY = 16, 8

elseif topCenter then
quadX, quadY = 8, 16
end

if quadX and quadY then
local sprite = drawableSprite.fromTexture(texture, entity)

sprite:addPosition(x * 8, y * 8)
sprite:useRelativeQuad(quadX, quadY, 8, 8, nil, true)

return sprite
end
end
end

local function addTileSprite(sprites, entity, x, y, texture, rectangles)
local sprite = getTileSprite(entity, x, y, texture, rectangles)

if sprite then
table.insert(sprites, sprite)
end
end

function playbackBillboard.sprite(room, entity)
local relevantBlocks = utils.filter(getSearchPredicate(entity), room.entities)

connectedEntities.appendIfMissing(relevantBlocks, entity)

local rectangles = connectedEntities.getEntityRectangles(relevantBlocks)

local sprites = {}

local x, y = entity.x or 0, entity.y or 0
local width, height = entity.width or 32, entity.height or 32
local tileWidth, tileHeight = math.ceil(width / 8), math.ceil(height / 8)

local backgroundRectangle = drawableRectangle.fromRectangle("fill", x, y, width, height, fillColor)

table.insert(sprites, backgroundRectangle:getDrawableSprite())

for i = -1, tileWidth do
addTileSprite(sprites, entity, i, -1, borderTexture, rectangles)
addTileSprite(sprites, entity, i, tileHeight, borderTexture, rectangles)
end

for j = 0, tileHeight - 1 do
addTileSprite(sprites, entity, -1, j, borderTexture, rectangles)
addTileSprite(sprites, entity, tileWidth, j, borderTexture, rectangles)
end

return sprites
end

return playbackBillboard
Loading

0 comments on commit 9c3bc06

Please sign in to comment.