appease the clip
This commit is contained in:
parent
22f630f562
commit
a6e50555de
@ -160,19 +160,11 @@ pub struct CharacterAppearance {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TechLevel(pub u8);
|
pub struct TechLevel(pub u8);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct CharacterTechniques {
|
pub struct CharacterTechniques {
|
||||||
pub techs: HashMap<Technique, TechLevel>
|
pub techs: HashMap<Technique, TechLevel>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CharacterTechniques {
|
|
||||||
fn default() -> CharacterTechniques {
|
|
||||||
CharacterTechniques {
|
|
||||||
techs: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharacterTechniques {
|
impl CharacterTechniques {
|
||||||
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
|
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
|
||||||
self.techs.insert(tech, TechLevel(level.0 - 1));
|
self.techs.insert(tech, TechLevel(level.0 - 1));
|
||||||
|
@ -231,7 +231,7 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
Ok(new_item)
|
Ok(new_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_item_note(&mut self, item_id: &ItemEntityId, item_note: ItemNote) -> Result<(), GatewayError> {
|
async fn add_item_note(&mut self, _item_id: &ItemEntityId, _item_note: ItemNote) -> Result<(), GatewayError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ impl EntityGateway for InMemoryGateway {
|
|||||||
|
|
||||||
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
|
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
|
||||||
let mut character_meseta = self.character_meseta.lock().unwrap();
|
let mut character_meseta = self.character_meseta.lock().unwrap();
|
||||||
if let Some(meseta) = character_meseta.get_mut(&char_id) {
|
if let Some(meseta) = character_meseta.get_mut(char_id) {
|
||||||
Ok(*meseta)
|
Ok(*meseta)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
@ -224,7 +224,7 @@ impl InventoryItemEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn individual<'a>(&'a self) -> Option<&'a ItemEntity> {
|
pub fn individual(&self) -> Option<&ItemEntity> {
|
||||||
match self {
|
match self {
|
||||||
InventoryItemEntity::Individual(i) => Some(i),
|
InventoryItemEntity::Individual(i) => Some(i),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -260,7 +260,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
|
|||||||
let (monomates, monofluids) = futures::future::join_all((0..4usize).map(|_| {
|
let (monomates, monofluids) = futures::future::join_all((0..4usize).map(|_| {
|
||||||
let mut eg = entity_gateway.clone();
|
let mut eg = entity_gateway.clone();
|
||||||
let character_id = character.id;
|
let character_id = character.id;
|
||||||
return async move {
|
async move {
|
||||||
let monomate = eg.create_item(
|
let monomate = eg.create_item(
|
||||||
NewItemEntity {
|
NewItemEntity {
|
||||||
item: ItemDetail::Tool (
|
item: ItemDetail::Tool (
|
||||||
|
@ -4,6 +4,8 @@ use crate::entity::character::CharacterEntity;
|
|||||||
use crate::ship::items::{CharacterInventory, CharacterBank};
|
use crate::ship::items::{CharacterInventory, CharacterBank};
|
||||||
use crate::entity::item::Meseta;
|
use crate::entity::item::Meseta;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct CharacterBytesBuilder<'a> {
|
pub struct CharacterBytesBuilder<'a> {
|
||||||
character: Option<&'a CharacterEntity>,
|
character: Option<&'a CharacterEntity>,
|
||||||
stats: Option<&'a CharacterStats>,
|
stats: Option<&'a CharacterStats>,
|
||||||
@ -11,18 +13,6 @@ pub struct CharacterBytesBuilder<'a> {
|
|||||||
meseta: Option<Meseta>,
|
meseta: Option<Meseta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for CharacterBytesBuilder<'a> {
|
|
||||||
fn default() -> CharacterBytesBuilder<'a> {
|
|
||||||
CharacterBytesBuilder {
|
|
||||||
character: None,
|
|
||||||
stats: None,
|
|
||||||
level: None,
|
|
||||||
meseta: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl<'a> CharacterBytesBuilder<'a> {
|
impl<'a> CharacterBytesBuilder<'a> {
|
||||||
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
|
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
|
||||||
CharacterBytesBuilder {
|
CharacterBytesBuilder {
|
||||||
@ -89,6 +79,7 @@ impl<'a> CharacterBytesBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct FullCharacterBytesBuilder<'a> {
|
pub struct FullCharacterBytesBuilder<'a> {
|
||||||
character: Option<&'a CharacterEntity>,
|
character: Option<&'a CharacterEntity>,
|
||||||
stats: Option<&'a CharacterStats>,
|
stats: Option<&'a CharacterStats>,
|
||||||
@ -103,25 +94,6 @@ pub struct FullCharacterBytesBuilder<'a> {
|
|||||||
option_flags: Option<u32>,
|
option_flags: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for FullCharacterBytesBuilder<'a> {
|
|
||||||
fn default() -> FullCharacterBytesBuilder<'a> {
|
|
||||||
FullCharacterBytesBuilder {
|
|
||||||
character: None,
|
|
||||||
stats: None,
|
|
||||||
level: None,
|
|
||||||
meseta: None,
|
|
||||||
inventory: None,
|
|
||||||
bank: None,
|
|
||||||
key_config: None,
|
|
||||||
joystick_config: None,
|
|
||||||
symbol_chat: None,
|
|
||||||
tech_menu: None,
|
|
||||||
option_flags: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl<'a> FullCharacterBytesBuilder<'a> {
|
impl<'a> FullCharacterBytesBuilder<'a> {
|
||||||
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
|
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
|
||||||
FullCharacterBytesBuilder {
|
FullCharacterBytesBuilder {
|
||||||
|
@ -293,7 +293,7 @@ impl CharacterBank {
|
|||||||
self.items.last()
|
self.items.last()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_bank_entity(&self, character_id: &CharacterEntityId, bank_name: &BankName) -> BankEntity {
|
pub fn as_bank_entity(&self, _character_id: &CharacterEntityId, _bank_name: &BankName) -> BankEntity {
|
||||||
BankEntity {
|
BankEntity {
|
||||||
items: self.items.iter()
|
items: self.items.iter()
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
|
@ -159,15 +159,9 @@ impl<'a> FloorItemHandle<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: floors should keep track of their own item_ids
|
// TODO: floors should keep track of their own item_ids
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct RoomFloorItems(Vec<FloorItem>);
|
pub struct RoomFloorItems(Vec<FloorItem>);
|
||||||
|
|
||||||
impl Default for RoomFloorItems {
|
|
||||||
fn default() -> RoomFloorItems {
|
|
||||||
RoomFloorItems(Vec::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RoomFloorItems {
|
impl RoomFloorItems {
|
||||||
pub fn add_item(&mut self, item: FloorItem) {
|
pub fn add_item(&mut self, item: FloorItem) {
|
||||||
self.0.push(item);
|
self.0.push(item);
|
||||||
|
@ -897,7 +897,7 @@ impl CharacterInventory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_inventory_entity(&self, character_id: &CharacterEntityId) -> InventoryEntity {
|
pub fn as_inventory_entity(&self, _character_id: &CharacterEntityId) -> InventoryEntity {
|
||||||
InventoryEntity {
|
InventoryEntity {
|
||||||
items: self.items.iter()
|
items: self.items.iter()
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use log::warn;
|
|
||||||
use crate::ship::items::ClientItemId;
|
use crate::ship::items::ClientItemId;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -6,7 +5,7 @@ use thiserror::Error;
|
|||||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||||
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
||||||
use crate::entity::item::{ItemDetail, ItemNote, BankName};
|
use crate::entity::item::{ItemDetail, ItemNote, BankName};
|
||||||
use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, ItemEntityId, InventoryItemEntity, BankItemEntity};
|
use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, BankItemEntity};
|
||||||
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;
|
||||||
@ -239,38 +238,36 @@ impl ItemManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
self.character_bank
|
||||||
.get(&character.id)
|
.get(&character.id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(character.id))?)
|
.ok_or_else(|| ItemManagerError::NoCharacter(character.id).into())
|
||||||
//.get(&BankName("".to_string()))
|
|
||||||
//.ok_or(ItemManagerError::InvalidBankName(BankName("".to_string())))?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_character_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
pub fn get_character_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
||||||
Ok(self.character_meseta.get(&character_id)
|
self.character_meseta.get(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
.ok_or(ItemManagerError::NoCharacter(*character_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_character_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> {
|
pub fn get_character_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> {
|
||||||
Ok(self.character_meseta.get_mut(&character_id)
|
self.character_meseta.get_mut(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
.ok_or(ItemManagerError::NoCharacter(*character_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bank_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
pub fn get_bank_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
||||||
Ok(self.bank_meseta.get(&character_id)
|
self.bank_meseta.get(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
.ok_or(ItemManagerError::NoCharacter(*character_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> {
|
pub fn get_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<&'a mut Meseta, ItemManagerError> {
|
||||||
Ok(self.bank_meseta.get_mut(&character_id)
|
self.bank_meseta.get_mut(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
.ok_or(ItemManagerError::NoCharacter(*character_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_character_and_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<(&'a mut Meseta, &'a mut Meseta), ItemManagerError> {
|
pub fn get_character_and_bank_meseta_mut<'a>(&'a mut self, character_id: &CharacterEntityId) -> Result<(&'a mut Meseta, &'a mut Meseta), ItemManagerError> {
|
||||||
Ok((
|
Ok((
|
||||||
self.character_meseta.get_mut(&character_id)
|
self.character_meseta.get_mut(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?,
|
.ok_or(ItemManagerError::NoCharacter(*character_id))?,
|
||||||
self.bank_meseta.get_mut(&character_id)
|
self.bank_meseta.get_mut(character_id)
|
||||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?
|
.ok_or(ItemManagerError::NoCharacter(*character_id))?
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -299,7 +296,7 @@ impl ItemManager {
|
|||||||
|
|
||||||
pub async fn character_picks_up_item<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, item_id: ClientItemId)
|
pub async fn character_picks_up_item<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, item_id: ClientItemId)
|
||||||
-> Result<TriggerCreateItem, anyhow::Error> {
|
-> Result<TriggerCreateItem, anyhow::Error> {
|
||||||
let it = ItemTransaction::new(&self, (character, item_id))
|
let it = ItemTransaction::new(self, (character, item_id))
|
||||||
.act(|it, (character, item_id)| -> Result<_, ItemManagerError> {
|
.act(|it, (character, item_id)| -> Result<_, ItemManagerError> {
|
||||||
let local_floor = it.manager.character_floor.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
let local_floor = it.manager.character_floor.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||||
let inventory = it.manager.character_inventory.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
let inventory = it.manager.character_inventory.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||||
@ -310,7 +307,7 @@ impl ItemManager {
|
|||||||
Some(floor_item) => {
|
Some(floor_item) => {
|
||||||
it.action(Box::new(RemoveFromLocalFloor {
|
it.action(Box::new(RemoveFromLocalFloor {
|
||||||
character_id: character.id,
|
character_id: character.id,
|
||||||
item_id: item_id.clone()
|
item_id: *item_id
|
||||||
}));
|
}));
|
||||||
floor_item
|
floor_item
|
||||||
},
|
},
|
||||||
@ -319,12 +316,12 @@ impl ItemManager {
|
|||||||
Some(floor_item) => {
|
Some(floor_item) => {
|
||||||
it.action(Box::new(RemoveFromSharedFloor {
|
it.action(Box::new(RemoveFromSharedFloor {
|
||||||
room_id: *room_id,
|
room_id: *room_id,
|
||||||
item_id: item_id.clone()
|
item_id: *item_id
|
||||||
}));
|
}));
|
||||||
floor_item
|
floor_item
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
return Err(ItemManagerError::NoSuchItemId(item_id.clone())).into()
|
return Err(ItemManagerError::NoSuchItemId(*item_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,7 +336,7 @@ impl ItemManager {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||||
}
|
}
|
||||||
TriggerCreateItem::Yes
|
TriggerCreateItem::Yes
|
||||||
},
|
},
|
||||||
@ -360,14 +357,14 @@ impl ItemManager {
|
|||||||
TriggerCreateItem::No
|
TriggerCreateItem::No
|
||||||
},
|
},
|
||||||
SpaceForStack::No(_) => {
|
SpaceForStack::No(_) => {
|
||||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FloorItem::Meseta(meseta_floor_item) => {
|
FloorItem::Meseta(meseta_floor_item) => {
|
||||||
let character_meseta = it.manager.character_meseta.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
let character_meseta = it.manager.character_meseta.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||||
if character_meseta.0 >= 999999 {
|
if character_meseta.0 >= 999999 {
|
||||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||||
}
|
}
|
||||||
it.action(Box::new(AddMesetaFloorItemToInventory {
|
it.action(Box::new(AddMesetaFloorItemToInventory {
|
||||||
character_id: character.id,
|
character_id: character.id,
|
||||||
@ -615,7 +612,7 @@ impl ItemManager {
|
|||||||
.ok_or(ItemManagerError::NoCharacter(character.id))?;
|
.ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||||
|
|
||||||
let item_to_deposit = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
let item_to_deposit = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
||||||
let bank_item = bank.deposit_item(item_to_deposit, amount).ok_or(ItemManagerError::Idunnoman)?;
|
let _bank_item = bank.deposit_item(item_to_deposit, amount).ok_or(ItemManagerError::Idunnoman)?;
|
||||||
|
|
||||||
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||||
entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), BankName("".into())).await?;
|
entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), BankName("".into())).await?;
|
||||||
@ -972,7 +969,7 @@ impl ItemManager {
|
|||||||
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, usize),
|
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, usize),
|
||||||
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, usize))
|
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, usize))
|
||||||
-> Result<Vec<ItemToTrade>, anyhow::Error> {
|
-> Result<Vec<ItemToTrade>, anyhow::Error> {
|
||||||
let it = ItemTransaction::new(&self, (p1, p2, room_id))
|
let it = ItemTransaction::new(self, (p1, p2, room_id))
|
||||||
.act(|it, (p1, p2, room_id)| -> Result<_, anyhow::Error> {
|
.act(|it, (p1, p2, room_id)| -> Result<_, anyhow::Error> {
|
||||||
let p1_inventory = it.manager.get_character_inventory(p1.1)?;
|
let p1_inventory = it.manager.get_character_inventory(p1.1)?;
|
||||||
let p2_inventory = it.manager.get_character_inventory(p2.1)?;
|
let p2_inventory = it.manager.get_character_inventory(p2.1)?;
|
||||||
@ -1049,27 +1046,27 @@ impl ItemManager {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
let trade_items = [(p1, p2, p1_inventory, p2_inventory), (p2, p1, p2_inventory, p1_inventory)]
|
let trade_items = [(p1, p2, p1_inventory), (p2, p1, p2_inventory)]
|
||||||
.map(|(src_client, dest_client, src_inventory, dest_inventory)| {
|
.map(|(src_client, dest_client, src_inventory)| {
|
||||||
src_client.2.iter()
|
src_client.2.iter()
|
||||||
.map(|item| -> Option<(Option<ItemToTrade>, Box<dyn ItemAction<EG>>)> {
|
.map(|item| -> Option<(Option<ItemToTrade>, Box<dyn ItemAction<EG>>)> {
|
||||||
match item {
|
match item {
|
||||||
TradeItem::Individual(item_id) => {
|
TradeItem::Individual(item_id) => {
|
||||||
let item = src_inventory.get_item_by_id(*item_id)?.individual()?;
|
let item = src_inventory.get_item_by_id(*item_id)?.individual()?;
|
||||||
let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(&room_id)?();
|
let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(room_id)?();
|
||||||
Some((
|
Some((
|
||||||
Some(ItemToTrade {
|
Some(ItemToTrade {
|
||||||
add_to: *dest_client.0,
|
add_to: *dest_client.0,
|
||||||
remove_from: *src_client.0,
|
remove_from: *src_client.0,
|
||||||
current_item_id: *item_id,
|
current_item_id: *item_id,
|
||||||
new_item_id: new_item_id,
|
new_item_id,
|
||||||
item_detail: ItemToTradeDetail::Individual(item.item.clone())
|
item_detail: ItemToTradeDetail::Individual(item.item.clone())
|
||||||
}),
|
}),
|
||||||
Box::new(TradeIndividualItem {
|
Box::new(TradeIndividualItem {
|
||||||
src_character_id: src_client.1.id,
|
src_character_id: src_client.1.id,
|
||||||
dest_character_id: dest_client.1.id,
|
dest_character_id: dest_client.1.id,
|
||||||
current_item_id: *item_id,
|
current_item_id: *item_id,
|
||||||
new_item_id: new_item_id,
|
new_item_id,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
@ -1079,13 +1076,13 @@ impl ItemManager {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(&room_id)?();
|
let new_item_id = it.manager.room_item_id_counter.borrow_mut().get_mut(room_id)?();
|
||||||
Some((
|
Some((
|
||||||
Some(ItemToTrade {
|
Some(ItemToTrade {
|
||||||
add_to: *dest_client.0,
|
add_to: *dest_client.0,
|
||||||
remove_from: *src_client.0,
|
remove_from: *src_client.0,
|
||||||
current_item_id: *item_id,
|
current_item_id: *item_id,
|
||||||
new_item_id: new_item_id,
|
new_item_id,
|
||||||
item_detail: ItemToTradeDetail::Stacked(item.tool, *amount)
|
item_detail: ItemToTradeDetail::Stacked(item.tool, *amount)
|
||||||
}),
|
}),
|
||||||
Box::new(TradeStackedItem {
|
Box::new(TradeStackedItem {
|
||||||
@ -1093,7 +1090,7 @@ impl ItemManager {
|
|||||||
dest_character_id: dest_client.1.id,
|
dest_character_id: dest_client.1.id,
|
||||||
//item_ids: item.entity_ids.iter().cloned().take(*amount).collect(),
|
//item_ids: item.entity_ids.iter().cloned().take(*amount).collect(),
|
||||||
current_item_id: *item_id,
|
current_item_id: *item_id,
|
||||||
new_item_id: new_item_id,
|
new_item_id,
|
||||||
amount: *amount,
|
amount: *amount,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
@ -1125,8 +1122,8 @@ impl ItemManager {
|
|||||||
|
|
||||||
|
|
||||||
if let [Some(p1_trades), Some(p2_trades)] = trade_items {
|
if let [Some(p1_trades), Some(p2_trades)] = trade_items {
|
||||||
let (p1_item_trades, p1_item_actions): (Vec<Option<ItemToTrade>>, Vec<Box<dyn ItemAction<EG>>>) = p1_trades.into_iter().unzip();
|
let (p1_item_trades, p1_item_actions): (Vec<_>, Vec<_>) = p1_trades.into_iter().unzip();
|
||||||
let (p2_item_trades, p2_item_actions): (Vec<Option<ItemToTrade>>, Vec<Box<dyn ItemAction<EG>>>) = p2_trades.into_iter().unzip();
|
let (p2_item_trades, p2_item_actions): (Vec<_>, Vec<_>) = p2_trades.into_iter().unzip();
|
||||||
|
|
||||||
let item_trades = p1_item_trades.into_iter().flatten().chain(p2_item_trades.into_iter().flatten());
|
let item_trades = p1_item_trades.into_iter().flatten().chain(p2_item_trades.into_iter().flatten());
|
||||||
let item_actions = p1_item_actions.into_iter().chain(p2_item_actions.into_iter());
|
let item_actions = p1_item_actions.into_iter().chain(p2_item_actions.into_iter());
|
||||||
|
@ -1,17 +1,8 @@
|
|||||||
use crate::entity::gateway::EntityGateway;
|
use crate::entity::gateway::EntityGateway;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use std::borrow::Cow;
|
|
||||||
use crate::ship::items::manager::{ItemManager, ItemManagerError};
|
use crate::ship::items::manager::{ItemManager, ItemManagerError};
|
||||||
use std::collections::HashMap;
|
|
||||||
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
|
||||||
use crate::ship::items::bank::*;
|
|
||||||
use crate::ship::items::floor::*;
|
|
||||||
use crate::ship::items::inventory::*;
|
|
||||||
use crate::ship::items::ClientItemId;
|
|
||||||
use crate::entity::gateway::GatewayError;
|
use crate::entity::gateway::GatewayError;
|
||||||
|
|
||||||
use crate::ship::location::{AreaClient, RoomId};
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum TransactionCommitError {
|
pub enum TransactionCommitError {
|
||||||
#[error("transaction commit gateway error {0}")]
|
#[error("transaction commit gateway error {0}")]
|
||||||
|
@ -287,18 +287,11 @@ impl MapAreaLookup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct MapAreaLookupBuilder {
|
pub struct MapAreaLookupBuilder {
|
||||||
map_areas: HashMap<u16, MapArea>,
|
map_areas: HashMap<u16, MapArea>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MapAreaLookupBuilder {
|
|
||||||
fn default() -> MapAreaLookupBuilder {
|
|
||||||
MapAreaLookupBuilder {
|
|
||||||
map_areas: HashMap::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MapAreaLookupBuilder {
|
impl MapAreaLookupBuilder {
|
||||||
pub fn add(mut self, value: u16, map_area: MapArea) -> MapAreaLookupBuilder {
|
pub fn add(mut self, value: u16, map_area: MapArea) -> MapAreaLookupBuilder {
|
||||||
self.map_areas.insert(value, map_area);
|
self.map_areas.insert(value, map_area);
|
||||||
|
@ -14,17 +14,17 @@ pub struct RawMapEnemy {
|
|||||||
id: u32,
|
id: u32,
|
||||||
_unknown1: u16,
|
_unknown1: u16,
|
||||||
pub children: u16,
|
pub children: u16,
|
||||||
map_area: u16,
|
_map_area: u16,
|
||||||
_unknown4: u16,
|
_unknown4: u16,
|
||||||
section: u16,
|
_section: u16,
|
||||||
wave_idd: u16,
|
_wave_idd: u16,
|
||||||
wave_id: u32,
|
_wave_id: u32,
|
||||||
x: f32,
|
_x: f32,
|
||||||
y: f32,
|
_y: f32,
|
||||||
z: f32,
|
_z: f32,
|
||||||
xrot: u32,
|
_xrot: u32,
|
||||||
yrot: u32,
|
_yrot: u32,
|
||||||
zrot: u32,
|
_zrot: u32,
|
||||||
_field1: u32,
|
_field1: u32,
|
||||||
field2: u32,
|
field2: u32,
|
||||||
_field3: u32,
|
_field3: u32,
|
||||||
@ -40,17 +40,17 @@ impl RawMapEnemy {
|
|||||||
id: cursor.read_u32::<LittleEndian>()?,
|
id: cursor.read_u32::<LittleEndian>()?,
|
||||||
_unknown1: cursor.read_u16::<LittleEndian>()?,
|
_unknown1: cursor.read_u16::<LittleEndian>()?,
|
||||||
children: cursor.read_u16::<LittleEndian>()?,
|
children: cursor.read_u16::<LittleEndian>()?,
|
||||||
map_area: cursor.read_u16::<LittleEndian>()?,
|
_map_area: cursor.read_u16::<LittleEndian>()?,
|
||||||
_unknown4: cursor.read_u16::<LittleEndian>()?,
|
_unknown4: cursor.read_u16::<LittleEndian>()?,
|
||||||
section: cursor.read_u16::<LittleEndian>()?,
|
_section: cursor.read_u16::<LittleEndian>()?,
|
||||||
wave_idd: cursor.read_u16::<LittleEndian>()?,
|
_wave_idd: cursor.read_u16::<LittleEndian>()?,
|
||||||
wave_id: cursor.read_u32::<LittleEndian>()?,
|
_wave_id: cursor.read_u32::<LittleEndian>()?,
|
||||||
x: cursor.read_f32::<LittleEndian>()?,
|
_x: cursor.read_f32::<LittleEndian>()?,
|
||||||
y: cursor.read_f32::<LittleEndian>()?,
|
_y: cursor.read_f32::<LittleEndian>()?,
|
||||||
z: cursor.read_f32::<LittleEndian>()?,
|
_z: cursor.read_f32::<LittleEndian>()?,
|
||||||
xrot: cursor.read_u32::<LittleEndian>()?,
|
_xrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
yrot: cursor.read_u32::<LittleEndian>()?,
|
_yrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
zrot: cursor.read_u32::<LittleEndian>()?,
|
_zrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
_field1: cursor.read_u32::<LittleEndian>()?,
|
_field1: cursor.read_u32::<LittleEndian>()?,
|
||||||
field2: cursor.read_u32::<LittleEndian>()?,
|
field2: cursor.read_u32::<LittleEndian>()?,
|
||||||
_field3: cursor.read_u32::<LittleEndian>()?,
|
_field3: cursor.read_u32::<LittleEndian>()?,
|
||||||
@ -75,7 +75,7 @@ pub enum MapEnemyError {
|
|||||||
pub struct MapEnemy {
|
pub struct MapEnemy {
|
||||||
pub monster: MonsterType,
|
pub monster: MonsterType,
|
||||||
pub map_area: MapArea,
|
pub map_area: MapArea,
|
||||||
hp: u32,
|
_hp: u32,
|
||||||
// TODO: other stats from battleparam
|
// TODO: other stats from battleparam
|
||||||
pub player_hit: [bool; 4],
|
pub player_hit: [bool; 4],
|
||||||
pub dropped_item: bool,
|
pub dropped_item: bool,
|
||||||
@ -254,7 +254,7 @@ impl MapEnemy {
|
|||||||
Ok(MapEnemy {
|
Ok(MapEnemy {
|
||||||
monster,
|
monster,
|
||||||
map_area: *map_area,
|
map_area: *map_area,
|
||||||
hp: 0,
|
_hp: 0,
|
||||||
dropped_item: false,
|
dropped_item: false,
|
||||||
gave_exp: false,
|
gave_exp: false,
|
||||||
player_hit: [false; 4],
|
player_hit: [false; 4],
|
||||||
@ -265,7 +265,7 @@ impl MapEnemy {
|
|||||||
MapEnemy {
|
MapEnemy {
|
||||||
monster,
|
monster,
|
||||||
map_area,
|
map_area,
|
||||||
hp: 0,
|
_hp: 0,
|
||||||
dropped_item: false,
|
dropped_item: false,
|
||||||
gave_exp: false,
|
gave_exp: false,
|
||||||
player_hit: [false; 4],
|
player_hit: [false; 4],
|
||||||
|
@ -13,50 +13,50 @@ use crate::ship::map::*;
|
|||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct RawMapObject {
|
pub struct RawMapObject {
|
||||||
otype: u16,
|
otype: u16,
|
||||||
unknown1: u16,
|
_unknown1: u16,
|
||||||
unknown2: u32,
|
_unknown2: u32,
|
||||||
id: u16,
|
_id: u16,
|
||||||
group: u16,
|
_group: u16,
|
||||||
section: u16,
|
_section: u16,
|
||||||
unknown3: u16,
|
_unknown3: u16,
|
||||||
x: f32,
|
_x: f32,
|
||||||
y: f32,
|
_y: f32,
|
||||||
z: f32,
|
_z: f32,
|
||||||
xrot: u32,
|
_xrot: u32,
|
||||||
yrot: u32,
|
_yrot: u32,
|
||||||
zrot: u32,
|
_zrot: u32,
|
||||||
field1: f32,
|
field1: f32,
|
||||||
field2: f32,
|
field2: f32,
|
||||||
field3: f32,
|
field3: f32,
|
||||||
field4: u32,
|
field4: u32,
|
||||||
field5: u32,
|
_field5: u32,
|
||||||
field6: u32,
|
_field6: u32,
|
||||||
field7: u32,
|
_field7: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawMapObject {
|
impl RawMapObject {
|
||||||
pub fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
|
pub fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
|
||||||
Ok(RawMapObject {
|
Ok(RawMapObject {
|
||||||
otype: cursor.read_u16::<LittleEndian>()?,
|
otype: cursor.read_u16::<LittleEndian>()?,
|
||||||
unknown1: cursor.read_u16::<LittleEndian>()?,
|
_unknown1: cursor.read_u16::<LittleEndian>()?,
|
||||||
unknown2: cursor.read_u32::<LittleEndian>()?,
|
_unknown2: cursor.read_u32::<LittleEndian>()?,
|
||||||
id: cursor.read_u16::<LittleEndian>()?,
|
_id: cursor.read_u16::<LittleEndian>()?,
|
||||||
group: cursor.read_u16::<LittleEndian>()?,
|
_group: cursor.read_u16::<LittleEndian>()?,
|
||||||
section: cursor.read_u16::<LittleEndian>()?,
|
_section: cursor.read_u16::<LittleEndian>()?,
|
||||||
unknown3: cursor.read_u16::<LittleEndian>()?,
|
_unknown3: cursor.read_u16::<LittleEndian>()?,
|
||||||
x: cursor.read_f32::<LittleEndian>()?,
|
_x: cursor.read_f32::<LittleEndian>()?,
|
||||||
y: cursor.read_f32::<LittleEndian>()?,
|
_y: cursor.read_f32::<LittleEndian>()?,
|
||||||
z: cursor.read_f32::<LittleEndian>()?,
|
_z: cursor.read_f32::<LittleEndian>()?,
|
||||||
xrot: cursor.read_u32::<LittleEndian>()?,
|
_xrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
yrot: cursor.read_u32::<LittleEndian>()?,
|
_yrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
zrot: cursor.read_u32::<LittleEndian>()?,
|
_zrot: cursor.read_u32::<LittleEndian>()?,
|
||||||
field1: cursor.read_f32::<LittleEndian>()?,
|
field1: cursor.read_f32::<LittleEndian>()?,
|
||||||
field2: cursor.read_f32::<LittleEndian>()?,
|
field2: cursor.read_f32::<LittleEndian>()?,
|
||||||
field3: cursor.read_f32::<LittleEndian>()?,
|
field3: cursor.read_f32::<LittleEndian>()?,
|
||||||
field4: cursor.read_u32::<LittleEndian>()?,
|
field4: cursor.read_u32::<LittleEndian>()?,
|
||||||
field5: cursor.read_u32::<LittleEndian>()?,
|
_field5: cursor.read_u32::<LittleEndian>()?,
|
||||||
field6: cursor.read_u32::<LittleEndian>()?,
|
_field6: cursor.read_u32::<LittleEndian>()?,
|
||||||
field7: cursor.read_u32::<LittleEndian>()?,
|
_field7: cursor.read_u32::<LittleEndian>()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use log::warn;
|
|
||||||
use rand::Rng;
|
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
use libpso::packet::ship::*;
|
use libpso::packet::ship::*;
|
||||||
use libpso::packet::messages::*;
|
use libpso::packet::messages::*;
|
||||||
use crate::common::leveltable::CharacterLevelTable;
|
|
||||||
use crate::common::serverstate::ClientId;
|
use crate::common::serverstate::ClientId;
|
||||||
use crate::ship::ship::{SendShipPacket, ShipError, Clients, Rooms, ItemShops};
|
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
|
||||||
use crate::ship::location::{ClientLocation, ClientLocationError, LocalClientId};
|
use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||||
use crate::ship::drops::ItemDrop;
|
use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, ItemToTradeDetail};
|
||||||
use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, TriggerCreateItem, FloorItem, FloorType, ItemToTradeDetail};
|
|
||||||
use crate::ship::items::inventory::InventoryItem;
|
use crate::ship::items::inventory::InventoryItem;
|
||||||
use crate::ship::trade::{TradeItem, TradeState, TradeStatus};
|
use crate::ship::trade::{TradeItem, TradeState, TradeStatus};
|
||||||
use crate::entity::gateway::EntityGateway;
|
use crate::entity::gateway::EntityGateway;
|
||||||
use crate::entity::item;
|
|
||||||
use libpso::utf8_to_utf16_array;
|
|
||||||
use crate::ship::packet::builder;
|
use crate::ship::packet::builder;
|
||||||
use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem};
|
|
||||||
|
|
||||||
pub const MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFF01);
|
pub const MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFF01);
|
||||||
pub const OTHER_MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFFFF);
|
pub const OTHER_MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFFFF);
|
||||||
@ -54,21 +46,18 @@ pub enum TradeError {
|
|||||||
|
|
||||||
|
|
||||||
// TODO: remove target
|
// TODO: remove target
|
||||||
pub async fn trade_request<EG>(id: ClientId,
|
pub async fn trade_request(id: ClientId,
|
||||||
trade_request: &TradeRequest,
|
trade_request: &TradeRequest,
|
||||||
target: u32,
|
target: u32,
|
||||||
entity_gateway: &mut EG,
|
|
||||||
client_location: &ClientLocation,
|
client_location: &ClientLocation,
|
||||||
clients: &mut Clients,
|
clients: &mut Clients,
|
||||||
item_manager: &mut ItemManager,
|
item_manager: &mut ItemManager,
|
||||||
trades: &mut TradeState)
|
trades: &mut TradeState)
|
||||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
where
|
|
||||||
EG: EntityGateway
|
|
||||||
{
|
{
|
||||||
let trade_request = trade_request.clone(); // TODO: make this function take ownership of packet
|
let trade_request = trade_request.clone(); // TODO: make this function take ownership of packet
|
||||||
match trade_request.trade {
|
match trade_request.trade {
|
||||||
TradeRequestCommand::Initialize(ref act, meseta) => {
|
TradeRequestCommand::Initialize(ref act, _meseta) => {
|
||||||
match act {
|
match act {
|
||||||
TradeRequestInitializeCommand::Initialize => {
|
TradeRequestInitializeCommand::Initialize => {
|
||||||
if trades.in_trade(&id) {
|
if trades.in_trade(&id) {
|
||||||
@ -76,10 +65,9 @@ where
|
|||||||
}
|
}
|
||||||
let trade_partner = client_location.get_client_neighbors(id)?
|
let trade_partner = client_location.get_client_neighbors(id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|ac| {
|
.find(|ac| {
|
||||||
ac.local_client.id() == target as u8 //trade_request.client
|
ac.local_client.id() == target as u8 //trade_request.client
|
||||||
})
|
})
|
||||||
.next()
|
|
||||||
.ok_or(TradeError::CouldNotFindTradePartner)?;
|
.ok_or(TradeError::CouldNotFindTradePartner)?;
|
||||||
if trades.in_trade(&trade_partner.client) {
|
if trades.in_trade(&trade_partner.client) {
|
||||||
return Err(TradeError::OtherAlreadyInTrade.into())
|
return Err(TradeError::OtherAlreadyInTrade.into())
|
||||||
@ -125,7 +113,7 @@ where
|
|||||||
Ok(trades
|
Ok(trades
|
||||||
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
||||||
if this.status == TradeStatus::Trading && other.status == TradeStatus::Trading {
|
if this.status == TradeStatus::Trading && other.status == TradeStatus::Trading {
|
||||||
let client = clients.get(&this.client()).ok_or(ShipError::ClientNotFound(this.client()))?;
|
let client = clients.get(&this.client()).ok_or_else(|| ShipError::ClientNotFound(this.client()))?;
|
||||||
let inventory = item_manager.get_character_inventory(&client.character)?;
|
let inventory = item_manager.get_character_inventory(&client.character)?;
|
||||||
if ClientItemId(item_id) == MESETA_ITEM_ID {
|
if ClientItemId(item_id) == MESETA_ITEM_ID {
|
||||||
this.meseta += amount as usize;
|
this.meseta += amount as usize;
|
||||||
@ -157,7 +145,7 @@ where
|
|||||||
Err(TradeError::MismatchedStatus.into())
|
Err(TradeError::MismatchedStatus.into())
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|_err| {
|
||||||
trades.remove_trade(&id);
|
trades.remove_trade(&id);
|
||||||
Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
||||||
.filter(move |client| client.local_client.id() == target as u8)
|
.filter(move |client| client.local_client.id() == target as u8)
|
||||||
@ -184,9 +172,8 @@ where
|
|||||||
this.items.retain(|item| {
|
this.items.retain(|item| {
|
||||||
item.item_id() != ClientItemId(item_id)
|
item.item_id() != ClientItemId(item_id)
|
||||||
})
|
})
|
||||||
//this.items.push(TradeItem::Individual(ClientItemId(item_id)));
|
|
||||||
},
|
},
|
||||||
InventoryItem::Stacked(stacked_item) => {
|
InventoryItem::Stacked(_stacked_item) => {
|
||||||
let trade_item_index = this.items.iter()
|
let trade_item_index = this.items.iter()
|
||||||
.position(|item| {
|
.position(|item| {
|
||||||
item.item_id() == ClientItemId(item_id)
|
item.item_id() == ClientItemId(item_id)
|
||||||
@ -302,16 +289,13 @@ fn status_is_not<const N: usize>(status: &TradeStatus, statuses: &[TradeStatus;
|
|||||||
!status_is(status, statuses)
|
!status_is(status, statuses)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn inner_items_to_trade<EG>(id: ClientId,
|
pub async fn inner_items_to_trade(id: ClientId,
|
||||||
items_to_trade: &ItemsToTrade,
|
items_to_trade: &ItemsToTrade,
|
||||||
entity_gateway: &mut EG,
|
client_location: &ClientLocation,
|
||||||
client_location: &ClientLocation,
|
clients: &mut Clients,
|
||||||
clients: &mut Clients,
|
item_manager: &mut ItemManager,
|
||||||
item_manager: &mut ItemManager,
|
trades: &mut TradeState)
|
||||||
trades: &mut TradeState)
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
|
||||||
where
|
|
||||||
EG: EntityGateway
|
|
||||||
{
|
{
|
||||||
Ok(trades
|
Ok(trades
|
||||||
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
||||||
@ -319,8 +303,8 @@ where
|
|||||||
return Err(TradeError::MismatchedStatus.into())
|
return Err(TradeError::MismatchedStatus.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = clients.get(&this.client()).ok_or(ShipError::ClientNotFound(this.client()))?;
|
let client = clients.get(&this.client()).ok_or_else(|| ShipError::ClientNotFound(this.client()))?;
|
||||||
let other_client = clients.get(&other.client()).ok_or(ShipError::ClientNotFound(other.client()))?;
|
let other_client = clients.get(&other.client()).ok_or_else(|| ShipError::ClientNotFound(other.client()))?;
|
||||||
let inventory = item_manager.get_character_inventory(&client.character)?;
|
let inventory = item_manager.get_character_inventory(&client.character)?;
|
||||||
|
|
||||||
if items_to_trade.count as usize != (this.items.len() + (if this.meseta != 0 { 1 } else { 0 })) {
|
if items_to_trade.count as usize != (this.items.len() + (if this.meseta != 0 { 1 } else { 0 })) {
|
||||||
@ -355,14 +339,14 @@ where
|
|||||||
let real_trade_item = this.items
|
let real_trade_item = this.items
|
||||||
.iter()
|
.iter()
|
||||||
.find(|i| i.item_id() == ClientItemId(item.item_id))
|
.find(|i| i.item_id() == ClientItemId(item.item_id))
|
||||||
.ok_or_else(|| TradeError::SketchyTrade)?;
|
.ok_or(TradeError::SketchyTrade)?;
|
||||||
let trade_item_bytes: [u8; 16] = item.item_data.iter()
|
let trade_item_bytes: [u8; 16] = item.item_data.iter()
|
||||||
.chain(item.item_data2.iter())
|
.chain(item.item_data2.iter())
|
||||||
.cloned().collect::<Vec<u8>>()
|
.cloned().collect::<Vec<u8>>()
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
match real_item {
|
match real_item {
|
||||||
InventoryItem::Individual(individual_inventory_item) => {
|
InventoryItem::Individual(_individual_inventory_item) => {
|
||||||
if real_item.as_client_bytes() == trade_item_bytes {
|
if real_item.as_client_bytes() == trade_item_bytes {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -374,7 +358,7 @@ where
|
|||||||
if real_item.as_client_bytes()[0..4] == trade_item_bytes[0..4] {
|
if real_item.as_client_bytes()[0..4] == trade_item_bytes[0..4] {
|
||||||
let amount = trade_item_bytes[5] as usize;
|
let amount = trade_item_bytes[5] as usize;
|
||||||
if amount <= stacked_inventory_item.entity_ids.len() {
|
if amount <= stacked_inventory_item.entity_ids.len() {
|
||||||
if real_trade_item.stacked().ok_or_else(|| TradeError::SketchyTrade)?.1 == amount {
|
if real_trade_item.stacked().ok_or(TradeError::SketchyTrade)?.1 == amount {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -407,7 +391,7 @@ where
|
|||||||
})?
|
})?
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
log::warn!("trade error: {:?}", err);
|
log::warn!("trade error: {:?}", err);
|
||||||
let (this, other) = trades.remove_trade(&id);
|
let (_this, other) = trades.remove_trade(&id);
|
||||||
Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
||||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client() ).unwrap_or_else(|| false))
|
.filter(move |client| other.as_ref().map(|other| client.client == other.client() ).unwrap_or_else(|| false))
|
||||||
.map(move |client| {
|
.map(move |client| {
|
||||||
@ -417,23 +401,20 @@ where
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn items_to_trade<EG>(id: ClientId,
|
pub async fn items_to_trade(id: ClientId,
|
||||||
items_to_trade_pkt: &ItemsToTrade,
|
items_to_trade_pkt: &ItemsToTrade,
|
||||||
entity_gateway: &mut EG,
|
client_location: &ClientLocation,
|
||||||
client_location: &ClientLocation,
|
clients: &mut Clients,
|
||||||
clients: &mut Clients,
|
item_manager: &mut ItemManager,
|
||||||
item_manager: &mut ItemManager,
|
trades: &mut TradeState)
|
||||||
trades: &mut TradeState)
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
-> 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, trades).await;
|
let t = inner_items_to_trade(id, items_to_trade_pkt, client_location, clients, item_manager, trades).await;
|
||||||
match t {
|
match t {
|
||||||
Ok(p) => Ok(p),
|
Ok(p) => Ok(p),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::warn!("atrade error: {:?}", err);
|
log::warn!("atrade error: {:?}", err);
|
||||||
let (this, other) = trades.remove_trade(&id);
|
let (_this, other) = trades.remove_trade(&id);
|
||||||
Ok(Box::new(client_location.get_all_clients_by_client(id)?.into_iter()
|
Ok(Box::new(client_location.get_all_clients_by_client(id)?.into_iter()
|
||||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
||||||
.map(move |client| {
|
.map(move |client| {
|
||||||
@ -469,8 +450,8 @@ where
|
|||||||
this.status = TradeStatus::TradeComplete;
|
this.status = TradeStatus::TradeComplete;
|
||||||
|
|
||||||
if this.status == TradeStatus::TradeComplete && other.status == TradeStatus::TradeComplete {
|
if this.status == TradeStatus::TradeComplete && other.status == TradeStatus::TradeComplete {
|
||||||
let this_client = clients.get(&this.client()).ok_or(ShipError::ClientNotFound(this.client()))?;
|
let this_client = clients.get(&this.client()).ok_or_else(|| ShipError::ClientNotFound(this.client()))?;
|
||||||
let other_client = clients.get(&other.client()).ok_or(ShipError::ClientNotFound(other.client()))?;
|
let other_client = clients.get(&other.client()).ok_or_else(|| ShipError::ClientNotFound(other.client()))?;
|
||||||
let this_local_client = client_location.get_local_client(this.client())?;
|
let this_local_client = client_location.get_local_client(this.client())?;
|
||||||
let other_local_client = client_location.get_local_client(other.client())?;
|
let other_local_client = client_location.get_local_client(other.client())?;
|
||||||
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
|
let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
|
||||||
@ -550,8 +531,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
err @ _ => {
|
_ => {
|
||||||
let (this, other) = trades.remove_trade(&id);
|
let (_this, other) = trades.remove_trade(&id);
|
||||||
Ok(Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
Ok(Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
||||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
||||||
.map(move |client| {
|
.map(move |client| {
|
||||||
|
@ -556,7 +556,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
handler::direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager).await?
|
handler::direct_message::accept_tek_item(id, tek_accept, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager).await?
|
||||||
},
|
},
|
||||||
GameMessage::TradeRequest(trade_request) => {
|
GameMessage::TradeRequest(trade_request) => {
|
||||||
handler::trade::trade_request(id, trade_request, target, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager, &mut self.trades).await?
|
handler::trade::trade_request(id, trade_request, target, &block.client_location, &mut self.clients, &mut self.item_manager, &mut self.trades).await?
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let cmsg = msg.clone();
|
let cmsg = msg.clone();
|
||||||
@ -727,7 +727,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
|||||||
},
|
},
|
||||||
RecvShipPacket::ItemsToTrade(items_to_trade) => {
|
RecvShipPacket::ItemsToTrade(items_to_trade) => {
|
||||||
let block = self.blocks.with_client(id, &self.clients)?;
|
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, &mut self.trades).await?
|
handler::trade::items_to_trade(id, items_to_trade, &block.client_location, &mut self.clients, &mut self.item_manager, &mut self.trades).await?
|
||||||
},
|
},
|
||||||
RecvShipPacket::TradeConfirmed(_) => {
|
RecvShipPacket::TradeConfirmed(_) => {
|
||||||
let block = self.blocks.with_client(id, &self.clients)?;
|
let block = self.blocks.with_client(id, &self.clients)?;
|
||||||
|
@ -315,7 +315,7 @@ fn number_of_weapons_to_generate(character_level: usize) -> usize {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WeaponShop<R: Rng + SeedableRng> {
|
pub struct WeaponShop<R: Rng + SeedableRng> {
|
||||||
difficulty: Difficulty,
|
_difficulty: Difficulty,
|
||||||
section_id: SectionID,
|
section_id: SectionID,
|
||||||
weapon: WeaponTable,
|
weapon: WeaponTable,
|
||||||
special: SpecialTable,
|
special: SpecialTable,
|
||||||
@ -329,7 +329,7 @@ pub struct WeaponShop<R: Rng + SeedableRng> {
|
|||||||
impl<R: Rng + SeedableRng> WeaponShop<R> {
|
impl<R: Rng + SeedableRng> WeaponShop<R> {
|
||||||
pub fn new(difficulty: Difficulty, section_id: SectionID) -> WeaponShop<R> {
|
pub fn new(difficulty: Difficulty, section_id: SectionID) -> WeaponShop<R> {
|
||||||
WeaponShop {
|
WeaponShop {
|
||||||
difficulty,
|
_difficulty: difficulty,
|
||||||
section_id,
|
section_id,
|
||||||
weapon: load_weapon_table(difficulty, section_id),
|
weapon: load_weapon_table(difficulty, section_id),
|
||||||
special: load_special_table(),
|
special: load_special_table(),
|
||||||
@ -358,8 +358,10 @@ impl<R: Rng + SeedableRng> WeaponShop<R> {
|
|||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let special_tier = WeightedIndex::new(tier.special.iter().map(|t| t.probability)).unwrap();
|
let special_tier_choice = WeightedIndex::new(tier.special.iter().map(|t| t.probability)).unwrap();
|
||||||
match special_tier.sample(&mut self.rng) {
|
let special_tier_index = special_tier_choice.sample(&mut self.rng);
|
||||||
|
let special_tier = tier.special.get(special_tier_index)?;
|
||||||
|
match special_tier.tier {
|
||||||
1 => TIER1_SPECIAL.choose(&mut self.rng).cloned(),
|
1 => TIER1_SPECIAL.choose(&mut self.rng).cloned(),
|
||||||
2 => TIER2_SPECIAL.choose(&mut self.rng).cloned(),
|
2 => TIER2_SPECIAL.choose(&mut self.rng).cloned(),
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use async_std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use crate::common::serverstate::ClientId;
|
use crate::common::serverstate::ClientId;
|
||||||
use crate::ship::items;
|
use crate::ship::items;
|
||||||
@ -67,38 +66,6 @@ impl ClientTradeState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub struct ClientTradeHandle<'a> {
|
|
||||||
handle: std::cell::Ref<'a, ClientTradeState>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ClientTradeHandle<'a> {
|
|
||||||
fn new(handle: std::cell::Ref<'a, ClientTradeState>) -> ClientTradeHandle<'a> {
|
|
||||||
ClientTradeHandle {
|
|
||||||
handle: handle,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> std::ops::Deref for ClientTradeHandle<'a> {
|
|
||||||
type Target = ClientTradeState;
|
|
||||||
fn deref(&self) -> &ClientTradeState {
|
|
||||||
&self.handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> std::ops::DerefMut for ClientTradeHandle<'a> {
|
|
||||||
fn deref_mut(&mut self) -> &mut ClientTradeState {
|
|
||||||
&mut self.handle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Clone for ClientTradeHandle<'a> {
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
#[error("")]
|
#[error("")]
|
||||||
pub enum TradeStateError {
|
pub enum TradeStateError {
|
||||||
@ -141,7 +108,7 @@ impl TradeState {
|
|||||||
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> T
|
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> T
|
||||||
{
|
{
|
||||||
let mut c1 = self.trades.get(client).ok_or_else(|| TradeStateError::ClientNotInTrade(*client))?.borrow_mut();
|
let mut c1 = self.trades.get(client).ok_or_else(|| TradeStateError::ClientNotInTrade(*client))?.borrow_mut();
|
||||||
let mut c2 = self.trades.get(&c1.other_client).ok_or_else(|| TradeStateError::ClientNotInTrade(c1.other_client))?.borrow_mut();
|
let mut c2 = self.trades.get(&c1.other_client).ok_or(TradeStateError::ClientNotInTrade(c1.other_client))?.borrow_mut();
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if c1.client != c2.other_client {
|
if c1.client != c2.other_client {
|
||||||
@ -150,22 +117,6 @@ impl TradeState {
|
|||||||
|
|
||||||
Ok(func(&mut *c1, &mut *c2))
|
Ok(func(&mut *c1, &mut *c2))
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
pub fn with<T, F> (&self, client: &ClientId, func: F) -> Result<T, TradeStateError>
|
|
||||||
where
|
|
||||||
F: Fn(&mut ClientTradeHandle, &mut ClientTradeHandle) -> T
|
|
||||||
{
|
|
||||||
let c1 = ClientTradeHandle::new(self.trades.get(client).ok_or_else(|| TradeStateError::ClientNotInTrade(*client))?.borrow_mut());
|
|
||||||
let c2 = ClientTradeHandle::new(self.trades.get(&c1.other_client).ok_or_else(|| TradeStateError::ClientNotInTrade(c1.other_client))?.borrow_mut());
|
|
||||||
|
|
||||||
// sanity check
|
|
||||||
if c1.client != c2.other_client {
|
|
||||||
return Err(TradeStateError::MismatchedTrade(c1.client, c2.client));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(func(&mut c1, &mut c2))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO: is it possible for this to not return Options?
|
// TODO: is it possible for this to not return Options?
|
||||||
pub fn remove_trade(&mut self, client: &ClientId) -> (Option<ClientTradeState>, Option<ClientTradeState>) {
|
pub fn remove_trade(&mut self, client: &ClientId) -> (Option<ClientTradeState>, Option<ClientTradeState>) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user