Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions engine/core/level.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,12 @@ function Level:updateOpacityCache(x, y)
break
end

local currentValue = self.opacityCache:get(x, y)
opaque = opaque or self.map.opacityCache:get(x, y)
self.opacityCache:set(x, y, opaque)
self.systemManager:afterOpacityChanged(self, x, y)
if currentValue ~= opaque then
self.opacityCache:set(x, y, opaque)
self.systemManager:afterOpacityChanged(self, x, y)
end
end

--- Finds a path between two positions.
Expand Down Expand Up @@ -608,4 +611,11 @@ function Level:__finalize()
end
end

--- Returns the width and height of the level.
--- @return integer width
--- @return integer height
function Level:getSize()
return self.map.w, self.map.h
end

return Level
310 changes: 217 additions & 93 deletions engine/math/color.lua
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
local bit = require("bit")

--- A color with red, green, blue, and alpha components.
--- @class Color4 : Object
--- @field r number The red component (0-1).
--- @field g number The green component (0-1).
--- @field b number The blue component (0-1).
--- @field a number The alpha component (0-1).
--- @field r number The red component (01).
--- @field g number The green component (01).
--- @field b number The blue component (01).
--- @field a number The alpha component (01).
--- @overload fun(r?: number, g?: number, b?: number, a?: number): Color4
local Color4 = prism.Object:extend("Color4")

--- Constructor for Color4 accepts red, green, blue, and alpha values. All default to 0, alpha to 1.
--- @param r number The red component (0-1).
--- @param g number The green component (0-1).
--- @param b number The blue component (0-1).
--- @param a number The alpha component (0-1).
--- Creates a new Color4.
--- @param r number? Red component (0–1)
--- @param g number? Green component (0–1)
--- @param b number? Blue component (0–1)
--- @param a number? Alpha component (0–1), defaults to 1
function Color4:__new(r, g, b, a)
self.r = r or 0
self.g = g or 0
self.b = b or 0
self.a = a or 1 -- Default alpha to 1 (fully opaque)
self.a = a or 1
end

--- Constructor for Color4 that accepts a hexadecimal number.
--- @param hex number A hex number representing a color, e.g. 0xFFFFFF. Alpha is optional and defaults to 1.
--- Creates a Color4 from a hexadecimal color value.
--- Accepts RGB (0xRRGGBB) or RGBA (0xRRGGBBAA).
--- Allocates a new Color4.
--- @param hex number Hexadecimal color value
--- @return Color4
function Color4.fromHex(hex)
local hasAlpha = #string.format("%x", hex) > 6

Expand All @@ -32,109 +37,228 @@ function Color4.fromHex(hex)
return Color4(r, g, b, hasAlpha and a or 1)
end

--- Returns a copy of the color.
--- @param out Color4?
--- @return Color4 out A copy of the color.
function Color4:copy(out)
local out = out or Color4()
out:compose(self.r, self.g, self.b, self.a)
--- Copies a color.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4 Source color
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.copy(a, out)
out = out or Color4()
out.r, out.g, out.b, out.a = a.r, a.g, a.b, a.a
return out
end

--- Writes components directly into an existing color.
--- Does not allocate.
--- @param out Color4 Destination color
--- @param r number
--- @param g number
--- @param b number
--- @param a number
--- @return Color4 out
function Color4.compose(out, r, g, b, a)
out.r, out.g, out.b, out.a = r, g, b, a
return out
end

--- Adds two colors component-wise.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param b Color4
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.add(a, b, out)
out = out or Color4()
out.r = a.r + b.r
out.g = a.g + b.g
out.b = a.b + b.b
out.a = a.a + b.a
return out
end

--- Subtracts one color from another component-wise.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param b Color4
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.sub(a, b, out)
out = out or Color4()
out.r = a.r - b.r
out.g = a.g - b.g
out.b = a.b - b.b
out.a = a.a - b.a
return out
end

