Skip to content

Commit

Permalink
Write operation implementation for weapon objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neloreck committed Feb 25, 2024
1 parent 62f0188 commit f8e94da
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 5 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
78 changes: 76 additions & 2 deletions crates/xray-db/src/data/alife/alife_object_inventory_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::data::alife::alife_object_inherited_reader::{
AlifeObjectGeneric, AlifeObjectInheritedReader,
};
use crate::data::alife::alife_object_visual::AlifeObjectVisual;
use byteorder::{ByteOrder, ReadBytesExt};
use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
use std::io;

#[derive(Clone, Debug, PartialEq)]
Expand All @@ -16,6 +16,7 @@ pub struct AlifeObjectInventoryBox {
}

impl AlifeObjectInheritedReader<AlifeObjectInventoryBox> for AlifeObjectInventoryBox {
/// Read inventory object data from the chunk.
fn read_from_chunk<T: ByteOrder>(chunk: &mut Chunk) -> io::Result<AlifeObjectInventoryBox> {
let base: AlifeObjectVisual = AlifeObjectVisual::read_from_chunk::<T>(chunk)?;

Expand All @@ -31,9 +32,82 @@ impl AlifeObjectInheritedReader<AlifeObjectInventoryBox> for AlifeObjectInventor
})
}

/// Write inventory object data into the writer.
fn write<T: ByteOrder>(&self, writer: &mut ChunkWriter) -> io::Result<()> {
todo!("Implement write operation");
self.base.write::<T>(writer)?;

writer.write_u8(self.can_take)?;
writer.write_u8(self.is_closed)?;
writer.write_null_terminated_string(&self.tip)?;

Ok(())
}
}

impl AlifeObjectGeneric for AlifeObjectInventoryBox {}

