diff --git a/packages/lib-roblox/src/datatypes/types/color3.rs b/packages/lib-roblox/src/datatypes/types/color3.rs index 00731d4..e558c96 100644 --- a/packages/lib-roblox/src/datatypes/types/color3.rs +++ b/packages/lib-roblox/src/datatypes/types/color3.rs @@ -132,24 +132,29 @@ impl LuaUserData for Color3 { let min = r.min(g).min(b); let max = r.max(g).max(b); let diff = max - min; - let hue = match max { + + let hue = (match max { max if max == min => 0.0, - max if max == this.r => (g - b) + diff * (if g < b { 6.0 } else { 0.0 }), - max if max == this.g => (b - r) + diff * 2.0, - max if max == this.b => (r - g) + diff * 4.0, + max if max == r => (g - b) / diff + (if g < b { 6.0 } else { 0.0 }), + max if max == g => (b - r) / diff + 2.0, + max if max == b => (r - g) / diff + 4.0, _ => unreachable!(), + }) / 6.0; + + let sat = if max == 0.0 { + 0.0 + } else { + (diff / max).clamp(0.0, 1.0) }; - let hue = hue / 6.0 * diff; - let sat = if max == 0.0 { 0.0 } else { diff / max }; - let sat = sat.clamp(0.0, 1.0); + Ok((hue, sat, max)) }); methods.add_method("ToHex", |_, this, ()| { Ok(format!( "{:02X}{:02X}{:02X}", - this.r.clamp(u8::MIN as f32, u8::MAX as f32) as u8, - this.g.clamp(u8::MIN as f32, u8::MAX as f32) as u8, - this.b.clamp(u8::MIN as f32, u8::MAX as f32) as u8, + (this.r * 255.0).clamp(u8::MIN as f32, u8::MAX as f32) as u8, + (this.g * 255.0).clamp(u8::MIN as f32, u8::MAX as f32) as u8, + (this.b * 255.0).clamp(u8::MIN as f32, u8::MAX as f32) as u8, )) }); // Metamethods diff --git a/packages/lib-roblox/src/tests.rs b/packages/lib-roblox/src/tests.rs index ab1b6d0..58796de 100644 --- a/packages/lib-roblox/src/tests.rs +++ b/packages/lib-roblox/src/tests.rs @@ -38,6 +38,8 @@ macro_rules! create_tests { } create_tests! { + datatypes_brick_color: "datatypes/BrickColor", + datatypes_color3: "datatypes/Color3", datatypes_udim: "datatypes/UDim", datatypes_udim2: "datatypes/UDim2", datatypes_vector2: "datatypes/Vector2", diff --git a/tests/roblox/datatypes/BrickColor.luau b/tests/roblox/datatypes/BrickColor.luau new file mode 100644 index 0000000..917601e --- /dev/null +++ b/tests/roblox/datatypes/BrickColor.luau @@ -0,0 +1,36 @@ +-- HACK: Make luau happy, with the mlua rust +-- crate all globals are also present in _G +local BrickColor = _G.BrickColor +local Color3 = _G.Color3 + +-- Constructors & properties + +BrickColor.new(1) +BrickColor.new("Medium stone grey") + +assert(not pcall(function() + return BrickColor.new(false) +end)) +assert(not pcall(function() + return BrickColor.new({}) +end)) +assert(not pcall(function() + return BrickColor.new(newproxy(true)) +end)) + +assert(BrickColor.new("Really red").R == 1) +assert(BrickColor.new("Really red").G == 0) +assert(BrickColor.new("Really red").B == 0) + +assert(BrickColor.new("Really red").Number == 1004) +assert(BrickColor.new("Really red").Name == "Really red") +assert(BrickColor.new("Really red").Color == Color3.new(1, 0, 0)) + +-- Ops + +assert(not pcall(function() + return BrickColor.new(1) + BrickColor.new(2) +end)) +assert(not pcall(function() + return BrickColor.new(1) / BrickColor.new(2) +end)) diff --git a/tests/roblox/datatypes/Color3.luau b/tests/roblox/datatypes/Color3.luau new file mode 100644 index 0000000..7d4c13c --- /dev/null +++ b/tests/roblox/datatypes/Color3.luau @@ -0,0 +1,61 @@ +-- HACK: Make luau happy, with the mlua rust +-- crate all globals are also present in _G +local Color3 = _G.Color3 + +-- Constructors & properties + +Color3.new() +Color3.new(0) +Color3.new(0, 0) +Color3.new(0, 0, 0) +Color3.new(0 / 0, 0 / 0) +Color3.new(0 / 0, 0 / 0, 0 / 0) + +assert(not pcall(function() + return Color3.new(false) +end)) +assert(not pcall(function() + return Color3.new("", "") +end)) +assert(not pcall(function() + return Color3.new(newproxy(true)) +end)) + +assert(Color3.new(0.25, 0.5, 1).R == 0.25) +assert(Color3.new(0.25, 0.5, 1).G == 0.5) +assert(Color3.new(0.25, 0.5, 1).B == 1) + +assert(Color3.fromRGB(0, 0, 0) == Color3.new(0, 0, 0)) +assert(Color3.fromRGB(255, 255, 255) == Color3.new(1, 1, 1)) + +assert(Color3.fromHex("00F") == Color3.new(0, 0, 1)) +assert(Color3.fromHex("0000FF") == Color3.new(0, 0, 1)) + +assert(Color3.fromHSV(0, 1, 1) == Color3.new(1, 0, 0)) +assert(Color3.fromHSV(0, 1, 0) == Color3.new(0, 0, 0)) +assert(Color3.fromHSV(0, 0, 1) == Color3.new(1, 1, 1)) + +-- Ops + +assert(Color3.new(0.25, 0.5, 1) + Color3.new(0.25, 0.25, 0.25) == Color3.new(0.5, 0.75, 1.25)) +assert(Color3.new(0.25, 0.5, 1) - Color3.new(0.25, 0.25, 0.25) == Color3.new(0, 0.25, 0.75)) +assert(Color3.new(0.25, 0.5, 1) * Color3.new(0.25, 0.25, 0.5) == Color3.new(0.0625, 0.125, 0.5)) +assert(Color3.new(0.25, 0.5, 1) / Color3.new(0.25, 0.25, 0.5) == Color3.new(1, 2, 2)) + +assert(Color3.new(0.25, 0.5, 1) * 2 == Color3.new(0.5, 1, 2)) +assert(Color3.new(0.25, 0.5, 1) / 2 == Color3.new(0.125, 0.25, 0.5)) + +-- Methods + +local h, s, v + +h, s, v = Color3.fromHSV(0, 0.25, 0.75):ToHSV() +assert(h == 0 and s == 0.25 and v == 0.75) + +h, s, v = Color3.fromHSV(0.5, 1, 0.125):ToHSV() +assert(h == 0.5 and s == 1 and v == 0.125) + +assert(Color3.fromHex("FFF"):ToHex() == "FFFFFF") +assert(Color3.fromHex("FA0"):ToHex() == "FFAA00") +assert(Color3.fromHex("FFFFFF"):ToHex() == "FFFFFF") +assert(Color3.fromHex("FFAA00"):ToHex() == "FFAA00")