diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f12de9..e458eb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased Changes +* Add Color3.fromRGB(red, blue, green) ([#44](https://github.com/rojo-rbx/remodel/issues/44)) + ## 0.8.1 (2021-04-09) * Updated to latest rbx_xml, which should fix `OptionalCoordinateFrame`-related issues. diff --git a/src/roblox_api/mod.rs b/src/roblox_api/mod.rs index dd5798f..9aea770 100644 --- a/src/roblox_api/mod.rs +++ b/src/roblox_api/mod.rs @@ -5,7 +5,10 @@ use std::sync::Arc; use rbx_dom_weak::InstanceBuilder; use rlua::{Context, UserData, UserDataMethods}; -use crate::{remodel_context::RemodelContext, value::Vector3int16Value}; +use crate::{ + remodel_context::RemodelContext, + value::{Color3Value, Vector3int16Value}, +}; pub use instance::LuaInstance; @@ -15,6 +18,7 @@ impl RobloxApi { pub fn inject(context: Context<'_>) -> rlua::Result<()> { context.globals().set("Instance", Instance)?; context.globals().set("Vector3int16", Vector3int16)?; + context.globals().set("Color3", Color3)?; Ok(()) } @@ -58,3 +62,20 @@ impl UserData for Vector3int16 { }) } } + +struct Color3; + +impl UserData for Color3 { + fn add_methods<'lua, T: UserDataMethods<'lua, Self>>(methods: &mut T) { + methods.add_function("new", |_context, (x, y, z): (f32, f32, f32)| { + Ok(Color3Value::new(rbx_dom_weak::types::Color3::new(x, y, z))) + }); + methods.add_function("fromRGB", |_context, (x, y, z): (f32, f32, f32)| { + Ok(Color3Value::new(rbx_dom_weak::types::Color3::new( + x / 255.0, + y / 255.0, + z / 255.0, + ))) + }); + } +} diff --git a/src/value.rs b/src/value.rs index a4e94e4..0ed48c4 100644 --- a/src/value.rs +++ b/src/value.rs @@ -21,8 +21,8 @@ pub fn rbxvalue_to_lua<'lua>(context: Context<'lua>, value: &Variant) -> LuaResu Variant::BrickColor(_) => unimplemented_type("BrickColor"), Variant::Bool(value) => value.to_lua(context), Variant::CFrame(_) => unimplemented_type("CFrame"), - Variant::Color3(value) => Color3Value::new(value.clone()).to_lua(context), - Variant::Color3uint8(value) => Color3uint8Value::new(value.clone()).to_lua(context), + Variant::Color3(value) => Color3Value::new(*value).to_lua(context), + Variant::Color3uint8(value) => Color3uint8Value::new(*value).to_lua(context), Variant::ColorSequence(_) => unimplemented_type("ColorSequence"), Variant::Content(value) => AsRef::::as_ref(value).to_lua(context), Variant::Enum(_) => unimplemented_type("Enum"), @@ -43,7 +43,7 @@ pub fn rbxvalue_to_lua<'lua>(context: Context<'lua>, value: &Variant) -> LuaResu Variant::Vector2(_) => unimplemented_type("Vector2"), Variant::Vector2int16(_) => unimplemented_type("Vector2int16"), Variant::Vector3(_) => unimplemented_type("Vector3"), - Variant::Vector3int16(value) => Vector3int16Value::new(value.clone()).to_lua(context), + Variant::Vector3int16(value) => Vector3int16Value::new(*value).to_lua(context), _ => Err(rlua::Error::external(format!( "The type '{:?}' is unknown to Remodel, please file a bug!", @@ -138,7 +138,7 @@ pub fn type_from_str(name: &str) -> Option { } #[derive(Debug, Clone, Copy)] -struct Color3Value(Color3); +pub struct Color3Value(Color3); impl fmt::Display for Color3Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -157,9 +157,9 @@ impl Color3Value { key: &str, ) -> rlua::Result> { match key { - "r" => self.0.r.to_lua(context), - "g" => self.0.g.to_lua(context), - "b" => self.0.b.to_lua(context), + "r" | "R" => self.0.r.to_lua(context), + "g" | "G" => self.0.g.to_lua(context), + "b" | "B" => self.0.b.to_lua(context), _ => Err(rlua::Error::external(format!( "'{}' is not a valid member of Color3", key diff --git a/test-scripts/type-color3.lua b/test-scripts/type-color3.lua index 9bcb485..dec964c 100644 --- a/test-scripts/type-color3.lua +++ b/test-scripts/type-color3.lua @@ -1,12 +1,28 @@ -local value = remodel.readModelFile("test-models/color3value.rbxmx")[1] - -local color3 = remodel.getRawProperty(value, "Value") - local function round(number) local integral, fraction = math.modf(number) return integral + (fraction > 0.5 and 1 or 0) end -assert(round(color3.r * 255) == 255) -assert(round(color3.g * 255) == 186) -assert(round(color3.b * 255) == 65) +local function assertColor(color3Object, red, green, blue) + assert(round(color3Object.r * 255) == red) + assert(round(color3Object.R * 255) == red) + assert(round(color3Object.g * 255) == green) + assert(round(color3Object.G * 255) == green) + assert(round(color3Object.b * 255) == blue) + assert(round(color3Object.B * 255) == blue) +end + +local value = remodel.readModelFile("test-models/color3value.rbxmx")[1] +local color3 = remodel.getRawProperty(value, "Value") + +assertColor(color3, 255, 186, 65) + +local red = 45 +local green = 7 +local blue = 12 + +local newRGBColor = Color3.fromRGB(red, green, blue) +assertColor(newRGBColor, red, green, blue) + +local newColor = Color3.new(red / 255, green / 255, blue / 255) +assertColor(newColor, red, green, blue)