#[cfg(test)]
mod tests {
use crate::chunk::chunk::Chunk;
use crate::chunk::writer::ChunkWriter;
use crate::data::alife::alife_object_abstract::AlifeObjectAbstract;
use crate::data::alife::alife_object_inherited_reader::AlifeObjectInheritedReader;
use crate::data::alife::alife_object_inventory_box::AlifeObjectInventoryBox;
use crate::data::alife::alife_object_visual::AlifeObjectVisual;
use crate::test::utils::{
get_test_chunk_file_sub_dir, open_test_resource_as_slice, overwrite_test_resource_as_file,
};
use crate::types::SpawnByteOrder;
use fileslice::FileSlice;
use std::io;

#[test]
fn test_read_write_object() -> io::Result<()> {
let mut writer: ChunkWriter = ChunkWriter::new();
let filename: String =
get_test_chunk_file_sub_dir(file!(), &String::from("alife_object_inventory_box.chunk"));

let object: AlifeObjectInventoryBox = AlifeObjectInventoryBox {
base: AlifeObjectVisual {
base: AlifeObjectAbstract {
game_vertex_id: 0,
distance: 0.0,
direct_control: 0,
level_vertex_id: 0,
flags: 0,
custom_data: "".to_string(),
story_id: 0,
spawn_story_id: 0,
},
visual_name: "".to_string(),
visual_flags: 0,
},
can_take: 0,
is_closed: 0,
tip: "".to_string(),
};

object.write::<SpawnByteOrder>(&mut writer)?;

assert_eq!(writer.bytes_written(), 32);

let bytes_written: usize = writer.flush_chunk_into_file::<SpawnByteOrder>(
&mut overwrite_test_resource_as_file(&filename)?,
0,
)?;

assert_eq!(bytes_written, 32);

let file: FileSlice = open_test_resource_as_slice(&filename)?;

assert_eq!(file.bytes_remaining(), 32 + 8);

let mut chunk: Chunk = Chunk::from_file(file)?.read_child_by_index(0)?;
let read_object: AlifeObjectInventoryBox =
AlifeObjectInventoryBox::read_from_chunk::<SpawnByteOrder>(&mut chunk)?;

assert_eq!(read_object, object);

Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ use crate::data::alife::alife_object_item_weapon::AlifeObjectItemWeapon;
use byteorder::ByteOrder;
use std::io;

#[derive(Clone, Debug, PartialEq)]
pub struct AlifeObjectItemWeaponMagazined {
pub base: AlifeObjectItemWeapon,
}

impl AlifeObjectInheritedReader<AlifeObjectItemWeaponMagazined> for AlifeObjectItemWeaponMagazined {
/// Read magazined weapon data from the chunk.
fn read_from_chunk<T: ByteOrder>(
chunk: &mut Chunk,
) -> io::Result<AlifeObjectItemWeaponMagazined> {
Expand All @@ -20,9 +22,94 @@ impl AlifeObjectInheritedReader<AlifeObjectItemWeaponMagazined> for AlifeObjectI
Ok(AlifeObjectItemWeaponMagazined { base })
}

/// Write magazined weapon item into the writer.
fn write<T: ByteOrder>(&self, writer: &mut ChunkWriter) -> io::Result<()> {
todo!("Implement write operation");
self.base.write::<T>(writer)?;

Ok(())
}
}

impl AlifeObjectGeneric for AlifeObjectItemWeaponMagazined {}

#[cfg(test)]
mod tests {
use crate::chunk::chunk::Chunk;
use crate::chunk::writer::ChunkWriter;
use crate::data::alife::alife_object_abstract::AlifeObjectAbstract;
use crate::data::alife::alife_object_inherited_reader::AlifeObjectInheritedReader;
use crate::data::alife::alife_object_item::AlifeObjectItem;
use crate::data::alife::alife_object_item_weapon::AlifeObjectItemWeapon;
use crate::data::alife::alife_object_item_weapon_magazined::AlifeObjectItemWeaponMagazined;
use crate::data::alife::alife_object_item_weapon_magazined_wgl::AlifeObjectItemWeaponMagazinedWgl;
use crate::data::alife::alife_object_visual::AlifeObjectVisual;
use crate::test::utils::{
get_test_chunk_file_sub_dir, open_test_resource_as_slice, overwrite_test_resource_as_file,
};
use crate::types::SpawnByteOrder;
use fileslice::FileSlice;
use std::io;

#[test]
fn test_read_write_object() -> io::Result<()> {
let mut writer: ChunkWriter = ChunkWriter::new();
let filename: String = get_test_chunk_file_sub_dir(
file!(),
&String::from("alife_object_item_weapon_magazined.chunk"),
);

let object: AlifeObjectItemWeaponMagazinedWgl = AlifeObjectItemWeaponMagazinedWgl {
base: AlifeObjectItemWeaponMagazined {
base: AlifeObjectItemWeapon {
base: AlifeObjectItem {
base: AlifeObjectVisual {
base: AlifeObjectAbstract {
game_vertex_id: 5232,
distance: 53.1213,
direct_control: 67,
level_vertex_id: 25313,
flags: 32,
custom_data: String::from("custom-data"),
story_id: 3486,
spawn_story_id: 37663,
},
visual_name: String::from("visual-name"),
visual_flags: 33,
},
condition: 1.0,
upgrades_count: 0,
},
ammo_current: 20,
ammo_elapsed: 10,
weapon_state: 1,
addon_flags: 1,
ammo_type: 1,
elapsed_grenades: 0,
},
},
};

object.write::<SpawnByteOrder>(&mut writer)?;

assert_eq!(writer.bytes_written(), 67);

let bytes_written: usize = writer.flush_chunk_into_file::<SpawnByteOrder>(
&mut overwrite_test_resource_as_file(&filename)?,
0,
)?;

assert_eq!(bytes_written, 67);

let file: FileSlice = open_test_resource_as_slice(&filename)?;

assert_eq!(file.bytes_remaining(), 67 + 8);

let mut chunk: Chunk = Chunk::from_file(file)?.read_child_by_index(0)?;
let read_object: AlifeObjectItemWeaponMagazinedWgl =
AlifeObjectItemWeaponMagazinedWgl::read_from_chunk::<SpawnByteOrder>(&mut chunk)?;

assert_eq!(read_object, object);

Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ use crate::data::alife::alife_object_item_weapon_magazined::AlifeObjectItemWeapo
use byteorder::ByteOrder;
use std::io;

#[derive(Clone, Debug, PartialEq)]
pub struct AlifeObjectItemWeaponMagazinedWgl {
pub base: AlifeObjectItemWeaponMagazined,
}

impl AlifeObjectInheritedReader<AlifeObjectItemWeaponMagazinedWgl>
for AlifeObjectItemWeaponMagazinedWgl
{
/// Read magazined weapon with launcher from the chunk.
fn read_from_chunk<T: ByteOrder>(
chunk: &mut Chunk,
) -> io::Result<AlifeObjectItemWeaponMagazinedWgl> {
Expand All @@ -23,9 +25,94 @@ impl AlifeObjectInheritedReader<AlifeObjectItemWeaponMagazinedWgl>
Ok(AlifeObjectItemWeaponMagazinedWgl { base })
}

/// Write magazined weapon with launcher data into the writer.
fn write<T: ByteOrder>(&self, writer: &mut ChunkWriter) -> io::Result<()> {
todo!("Implement write operation");
self.base.write::<T>(writer)?;

Ok(())
}
}

impl AlifeObjectGeneric for AlifeObjectItemWeaponMagazinedWgl {}

#[cfg(test)]
mod tests {
use crate::chunk::chunk::Chunk;
use crate::chunk::writer::ChunkWriter;
use crate::data::alife::alife_object_abstract::AlifeObjectAbstract;
use crate::data::alife::alife_object_inherited_reader::AlifeObjectInheritedReader;
use crate::data::alife::alife_object_item::AlifeObjectItem;
use crate::data::alife::alife_object_item_weapon::AlifeObjectItemWeapon;
use crate::data::alife::alife_object_item_weapon_magazined::AlifeObjectItemWeaponMagazined;
use crate::data::alife::alife_object_item_weapon_magazined_wgl::AlifeObjectItemWeaponMagazinedWgl;
use crate::data::alife::alife_object_visual::AlifeObjectVisual;
use crate::test::utils::{
get_test_chunk_file_sub_dir, open_test_resource_as_slice, overwrite_test_resource_as_file,
};
use crate::types::SpawnByteOrder;
use fileslice::FileSlice;
use std::io;

#[test]
fn test_read_write_object() -> io::Result<()> {
let mut writer: ChunkWriter = ChunkWriter::new();
let filename: String = get_test_chunk_file_sub_dir(
file!(),
&String::from("alife_object_item_weapon_magazined_wgl.chunk"),
);

let object: AlifeObjectItemWeaponMagazinedWgl = AlifeObjectItemWeaponMagazinedWgl {
base: AlifeObjectItemWeaponMagazined {
base: AlifeObjectItemWeapon {
base: AlifeObjectItem {
base: AlifeObjectVisual {
base: AlifeObjectAbstract {
game_vertex_id: 2413,
distance: 53.1213,
direct_control: 3643,
level_vertex_id: 25313,
flags: 32,
custom_data: String::from("custom-data"),
story_id: 3486,
spawn_story_id: 37663,
},
visual_name: String::from("visual-name"),
visual_flags: 36,
},
condition: 1.0,
upgrades_count: 0,
},
ammo_current: 20,
ammo_elapsed: 10,
weapon_state: 1,
addon_flags: 1,
ammo_type: 1,
elapsed_grenades: 0,
},
},
};

object.write::<SpawnByteOrder>(&mut writer)?;

assert_eq!(writer.bytes_written(), 67);

let bytes_written: usize = writer.flush_chunk_into_file::<SpawnByteOrder>(
&mut overwrite_test_resource_as_file(&filename)?,
0,
)?;

assert_eq!(bytes_written, 67);

let file: FileSlice = open_test_resource_as_slice(&filename)?;

assert_eq!(file.bytes_remaining(), 67 + 8);

let mut chunk: Chunk = Chunk::from_file(file)?.read_child_by_index(0)?;
let read_object: AlifeObjectItemWeaponMagazinedWgl =
AlifeObjectItemWeaponMagazinedWgl::read_from_chunk::<SpawnByteOrder>(&mut chunk)?;

assert_eq!(read_object, object);

Ok(())
}
}
Loading

0 comments on commit f8e94da

Please sign in to comment.