use crate::vpx::biff::{self, BiffRead, BiffReader, BiffWrite};
use super::dragpoint::DragPoint;
#[derive(Debug, PartialEq)]
pub struct Rubber {
pub height: f32,
pub hit_height: Option<f32>, pub thickness: i32,
pub hit_event: bool,
pub material: String,
pub is_timer_enabled: bool,
pub timer_interval: i32,
pub name: String,
pub image: String,
pub elasticity: f32,
pub elasticity_falloff: f32,
pub friction: f32,
pub scatter: f32,
pub is_collidable: bool,
pub is_visible: bool,
pub static_rendering: bool,
pub show_in_editor: bool,
pub rot_x: f32,
pub rot_y: f32,
pub rot_z: f32,
pub is_reflection_enabled: bool,
pub physics_material: Option<String>, pub overwrite_physics: Option<bool>,
pub is_locked: bool,
pub editor_layer: u32,
pub editor_layer_name: Option<String>, pub editor_layer_visibility: Option<bool>,
points: Vec<DragPoint>,
}
impl BiffRead for Rubber {
fn biff_read(reader: &mut BiffReader<'_>) -> Self {
let mut height: f32 = 25.0;
let mut hit_height: Option<f32> = None; let mut thickness: i32 = 8;
let mut hit_event: bool = false;
let mut material: String = Default::default();
let mut is_timer_enabled: bool = false;
let mut timer_interval: i32 = Default::default();
let mut name: String = Default::default();
let mut image: String = Default::default();
let mut elasticity: f32 = Default::default();
let mut elasticity_falloff: f32 = Default::default();
let mut friction: f32 = Default::default();
let mut scatter: f32 = Default::default();
let mut is_collidable: bool = true;
let mut is_visible: bool = true;
let mut static_rendering: bool = true;
let mut show_in_editor: bool = true;
let mut rot_x: f32 = 0.0;
let mut rot_y: f32 = 0.0;
let mut rot_z: f32 = 0.0;
let mut is_reflection_enabled: bool = true;
let mut physics_material: Option<String> = None;
let mut overwrite_physics: Option<bool> = None;
let mut is_locked: bool = false;
let mut editor_layer: u32 = Default::default();
let mut editor_layer_name: Option<String> = None;
let mut editor_layer_visibility: Option<bool> = None;
let mut points: Vec<DragPoint> = Default::default();
loop {
reader.next(biff::WARN);
if reader.is_eof() {
break;
}
let tag = reader.tag();
let tag_str = tag.as_str();
match tag_str {
"HTTP" => {
height = reader.get_f32();
}
"HTHI" => {
hit_height = Some(reader.get_f32());
}
"WDTP" => {
thickness = reader.get_i32();
}
"HTEV" => {
hit_event = reader.get_bool();
}
"MATR" => {
material = reader.get_string();
}
"TMON" => {
is_timer_enabled = reader.get_bool();
}
"TMIN" => {
timer_interval = reader.get_i32();
}
"NAME" => {
name = reader.get_wide_string();
}
"IMAG" => {
image = reader.get_string();
}
"ELAS" => {
elasticity = reader.get_f32();
}
"ELFO" => {
elasticity_falloff = reader.get_f32();
}
"RFCT" => {
friction = reader.get_f32();
}
"RSCT" => {
scatter = reader.get_f32();
}
"CLDR" => {
is_collidable = reader.get_bool();
}
"RVIS" => {
is_visible = reader.get_bool();
}
"ESTR" => {
static_rendering = reader.get_bool();
}
"ESIE" => {
show_in_editor = reader.get_bool();
}
"ROTX" => {
rot_x = reader.get_f32();
}
"ROTY" => {
rot_y = reader.get_f32();
}
"ROTZ" => {
rot_z = reader.get_f32();
}
"REEN" => {
is_reflection_enabled = reader.get_bool();
}
"MAPH" => {
physics_material = Some(reader.get_string());
}
"OVPH" => {
overwrite_physics = Some(reader.get_bool());
}
"LOCK" => {
is_locked = reader.get_bool();
}
"LAYR" => {
editor_layer = reader.get_u32();
}
"LANR" => {
editor_layer_name = Some(reader.get_string());
}
"LVIS" => {
editor_layer_visibility = Some(reader.get_bool());
}
"PNTS" => {
}
"DPNT" => {
let point = DragPoint::biff_read(reader);
points.push(point);
}
_ => {
println!(
"Unknown tag {} for {}",
tag_str,
std::any::type_name::<Self>()
);
reader.skip_tag();
}
}
}
Rubber {
height,
hit_height,
thickness,
hit_event,
material,
is_timer_enabled,
timer_interval,
name,
image,
elasticity,
elasticity_falloff,
friction,
scatter,
is_collidable,
is_visible,
static_rendering,
show_in_editor,
rot_x,
rot_y,
rot_z,
is_reflection_enabled,
physics_material,
overwrite_physics,
is_locked,
editor_layer,
editor_layer_name,
editor_layer_visibility,
points,
}
}
}
impl BiffWrite for Rubber {
fn biff_write(&self, writer: &mut biff::BiffWriter) {
writer.write_tagged_f32("HTTP", self.height);
if let Some(hthi) = self.hit_height {
writer.write_tagged_f32("HTHI", hthi);
}
writer.write_tagged_i32("WDTP", self.thickness);
writer.write_tagged_bool("HTEV", self.hit_event);
writer.write_tagged_string("MATR", &self.material);
writer.write_tagged_bool("TMON", self.is_timer_enabled);
writer.write_tagged_i32("TMIN", self.timer_interval);
writer.write_tagged_wide_string("NAME", &self.name);
writer.write_tagged_string("IMAG", &self.image);
writer.write_tagged_f32("ELAS", self.elasticity);
writer.write_tagged_f32("ELFO", self.elasticity_falloff);
writer.write_tagged_f32("RFCT", self.friction);
writer.write_tagged_f32("RSCT", self.scatter);
writer.write_tagged_bool("CLDR", self.is_collidable);
writer.write_tagged_bool("RVIS", self.is_visible);
writer.write_tagged_bool("ESTR", self.static_rendering);
writer.write_tagged_bool("ESIE", self.show_in_editor);
writer.write_tagged_f32("ROTX", self.rot_x);
writer.write_tagged_f32("ROTY", self.rot_y);
writer.write_tagged_f32("ROTZ", self.rot_z);
writer.write_tagged_bool("REEN", self.is_reflection_enabled);
if let Some(physics_material) = &self.physics_material {
writer.write_tagged_string("MAPH", physics_material);
}
if let Some(overwrite_physics) = self.overwrite_physics {
writer.write_tagged_bool("OVPH", overwrite_physics);
}
writer.write_tagged_bool("LOCK", self.is_locked);
writer.write_tagged_u32("LAYR", self.editor_layer);
if let Some(editor_layer_name) = &self.editor_layer_name {
writer.write_tagged_string("LANR", editor_layer_name);
}
if let Some(editor_layer_visibility) = self.editor_layer_visibility {
writer.write_tagged_bool("LVIS", editor_layer_visibility);
}
writer.write_marker_tag("PNTS");
for point in &self.points {
writer.write_tagged("DPNT", point);
}
writer.close(true);
}
}
#[cfg(test)]
mod tests {
use crate::vpx::biff::BiffWriter;
use super::*;
use pretty_assertions::assert_eq;
use rand::Rng;
#[test]
fn test_write_read() {
let mut rng = rand::thread_rng();
let rubber: Rubber = Rubber {
height: 1.0,
hit_height: Some(2.0),
thickness: 3,
hit_event: rng.gen(),
material: "material".to_string(),
is_timer_enabled: rng.gen(),
timer_interval: 4,
name: "name".to_string(),
image: "image".to_string(),
elasticity: 5.0,
elasticity_falloff: 6.0,
friction: 7.0,
scatter: 8.0,
is_collidable: rng.gen(),
is_visible: rng.gen(),
static_rendering: rng.gen(),
show_in_editor: rng.gen(),
rot_x: 9.0,
rot_y: 10.0,
rot_z: 11.0,
is_reflection_enabled: rng.gen(),
physics_material: Some("physics_material".to_string()),
overwrite_physics: rng.gen(),
is_locked: rng.gen(),
editor_layer: 12,
editor_layer_name: Some("editor_layer_name".to_string()),
editor_layer_visibility: rng.gen(),
points: vec![DragPoint::default()],
};
let mut writer = BiffWriter::new();
Rubber::biff_write(&rubber, &mut writer);
let rubber_read = Rubber::biff_read(&mut BiffReader::new(writer.get_data()));
assert_eq!(rubber, rubber_read);
}
}