use macros::named_list_chunk;
use crate::prelude::*;
use crate::util::init::vec_with_capacity;
use crate::wad::deserialize::reader::DataReader;
use crate::wad::elements::GMElement;
use crate::wad::elements::game_object;
use crate::wad::serialize::builder::DataBuilder;
#[named_list_chunk("TMLN")]
pub struct GMTimelines {
pub timelines: Vec<GMTimeline>,
pub exists: bool,
}
impl GMElement for GMTimelines {
fn deserialize(reader: &mut DataReader) -> Result<Self> {
let timelines: Vec<GMTimeline> = reader.read_pointer_list()?;
Ok(Self { timelines, exists: true })
}
fn serialize(&self, builder: &mut DataBuilder) -> Result<()> {
builder.write_pointer_list(&self.timelines)?;
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GMTimeline {
pub name: String,
pub moments: Vec<Moment>,
}
impl GMElement for GMTimeline {
fn deserialize(reader: &mut DataReader) -> Result<Self> {
let name: String = reader.read_gm_string()?;
let moment_count = reader.read_u32()?;
let mut time_points: Vec<u32> = vec_with_capacity(moment_count)?;
let mut event_pointers: Vec<u32> = vec_with_capacity(moment_count)?;
for _ in 0..moment_count {
time_points.push(reader.read_u32()?);
event_pointers.push(reader.read_u32()?);
}
let mut moments: Vec<Moment> = vec_with_capacity(moment_count)?;
for (i, time_point) in time_points.into_iter().enumerate() {
reader.assert_pos(event_pointers[i], "Timeline Event")?;
let actions = reader.read_pointer_list()?;
moments.push(Moment { time_point, actions });
}
Ok(Self { name, moments })
}
fn serialize(&self, builder: &mut DataBuilder) -> Result<()> {
builder.write_gm_string(&self.name);
builder.write_usize(self.moments.len())?;
for moment in &self.moments {
builder.write_u32(moment.time_point);
builder.write_pointer(&moment.actions);
}
for moment in &self.moments {
builder.resolve_pointer(&moment.actions)?;
builder.write_pointer_list(&moment.actions)?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Moment {
pub time_point: u32,
pub actions: Vec<game_object::event::Action>,
}