mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Implement Terrain:GetMaterialColor and Terrain:SetMaterialColor (#93)
This commit is contained in:
parent
603cc10b42
commit
bcfc7d2f55
7 changed files with 173 additions and 11 deletions
|
@ -108,6 +108,20 @@ impl LuaExportsTable<'_> for Color3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'lua> FromLua<'lua> for Color3 {
|
||||||
|
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
||||||
|
if let LuaValue::UserData(ud) = value {
|
||||||
|
Ok(*ud.borrow::<Color3>()?)
|
||||||
|
} else {
|
||||||
|
Err(LuaError::FromLuaConversionError {
|
||||||
|
from: value.type_name(),
|
||||||
|
to: "Color3",
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LuaUserData for Color3 {
|
impl LuaUserData for Color3 {
|
||||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("R", |_, this| Ok(this.r));
|
fields.add_field_method_get("R", |_, this| Ok(this.r));
|
||||||
|
@ -287,20 +301,12 @@ impl From<Color3> for DomColor3 {
|
||||||
|
|
||||||
impl From<DomColor3uint8> for Color3 {
|
impl From<DomColor3uint8> for Color3 {
|
||||||
fn from(v: DomColor3uint8) -> Self {
|
fn from(v: DomColor3uint8) -> Self {
|
||||||
Self {
|
Color3::from(DomColor3::from(v))
|
||||||
r: (v.r as f32) / 255f32,
|
|
||||||
g: (v.g as f32) / 255f32,
|
|
||||||
b: (v.b as f32) / 255f32,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color3> for DomColor3uint8 {
|
impl From<Color3> for DomColor3uint8 {
|
||||||
fn from(v: Color3) -> Self {
|
fn from(v: Color3) -> Self {
|
||||||
Self {
|
DomColor3uint8::from(DomColor3::from(v))
|
||||||
r: v.r.clamp(u8::MIN as f32, u8::MAX as f32) as u8,
|
|
||||||
g: v.g.clamp(u8::MIN as f32, u8::MAX as f32) as u8,
|
|
||||||
b: v.b.clamp(u8::MIN as f32, u8::MAX as f32) as u8,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,20 @@ impl LuaUserData for EnumItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'lua> FromLua<'lua> for EnumItem {
|
||||||
|
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
||||||
|
if let LuaValue::UserData(ud) = value {
|
||||||
|
Ok(ud.borrow::<EnumItem>()?.to_owned())
|
||||||
|
} else {
|
||||||
|
Err(LuaError::FromLuaConversionError {
|
||||||
|
from: value.type_name(),
|
||||||
|
to: "EnumItem",
|
||||||
|
message: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for EnumItem {
|
impl fmt::Display for EnumItem {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{}.{}", self.parent, self.name)
|
write!(f, "{}.{}", self.parent, self.name)
|
||||||
|
|
|
@ -20,6 +20,7 @@ use crate::{
|
||||||
|
|
||||||
pub(crate) mod base;
|
pub(crate) mod base;
|
||||||
pub(crate) mod data_model;
|
pub(crate) mod data_model;
|
||||||
|
pub(crate) mod terrain;
|
||||||
pub(crate) mod workspace;
|
pub(crate) mod workspace;
|
||||||
|
|
||||||
const PROPERTY_NAME_ATTRIBUTES: &str = "Attributes";
|
const PROPERTY_NAME_ATTRIBUTES: &str = "Attributes";
|
||||||
|
@ -729,6 +730,7 @@ impl LuaUserData for Instance {
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
base::add_methods(methods);
|
base::add_methods(methods);
|
||||||
data_model::add_methods(methods);
|
data_model::add_methods(methods);
|
||||||
|
terrain::add_methods(methods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
127
src/roblox/instance/terrain.rs
Normal file
127
src/roblox/instance/terrain.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
use mlua::prelude::*;
|
||||||
|
use rbx_dom_weak::types::{MaterialColors, TerrainMaterials, Variant};
|
||||||
|
|
||||||
|
use crate::roblox::{
|
||||||
|
datatypes::types::{Color3, EnumItem},
|
||||||
|
shared::classes::{add_class_restricted_method, add_class_restricted_method_mut},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::Instance;
|
||||||
|
|
||||||
|
pub const CLASS_NAME: &str = "Terrain";
|
||||||
|
|
||||||
|
fn material_from_name(material_name: &str) -> Option<TerrainMaterials> {
|
||||||
|
match material_name {
|
||||||
|
"Grass" => Some(TerrainMaterials::Grass),
|
||||||
|
"Slate" => Some(TerrainMaterials::Slate),
|
||||||
|
"Concrete" => Some(TerrainMaterials::Concrete),
|
||||||
|
"Brick" => Some(TerrainMaterials::Brick),
|
||||||
|
"Sand" => Some(TerrainMaterials::Sand),
|
||||||
|
"WoodPlanks" => Some(TerrainMaterials::WoodPlanks),
|
||||||
|
"Rock" => Some(TerrainMaterials::Rock),
|
||||||
|
"Glacier" => Some(TerrainMaterials::Glacier),
|
||||||
|
"Snow" => Some(TerrainMaterials::Snow),
|
||||||
|
"Sandstone" => Some(TerrainMaterials::Sandstone),
|
||||||
|
"Mud" => Some(TerrainMaterials::Mud),
|
||||||
|
"Basalt" => Some(TerrainMaterials::Basalt),
|
||||||
|
"Ground" => Some(TerrainMaterials::Ground),
|
||||||
|
"CrackedLava" => Some(TerrainMaterials::CrackedLava),
|
||||||
|
"Asphalt" => Some(TerrainMaterials::Asphalt),
|
||||||
|
"Cobblestone" => Some(TerrainMaterials::Cobblestone),
|
||||||
|
"Ice" => Some(TerrainMaterials::Ice),
|
||||||
|
"LeafyGrass" => Some(TerrainMaterials::LeafyGrass),
|
||||||
|
"Salt" => Some(TerrainMaterials::Salt),
|
||||||
|
"Limestone" => Some(TerrainMaterials::Limestone),
|
||||||
|
"Pavement" => Some(TerrainMaterials::Pavement),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(methods: &mut M) {
|
||||||
|
add_class_restricted_method(
|
||||||
|
methods,
|
||||||
|
CLASS_NAME,
|
||||||
|
"GetMaterialColor",
|
||||||
|
terrain_get_material_color,
|
||||||
|
);
|
||||||
|
|
||||||
|
add_class_restricted_method_mut(
|
||||||
|
methods,
|
||||||
|
CLASS_NAME,
|
||||||
|
"SetMaterialColor",
|
||||||
|
terrain_set_material_color,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_or_create_material_colors(instance: &Instance) -> MaterialColors {
|
||||||
|
if let Some(Variant::MaterialColors(material_colors)) = instance.get_property("MaterialColors")
|
||||||
|
{
|
||||||
|
material_colors
|
||||||
|
} else {
|
||||||
|
MaterialColors::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the color of the given terrain material.
|
||||||
|
|
||||||
|
### See Also
|
||||||
|
* [`GetMaterialColor`](https://create.roblox.com/docs/reference/engine/classes/Terrain#GetMaterialColor)
|
||||||
|
on the Roblox Developer Hub
|
||||||
|
*/
|
||||||
|
fn terrain_get_material_color(_: &Lua, this: &Instance, material: EnumItem) -> LuaResult<Color3> {
|
||||||
|
let material_colors = get_or_create_material_colors(this);
|
||||||
|
|
||||||
|
if &material.parent.desc.name != "Material" {
|
||||||
|
return Err(LuaError::RuntimeError(format!(
|
||||||
|
"Expected Enum.Material, got Enum.{}",
|
||||||
|
&material.parent.desc.name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(terrain_material) = material_from_name(&material.name) {
|
||||||
|
Ok(material_colors.get_color(terrain_material).into())
|
||||||
|
} else {
|
||||||
|
Err(LuaError::RuntimeError(format!(
|
||||||
|
"{} is not a valid Terrain material",
|
||||||
|
&material.name
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the color of the given terrain material.
|
||||||
|
|
||||||
|
### See Also
|
||||||
|
* [`SetMaterialColor`](https://create.roblox.com/docs/reference/engine/classes/Terrain#SetMaterialColor)
|
||||||
|
on the Roblox Developer Hub
|
||||||
|
*/
|
||||||
|
fn terrain_set_material_color(
|
||||||
|
_: &Lua,
|
||||||
|
this: &mut Instance,
|
||||||
|
args: (EnumItem, Color3),
|
||||||
|
) -> LuaResult<()> {
|
||||||
|
let mut material_colors = get_or_create_material_colors(this);
|
||||||
|
let material = args.0;
|
||||||
|
let color = args.1;
|
||||||
|
|
||||||
|
if &material.parent.desc.name != "Material" {
|
||||||
|
return Err(LuaError::RuntimeError(format!(
|
||||||
|
"Expected Enum.Material, got Enum.{}",
|
||||||
|
&material.parent.desc.name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let terrain_material = if let Some(terrain_material) = material_from_name(&material.name) {
|
||||||
|
terrain_material
|
||||||
|
} else {
|
||||||
|
return Err(LuaError::RuntimeError(format!(
|
||||||
|
"{} is not a valid Terrain material",
|
||||||
|
&material.name
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
material_colors.set_color(terrain_material, color.into());
|
||||||
|
this.set_property("MaterialColors", Variant::MaterialColors(material_colors));
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -71,7 +71,6 @@ pub(crate) fn add_class_restricted_method<'lua, M: LuaUserDataMethods<'lua, Inst
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) fn add_class_restricted_method_mut<
|
pub(crate) fn add_class_restricted_method_mut<
|
||||||
'lua,
|
'lua,
|
||||||
M: LuaUserDataMethods<'lua, Instance>,
|
M: LuaUserDataMethods<'lua, Instance>,
|
||||||
|
|
|
@ -146,6 +146,7 @@ create_tests! {
|
||||||
|
|
||||||
roblox_instance_classes_data_model: "roblox/instance/classes/DataModel",
|
roblox_instance_classes_data_model: "roblox/instance/classes/DataModel",
|
||||||
roblox_instance_classes_workspace: "roblox/instance/classes/Workspace",
|
roblox_instance_classes_workspace: "roblox/instance/classes/Workspace",
|
||||||
|
roblox_instance_classes_terrain: "roblox/instance/classes/Terrain",
|
||||||
|
|
||||||
roblox_instance_methods_clear_all_children: "roblox/instance/methods/ClearAllChildren",
|
roblox_instance_methods_clear_all_children: "roblox/instance/methods/ClearAllChildren",
|
||||||
roblox_instance_methods_clone: "roblox/instance/methods/Clone",
|
roblox_instance_methods_clone: "roblox/instance/methods/Clone",
|
||||||
|
|
13
tests/roblox/instance/classes/Terrain.luau
Normal file
13
tests/roblox/instance/classes/Terrain.luau
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
local roblox = require("@lune/roblox")
|
||||||
|
local Instance = roblox.Instance
|
||||||
|
local Color3 = roblox.Color3
|
||||||
|
local Enum = roblox.Enum
|
||||||
|
|
||||||
|
local game = Instance.new("DataModel")
|
||||||
|
local workspace = game:GetService("Workspace")
|
||||||
|
local terrain = (workspace :: any).Terrain
|
||||||
|
|
||||||
|
assert(terrain:GetMaterialColor(Enum.Material.Grass) == Color3.fromRGB(106, 127, 63))
|
||||||
|
|
||||||
|
terrain:SetMaterialColor(Enum.Material.Sand, Color3.new(1, 1, 1))
|
||||||
|
assert(terrain:GetMaterialColor(Enum.Material.Sand) == Color3.new(1, 1, 1))
|
Loading…
Reference in a new issue