start of trading
This commit is contained in:
parent
571bab2534
commit
0d30df8da6
@ -597,18 +597,42 @@ pub enum PgItemLocationDetail {
|
|||||||
mag: u32,
|
mag: u32,
|
||||||
},
|
},
|
||||||
Shop,
|
Shop,
|
||||||
|
Trade {
|
||||||
|
id: i32,
|
||||||
|
character_to: i32,
|
||||||
|
character_from: i32,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ItemLocation> for PgItemLocationDetail {
|
impl From<ItemLocation> for PgItemLocationDetail {
|
||||||
fn from(other: ItemLocation) -> PgItemLocationDetail {
|
fn from(other: ItemLocation) -> PgItemLocationDetail {
|
||||||
match other {
|
match other {
|
||||||
ItemLocation::Inventory{character_id} => PgItemLocationDetail::Inventory{character_id: character_id.0},
|
ItemLocation::Inventory{character_id} => PgItemLocationDetail::Inventory{
|
||||||
ItemLocation::Bank{character_id, name} => PgItemLocationDetail::Bank{character_id: character_id.0, name: name.0},
|
character_id: character_id.0
|
||||||
ItemLocation::LocalFloor{character_id, map_area, x,y,z} => PgItemLocationDetail::LocalFloor{character_id: character_id.0, map_area, x,y,z},
|
},
|
||||||
ItemLocation::SharedFloor{map_area, x,y,z} => PgItemLocationDetail::SharedFloor{map_area, x,y,z},
|
ItemLocation::Bank{character_id, name} => PgItemLocationDetail::Bank{
|
||||||
|
character_id: character_id.0,
|
||||||
|
name: name.0
|
||||||
|
},
|
||||||
|
ItemLocation::LocalFloor{character_id, map_area, x,y,z} => PgItemLocationDetail::LocalFloor{
|
||||||
|
character_id: character_id.0,
|
||||||
|
map_area,
|
||||||
|
x,y,z
|
||||||
|
},
|
||||||
|
ItemLocation::SharedFloor{map_area, x,y,z} => PgItemLocationDetail::SharedFloor{
|
||||||
|
map_area,
|
||||||
|
x,y,z
|
||||||
|
},
|
||||||
ItemLocation::Consumed => PgItemLocationDetail::Consumed,
|
ItemLocation::Consumed => PgItemLocationDetail::Consumed,
|
||||||
ItemLocation::FedToMag{mag} => PgItemLocationDetail::FedToMag{mag: mag.0},
|
ItemLocation::FedToMag{mag} => PgItemLocationDetail::FedToMag{
|
||||||
|
mag: mag.0
|
||||||
|
},
|
||||||
ItemLocation::Shop => PgItemLocationDetail::Shop,
|
ItemLocation::Shop => PgItemLocationDetail::Shop,
|
||||||
|
ItemLocation::Trade{id, character_to, character_from} => PgItemLocationDetail::Trade {
|
||||||
|
id: id.0 as i32,
|
||||||
|
character_to: character_to.0 as i32,
|
||||||
|
character_from: character_from.0 as i32,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,13 +640,32 @@ impl From<ItemLocation> for PgItemLocationDetail {
|
|||||||
impl From<PgItemLocationDetail> for ItemLocation {
|
impl From<PgItemLocationDetail> for ItemLocation {
|
||||||
fn from(other: PgItemLocationDetail) -> ItemLocation {
|
fn from(other: PgItemLocationDetail) -> ItemLocation {
|
||||||
match other {
|
match other {
|
||||||
PgItemLocationDetail::Inventory{character_id} => ItemLocation::Inventory{character_id: CharacterEntityId(character_id)},
|
PgItemLocationDetail::Inventory{character_id} => ItemLocation::Inventory{
|
||||||
PgItemLocationDetail::Bank{character_id, name} => ItemLocation::Bank{character_id: CharacterEntityId(character_id), name: BankName(name)},
|
character_id: CharacterEntityId(character_id)
|
||||||
PgItemLocationDetail::LocalFloor{character_id, map_area, x,y,z} => ItemLocation::LocalFloor{character_id: CharacterEntityId(character_id), map_area, x,y,z},
|
},
|
||||||
PgItemLocationDetail::SharedFloor{map_area, x,y,z} => ItemLocation::SharedFloor{map_area, x,y,z},
|
PgItemLocationDetail::Bank{character_id, name} => ItemLocation::Bank{
|
||||||
|
character_id: CharacterEntityId(character_id),
|
||||||
|
name: BankName(name)
|
||||||
|
},
|
||||||
|
PgItemLocationDetail::LocalFloor{character_id, map_area, x,y,z} => ItemLocation::LocalFloor{
|
||||||
|
character_id: CharacterEntityId(character_id),
|
||||||
|
map_area,
|
||||||
|
x,y,z
|
||||||
|
},
|
||||||
|
PgItemLocationDetail::SharedFloor{map_area, x,y,z} => ItemLocation::SharedFloor{
|
||||||
|
map_area,
|
||||||
|
x,y,z
|
||||||
|
},
|
||||||
PgItemLocationDetail::Consumed => ItemLocation::Consumed,
|
PgItemLocationDetail::Consumed => ItemLocation::Consumed,
|
||||||
PgItemLocationDetail::FedToMag{mag} => ItemLocation::FedToMag{mag: ItemEntityId(mag)},
|
PgItemLocationDetail::FedToMag{mag} => ItemLocation::FedToMag{
|
||||||
|
mag: ItemEntityId(mag)
|
||||||
|
},
|
||||||
PgItemLocationDetail::Shop => ItemLocation::Shop,
|
PgItemLocationDetail::Shop => ItemLocation::Shop,
|
||||||
|
PgItemLocationDetail::Trade {id, character_to, character_from} => ItemLocation::Trade {
|
||||||
|
id: TradeId(id as usize),
|
||||||
|
character_to: CharacterEntityId(character_to as u32),
|
||||||
|
character_from: CharacterEntityId(character_from as u32),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ pub enum ItemLocation {
|
|||||||
mag: ItemEntityId,
|
mag: ItemEntityId,
|
||||||
},
|
},
|
||||||
Shop,
|
Shop,
|
||||||
|
Trade {
|
||||||
|
//id: TradeId,
|
||||||
|
character_to: CharacterEntityId,
|
||||||
|
character_from: CharacterEntityId,
|
||||||
|
},
|
||||||
/*Destroyed {
|
/*Destroyed {
|
||||||
// marks an item that has been consumed in some way
|
// marks an item that has been consumed in some way
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@ use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity
|
|||||||
use crate::entity::item::tool::{Tool, ToolType};
|
use crate::entity::item::tool::{Tool, ToolType};
|
||||||
use crate::entity::item::weapon;
|
use crate::entity::item::weapon;
|
||||||
use crate::ship::map::MapArea;
|
use crate::ship::map::MapArea;
|
||||||
use crate::ship::ship::ItemDropLocation;
|
use crate::ship::ship::{TradeItem, ItemDropLocation};
|
||||||
use crate::ship::drops::{ItemDrop, ItemDropType};
|
use crate::ship::drops::{ItemDrop, ItemDropType};
|
||||||
use crate::ship::location::{AreaClient, RoomId};
|
use crate::ship::location::{AreaClient, RoomId};
|
||||||
use crate::ship::shops::ShopItem;
|
use crate::ship::shops::ShopItem;
|
||||||
@ -180,6 +180,11 @@ impl ItemManager {
|
|||||||
.ok_or(ItemManagerError::NoCharacter(character.id))?)
|
.ok_or(ItemManagerError::NoCharacter(character.id))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_character_inventory_mut<'a>(&'a mut self, character: &CharacterEntity) -> Result<&'a mut CharacterInventory, anyhow::Error> {
|
||||||
|
Ok(self.character_inventory.get_mut(&character.id)
|
||||||
|
.ok_or(ItemManagerError::NoCharacter(character.id))?)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, anyhow::Error> {
|
pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, anyhow::Error> {
|
||||||
Ok(self.character_bank
|
Ok(self.character_bank
|
||||||
.get(&character.id)
|
.get(&character.id)
|
||||||
@ -919,4 +924,15 @@ impl ItemManager {
|
|||||||
|
|
||||||
Ok(weapon)
|
Ok(weapon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_items_to_other_player<EG: EntityGateway>(&mut self,
|
||||||
|
entity_gateway: &mut EG,
|
||||||
|
source_character: &CharacterEntity,
|
||||||
|
dest_character: &CharacterEntity,
|
||||||
|
items: &Vec<TradeItem>)
|
||||||
|
-> Result<(), anyhow::Error> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
0
src/ship/packet/builder/trade.rs
Normal file
0
src/ship/packet/builder/trade.rs
Normal file
@ -7,3 +7,4 @@ pub mod room;
|
|||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod quest;
|
pub mod quest;
|
||||||
pub mod ship;
|
pub mod ship;
|
||||||
|
pub mod trade;
|
||||||
|
181
src/ship/packet/handler/trade.rs
Normal file
181
src/ship/packet/handler/trade.rs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
use std::convert::TryInto;
|
||||||
|
use log::warn;
|
||||||
|
use rand::Rng;
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use libpso::packet::ship::*;
|
||||||
|
use libpso::packet::messages::*;
|
||||||
|
use crate::common::leveltable::CharacterLevelTable;
|
||||||
|
use crate::common::serverstate::ClientId;
|
||||||
|
use crate::ship::ship::{SendShipPacket, ShipError, Clients, Rooms, ItemShops, TradeItem};
|
||||||
|
use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||||
|
use crate::ship::drops::ItemDrop;
|
||||||
|
use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, TriggerCreateItem, FloorItem, FloorType};
|
||||||
|
use crate::ship::items::inventory::InventoryItem;
|
||||||
|
use crate::entity::gateway::EntityGateway;
|
||||||
|
use crate::entity::item;
|
||||||
|
use libpso::utf8_to_utf16_array;
|
||||||
|
use crate::ship::packet::builder;
|
||||||
|
use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem};
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error("")]
|
||||||
|
pub enum TradeError {
|
||||||
|
CouldNotFindTradePartner,
|
||||||
|
ClientItemIdDidNotMatchItem(ClientItemId, [u8; 16]),
|
||||||
|
InvalidStackAmount(ClientItemId, usize),
|
||||||
|
NotInTradeMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn inner_items_to_trade<EG>(id: ClientId,
|
||||||
|
items_to_trade: &ItemsToTrade,
|
||||||
|
entity_gateway: &mut EG,
|
||||||
|
client_location: &ClientLocation,
|
||||||
|
clients: &mut Clients,
|
||||||
|
item_manager: &mut ItemManager)
|
||||||
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
|
where
|
||||||
|
EG: EntityGateway
|
||||||
|
{
|
||||||
|
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
let inventory = item_manager.get_character_inventory_mut(&client.character)?;
|
||||||
|
let trade_partner = client_location.get_client_neighbors(id)?;
|
||||||
|
let trade_partner = trade_partner
|
||||||
|
.iter()
|
||||||
|
.filter(|ac| {
|
||||||
|
ac.local_client.id() == items_to_trade.trade_target
|
||||||
|
})
|
||||||
|
.nth(0)
|
||||||
|
.ok_or(TradeError::CouldNotFindTradePartner)?;
|
||||||
|
|
||||||
|
|
||||||
|
let item_blobs = items_to_trade.items.iter().take(items_to_trade.count as usize);
|
||||||
|
let trade_items = item_blobs
|
||||||
|
.map(|item| {
|
||||||
|
// TOOD: meseta?
|
||||||
|
let real_item = inventory.get_item_handle_by_id(ClientItemId(item.item_id))
|
||||||
|
.ok_or(ItemManagerError::NoSuchItemId(ClientItemId(item.item_id)))?;
|
||||||
|
let real_item = real_item
|
||||||
|
.item()
|
||||||
|
.ok_or(ItemManagerError::NoSuchItemId(ClientItemId(item.item_id)))?;
|
||||||
|
let trade_item_bytes: [u8; 16] = item.item_data.iter()
|
||||||
|
.chain(item.item_data2.iter())
|
||||||
|
.cloned().collect::<Vec<u8>>()
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
|
if real_item.as_client_bytes() == trade_item_bytes {
|
||||||
|
match real_item {
|
||||||
|
InventoryItem::Individual(individual_inventory_item) => {
|
||||||
|
Ok(TradeItem::Individual(individual_inventory_item.item_id))
|
||||||
|
},
|
||||||
|
InventoryItem::Stacked(stacked_inventory_item) => {
|
||||||
|
let amount = trade_item_bytes[5] as usize;
|
||||||
|
if amount > stacked_inventory_item.entity_ids.len() {
|
||||||
|
Ok(TradeItem::Stacked(stacked_inventory_item.item_id, amount))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Err(TradeError::InvalidStackAmount(stacked_inventory_item.item_id, amount).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Err(TradeError::ClientItemIdDidNotMatchItem(ClientItemId(item.item_id), trade_item_bytes).into())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, anyhow::Error>>()?;
|
||||||
|
|
||||||
|
// TODO: check room in inventory for items
|
||||||
|
client.trade = Some((trade_partner.client, trade_items));
|
||||||
|
|
||||||
|
Ok(Box::new(vec![(trade_partner.client, SendShipPacket::AcknowledgeTrade(AcknowledgeTrade {}))].into_iter()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn items_to_trade<EG>(id: ClientId,
|
||||||
|
items_to_trade_pkt: &ItemsToTrade,
|
||||||
|
entity_gateway: &mut EG,
|
||||||
|
client_location: &ClientLocation,
|
||||||
|
clients: &mut Clients,
|
||||||
|
item_manager: &mut ItemManager)
|
||||||
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
|
where
|
||||||
|
EG: EntityGateway
|
||||||
|
{
|
||||||
|
let t = inner_items_to_trade(id, items_to_trade_pkt, entity_gateway, client_location, clients, item_manager).await;
|
||||||
|
match t {
|
||||||
|
Ok(p) => Ok(p),
|
||||||
|
Err(err) => {
|
||||||
|
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
let trade_partner = client.trade.as_ref()
|
||||||
|
.and_then(|(trade_partner, _)| {
|
||||||
|
client_location.get_local_client(*trade_partner).ok()
|
||||||
|
})
|
||||||
|
.map(|trade_partner| {
|
||||||
|
(trade_partner.client, SendShipPacket::CancelTrade(CancelTrade {}))
|
||||||
|
});
|
||||||
|
|
||||||
|
log::warn!("error in trading: {:?}", err);
|
||||||
|
Ok(Box::new(vec![(id, SendShipPacket::CancelTrade(CancelTrade {}))]
|
||||||
|
.into_iter()
|
||||||
|
.chain(trade_partner.into_iter())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function is a shitshow due to not thinking of what would happen if I needed more than 1 client at a time
|
||||||
|
pub async fn trade_confirmed<EG>(id: ClientId,
|
||||||
|
entity_gateway: &mut EG,
|
||||||
|
client_location: &ClientLocation,
|
||||||
|
clients: &mut Clients,
|
||||||
|
item_manager: &mut ItemManager)
|
||||||
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
|
where
|
||||||
|
EG: EntityGateway
|
||||||
|
{
|
||||||
|
let (this_client_confirmed, other_client_id) = {
|
||||||
|
let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
(client.confirmed_trade, client.trade.as_ref().ok_or(TradeError::NotInTradeMenu)?.0)
|
||||||
|
};
|
||||||
|
let other_client_confirmed = {
|
||||||
|
let client = clients.get(&other_client_id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
client.confirmed_trade
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let this_client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
this_client.confirmed_trade = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let both_confirmed = {
|
||||||
|
let this_client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
let other_client = clients.get(&other_client_id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
this_client.confirmed_trade && other_client.confirmed_trade
|
||||||
|
};
|
||||||
|
|
||||||
|
if both_confirmed {
|
||||||
|
{
|
||||||
|
let this_client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
let other_client = clients.get(&other_client_id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
|
||||||
|
let this_character_items = &this_client.trade.as_ref().ok_or(TradeError::NotInTradeMenu)?.1;
|
||||||
|
item_manager.send_items_to_other_player(entity_gateway, &this_client.character, &other_client.character, this_character_items).await?;
|
||||||
|
|
||||||
|
let other_character_items = &other_client.trade.as_ref().ok_or(TradeError::NotInTradeMenu)?.1;
|
||||||
|
item_manager.send_items_to_other_player(entity_gateway, &other_client.character, &this_client.character, other_character_items).await?;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let this_client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
this_client.trade = None;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let other_client = clients.get_mut(&other_client_id).ok_or(ShipError::ClientNotFound(id))?;
|
||||||
|
other_client.trade = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Box::new(None.into_iter()))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ok(Box::new(None.into_iter()))
|
||||||
|
}
|
||||||
|
}
|
@ -106,6 +106,8 @@ pub enum RecvShipPacket {
|
|||||||
SaveOptions(SaveOptions),
|
SaveOptions(SaveOptions),
|
||||||
RequestShipList(RequestShipList),
|
RequestShipList(RequestShipList),
|
||||||
RequestShipBlockList(RequestShipBlockList),
|
RequestShipBlockList(RequestShipBlockList),
|
||||||
|
ItemsToTrade(ItemsToTrade),
|
||||||
|
TradeConfirmed(TradeConfirmed),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecvServerPacket for RecvShipPacket {
|
impl RecvServerPacket for RecvShipPacket {
|
||||||
@ -143,6 +145,8 @@ impl RecvServerPacket for RecvShipPacket {
|
|||||||
0xA1 => Ok(RecvShipPacket::RequestShipBlockList(RequestShipBlockList::from_bytes(data)?)),
|
0xA1 => Ok(RecvShipPacket::RequestShipBlockList(RequestShipBlockList::from_bytes(data)?)),
|
||||||
0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)),
|
0xA2 => Ok(RecvShipPacket::RequestQuestList(RequestQuestList::from_bytes(data)?)),
|
||||||
0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)),
|
0xAC => Ok(RecvShipPacket::DoneLoadingQuest(DoneLoadingQuest::from_bytes(data)?)),
|
||||||
|
0xD0 => Ok(RecvShipPacket::ItemsToTrade(ItemsToTrade::from_bytes(data)?)),
|
||||||
|
0xD2 => Ok(RecvShipPacket::TradeConfirmed(TradeConfirmed::from_bytes(data)?)),
|
||||||
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
|
0xE7 => Ok(RecvShipPacket::FullCharacterData(Box::new(FullCharacterData::from_bytes(data)?))),
|
||||||
0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)),
|
0x1ED => Ok(RecvShipPacket::SaveOptions(SaveOptions::from_bytes(data)?)),
|
||||||
_ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec()))
|
_ => Err(PacketParseError::WrongPacketForServerType(u16::from_le_bytes([data[2], data[3]]), data.to_vec()))
|
||||||
@ -184,6 +188,8 @@ pub enum SendShipPacket {
|
|||||||
DoneLoadingQuest(DoneLoadingQuest),
|
DoneLoadingQuest(DoneLoadingQuest),
|
||||||
BankItemList(BankItemList),
|
BankItemList(BankItemList),
|
||||||
RedirectClient(RedirectClient),
|
RedirectClient(RedirectClient),
|
||||||
|
AcknowledgeTrade(AcknowledgeTrade),
|
||||||
|
CancelTrade(CancelTrade),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SendServerPacket for SendShipPacket {
|
impl SendServerPacket for SendShipPacket {
|
||||||
@ -221,6 +227,8 @@ impl SendServerPacket for SendShipPacket {
|
|||||||
SendShipPacket::DoneLoadingQuest(pkt) => pkt.as_bytes(),
|
SendShipPacket::DoneLoadingQuest(pkt) => pkt.as_bytes(),
|
||||||
SendShipPacket::BankItemList(pkt) => pkt.as_bytes(),
|
SendShipPacket::BankItemList(pkt) => pkt.as_bytes(),
|
||||||
SendShipPacket::RedirectClient(pkt) => pkt.as_bytes(),
|
SendShipPacket::RedirectClient(pkt) => pkt.as_bytes(),
|
||||||
|
SendShipPacket::AcknowledgeTrade(pkt) => pkt.as_bytes(),
|
||||||
|
SendShipPacket::CancelTrade(pkt) => pkt.as_bytes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,6 +247,14 @@ pub struct LoadingQuest {
|
|||||||
//pub quest_chunk_bin: Option<Box<dyn Iterator<Item = >>>,
|
//pub quest_chunk_bin: Option<Box<dyn Iterator<Item = >>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub enum TradeItem {
|
||||||
|
Individual(items::ClientItemId),
|
||||||
|
Stacked(items::ClientItemId, usize),
|
||||||
|
Meseta(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct ClientState {
|
pub struct ClientState {
|
||||||
pub user: UserAccountEntity,
|
pub user: UserAccountEntity,
|
||||||
pub settings: UserSettingsEntity,
|
pub settings: UserSettingsEntity,
|
||||||
@ -257,6 +273,8 @@ pub struct ClientState {
|
|||||||
pub tool_shop: Vec<ToolShopItem>,
|
pub tool_shop: Vec<ToolShopItem>,
|
||||||
pub armor_shop: Vec<ArmorShopItem>,
|
pub armor_shop: Vec<ArmorShopItem>,
|
||||||
pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>,
|
pub tek: Option<(items::ClientItemId, item::weapon::TekSpecialModifier, item::weapon::TekPercentModifier, i32)>,
|
||||||
|
pub trade: Option<(ClientId, Vec<TradeItem>)>,
|
||||||
|
pub confirmed_trade: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientState {
|
impl ClientState {
|
||||||
@ -277,6 +295,8 @@ impl ClientState {
|
|||||||
tool_shop: Vec::new(),
|
tool_shop: Vec::new(),
|
||||||
armor_shop: Vec::new(),
|
armor_shop: Vec::new(),
|
||||||
tek: None,
|
tek: None,
|
||||||
|
trade: None,
|
||||||
|
confirmed_trade: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,7 +716,16 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
|||||||
},
|
},
|
||||||
RecvShipPacket::RequestShipBlockList(_) => {
|
RecvShipPacket::RequestShipBlockList(_) => {
|
||||||
handler::ship::block_list(id, &self.name, self.blocks.0.len())
|
handler::ship::block_list(id, &self.name, self.blocks.0.len())
|
||||||
}
|
},
|
||||||
|
RecvShipPacket::ItemsToTrade(items_to_trade) => {
|
||||||
|
log::warn!("trade! {:?} {:?}", id, items_to_trade);
|
||||||
|
let block = self.blocks.with_client(id, &self.clients)?;
|
||||||
|
handler::trade::items_to_trade(id, items_to_trade, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager).await?
|
||||||
|
},
|
||||||
|
RecvShipPacket::TradeConfirmed(_) => {
|
||||||
|
let block = self.blocks.with_client(id, &self.clients)?;
|
||||||
|
handler::trade::trade_confirmed(id, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager).await?
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user