--- Multiplies a color by a scalar.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param s number Scalar value
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.mul(a, s, out)
out = out or Color4()
out.r = a.r * s
out.g = a.g * s
out.b = a.b * s
out.a = a.a * s
return out
end

--- Divides a color by a scalar.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param s number Scalar divisor
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.div(a, s, out)
out = out or Color4()
out.r = a.r / s
out.g = a.g / s
out.b = a.b / s
out.a = a.a / s
return out
end

--- Negates all components of a color.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.neg(a, out)
out = out or Color4()
out.r = -a.r
out.g = -a.g
out.b = -a.b
out.a = -a.a
return out
end

--- Linearly interpolates between two colors.
--- @param target Color4 The target color.
--- @param t number A value between 0 and 1, where 0 is this color and 1 is the target color.
--- @return Color4 The interpolated color.
function Color4:lerp(target, t)
return Color4(
self.r + (target.r - self.r) * t,
self.g + (target.g - self.g) * t,
self.b + (target.b - self.b) * t,
self.a + (target.a - self.a) * t
)
end

--- Multiplies the color's components by a scalar.
--- @param scalar number The scalar value.
--- @return Color4 The scaled color.
function Color4.__mul(self, scalar)
return Color4(self.r * scalar, self.g * scalar, self.b * scalar, self.a * scalar)
end

--- Adds two colors together.
--- @param a Color4 The first color.
--- @param b Color4 The second color.
--- @return Color4 The sum of the two colors.
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4 Start color
--- @param b Color4 End color
--- @param t number Interpolation factor (0–1)
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.lerp(a, b, t, out)
out = out or Color4()
out.r = a.r + (b.r - a.r) * t
out.g = a.g + (b.g - a.g) * t
out.b = a.b + (b.b - a.b) * t
out.a = a.a + (b.a - a.a) * t
return out
end

--- Clamps all components of a color to the range [0, 1].
--- Allocates a new Color4 if `out` is nil.
--- @param a Color4
--- @param out Color4? Optional output color
--- @return Color4 out
function Color4.clamp(a, out)
out = out or Color4()
out.r = math.min(1, math.max(0, a.r))
out.g = math.min(1, math.max(0, a.g))
out.b = math.min(1, math.max(0, a.b))
out.a = math.min(1, math.max(0, a.a))
return out
end

--- Adds two colors.
--- Always allocates a new Color4.
--- @param a Color4
--- @param b Color4
--- @return Color4
function Color4.__add(a, b)
return Color4(a.r + b.r, a.g + b.g, a.b + b.b, a.a + b.a)
return Color4.add(a, b)
end

--- Subtracts one color from another.
--- @param a Color4 The first color.
--- @param b Color4 The second color.
--- @return Color4 The difference of the two colors.
--- Subtracts two colors.
--- Always allocates a new Color4.
--- @param a Color4
--- @param b Color4
--- @return Color4
function Color4.__sub(a, b)
return Color4(a.r - b.r, a.g - b.g, a.b - b.b, a.a - b.a)
return Color4.sub(a, b)
end

--- Multiplies a color by a scalar.
--- Always allocates a new Color4.
--- @param a Color4
--- @param s number
--- @return Color4
function Color4.__mul(a, s)
return Color4.mul(a, s)
end

--- Negates the color's components.
--- @return Color4 The negated color.
function Color4.__unm(self)
return Color4(-self.r, -self.g, -self.b, -self.a)
--- Divides a color by a scalar.
--- Always allocates a new Color4.
--- @param a Color4
--- @param s number
--- @return Color4
function Color4.__div(a, s)
return Color4.div(a, s)
end

--- Checks equality between two colors.
--- @param a Color4 The first color.
--- @param b Color4 The second color.
--- @return boolean True if the colors are equal, false otherwise.
--- Negates a color.
--- Always allocates a new Color4.
--- @param a Color4
--- @return Color4
function Color4.__unm(a)
return Color4.neg(a)
end

