use phf::phf_map;
static WEAPON_INFO: phf::Map<u64, (&'static str, &'static str)> = phf_map! {
8u64 => ("Daedalus", "Shotgun"), 12u64 => ("Torgue", "Shotgun"), 10u64 => ("Maliwan", "Shotgun"), 9u64 => ("Jakobs", "Shotgun"), 11u64 => ("Tediore", "Shotgun"), 7u64 => ("Ripper", "Shotgun"),
4u64 => ("Jakobs", "Pistol"), 2u64 => ("Daedalus", "Pistol"), 6u64 => ("Torgue", "Pistol"), 5u64 => ("Tediore", "Pistol"), 3u64 => ("Jakobs", "Pistol"),
14u64 => ("Tediore", "AR"), 13u64 => ("Daedalus", "AR"), 15u64 => ("Order", "AR"),
16u64 => ("Vladof", "Sniper"), 24u64 => ("Jakobs", "Sniper"), 26u64 => ("Order", "Sniper"), 25u64 => ("Maliwan", "Sniper"), 23u64 => ("Ripper", "Sniper"),
20u64 => ("Daedalus", "SMG"), 22u64 => ("Ripper", "SMG"), 21u64 => ("Maliwan", "SMG"), 19u64 => ("Vladof", "SMG"),
18u64 => ("Vladof", "AR"), 17u64 => ("Torgue", "AR"), 27u64 => ("Jakobs", "AR"), };
static SERIAL_TO_PARTS_CAT: phf::Map<u64, u64> = phf_map! {
8u64 => 8, 12u64 => 12, 10u64 => 10, 9u64 => 9, 11u64 => 11, 7u64 => 7,
4u64 => 3, 2u64 => 2, 6u64 => 6, 5u64 => 5, 3u64 => 3,
14u64 => 14, 13u64 => 13, 15u64 => 15, 18u64 => 18, 17u64 => 17, 27u64 => 27,
16u64 => 16, 24u64 => 24, 26u64 => 26, 25u64 => 25, 23u64 => 23,
20u64 => 20, 22u64 => 19, 21u64 => 21, 19u64 => 22, };
pub fn serial_id_to_parts_category(serial_id: u64) -> u64 {
SERIAL_TO_PARTS_CAT
.get(&serial_id)
.copied()
.unwrap_or(serial_id)
}
pub fn varbit_divisor(_varbit: u64) -> u64 {
1
}
pub fn category_from_varbit(varbit: u64) -> i64 {
varbit as i64
}
pub fn weapon_info_from_first_varint(id: u64) -> Option<(&'static str, &'static str)> {
WEAPON_INFO.get(&id).copied()
}
pub fn manufacturer_name(id: u64) -> Option<&'static str> {
weapon_info_from_first_varint(id).map(|(mfg, _)| mfg)
}
pub fn weapon_type_from_first_varint(id: u64) -> Option<&'static str> {
weapon_info_from_first_varint(id).map(|(_, wtype)| wtype)
}
pub fn category_name(category: i64) -> Option<&'static str> {
if let Some(name) = crate::manifest::category_name(category) {
return Some(name);
}
if (300..400).contains(&category) {
let base = category / 10 * 10;
return crate::manifest::category_name(base);
}
None
}
pub fn level_from_code(code: u64) -> Option<(u8, u8)> {
if matches!(code, 1..=60) {
Some((code as u8, code as u8))
} else {
None
}
}
pub fn code_from_level(level: u8) -> Option<u64> {
if level == 0 || level > 60 {
return None;
}
Some(level as u64)
}
pub fn weapon_level_code(level: u8, _rarity: crate::serial::Rarity) -> Option<u64> {
code_from_level(level)
}
pub fn first_varint_from_weapon_info(manufacturer: &str, weapon_type: &str) -> Option<u64> {
WEAPON_INFO.entries().find_map(|(id, (mfr, wtype))| {
if *mfr == manufacturer && *wtype == weapon_type {
Some(*id)
} else {
None
}
})
}
pub fn varbit_from_category(category: i64, _divisor: u64, _metadata: u64) -> u64 {
category as u64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_weapon_info_lookup() {
assert_eq!(weapon_info_from_first_varint(3), Some(("Jakobs", "Pistol")));
assert_eq!(
weapon_info_from_first_varint(16),
Some(("Vladof", "Sniper"))
);
assert_eq!(weapon_info_from_first_varint(17), Some(("Torgue", "AR")));
assert_eq!(weapon_info_from_first_varint(21), Some(("Maliwan", "SMG")));
assert_eq!(weapon_info_from_first_varint(999), None);
}
#[test]
fn test_manufacturer_lookup() {
assert_eq!(manufacturer_name(2), Some("Daedalus"));
assert_eq!(manufacturer_name(17), Some("Torgue"));
assert_eq!(manufacturer_name(21), Some("Maliwan"));
assert_eq!(manufacturer_name(999), None);
}
#[test]
fn test_varbit_divisor() {
assert_eq!(varbit_divisor(279), 1);
assert_eq!(varbit_divisor(22), 1);
assert_eq!(varbit_divisor(0), 1);
}
#[test]
fn test_category_from_varbit() {
assert_eq!(category_from_varbit(279), 279); assert_eq!(category_from_varbit(269), 269); assert_eq!(category_from_varbit(289), 289); assert_eq!(category_from_varbit(22), 22); assert_eq!(category_from_varbit(16), 16); }
#[test]
fn test_category_name_lookup() {
assert_eq!(category_name(2), Some("Daedalus Pistol"));
assert_eq!(category_name(22), Some("Vladof SMG"));
assert_eq!(category_name(283), Some("Vladof Shield"));
assert_eq!(category_name(999), None);
}
#[test]
fn test_level_from_code() {
assert_eq!(level_from_code(1), Some((1, 1)));
assert_eq!(level_from_code(30), Some((30, 30)));
assert_eq!(level_from_code(50), Some((50, 50)));
assert_eq!(level_from_code(60), Some((60, 60)));
assert_eq!(level_from_code(0), None);
assert_eq!(level_from_code(61), None);
}
#[test]
fn test_serial_id_to_parts_category() {
assert_eq!(serial_id_to_parts_category(8), 8);
assert_eq!(serial_id_to_parts_category(9), 9);
assert_eq!(serial_id_to_parts_category(16), 16);
assert_eq!(serial_id_to_parts_category(21), 21);
assert_eq!(serial_id_to_parts_category(999), 999);
}
#[test]
fn test_weapon_type_from_first_varint() {
assert_eq!(weapon_type_from_first_varint(8), Some("Shotgun"));
assert_eq!(weapon_type_from_first_varint(4), Some("Pistol"));
assert_eq!(weapon_type_from_first_varint(16), Some("Sniper"));
assert_eq!(weapon_type_from_first_varint(21), Some("SMG"));
assert_eq!(weapon_type_from_first_varint(17), Some("AR"));
assert_eq!(weapon_type_from_first_varint(999), None);
}
#[test]
fn test_code_from_level() {
assert_eq!(code_from_level(1), Some(1));
assert_eq!(code_from_level(15), Some(15));
assert_eq!(code_from_level(16), Some(16));
assert_eq!(code_from_level(30), Some(30));
assert_eq!(code_from_level(50), Some(50));
assert_eq!(code_from_level(60), Some(60));
assert_eq!(code_from_level(0), None);
assert_eq!(code_from_level(61), None);
}
#[test]
fn test_code_from_level_roundtrip() {
for level in 1..=50u8 {
let code = code_from_level(level).unwrap();
let (decoded, _) = level_from_code(code).unwrap();
assert_eq!(decoded, level, "roundtrip failed for level {}", level);
}
}
#[test]
fn test_first_varint_from_weapon_info() {
let id = first_varint_from_weapon_info("Jakobs", "Shotgun").unwrap();
assert_eq!(id, 9);
assert_eq!(
weapon_info_from_first_varint(id),
Some(("Jakobs", "Shotgun"))
);
let id = first_varint_from_weapon_info("Vladof", "SMG").unwrap();
assert_eq!(id, 19);
assert_eq!(weapon_info_from_first_varint(id), Some(("Vladof", "SMG")));
assert!(first_varint_from_weapon_info("FakeManufacturer", "Pistol").is_none());
}
#[test]
fn test_varbit_from_category_roundtrip() {
let varbit = varbit_from_category(279, 1, 0);
assert_eq!(category_from_varbit(varbit), 279);
let varbit = varbit_from_category(22, 1, 0);
assert_eq!(category_from_varbit(varbit), 22);
}
}