diff --git a/src/fot/entity.rs b/src/fot/entity.rs index 40c34d9..235c9e4 100644 --- a/src/fot/entity.rs +++ b/src/fot/entity.rs @@ -62,7 +62,7 @@ impl DecoderCtx<&mut EntityList, &EntityList> for Entity { wd.write_u16(self.type_idx as u16)?; match self.esh.as_ref() { Some(esh) => wd.write(esh)?, - None => () + None => (), } } } diff --git a/src/fot/entitylist.rs b/src/fot/entitylist.rs index 3bc3794..8f00b10 100644 --- a/src/fot/entitylist.rs +++ b/src/fot/entitylist.rs @@ -4,16 +4,21 @@ use super::esh::ESH; use super::fstring::FString; use super::raw::Raw; use super::stream::{ReadStream, WriteStream}; -use super::tag::Tag; +use super::tag::{CTag, Tag}; use anyhow::anyhow; use anyhow::Result; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] pub enum EntityEncoding { File, World, } +const DEFAULT_ENTITY_TAG: CTag<'static> = CTag { + name: "", + version: "2", +}; + pub struct EntityList { encoding: EntityEncoding, entity_file_tag: Option, @@ -22,7 +27,7 @@ pub struct EntityList { enc_size: usize, pub types: Vec, - pub entities: Vec + pub entities: Vec, } impl EntityList { @@ -42,16 +47,23 @@ impl EntityList { pub fn add_or_get_type(&mut self, type_name: FString) -> usize { match self.types.iter().position(|f| f.eq(&type_name)) { Some(idx) => idx, - None => self.add_new_type(type_name) + None => self.add_new_type(type_name), } } pub fn get_type_name(&self, type_idx: usize) -> &FString { &self.types[type_idx] } + + pub fn convert(&mut self, new: EntityEncoding) { + use EntityEncoding as EE; + if self.encoding == EE::World && new == EE::File { + self.entity_tag = Some(DEFAULT_ENTITY_TAG.to_tag()); + } + } } -impl DecoderCtx for EntityList { +impl DecoderCtx for EntityList { fn decode(raw: &Raw, offset: usize, size: usize, ctx: EntityEncoding) -> Result { let mut rd = ReadStream::new(raw, offset); let mut ent_list = EntityList { @@ -61,7 +73,7 @@ impl DecoderCtx for EntityList { unk1: 0, enc_size: 0, types: Vec::new(), - entities: Vec::new() + entities: Vec::new(), }; Ok(match ctx { @@ -77,10 +89,10 @@ impl DecoderCtx for EntityList { let ent: Entity = rd.read_opt(0, &mut ent_list)?; ent_list.entities.push(ent); } - + ent_list.enc_size = rd.offset() - offset; ent_list - }, + } EntityEncoding::World => { ent_list.entity_file_tag = Some(rd.read(0)?); @@ -110,7 +122,7 @@ impl DecoderCtx for EntityList { wd.write(self.get_entity_tag())?; wd.write_opt(ent, &self)?; } - }, + } EntityEncoding::World => { wd.write(self.entity_file_tag.as_ref().unwrap())?; wd.write_u32(self.types.len() as u32)?; diff --git a/src/fot/stream.rs b/src/fot/stream.rs index 4064fac..07a9908 100644 --- a/src/fot/stream.rs +++ b/src/fot/stream.rs @@ -46,7 +46,11 @@ impl<'a> ReadStream<'a> { // read_opt - decode with optional paramters. required for complex structure // with different origins (save / entfile) like entities - pub fn read_opt, DCtx, ECtx>(&mut self, size: usize, ctx: DCtx) -> Result { + pub fn read_opt, DCtx, ECtx>( + &mut self, + size: usize, + ctx: DCtx, + ) -> Result { let val = T::decode(&self.raw, self.offset(), size, ctx)?; self.skip(val.get_enc_size()); Ok(val) @@ -112,7 +116,11 @@ impl WriteStream { self.buf.get_mut().extend(bytes.iter()); } - pub fn write_opt, DCtx, ECtx>(&mut self, val: &T, ctx: ECtx) -> Result<()> { + pub fn write_opt, DCtx, ECtx>( + &mut self, + val: &T, + ctx: ECtx, + ) -> Result<()> { let mut raw = val.encode(ctx)?; self.skip(raw.mem.len()); self.buf.get_mut().append(&mut raw.mem); diff --git a/src/fot/tag.rs b/src/fot/tag.rs index b21e66f..b939f68 100644 --- a/src/fot/tag.rs +++ b/src/fot/tag.rs @@ -28,3 +28,18 @@ impl Decoder for Tag { self.name.get_enc_size() + self.version.get_enc_size() } } + +// struct for Tag consts +pub struct CTag<'a> { + pub name: &'a str, + pub version: &'a str, +} + +impl<'a> CTag<'a> { + pub fn to_tag(&self) -> Tag { + Tag { + name: self.name.to_string(), + version: self.version.to_string(), + } + } +} diff --git a/src/fot/world.rs b/src/fot/world.rs index 6e0e705..1552d97 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -1,6 +1,6 @@ use super::decoder::{Decoder, DecoderCtx}; +use super::entitylist::{EntityEncoding, EntityList}; use super::fstring::FString; -use super::entitylist::{EntityList, EntityEncoding}; use super::raw::Raw; use super::sgd::SGD; use super::ssg::SSG; @@ -25,7 +25,7 @@ pub struct World { pub sgd: SGD, pub ssg: SSG, - pub ents: EntityList + pub ents: EntityList, } impl World { @@ -37,7 +37,7 @@ impl World { let raw1 = Raw { offset: 0, size: self.ents.get_enc_size(), - mem: self.data.mem[entfile_start..entfile_start+self.ents.get_enc_size()].to_vec() + mem: self.data.mem[entfile_start..entfile_start + self.ents.get_enc_size()].to_vec(), }; raw1.dump(Path::new("entfile1.bin"))?; @@ -79,7 +79,7 @@ impl Decoder for World { mission, sgd, ssg, - ents + ents, }) }