--- Checks component-wise equality.
--- @param a Color4
--- @param b Color4
--- @return boolean
function Color4.__eq(a, b)
return a.r == b.r and a.g == b.g and a.b == b.b and a.a == b.a
end

--- Creates a string representation of the color.
--- @return string The string representation.
function Color4:__tostring()
return string.format("r: %.2f, g: %.2f, b: %.2f, a: %.2f", self.r, self.g, self.b, self.a)
--- Returns the average of the RGB components.
--- Does not allocate.
--- @return number
function Color4:average()
return (self.r + self.g + self.b) / 3
end

--- Returns the components of the color as numbers.
--- @return number r, number g, number b, number a The components of the color.
--- Returns the components as separate values.
--- Does not allocate.
--- @return number r
--- @return number g
--- @return number b
--- @return number a
function Color4:decompose()
return self.r, self.g, self.b, self.a
end

function Color4:compose(r, g, b, a)
self.r, self.g, self.b, self.a = r, g, b, a
end

--- Clamps the components of the color between 0 and 1.
--- @return Color4 The clamped color.
function Color4:clamp()
return Color4(
math.min(1, math.max(0, self.r)),
math.min(1, math.max(0, self.g)),
math.min(1, math.max(0, self.b)),
math.min(1, math.max(0, self.a))
)
end

--- PICO-8 palette
Color4.BLACK = Color4(0, 0, 0, 1)
Color4.WHITE = Color4.fromHex(0xFFF1E8)
Color4.RED = Color4.fromHex(0xFF004D)
Color4.GREEN = Color4.fromHex(0x008751)
Color4.LIME = Color4.fromHex(0x00E436)
Color4.BLUE = Color4.fromHex(0x29ADFF)
Color4.NAVY = Color4.fromHex(0x1D2B53)
Color4.PURPLE = Color4.fromHex(0x7E2553)
Color4.BROWN = Color4.fromHex(0xAB5236)
Color4.DARKGREY = Color4.fromHex(0x5F574F)
Color4.GREY = Color4.fromHex(0xC2C3C7)
Color4.YELLOW = Color4.fromHex(0xFFEC27)
Color4.ORANGE = Color4.fromHex(0xFFA300)
Color4.PINK = Color4.fromHex(0xFF77A8)
Color4.LAVENDER = Color4.fromHex(0x83769C)
Color4.PEACH = Color4.fromHex(0xFFCCAA)
--- Returns a human-readable string representation.
--- Does not allocate a Color4.
--- @return string
function Color4:__tostring()
return string.format("r: %.2f, g: %.2f, b: %.2f, a: %.2f", self.r, self.g, self.b, self.a)
end

-- stylua: ignore start
Color4.BLACK = Color4(0, 0, 0, 1)
Color4.WHITE = Color4.fromHex(0xFFF1E8)
Color4.RED = Color4.fromHex(0xFF004D)
Color4.GREEN = Color4.fromHex(0x008751)
Color4.LIME = Color4.fromHex(0x00E436)
Color4.BLUE = Color4.fromHex(0x29ADFF)
Color4.NAVY = Color4.fromHex(0x1D2B53)
Color4.PURPLE = Color4.fromHex(0x7E2553)
Color4.BROWN = Color4.fromHex(0xAB5236)
Color4.DARKGREY = Color4.fromHex(0x5F574F)
Color4.GREY = Color4.fromHex(0xC2C3C7)
Color4.YELLOW = Color4.fromHex(0xFFEC27)
Color4.ORANGE = Color4.fromHex(0xFFA300)
Color4.PINK = Color4.fromHex(0xFF77A8)
Color4.LAVENDER = Color4.fromHex(0x83769C)
Color4.PEACH = Color4.fromHex(0xFFCCAA)
Color4.TRANSPARENT = Color4(0, 0, 0, 0)
-- stylua: ignore end

return Color4
Loading