use crate::vpx::biff::{self, BiffRead, BiffReader, BiffWrite};
use super::vertex2d::Vertex2D;
#[derive(Debug, PartialEq)]
pub struct Plunger {
center: Vertex2D,
width: f32,
height: f32,
z_adjust: f32,
stroke: f32,
speed_pull: f32,
speed_fire: f32,
plunger_type: u32,
anim_frames: u32,
material: String,
image: String,
mech_strength: f32,
is_mech_plunger: bool,
auto_plunger: bool,
park_position: f32,
scatter_velocity: f32,
momentum_xfer: f32,
is_timer_enabled: bool,
timer_interval: u32,
is_visible: bool,
is_reflection_enabled: bool,
surface: String,
pub name: String,
tip_shape: String,
rod_diam: f32,
ring_gap: f32,
ring_diam: f32,
ring_width: f32,
spring_diam: f32,
spring_gauge: f32,
spring_loops: f32,
spring_end_loops: f32,
pub is_locked: bool,
pub editor_layer: u32,
pub editor_layer_name: Option<String>, pub editor_layer_visibility: Option<bool>,
}
impl Plunger {
pub const PLUNGER_TYPE_MODERN: u32 = 1;
pub const PLUNGER_TYPE_FLAT: u32 = 2;
pub const PLUNGER_TYPE_CUSTOM: u32 = 3;
}
impl BiffRead for Plunger {
fn biff_read(reader: &mut BiffReader<'_>) -> Self {
let mut center = Vertex2D::default();
let mut width: f32 = 25.0;
let mut height: f32 = 20.0;
let mut z_adjust: f32 = 0.0;
let mut stroke: f32 = 80.0;
let mut speed_pull: f32 = 0.5;
let mut speed_fire: f32 = 80.0;
let mut plunger_type: u32 = Self::PLUNGER_TYPE_MODERN;
let mut anim_frames: u32 = 1;
let mut material = String::default();
let mut image = String::default();
let mut mech_strength: f32 = 85.0;
let mut is_mech_plunger: bool = false;
let mut auto_plunger: bool = false;
let mut park_position: f32 = 0.5 / 3.0;
let mut scatter_velocity: f32 = 0.0;
let mut momentum_xfer: f32 = 1.0;
let mut is_timer_enabled: bool = false;
let mut timer_interval: u32 = 0;
let mut is_visible: bool = true;
let mut is_reflection_enabled: bool = true;
let mut surface = String::default();
let mut name = Default::default();
let mut tip_shape =
"0 .34; 2 .6; 3 .64; 5 .7; 7 .84; 8 .88; 9 .9; 11 .92; 14 .92; 39 .84".to_string();
let mut rod_diam: f32 = 0.6;
let mut ring_gap: f32 = 2.0;
let mut ring_diam: f32 = 0.94;
let mut ring_width: f32 = 3.0;
let mut spring_diam: f32 = 0.77;
let mut spring_gauge: f32 = 1.38;
let mut spring_loops: f32 = 8.0;
let mut spring_end_loops: f32 = 2.5;
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;
loop {
reader.next(biff::WARN);
if reader.is_eof() {
break;
}
let tag = reader.tag();
let tag_str = tag.as_str();
match tag_str {
"VCEN" => {
center = Vertex2D::biff_read(reader);
}
"WDTH" => {
width = reader.get_f32();
}
"HIGH" => {
height = reader.get_f32();
}
"ZADJ" => {
z_adjust = reader.get_f32();
}
"HPSL" => {
stroke = reader.get_f32();
}
"SPDP" => {
speed_pull = reader.get_f32();
}
"SPDF" => {
speed_fire = reader.get_f32();
}
"TYPE" => {
plunger_type = reader.get_u32();
}
"ANFR" => {
anim_frames = reader.get_u32();
}
"MATR" => {
material = reader.get_string();
}
"IMAG" => {
image = reader.get_string();
}
"MEST" => {
mech_strength = reader.get_f32();
}
"MECH" => {
is_mech_plunger = reader.get_bool();
}
"APLG" => {
auto_plunger = reader.get_bool();
}
"MPRK" => {
park_position = reader.get_f32();
}
"PSCV" => {
scatter_velocity = reader.get_f32();
}
"MOMX" => {
momentum_xfer = reader.get_f32();
}
"TMON" => {
is_timer_enabled = reader.get_bool();
}
"TMIN" => {
timer_interval = reader.get_u32();
}
"VSBL" => {
is_visible = reader.get_bool();
}
"REEN" => {
is_reflection_enabled = reader.get_bool();
}
"SURF" => {
surface = reader.get_string();
}
"NAME" => {
name = reader.get_wide_string();
}
"TIPS" => {
tip_shape = reader.get_string();
}
"RODD" => {
rod_diam = reader.get_f32();
}
"RNGG" => {
ring_gap = reader.get_f32();
}
"RNGD" => {
ring_diam = reader.get_f32();
}
"RNGW" => {
ring_width = reader.get_f32();
}
"SPRD" => {
spring_diam = reader.get_f32();
}
"SPRG" => {
spring_gauge = reader.get_f32();
}
"SPRL" => {
spring_loops = reader.get_f32();
}
"SPRE" => {
spring_end_loops = reader.get_f32();
}
"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());
}
_ => {
println!(
"Unknown tag {} for {}",
tag_str,
std::any::type_name::<Self>()
);
reader.skip_tag();
}
}
}
Self {
center,
width,
height,
z_adjust,
stroke,
speed_pull,
speed_fire,
plunger_type,
anim_frames,
material,
image,
mech_strength,
is_mech_plunger,
auto_plunger,
park_position,
scatter_velocity,
momentum_xfer,
is_timer_enabled,
timer_interval,
is_visible,
is_reflection_enabled,
surface,
name,
tip_shape,
rod_diam,
ring_gap,
ring_diam,
ring_width,
spring_diam,
spring_gauge,
spring_loops,
spring_end_loops,
is_locked,
editor_layer,
editor_layer_name,
editor_layer_visibility,
}
}
}
impl BiffWrite for Plunger {
fn biff_write(&self, writer: &mut biff::BiffWriter) {
writer.write_tagged("VCEN", &self.center);
writer.write_tagged_f32("WDTH", self.width);
writer.write_tagged_f32("HIGH", self.height);
writer.write_tagged_f32("ZADJ", self.z_adjust);
writer.write_tagged_f32("HPSL", self.stroke);
writer.write_tagged_f32("SPDP", self.speed_pull);
writer.write_tagged_f32("SPDF", self.speed_fire);
writer.write_tagged_u32("TYPE", self.plunger_type);
writer.write_tagged_u32("ANFR", self.anim_frames);
writer.write_tagged_string("MATR", &self.material);
writer.write_tagged_string("IMAG", &self.image);
writer.write_tagged_f32("MEST", self.mech_strength);
writer.write_tagged_bool("MECH", self.is_mech_plunger);
writer.write_tagged_bool("APLG", self.auto_plunger);
writer.write_tagged_f32("MPRK", self.park_position);
writer.write_tagged_f32("PSCV", self.scatter_velocity);
writer.write_tagged_f32("MOMX", self.momentum_xfer);
writer.write_tagged_bool("TMON", self.is_timer_enabled);
writer.write_tagged_u32("TMIN", self.timer_interval);
writer.write_tagged_bool("VSBL", self.is_visible);
writer.write_tagged_bool("REEN", self.is_reflection_enabled);
writer.write_tagged_string("SURF", &self.surface);
writer.write_tagged_wide_string("NAME", &self.name);
writer.write_tagged_string("TIPS", &self.tip_shape);
writer.write_tagged_f32("RODD", self.rod_diam);
writer.write_tagged_f32("RNGG", self.ring_gap);
writer.write_tagged_f32("RNGD", self.ring_diam);
writer.write_tagged_f32("RNGW", self.ring_width);
writer.write_tagged_f32("SPRD", self.spring_diam);
writer.write_tagged_f32("SPRG", self.spring_gauge);
writer.write_tagged_f32("SPRL", self.spring_loops);
writer.write_tagged_f32("SPRE", self.spring_end_loops);
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.close(true);
}
}
#[cfg(test)]
mod tests {
use crate::vpx::biff::BiffWriter;
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_write_read() {
let plunger = Plunger {
center: Vertex2D::new(1.0, 2.0),
width: 1.0,
height: 1.0,
z_adjust: 0.1,
stroke: 2.0,
speed_pull: 0.5,
speed_fire: 3.0,
plunger_type: Plunger::PLUNGER_TYPE_MODERN,
anim_frames: 1,
material: "test material".to_string(),
image: "test image".to_string(),
mech_strength: 85.0,
is_mech_plunger: false,
auto_plunger: false,
park_position: 0.5 / 3.0,
scatter_velocity: 0.0,
momentum_xfer: 1.0,
is_timer_enabled: false,
timer_interval: 0,
is_visible: true,
is_reflection_enabled: true,
surface: "test surface".to_string(),
name: "test plunger".to_string(),
tip_shape: "0 .34; 2 .6; 3 .64; 5 .7; 7 .84; 8 .88; 9 .9; 11 .92; 14 .92; 39 .83"
.to_string(),
rod_diam: 0.6,
ring_gap: 2.0,
ring_diam: 0.94,
ring_width: 3.0,
spring_diam: 0.77,
spring_gauge: 1.38,
spring_loops: 8.0,
spring_end_loops: 2.5,
is_locked: true,
editor_layer: 0,
editor_layer_name: Some("test layer".to_string()),
editor_layer_visibility: Some(false),
};
let mut writer = BiffWriter::new();
Plunger::biff_write(&plunger, &mut writer);
let plunger_read = Plunger::biff_read(&mut BiffReader::new(writer.get_data()));
assert_eq!(plunger, plunger_read);
}
}