appease the clip
This commit is contained in:
parent
22f630f562
commit
a6e50555de
@ -160,19 +160,11 @@ pub struct CharacterAppearance {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TechLevel(pub u8);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CharacterTechniques {
|
||||
pub techs: HashMap<Technique, TechLevel>
|
||||
}
|
||||
|
||||
impl Default for CharacterTechniques {
|
||||
fn default() -> CharacterTechniques {
|
||||
CharacterTechniques {
|
||||
techs: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CharacterTechniques {
|
||||
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
|
||||
self.techs.insert(tech, TechLevel(level.0 - 1));
|
||||
|
@ -231,7 +231,7 @@ impl EntityGateway for InMemoryGateway {
|
||||
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(())
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ impl EntityGateway for InMemoryGateway {
|
||||
|
||||
async fn get_character_meseta(&mut self, char_id: &CharacterEntityId) -> Result<Meseta, GatewayError> {
|
||||
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)
|
||||
}
|
||||
else {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![allow(dead_code)]
|
||||
use std::collections::HashMap;
|
||||
use std::convert::Into;
|
||||
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 {
|
||||
InventoryItemEntity::Individual(i) => Some(i),
|
||||
_ => 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 mut eg = entity_gateway.clone();
|
||||
let character_id = character.id;
|
||||
return async move {
|
||||
async move {
|
||||
let monomate = eg.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::Tool (
|
||||
|
@ -4,6 +4,8 @@ use crate::entity::character::CharacterEntity;
|
||||
use crate::ship::items::{CharacterInventory, CharacterBank};
|
||||
use crate::entity::item::Meseta;
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CharacterBytesBuilder<'a> {
|
||||
character: Option<&'a CharacterEntity>,
|
||||
stats: Option<&'a CharacterStats>,
|
||||
@ -11,18 +13,6 @@ pub struct CharacterBytesBuilder<'a> {
|
||||
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> {
|
||||
pub fn character(self, character: &'a CharacterEntity) -> CharacterBytesBuilder<'a> {
|
||||
CharacterBytesBuilder {
|
||||
@ -89,6 +79,7 @@ impl<'a> CharacterBytesBuilder<'a> {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FullCharacterBytesBuilder<'a> {
|
||||
character: Option<&'a CharacterEntity>,
|
||||
stats: Option<&'a CharacterStats>,
|
||||
@ -103,25 +94,6 @@ pub struct FullCharacterBytesBuilder<'a> {
|
||||
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> {
|
||||
pub fn character(self, character: &'a CharacterEntity) -> FullCharacterBytesBuilder<'a> {
|
||||
FullCharacterBytesBuilder {
|
||||
|
@ -293,7 +293,7 @@ impl CharacterBank {
|
||||
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 {
|
||||
items: self.items.iter()
|
||||
.map(|item| {
|
||||
|
@ -159,15 +159,9 @@ impl<'a> FloorItemHandle<'a> {
|
||||
}
|
||||
|
||||
// TODO: floors should keep track of their own item_ids
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct RoomFloorItems(Vec<FloorItem>);
|
||||
|
||||
impl Default for RoomFloorItems {
|
||||
fn default() -> RoomFloorItems {
|
||||
RoomFloorItems(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl RoomFloorItems {
|
||||
pub fn add_item(&mut self, item: FloorItem) {
|
||||
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 {
|
||||
items: self.items.iter()
|
||||
.map(|item| {
|
||||
|
@ -1,4 +1,3 @@
|
||||
use log::warn;
|
||||
use crate::ship::items::ClientItemId;
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
@ -6,7 +5,7 @@ use thiserror::Error;
|
||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
||||
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::weapon;
|
||||
use crate::ship::map::MapArea;
|
||||
@ -239,38 +238,36 @@ impl ItemManager {
|
||||
}
|
||||
|
||||
pub fn get_character_bank(&self, character: &CharacterEntity) -> Result<&CharacterBank, anyhow::Error> {
|
||||
Ok(self.character_bank
|
||||
self.character_bank
|
||||
.get(&character.id)
|
||||
.ok_or(ItemManagerError::NoCharacter(character.id))?)
|
||||
//.get(&BankName("".to_string()))
|
||||
//.ok_or(ItemManagerError::InvalidBankName(BankName("".to_string())))?)
|
||||
.ok_or_else(|| ItemManagerError::NoCharacter(character.id).into())
|
||||
}
|
||||
|
||||
pub fn get_character_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
||||
Ok(self.character_meseta.get(&character_id)
|
||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
||||
self.character_meseta.get(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> {
|
||||
Ok(self.character_meseta.get_mut(&character_id)
|
||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
||||
self.character_meseta.get_mut(character_id)
|
||||
.ok_or(ItemManagerError::NoCharacter(*character_id))
|
||||
}
|
||||
|
||||
pub fn get_bank_meseta(&self, character_id: &CharacterEntityId) -> Result<&Meseta, ItemManagerError> {
|
||||
Ok(self.bank_meseta.get(&character_id)
|
||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
||||
self.bank_meseta.get(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> {
|
||||
Ok(self.bank_meseta.get_mut(&character_id)
|
||||
.ok_or(ItemManagerError::NoCharacter(*character_id))?)
|
||||
self.bank_meseta.get_mut(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> {
|
||||
Ok((
|
||||
self.character_meseta.get_mut(&character_id)
|
||||
self.character_meseta.get_mut(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))?
|
||||
))
|
||||
}
|
||||
@ -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)
|
||||
-> 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> {
|
||||
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))?;
|
||||
@ -310,7 +307,7 @@ impl ItemManager {
|
||||
Some(floor_item) => {
|
||||
it.action(Box::new(RemoveFromLocalFloor {
|
||||
character_id: character.id,
|
||||
item_id: item_id.clone()
|
||||
item_id: *item_id
|
||||
}));
|
||||
floor_item
|
||||
},
|
||||
@ -319,12 +316,12 @@ impl ItemManager {
|
||||
Some(floor_item) => {
|
||||
it.action(Box::new(RemoveFromSharedFloor {
|
||||
room_id: *room_id,
|
||||
item_id: item_id.clone()
|
||||
item_id: *item_id
|
||||
}));
|
||||
floor_item
|
||||
},
|
||||
None => {
|
||||
return Err(ItemManagerError::NoSuchItemId(item_id.clone())).into()
|
||||
return Err(ItemManagerError::NoSuchItemId(*item_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -339,7 +336,7 @@ impl ItemManager {
|
||||
}))
|
||||
}
|
||||
else {
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||
}
|
||||
TriggerCreateItem::Yes
|
||||
},
|
||||
@ -360,14 +357,14 @@ impl ItemManager {
|
||||
TriggerCreateItem::No
|
||||
},
|
||||
SpaceForStack::No(_) => {
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||
},
|
||||
}
|
||||
},
|
||||
FloorItem::Meseta(meseta_floor_item) => {
|
||||
let character_meseta = it.manager.character_meseta.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
if character_meseta.0 >= 999999 {
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id).into());
|
||||
return Err(ItemManagerError::CouldNotAddToInventory(*item_id));
|
||||
}
|
||||
it.action(Box::new(AddMesetaFloorItemToInventory {
|
||||
character_id: character.id,
|
||||
@ -615,7 +612,7 @@ impl ItemManager {
|
||||
.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 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_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),
|
||||
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, usize))
|
||||
-> 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> {
|
||||
let p1_inventory = it.manager.get_character_inventory(p1.1)?;
|
||||
let p2_inventory = it.manager.get_character_inventory(p2.1)?;
|
||||
@ -1049,27 +1046,27 @@ impl ItemManager {
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let trade_items = [(p1, p2, p1_inventory, p2_inventory), (p2, p1, p2_inventory, p1_inventory)]
|
||||
.map(|(src_client, dest_client, src_inventory, dest_inventory)| {
|
||||
let trade_items = [(p1, p2, p1_inventory), (p2, p1, p2_inventory)]
|
||||
.map(|(src_client, dest_client, src_inventory)| {
|
||||
src_client.2.iter()
|
||||
.map(|item| -> Option<(Option<ItemToTrade>, Box<dyn ItemAction<EG>>)> {
|
||||
match item {
|
||||
TradeItem::Individual(item_id) => {
|
||||
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(ItemToTrade {
|
||||
add_to: *dest_client.0,
|
||||
remove_from: *src_client.0,
|
||||
current_item_id: *item_id,
|
||||
new_item_id: new_item_id,
|
||||
new_item_id,
|
||||
item_detail: ItemToTradeDetail::Individual(item.item.clone())
|
||||
}),
|
||||
Box::new(TradeIndividualItem {
|
||||
src_character_id: src_client.1.id,
|
||||
dest_character_id: dest_client.1.id,
|
||||
current_item_id: *item_id,
|
||||
new_item_id: new_item_id,
|
||||
new_item_id,
|
||||
}),
|
||||
))
|
||||
},
|
||||
@ -1079,13 +1076,13 @@ impl ItemManager {
|
||||
None
|
||||
}
|
||||
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(ItemToTrade {
|
||||
add_to: *dest_client.0,
|
||||
remove_from: *src_client.0,
|
||||
current_item_id: *item_id,
|
||||
new_item_id: new_item_id,
|
||||
new_item_id,
|
||||
item_detail: ItemToTradeDetail::Stacked(item.tool, *amount)
|
||||
}),
|
||||
Box::new(TradeStackedItem {
|
||||
@ -1093,7 +1090,7 @@ impl ItemManager {
|
||||
dest_character_id: dest_client.1.id,
|
||||
//item_ids: item.entity_ids.iter().cloned().take(*amount).collect(),
|
||||
current_item_id: *item_id,
|
||||
new_item_id: new_item_id,
|
||||
new_item_id,
|
||||
amount: *amount,
|
||||
}),
|
||||
))
|
||||
@ -1125,8 +1122,8 @@ impl ItemManager {
|
||||
|
||||
|
||||
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 (p2_item_trades, p2_item_actions): (Vec<Option<ItemToTrade>>, Vec<Box<dyn ItemAction<EG>>>) = p2_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<_>, Vec<_>) = p2_trades.into_iter().unzip();
|
||||
|
||||
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());
|
||||
|
@ -1,17 +1,8 @@
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use thiserror::Error;
|
||||
use std::borrow::Cow;
|
||||
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::ship::location::{AreaClient, RoomId};
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TransactionCommitError {
|
||||
#[error("transaction commit gateway error {0}")]
|
||||
|
@ -287,18 +287,11 @@ impl MapAreaLookup {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MapAreaLookupBuilder {
|
||||
map_areas: HashMap<u16, MapArea>,
|
||||
}
|
||||
|
||||
impl Default for MapAreaLookupBuilder {
|
||||
fn default() -> MapAreaLookupBuilder {
|
||||
MapAreaLookupBuilder {
|
||||
map_areas: HashMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MapAreaLookupBuilder {
|
||||
pub fn add(mut self, value: u16, map_area: MapArea) -> MapAreaLookupBuilder {
|
||||
self.map_areas.insert(value, map_area);
|
||||
|
@ -14,17 +14,17 @@ pub struct RawMapEnemy {
|
||||
id: u32,
|
||||
_unknown1: u16,
|
||||
pub children: u16,
|
||||
map_area: u16,
|
||||
_map_area: u16,
|
||||
_unknown4: u16,
|
||||
section: u16,
|
||||
wave_idd: u16,
|
||||
wave_id: u32,
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
xrot: u32,
|
||||
yrot: u32,
|
||||
zrot: u32,
|
||||
_section: u16,
|
||||
_wave_idd: u16,
|
||||
_wave_id: u32,
|
||||
_x: f32,
|
||||
_y: f32,
|
||||
_z: f32,
|
||||
_xrot: u32,
|
||||
_yrot: u32,
|
||||
_zrot: u32,
|
||||
_field1: u32,
|
||||
field2: u32,
|
||||
_field3: u32,
|
||||
@ -40,17 +40,17 @@ impl RawMapEnemy {
|
||||
id: cursor.read_u32::<LittleEndian>()?,
|
||||
_unknown1: 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>()?,
|
||||
section: cursor.read_u16::<LittleEndian>()?,
|
||||
wave_idd: cursor.read_u16::<LittleEndian>()?,
|
||||
wave_id: cursor.read_u32::<LittleEndian>()?,
|
||||
x: cursor.read_f32::<LittleEndian>()?,
|
||||
y: cursor.read_f32::<LittleEndian>()?,
|
||||
z: cursor.read_f32::<LittleEndian>()?,
|
||||
xrot: cursor.read_u32::<LittleEndian>()?,
|
||||
yrot: cursor.read_u32::<LittleEndian>()?,
|
||||
zrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_section: cursor.read_u16::<LittleEndian>()?,
|
||||
_wave_idd: cursor.read_u16::<LittleEndian>()?,
|
||||
_wave_id: cursor.read_u32::<LittleEndian>()?,
|
||||
_x: cursor.read_f32::<LittleEndian>()?,
|
||||
_y: cursor.read_f32::<LittleEndian>()?,
|
||||
_z: cursor.read_f32::<LittleEndian>()?,
|
||||
_xrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_yrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_zrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_field1: cursor.read_u32::<LittleEndian>()?,
|
||||
field2: cursor.read_u32::<LittleEndian>()?,
|
||||
_field3: cursor.read_u32::<LittleEndian>()?,
|
||||
@ -75,7 +75,7 @@ pub enum MapEnemyError {
|
||||
pub struct MapEnemy {
|
||||
pub monster: MonsterType,
|
||||
pub map_area: MapArea,
|
||||
hp: u32,
|
||||
_hp: u32,
|
||||
// TODO: other stats from battleparam
|
||||
pub player_hit: [bool; 4],
|
||||
pub dropped_item: bool,
|
||||
@ -254,7 +254,7 @@ impl MapEnemy {
|
||||
Ok(MapEnemy {
|
||||
monster,
|
||||
map_area: *map_area,
|
||||
hp: 0,
|
||||
_hp: 0,
|
||||
dropped_item: false,
|
||||
gave_exp: false,
|
||||
player_hit: [false; 4],
|
||||
@ -265,7 +265,7 @@ impl MapEnemy {
|
||||
MapEnemy {
|
||||
monster,
|
||||
map_area,
|
||||
hp: 0,
|
||||
_hp: 0,
|
||||
dropped_item: false,
|
||||
gave_exp: false,
|
||||
player_hit: [false; 4],
|
||||
|
@ -13,50 +13,50 @@ use crate::ship::map::*;
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct RawMapObject {
|
||||
otype: u16,
|
||||
unknown1: u16,
|
||||
unknown2: u32,
|
||||
id: u16,
|
||||
group: u16,
|
||||
section: u16,
|
||||
unknown3: u16,
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
xrot: u32,
|
||||
yrot: u32,
|
||||
zrot: u32,
|
||||
_unknown1: u16,
|
||||
_unknown2: u32,
|
||||
_id: u16,
|
||||
_group: u16,
|
||||
_section: u16,
|
||||
_unknown3: u16,
|
||||
_x: f32,
|
||||
_y: f32,
|
||||
_z: f32,
|
||||
_xrot: u32,
|
||||
_yrot: u32,
|
||||
_zrot: u32,
|
||||
field1: f32,
|
||||
field2: f32,
|
||||
field3: f32,
|
||||
field4: u32,
|
||||
field5: u32,
|
||||
field6: u32,
|
||||
field7: u32,
|
||||
_field5: u32,
|
||||
_field6: u32,
|
||||
_field7: u32,
|
||||
}
|
||||
|
||||
impl RawMapObject {
|
||||
pub fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
|
||||
Ok(RawMapObject {
|
||||
otype: cursor.read_u16::<LittleEndian>()?,
|
||||
unknown1: cursor.read_u16::<LittleEndian>()?,
|
||||
unknown2: cursor.read_u32::<LittleEndian>()?,
|
||||
id: cursor.read_u16::<LittleEndian>()?,
|
||||
group: cursor.read_u16::<LittleEndian>()?,
|
||||
section: cursor.read_u16::<LittleEndian>()?,
|
||||
unknown3: cursor.read_u16::<LittleEndian>()?,
|
||||
x: cursor.read_f32::<LittleEndian>()?,
|
||||
y: cursor.read_f32::<LittleEndian>()?,
|
||||
z: cursor.read_f32::<LittleEndian>()?,
|
||||
xrot: cursor.read_u32::<LittleEndian>()?,
|
||||
yrot: cursor.read_u32::<LittleEndian>()?,
|
||||
zrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_unknown1: cursor.read_u16::<LittleEndian>()?,
|
||||
_unknown2: cursor.read_u32::<LittleEndian>()?,
|
||||
_id: cursor.read_u16::<LittleEndian>()?,
|
||||
_group: cursor.read_u16::<LittleEndian>()?,
|
||||
_section: cursor.read_u16::<LittleEndian>()?,
|
||||
_unknown3: cursor.read_u16::<LittleEndian>()?,
|
||||
_x: cursor.read_f32::<LittleEndian>()?,
|
||||
_y: cursor.read_f32::<LittleEndian>()?,
|
||||
_z: cursor.read_f32::<LittleEndian>()?,
|
||||
_xrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_yrot: cursor.read_u32::<LittleEndian>()?,
|
||||
_zrot: cursor.read_u32::<LittleEndian>()?,
|
||||
field1: cursor.read_f32::<LittleEndian>()?,
|
||||
field2: cursor.read_f32::<LittleEndian>()?,
|
||||
field3: cursor.read_f32::<LittleEndian>()?,
|
||||
field4: cursor.read_u32::<LittleEndian>()?,
|
||||
field5: cursor.read_u32::<LittleEndian>()?,
|
||||
field6: cursor.read_u32::<LittleEndian>()?,
|
||||
field7: cursor.read_u32::<LittleEndian>()?,
|
||||
_field5: cursor.read_u32::<LittleEndian>()?,
|
||||
_field6: cursor.read_u32::<LittleEndian>()?,
|
||||
_field7: cursor.read_u32::<LittleEndian>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,14 @@
|
||||
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};
|
||||
use crate::ship::location::{ClientLocation, ClientLocationError, LocalClientId};
|
||||
use crate::ship::drops::ItemDrop;
|
||||
use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, TriggerCreateItem, FloorItem, FloorType, ItemToTradeDetail};
|
||||
use crate::ship::ship::{SendShipPacket, ShipError, Clients};
|
||||
use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||
use crate::ship::items::{ItemManager, ItemManagerError, ClientItemId, ItemToTradeDetail};
|
||||
use crate::ship::items::inventory::InventoryItem;
|
||||
use crate::ship::trade::{TradeItem, TradeState, TradeStatus};
|
||||
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};
|
||||
|
||||
pub const MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFF01);
|
||||
pub const OTHER_MESETA_ITEM_ID: ClientItemId = ClientItemId(0xFFFFFFFF);
|
||||
@ -54,21 +46,18 @@ pub enum TradeError {
|
||||
|
||||
|
||||
// TODO: remove target
|
||||
pub async fn trade_request<EG>(id: ClientId,
|
||||
pub async fn trade_request(id: ClientId,
|
||||
trade_request: &TradeRequest,
|
||||
target: u32,
|
||||
entity_gateway: &mut EG,
|
||||
client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
item_manager: &mut ItemManager,
|
||||
trades: &mut TradeState)
|
||||
-> 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
|
||||
match trade_request.trade {
|
||||
TradeRequestCommand::Initialize(ref act, meseta) => {
|
||||
TradeRequestCommand::Initialize(ref act, _meseta) => {
|
||||
match act {
|
||||
TradeRequestInitializeCommand::Initialize => {
|
||||
if trades.in_trade(&id) {
|
||||
@ -76,10 +65,9 @@ where
|
||||
}
|
||||
let trade_partner = client_location.get_client_neighbors(id)?
|
||||
.into_iter()
|
||||
.filter(|ac| {
|
||||
.find(|ac| {
|
||||
ac.local_client.id() == target as u8 //trade_request.client
|
||||
})
|
||||
.next()
|
||||
.ok_or(TradeError::CouldNotFindTradePartner)?;
|
||||
if trades.in_trade(&trade_partner.client) {
|
||||
return Err(TradeError::OtherAlreadyInTrade.into())
|
||||
@ -125,7 +113,7 @@ where
|
||||
Ok(trades
|
||||
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
||||
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)?;
|
||||
if ClientItemId(item_id) == MESETA_ITEM_ID {
|
||||
this.meseta += amount as usize;
|
||||
@ -157,7 +145,7 @@ where
|
||||
Err(TradeError::MismatchedStatus.into())
|
||||
}
|
||||
})?
|
||||
.unwrap_or_else(|err| {
|
||||
.unwrap_or_else(|_err| {
|
||||
trades.remove_trade(&id);
|
||||
Box::new(client_location.get_all_clients_by_client(id).unwrap().into_iter()
|
||||
.filter(move |client| client.local_client.id() == target as u8)
|
||||
@ -184,9 +172,8 @@ where
|
||||
this.items.retain(|item| {
|
||||
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()
|
||||
.position(|item| {
|
||||
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)
|
||||
}
|
||||
|
||||
pub async fn inner_items_to_trade<EG>(id: ClientId,
|
||||
pub async fn inner_items_to_trade(id: ClientId,
|
||||
items_to_trade: &ItemsToTrade,
|
||||
entity_gateway: &mut EG,
|
||||
client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
item_manager: &mut ItemManager,
|
||||
trades: &mut TradeState)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||
where
|
||||
EG: EntityGateway
|
||||
{
|
||||
Ok(trades
|
||||
.with(&id, |this, other| -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> {
|
||||
@ -319,8 +303,8 @@ where
|
||||
return Err(TradeError::MismatchedStatus.into())
|
||||
}
|
||||
|
||||
let client = clients.get(&this.client()).ok_or(ShipError::ClientNotFound(this.client()))?;
|
||||
let other_client = clients.get(&other.client()).ok_or(ShipError::ClientNotFound(other.client()))?;
|
||||
let client = clients.get(&this.client()).ok_or_else(|| ShipError::ClientNotFound(this.client()))?;
|
||||
let other_client = clients.get(&other.client()).ok_or_else(|| ShipError::ClientNotFound(other.client()))?;
|
||||
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 })) {
|
||||
@ -355,14 +339,14 @@ where
|
||||
let real_trade_item = this.items
|
||||
.iter()
|
||||
.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()
|
||||
.chain(item.item_data2.iter())
|
||||
.cloned().collect::<Vec<u8>>()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
match real_item {
|
||||
InventoryItem::Individual(individual_inventory_item) => {
|
||||
InventoryItem::Individual(_individual_inventory_item) => {
|
||||
if real_item.as_client_bytes() == trade_item_bytes {
|
||||
Ok(())
|
||||
}
|
||||
@ -374,7 +358,7 @@ where
|
||||
if real_item.as_client_bytes()[0..4] == trade_item_bytes[0..4] {
|
||||
let amount = trade_item_bytes[5] as usize;
|
||||
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(())
|
||||
}
|
||||
else {
|
||||
@ -407,7 +391,7 @@ where
|
||||
})?
|
||||
.unwrap_or_else(|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()
|
||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client() ).unwrap_or_else(|| false))
|
||||
.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,
|
||||
entity_gateway: &mut EG,
|
||||
client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
item_manager: &mut ItemManager,
|
||||
trades: &mut TradeState)
|
||||
-> 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 {
|
||||
Ok(p) => Ok(p),
|
||||
Err(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()
|
||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
||||
.map(move |client| {
|
||||
@ -469,8 +450,8 @@ where
|
||||
this.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 other_client = clients.get(&other.client()).ok_or(ShipError::ClientNotFound(other.client()))?;
|
||||
let this_client = clients.get(&this.client()).ok_or_else(|| ShipError::ClientNotFound(this.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 other_local_client = client_location.get_local_client(other.client())?;
|
||||
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()
|
||||
.filter(move |client| other.as_ref().map(|other| client.client == other.client()).unwrap_or_else(|| false))
|
||||
.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?
|
||||
},
|
||||
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();
|
||||
@ -727,7 +727,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
||||
},
|
||||
RecvShipPacket::ItemsToTrade(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, &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(_) => {
|
||||
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)]
|
||||
pub struct WeaponShop<R: Rng + SeedableRng> {
|
||||
difficulty: Difficulty,
|
||||
_difficulty: Difficulty,
|
||||
section_id: SectionID,
|
||||
weapon: WeaponTable,
|
||||
special: SpecialTable,
|
||||
@ -329,7 +329,7 @@ pub struct WeaponShop<R: Rng + SeedableRng> {
|
||||
impl<R: Rng + SeedableRng> WeaponShop<R> {
|
||||
pub fn new(difficulty: Difficulty, section_id: SectionID) -> WeaponShop<R> {
|
||||
WeaponShop {
|
||||
difficulty,
|
||||
_difficulty: difficulty,
|
||||
section_id,
|
||||
weapon: load_weapon_table(difficulty, section_id),
|
||||
special: load_special_table(),
|
||||
@ -358,8 +358,10 @@ impl<R: Rng + SeedableRng> WeaponShop<R> {
|
||||
.last()
|
||||
.unwrap();
|
||||
|
||||
let special_tier = WeightedIndex::new(tier.special.iter().map(|t| t.probability)).unwrap();
|
||||
match special_tier.sample(&mut self.rng) {
|
||||
let special_tier_choice = WeightedIndex::new(tier.special.iter().map(|t| t.probability)).unwrap();
|
||||
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(),
|
||||
2 => TIER2_SPECIAL.choose(&mut self.rng).cloned(),
|
||||
_ => None
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::common::serverstate::ClientId;
|
||||
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)]
|
||||
#[error("")]
|
||||
pub enum TradeStateError {
|
||||
@ -141,7 +108,7 @@ impl TradeState {
|
||||
F: Fn(&mut ClientTradeState, &mut ClientTradeState) -> T
|
||||
{
|
||||
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
|
||||
if c1.client != c2.other_client {
|
||||
@ -150,22 +117,6 @@ impl TradeState {
|
||||
|
||||
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?
|
||||
pub fn remove_trade(&mut self, client: &ClientId) -> (Option<ClientTradeState>, Option<ClientTradeState>) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user