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:
parent
b01a11f9b9
commit
5f63a69c38
3 changed files with 30 additions and 21 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue