use crate::vpx::biff::{self, BiffRead, BiffReader, BiffWrite};
use super::{dragpoint::DragPoint, vertex2d::Vertex2D, TRIGGER_SHAPE_WIRE_A};
#[derive(Debug, PartialEq)]
pub struct Trigger {
pub center: Vertex2D,
pub radius: f32,
pub rotation: f32,
pub wire_thickness: f32,
pub scale_x: f32,
pub scale_y: f32,
pub is_timer_enabled: bool,
pub timer_interval: i32,
pub material: String,
pub surface: String,
pub is_visible: bool,
pub is_enabled: bool,
pub hit_height: f32,
pub name: String,
pub shape: u32,
pub anim_speed: f32,
pub is_reflection_enabled: bool,
pub is_locked: bool,
pub editor_layer: u32,
pub editor_layer_name: Option<String>, pub editor_layer_visibility: Option<bool>,
drag_points: Vec<DragPoint>,
}
impl BiffRead for Trigger {
fn biff_read(reader: &mut BiffReader<'_>) -> Trigger {
let mut center: Vertex2D = Default::default();
let mut radius: f32 = 25.0;
let mut rotation: f32 = Default::default();
let mut wire_thickness: f32 = Default::default();
let mut scale_x: f32 = Default::default();
let mut scale_y: f32 = Default::default();
let mut is_timer_enabled: bool = false;
let mut timer_interval: i32 = Default::default();
let mut material: String = Default::default();
let mut surface: String = Default::default();
let mut is_visible: bool = true;
let mut is_enabled: bool = true;
let mut hit_height: f32 = 50.0;
let mut name = Default::default();
let mut shape: u32 = TRIGGER_SHAPE_WIRE_A;
let mut anim_speed: f32 = Default::default();
let mut is_reflection_enabled: bool = true;
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 drag_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 {
"VCEN" => {
center = Vertex2D::biff_read(reader);
}
"RADI" => {
radius = reader.get_f32();
}
"ROTA" => {
rotation = reader.get_f32();
}
"WITI" => {
wire_thickness = reader.get_f32();
}
"SCAX" => {
scale_x = reader.get_f32();
}
"SCAY" => {
scale_y = reader.get_f32();
}
"TMON" => {
is_timer_enabled = reader.get_bool();
}
"TMIN" => {
timer_interval = reader.get_i32();
}
"MATR" => {
material = reader.get_string();
}
"SURF" => {
surface = reader.get_string();
}
"VSBL" => {
is_visible = reader.get_bool();
}
"EBLD" => {
is_enabled = reader.get_bool();
}
"THOT" => {
hit_height = reader.get_f32();
}
"NAME" => {
name = reader.get_wide_string();
}
"SHAP" => {
shape = reader.get_u32();
}
"ANSP" => {
anim_speed = reader.get_f32();
}
"REEN" => {
is_reflection_enabled = 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());
}
"DPNT" => {
let point = DragPoint::biff_read(reader);
drag_points.push(point);
}
_ => {
println!(
"Unknown tag {} for {}",
tag_str,
std::any::type_name::<Self>()
);
reader.skip_tag();
}
}
}
Trigger {
center,
radius,
rotation,
wire_thickness,
scale_x,
scale_y,
is_timer_enabled,
timer_interval,
material,
surface,
is_visible,
is_enabled,
hit_height,
name,
shape,
anim_speed,
is_reflection_enabled,
is_locked,
editor_layer,
editor_layer_name,
editor_layer_visibility,
drag_points,
}
}
}
impl BiffWrite for Trigger {
fn biff_write(&self, writer: &mut biff::BiffWriter) {
writer.write_tagged("VCEN", &self.center);
writer.write_tagged_f32("RADI", self.radius);
writer.write_tagged_f32("ROTA", self.rotation);
writer.write_tagged_f32("WITI", self.wire_thickness);
writer.write_tagged_f32("SCAX", self.scale_x);
writer.write_tagged_f32("SCAY", self.scale_y);
writer.write_tagged_bool("TMON", self.is_timer_enabled);
writer.write_tagged_i32("TMIN", self.timer_interval);
writer.write_tagged_string("SURF", &self.surface);
writer.write_tagged_string("MATR", &self.material);
writer.write_tagged_bool("EBLD", self.is_enabled);
writer.write_tagged_bool("VSBL", self.is_visible);
writer.write_tagged_f32("THOT", self.hit_height);
writer.write_tagged_wide_string("NAME", &self.name);
writer.write_tagged_u32("SHAP", self.shape);
writer.write_tagged_f32("ANSP", self.anim_speed);
writer.write_tagged_bool("REEN", self.is_reflection_enabled);
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);
}
for point in &self.drag_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;
#[test]
fn test_write_read() {
let trigger = Trigger {
center: Vertex2D::new(1.0, 2.0),
radius: 25.0,
rotation: 3.0,
wire_thickness: 4.0,
scale_x: 5.0,
scale_y: 6.0,
is_timer_enabled: true,
timer_interval: 7,
material: "test material".to_string(),
surface: "test surface".to_string(),
is_visible: false,
is_enabled: false,
hit_height: 8.0,
name: "test name".to_string(),
shape: 9,
anim_speed: 10.0,
is_reflection_enabled: false,
is_locked: true,
editor_layer: 11,
editor_layer_name: Some("test layer name".to_string()),
editor_layer_visibility: Some(false),
drag_points: vec![DragPoint::default()],
};
let mut writer = BiffWriter::new();
Trigger::biff_write(&trigger, &mut writer);
let trigger_read = Trigger::biff_read(&mut BiffReader::new(writer.get_data()));
assert_eq!(trigger, trigger_read);
}
}