From 5f63a69c38d70f8f8dcf9ea1a2902c7eb63fb6b2 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:02:32 +0300 Subject: [PATCH] realized that ent file isn't list of entities, but a single entity, however it 100% compatible with entity_file block, so dump_to_entfile implemented to assist in reverse-engineering --- src/fot/entity.rs | 5 +++-- src/fot/entitylist.rs | 42 +++++++++++++++++++++++++----------------- src/fot/world.rs | 4 ++-- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/fot/entity.rs b/src/fot/entity.rs index 235c9e4..d2ae286 100644 --- a/src/fot/entity.rs +++ b/src/fot/entity.rs @@ -5,7 +5,8 @@ use super::raw::Raw; use super::stream::{ReadStream, WriteStream}; use anyhow::Result; -const NO_FLAGS: u32 = 0; +pub const NO_FLAGS: u32 = 0; +pub const NO_ESH: usize = 0xFFFF; pub struct Entity { pub flags: u32, @@ -33,7 +34,7 @@ impl DecoderCtx<&mut EntityList, &EntityList> for Entity { EntityEncoding::World => { let flags = rd.read_u32()?; let type_idx = rd.read_u16()? as usize; - let esh: Option = if type_idx != 0xFFFF { + let esh: Option = if type_idx != NO_ESH { Some(rd.read(0)?) } else { None diff --git a/src/fot/entitylist.rs b/src/fot/entitylist.rs index 46e5178..ac8f185 100644 --- a/src/fot/entitylist.rs +++ b/src/fot/entitylist.rs @@ -1,12 +1,12 @@ -use super::decoder::DecoderCtx; +use super::decoder::{DecoderCtx, Decoder}; use super::entity::Entity; -use super::esh::ESH; -use super::fstring::FString; +use super::fstring::{FString, FStringEncoding}; use super::raw::Raw; use super::stream::{ReadStream, WriteStream}; -use super::tag::{CTag, Tag}; -use anyhow::anyhow; +use super::tag::{Tag, CTag}; +use std::path::Path; use anyhow::Result; +use anyhow::anyhow; #[derive(Clone, Copy, PartialEq)] pub enum EntityEncoding { @@ -18,10 +18,6 @@ const DEFAULT_ENTITY_TAG: CTag<'static> = CTag { name: "", version: "2", }; -const DEFAULT_ENTITYFILE_TAG: CTag<'static> = CTag { - name: "", - version: "3", -}; pub struct EntityList { encoding: EntityEncoding, @@ -59,13 +55,22 @@ impl EntityList { &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()); - } else if self.encoding == EE::File && new == EE::World { - self.entity_file_tag = Some(DEFAULT_ENTITYFILE_TAG.to_tag()); - } + pub fn dump_to_entfile(&self, ent: &Entity, path: &Path) -> Result<()> { + let esh = match &ent.esh { + Some(esh) => esh, + None => return Err(anyhow!("entity has no esh")) + }; + + let tag = DEFAULT_ENTITY_TAG.to_tag(); + let mut type_name = self.get_type_name(ent.type_idx).clone(); + type_name.encoding = FStringEncoding::ANSI; + + let mut wd = WriteStream::new(tag.get_enc_size() + ent.get_enc_size()); + wd.write(&tag)?; + wd.write(esh)?; + + wd.into_raw(0, 0).dump(path)?; + Ok(()) } } @@ -87,7 +92,7 @@ impl DecoderCtx for EntityList { let mut first = true; while rd.offset() < size { let tag: Tag = rd.read(0)?; - if (first) { + if first { ent_list.entity_tag = Some(tag); first = false; } @@ -125,6 +130,9 @@ impl DecoderCtx for EntityList { match ctx { EntityEncoding::File => { for ent in self.ents.iter() { + if ent.esh.is_none() { + continue; + } wd.write(self.get_entity_tag())?; wd.write_opt(ent, &self)?; } diff --git a/src/fot/world.rs b/src/fot/world.rs index 4725ca5..8b7f011 100644 --- a/src/fot/world.rs +++ b/src/fot/world.rs @@ -33,10 +33,10 @@ impl World { const WORLD_HDR_LEN: usize = 0x13; pub fn test(&mut self) -> Result<()> { - self.entlist.convert(EntityEncoding::File); + /*self.entlist.convert(EntityEncoding::File); self.entlist .encode(EntityEncoding::File)? - .dump(Path::new("entlist.ent"))?; + .dump(Path::new("D:\\entlist.ent"))?;*/ Ok(()) }