199 lines
6.2 KiB
Rust
199 lines
6.2 KiB
Rust
|
use crate::ship::items::ClientItemId;
|
||
|
use std::collections::{HashMap, BTreeMap, BinaryHeap};
|
||
|
use std::cmp::{Ordering, PartialOrd, PartialEq};
|
||
|
use thiserror::Error;
|
||
|
use futures::future::join_all;
|
||
|
use libpso::character::character;//::InventoryItem;
|
||
|
use crate::entity::gateway::EntityGateway;
|
||
|
use crate::entity::character::{CharacterEntity, CharacterEntityId};
|
||
|
use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, ItemLocation, BankName};
|
||
|
use crate::entity::item::{Meseta, NewItemEntity};
|
||
|
use crate::entity::item::tool::{Tool, ToolType};
|
||
|
use crate::ship::map::MapArea;
|
||
|
use crate::ship::ship::ItemDropLocation;
|
||
|
use crate::ship::drops::{ItemDrop, ItemDropType};
|
||
|
use crate::ship::location::{AreaClient, RoomId};
|
||
|
|
||
|
|
||
|
#[derive(Debug, Clone)]
|
||
|
pub struct IndividualBankItem {
|
||
|
pub entity_id: ItemEntityId,
|
||
|
pub item_id: ClientItemId,
|
||
|
pub item: ItemDetail,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone)]
|
||
|
pub struct StackedBankItem {
|
||
|
pub entity_ids: Vec<ItemEntityId>,
|
||
|
pub item_id: ClientItemId,
|
||
|
pub tool: Tool,
|
||
|
}
|
||
|
|
||
|
impl StackedBankItem {
|
||
|
pub fn count(&self) -> usize {
|
||
|
self.entity_ids.len()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone)]
|
||
|
pub enum BankItem {
|
||
|
Individual(IndividualBankItem),
|
||
|
Stacked(StackedBankItem),
|
||
|
}
|
||
|
|
||
|
|
||
|
impl std::cmp::PartialEq for BankItem {
|
||
|
fn eq(&self, other: &BankItem) -> bool {
|
||
|
let mut self_bytes = [0u8; 4];
|
||
|
let mut other_bytes = [0u8; 4];
|
||
|
self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]);
|
||
|
other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]);
|
||
|
|
||
|
let self_value = u32::from_be_bytes(self_bytes);
|
||
|
let other_value = u32::from_be_bytes(other_bytes);
|
||
|
|
||
|
self_value.eq(&other_value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::cmp::Eq for BankItem {}
|
||
|
|
||
|
impl std::cmp::PartialOrd for BankItem {
|
||
|
fn partial_cmp(&self, other: &BankItem) -> Option<std::cmp::Ordering> {
|
||
|
//let self_bytes = self.as_client_bytes();
|
||
|
//let other_bytes = other.as_client_bytes();
|
||
|
let mut self_bytes = [0u8; 4];
|
||
|
let mut other_bytes = [0u8; 4];
|
||
|
self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]);
|
||
|
other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]);
|
||
|
|
||
|
|
||
|
let self_value = u32::from_be_bytes(self_bytes);
|
||
|
let other_value = u32::from_be_bytes(other_bytes);
|
||
|
|
||
|
self_value.partial_cmp(&other_value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::cmp::Ord for BankItem {
|
||
|
fn cmp(&self, other: &BankItem) -> std::cmp::Ordering {
|
||
|
//let self_bytes = self.as_client_bytes();
|
||
|
//let other_bytes = other.as_client_bytes();
|
||
|
let mut self_bytes = [0u8; 4];
|
||
|
let mut other_bytes = [0u8; 4];
|
||
|
self_bytes.copy_from_slice(&self.as_client_bytes()[0..4]);
|
||
|
other_bytes.copy_from_slice(&other.as_client_bytes()[0..4]);
|
||
|
|
||
|
|
||
|
let self_value = u32::from_le_bytes(self_bytes);
|
||
|
let other_value = u32::from_le_bytes(other_bytes);
|
||
|
|
||
|
self_value.cmp(&other_value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl BankItem {
|
||
|
pub fn set_item_id(&mut self, item_id: ClientItemId) {
|
||
|
match self {
|
||
|
BankItem::Individual(individual_bank_item) => {
|
||
|
individual_bank_item.item_id = item_id
|
||
|
},
|
||
|
BankItem::Stacked(stacked_bank_item) => {
|
||
|
stacked_bank_item.item_id = item_id
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn item_id(&self) -> ClientItemId {
|
||
|
match self {
|
||
|
BankItem::Individual(individual_bank_item) => {
|
||
|
individual_bank_item.item_id
|
||
|
},
|
||
|
BankItem::Stacked(stacked_bank_item) => {
|
||
|
stacked_bank_item.item_id
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn as_client_bytes(&self) -> [u8; 16] {
|
||
|
match self {
|
||
|
BankItem::Individual(item) => {
|
||
|
match &item.item {
|
||
|
ItemDetail::Weapon(w) => w.as_bytes(),
|
||
|
ItemDetail::Armor(a) => a.as_bytes(),
|
||
|
ItemDetail::Shield(s) => s.as_bytes(),
|
||
|
ItemDetail::Unit(u) => u.as_bytes(),
|
||
|
ItemDetail::Tool(t) => t.as_individual_bytes(),
|
||
|
ItemDetail::TechniqueDisk(d) => d.as_bytes(),
|
||
|
ItemDetail::Mag(m) => m.as_bytes(),
|
||
|
}
|
||
|
},
|
||
|
BankItem::Stacked(item) => {
|
||
|
item.tool.as_stacked_bytes(item.entity_ids.len())
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct CharacterBank(Vec<BankItem>);
|
||
|
|
||
|
impl CharacterBank {
|
||
|
pub fn new(mut items: Vec<BankItem>) -> CharacterBank {
|
||
|
items.sort();
|
||
|
CharacterBank(items)
|
||
|
}
|
||
|
|
||
|
pub fn initialize_item_ids(&mut self, base_item_id: u32) {
|
||
|
for (i, item) in self.0.iter_mut().enumerate() {
|
||
|
item.set_item_id(ClientItemId(base_item_id + i as u32));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn as_client_bank_items(&self) -> character::Bank {
|
||
|
self.0.iter()
|
||
|
.enumerate()
|
||
|
.fold(character::Bank::default(), |mut bank, (slot, item)| {
|
||
|
bank.item_count = (slot + 1) as u32;
|
||
|
let bytes = item.as_client_bytes();
|
||
|
bank.items[slot].data1.copy_from_slice(&bytes[0..12]);
|
||
|
bank.items[slot].data2.copy_from_slice(&bytes[12..16]);
|
||
|
bank.items[slot].item_id = item.item_id().0;
|
||
|
|
||
|
bank
|
||
|
})
|
||
|
}
|
||
|
|
||
|
pub fn as_client_bank_request(&self) -> Vec<character::BankItem> {
|
||
|
self.0.iter()
|
||
|
.map(|item| {
|
||
|
let bytes = item.as_client_bytes();
|
||
|
let mut data1 = [0; 12];
|
||
|
let mut data2 = [0; 4];
|
||
|
data1.copy_from_slice(&bytes[0..12]);
|
||
|
data2.copy_from_slice(&bytes[12..16]);
|
||
|
let amount = match item {
|
||
|
BankItem::Individual(_individual_bank_item) => {
|
||
|
1
|
||
|
},
|
||
|
BankItem::Stacked(stacked_bank_item) => {
|
||
|
stacked_bank_item.count()
|
||
|
},
|
||
|
};
|
||
|
character::BankItem {
|
||
|
data1: data1,
|
||
|
data2: data2,
|
||
|
item_id: item.item_id().0,
|
||
|
amount: amount as u16,
|
||
|
flags: 1,
|
||
|
}
|
||
|
})
|
||
|
.collect()
|
||
|
}
|
||
|
|
||
|
pub fn count(&self) -> usize {
|
||
|
self.0.len()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|