use binrw::BinWrite;
use std::io::Cursor;
use wow_wmo::api::{ParsedWmo, parse_wmo};
use wow_wmo::chunk_header::ChunkHeader;
use wow_wmo::chunk_id::ChunkId;
fn write_chunk(buffer: &mut Vec<u8>, id: &str, data: &[u8]) {
let header = ChunkHeader {
id: ChunkId::from_bytes([
id.as_bytes()[0],
id.as_bytes()[1],
id.as_bytes()[2],
id.as_bytes()[3],
]),
size: data.len() as u32,
};
let mut cursor = Cursor::new(buffer);
cursor.set_position(cursor.get_ref().len() as u64);
header.write(&mut cursor).unwrap();
cursor.get_mut().extend_from_slice(data);
}
#[test]
fn test_parse_motx_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mohd_data = vec![0u8; 64];
write_chunk(&mut buffer, "MOHD", &mohd_data);
let mut motx_data = Vec::new();
motx_data.extend_from_slice(b"texture1.blp\0");
motx_data.extend_from_slice(b"texture2.blp\0");
motx_data.extend_from_slice(b"path/to/texture3.blp\0");
write_chunk(&mut buffer, "MOTX", &motx_data);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.textures.len(), 3);
assert_eq!(root.textures[0], "texture1.blp");
assert_eq!(root.textures[1], "texture2.blp");
assert_eq!(root.textures[2], "path/to/texture3.blp");
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_mosb_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mohd_data = vec![0u8; 64];
write_chunk(&mut buffer, "MOHD", &mohd_data);
write_chunk(&mut buffer, "MOSB", b"skybox.mdx\0");
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert!(root.skybox.is_some());
assert_eq!(root.skybox.unwrap(), "skybox.mdx");
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_mopv_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mut mohd_data = vec![0u8; 64];
mohd_data[8..12].copy_from_slice(&1u32.to_le_bytes()); write_chunk(&mut buffer, "MOHD", &mohd_data);
let mut mopv_data = Vec::new();
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&10.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&10.0f32.to_le_bytes());
mopv_data.extend_from_slice(&10.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
mopv_data.extend_from_slice(&10.0f32.to_le_bytes());
mopv_data.extend_from_slice(&0.0f32.to_le_bytes());
write_chunk(&mut buffer, "MOPV", &mopv_data);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.portal_vertices.len(), 4);
assert_eq!(root.portal_vertices[0].x, 0.0);
assert_eq!(root.portal_vertices[1].x, 10.0);
assert_eq!(root.portal_vertices[2].y, 10.0);
assert_eq!(root.portal_vertices[3].x, 0.0);
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_mopt_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mut mohd_data = vec![0u8; 64];
mohd_data[8..12].copy_from_slice(&1u32.to_le_bytes()); write_chunk(&mut buffer, "MOHD", &mohd_data);
let mut mopt_data = Vec::new();
mopt_data.extend_from_slice(&0u16.to_le_bytes()); mopt_data.extend_from_slice(&4u16.to_le_bytes()); mopt_data.extend_from_slice(&1.0f32.to_le_bytes()); mopt_data.extend_from_slice(&0.0f32.to_le_bytes()); mopt_data.extend_from_slice(&0.0f32.to_le_bytes()); mopt_data.extend_from_slice(&5.0f32.to_le_bytes());
write_chunk(&mut buffer, "MOPT", &mopt_data);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.portals.len(), 1);
assert_eq!(root.portals[0].start_vertex, 0);
assert_eq!(root.portals[0].n_vertices, 4);
assert_eq!(root.portals[0].normal.x, 1.0);
assert_eq!(root.portals[0].distance, 5.0);
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_mopr_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mohd_data = vec![0u8; 64];
write_chunk(&mut buffer, "MOHD", &mohd_data);
let mut mopr_data = Vec::new();
mopr_data.extend_from_slice(&1u16.to_le_bytes()); mopr_data.extend_from_slice(&5u16.to_le_bytes()); mopr_data.extend_from_slice(&1i16.to_le_bytes()); mopr_data.extend_from_slice(&0u16.to_le_bytes());
write_chunk(&mut buffer, "MOPR", &mopr_data);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.portal_refs.len(), 1);
assert_eq!(root.portal_refs[0].portal_index, 1);
assert_eq!(root.portal_refs[0].group_index, 5);
assert_eq!(root.portal_refs[0].side, 1);
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_modn_chunk() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mut mohd_data = vec![0u8; 64];
mohd_data[16..20].copy_from_slice(&3u32.to_le_bytes()); write_chunk(&mut buffer, "MOHD", &mohd_data);
let mut modn_data = Vec::new();
modn_data.extend_from_slice(
b"World\\Kalimdor\\Orgrimmar\\PassiveDoodads\\Braziers\\OrcBrazier.m2\0",
);
modn_data.extend_from_slice(b"World\\Generic\\Human\\Passive Doodads\\Furniture\\Chair01.m2\0");
modn_data.extend_from_slice(b"World\\Generic\\Orc\\Passive Doodads\\Banners\\OrcBanner01.m2\0");
write_chunk(&mut buffer, "MODN", &modn_data);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.doodad_names.len(), 3);
assert!(root.doodad_names[0].ends_with("OrcBrazier.m2"));
assert!(root.doodad_names[1].ends_with("Chair01.m2"));
assert!(root.doodad_names[2].ends_with("OrcBanner01.m2"));
}
_ => panic!("Expected root file"),
}
}
#[test]
fn test_parse_movv_movb_chunks() {
let mut buffer = Vec::new();
write_chunk(&mut buffer, "MVER", &[17, 0, 0, 0]);
let mohd_data = vec![0u8; 64];
write_chunk(&mut buffer, "MOHD", &mohd_data);
write_chunk(&mut buffer, "MOVV", &[]);
write_chunk(&mut buffer, "MOVB", &[]);
let mut cursor = Cursor::new(buffer);
let result = parse_wmo(&mut cursor);
assert!(result.is_ok());
let wmo = result.unwrap();
match wmo {
ParsedWmo::Root(root) => {
assert_eq!(root.visible_vertices.len(), 0);
assert_eq!(root.visible_blocks.len(), 0);
}
_ => panic!("Expected root file"),
}
}