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

This commit is contained in:
mykola2312 2023-09-04 13:02:32 +03:00
parent b01a11f9b9
commit 5f63a69c38
3 changed files with 30 additions and 21 deletions

View file

@ -5,7 +5,8 @@ use super::raw::Raw;
use super::stream::{ReadStream, WriteStream}; use super::stream::{ReadStream, WriteStream};
use anyhow::Result; use anyhow::Result;
const NO_FLAGS: u32 = 0; pub const NO_FLAGS: u32 = 0;
pub const NO_ESH: usize = 0xFFFF;
pub struct Entity { pub struct Entity {
pub flags: u32, pub flags: u32,
@ -33,7 +34,7 @@ impl DecoderCtx<&mut EntityList, &EntityList> for Entity {
EntityEncoding::World => { EntityEncoding::World => {
let flags = rd.read_u32()?; let flags = rd.read_u32()?;
let type_idx = rd.read_u16()? as usize; let type_idx = rd.read_u16()? as usize;
let esh: Option<ESH> = if type_idx != 0xFFFF { let esh: Option<ESH> = if type_idx != NO_ESH {
Some(rd.read(0)?) Some(rd.read(0)?)
} else { } else {
None None

View file

@ -1,12 +1,12 @@
use super::decoder::DecoderCtx; use super::decoder::{DecoderCtx, Decoder};
use super::entity::Entity; use super::entity::Entity;
use super::esh::ESH; use super::fstring::{FString, FStringEncoding};
use super::fstring::FString;
use super::raw::Raw; use super::raw::Raw;
use super::stream::{ReadStream, WriteStream}; use super::stream::{ReadStream, WriteStream};
use super::tag::{CTag, Tag}; use super::tag::{Tag, CTag};
use anyhow::anyhow; use std::path::Path;
use anyhow::Result; use anyhow::Result;
use anyhow::anyhow;
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
pub enum EntityEncoding { pub enum EntityEncoding {
@ -18,10 +18,6 @@ const DEFAULT_ENTITY_TAG: CTag<'static> = CTag {
name: "<entity>", name: "<entity>",
version: "2", version: "2",
}; };
const DEFAULT_ENTITYFILE_TAG: CTag<'static> = CTag {
name: "<entity_file>",
version: "3",
};
pub struct EntityList { pub struct EntityList {
encoding: EntityEncoding, encoding: EntityEncoding,
@ -59,13 +55,22 @@ impl EntityList {
&self.types[type_idx] &self.types[type_idx]
} }
pub fn convert(&mut self, new: EntityEncoding) { pub fn dump_to_entfile(&self, ent: &Entity, path: &Path) -> Result<()> {
use EntityEncoding as EE; let esh = match &ent.esh {
if self.encoding == EE::World && new == EE::File { Some(esh) => esh,
self.entity_tag = Some(DEFAULT_ENTITY_TAG.to_tag()); None => return Err(anyhow!("entity has no esh"))
} else if self.encoding == EE::File && new == EE::World { };
self.entity_file_tag = Some(DEFAULT_ENTITYFILE_TAG.to_tag());
} 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<EntityEncoding, EntityEncoding> for EntityList {
let mut first = true; let mut first = true;
while rd.offset() < size { while rd.offset() < size {
let tag: Tag = rd.read(0)?; let tag: Tag = rd.read(0)?;
if (first) { if first {
ent_list.entity_tag = Some(tag); ent_list.entity_tag = Some(tag);
first = false; first = false;
} }
@ -125,6 +130,9 @@ impl DecoderCtx<EntityEncoding, EntityEncoding> for EntityList {
match ctx { match ctx {
EntityEncoding::File => { EntityEncoding::File => {
for ent in self.ents.iter() { for ent in self.ents.iter() {
if ent.esh.is_none() {
continue;
}
wd.write(self.get_entity_tag())?; wd.write(self.get_entity_tag())?;
wd.write_opt(ent, &self)?; wd.write_opt(ent, &self)?;
} }

View file

@ -33,10 +33,10 @@ impl World {
const WORLD_HDR_LEN: usize = 0x13; const WORLD_HDR_LEN: usize = 0x13;
pub fn test(&mut self) -> Result<()> { pub fn test(&mut self) -> Result<()> {
self.entlist.convert(EntityEncoding::File); /*self.entlist.convert(EntityEncoding::File);
self.entlist self.entlist
.encode(EntityEncoding::File)? .encode(EntityEncoding::File)?
.dump(Path::new("entlist.ent"))?; .dump(Path::new("D:\\entlist.ent"))?;*/
Ok(()) Ok(())
} }