use libpso::packet::messages::*; use libpso::packet::ship::*; use entity::item; use stats::leveltable::CharacterStats; //use crate::ship::ship::{ShipError}; use items::ClientItemId; use items::inventory::InventoryItem; use items::state::IndividualItemDetail; use items::bank::BankState; use items::floor::FloorItem; use location::AreaClient; use std::convert::TryInto; use shops::ShopItem; pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> ItemDrop { let item_bytes = item_drop.as_client_bytes(); ItemDrop { client, target, map_area: item_drop.map_area.area_value(), variety: 0, unknown: 0, x: item_drop.x, z: item_drop.z, y: item_drop.y, item_bytes: item_bytes[0..12].try_into().unwrap(), item_id: item_drop.item_id.0, item_bytes2: item_bytes[12..16].try_into().unwrap(), unknown2: 0, } } // TODO: this doesn't need to be a Result, just unwrap try_intos they are guaranteed to succeed pub fn create_individual_item(area_client: AreaClient, item_id: ClientItemId, item: &IndividualItemDetail) -> CreateItem { let bytes = item.as_client_bytes(); CreateItem { client: area_client.local_client.id(), target: 0, item_data: bytes[0..12].try_into().unwrap(), item_id: item_id.0, item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, } } // TODO: this doesn't need to be a Result, just unwrap try_intos they are guaranteed to succeed pub fn create_stacked_item(area_client: AreaClient, item_id: ClientItemId, tool: &item::tool::Tool, amount: usize) -> CreateItem { let bytes = tool.as_stacked_bytes(amount); CreateItem { client: area_client.local_client.id(), target: 0, item_data: bytes[0..12].try_into().unwrap(), item_id: item_id.0, item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, } } pub fn create_meseta(area_client: AreaClient, amount: usize) -> CreateItem { let bytes: [u8; 12] = [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; CreateItem { client: area_client.local_client.id(), target: 0, item_data: bytes, item_id: 0xFFFFFFFF, item_data2: u32::to_le_bytes(amount as u32), unknown: 0, } } pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem) -> CreateItem { let bytes = item.item.as_client_bytes(); CreateItem { client: area_client.local_client.id(), target: 0, item_data: bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, } } pub fn create_withdrawn_inventory_item2(area_client: AreaClient, item: &InventoryItem) -> CreateItem { let bytes = item.item.as_client_bytes(); CreateItem { client: area_client.local_client.id(), target: 0, item_data: bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, item_data2: bytes[12..16].try_into().unwrap(), unknown: 0, } } pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> RemoveItemFromFloor { RemoveItemFromFloor { client: area_client.local_client.id(), target: 0, client_id: area_client.local_client.id(), unknown: 0, map_area: item.map_area.area_value(), unknown2: 0, item_id: item.item_id.0, } } pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> DropSplitStack { let item_bytes = item.as_client_bytes(); DropSplitStack { client: area_client.local_client.id(), target: 0, variety: 0, unknown1: 0, map_area: item.map_area.area_value(), x: item.x, z: item.z, item_bytes: item_bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, item_bytes2: item_bytes[12..16].try_into().unwrap(), unknown2: 0, } } pub fn drop_split_meseta_stack(area_client: AreaClient, item: &FloorItem) -> DropSplitStack { let item_bytes = item.as_client_bytes(); DropSplitStack { client: area_client.local_client.id(), target: 0, variety: 0, unknown1: 0, map_area: item.map_area.area_value(), x: item.x, z: item.z, item_bytes: item_bytes[0..12].try_into().unwrap(), item_id: item.item_id.0, item_bytes2: item_bytes[12..16].try_into().unwrap(), unknown2: 0, } } pub fn character_gained_exp(area_client: AreaClient, exp: u32) -> GiveCharacterExp { GiveCharacterExp { client: area_client.local_client.id(), target: 0, exp, } } pub fn character_leveled_up(area_client: AreaClient, level: u32, before_stats: CharacterStats, after_stats: CharacterStats) -> PlayerLevelUp { PlayerLevelUp { client: area_client.local_client.id(), target: 0, atp: after_stats.atp - before_stats.atp, mst: after_stats.mst - before_stats.mst, evp: after_stats.evp - before_stats.evp, hp: after_stats. hp - before_stats. hp, dfp: after_stats.dfp - before_stats.dfp, ata: after_stats.ata - before_stats.ata, lvl: level, } } // TOOD: checksum? pub fn bank_item_list(bank: &BankState) -> BankItemList { BankItemList { aflag: 0, cmd: 0xBC, unknown: [0; 3], size: bank.count() as u32 * 0x18 + 0x14, checksum: 0x123434, item_count: bank.count() as u32, meseta: bank.meseta.0, items: bank.as_client_bank_request() } } pub fn player_no_longer_has_item(area_client: AreaClient, item_id: ClientItemId, amount: u32) -> PlayerNoLongerHasItem { PlayerNoLongerHasItem { client: area_client.local_client.id(), target: 0, item_id: item_id.0, amount, } } pub fn player_no_longer_has_meseta(area_client: AreaClient, amount: u32) -> PlayerNoLongerHasItem { PlayerNoLongerHasItem { client: area_client.local_client.id(), target: 0, item_id: 0xFFFFFFFF, amount, } } pub fn shop_list(shop_type: u8, items: &[I]) -> ShopList { let items = items.iter() .enumerate() .map(|(i, item)| { ShopListItem { item_bytes: item.as_bytes(), unknown: i as u32 + 23, price: item.price() as u32, } }) .collect(); ShopList { client: 0, target: 0, shop_type, num_items: 0, unused: 0, items, } } pub fn tek_preview(id: ClientItemId, weapon: &item::weapon::Weapon) -> TekPreview { let bytes = weapon.as_bytes(); TekPreview { client: 0x79, target: 0, item_bytes: bytes[0..12].try_into().unwrap(), item_id: id.0, item_bytes2: bytes[12..16].try_into().unwrap(), } }