withdraw from bank
This commit is contained in:
parent
0dca90ff5a
commit
4187e93455
@ -24,6 +24,15 @@ impl StackedBankItem {
|
||||
pub fn count(&self) -> usize {
|
||||
self.entity_ids.len()
|
||||
}
|
||||
|
||||
pub fn take_entity_ids(&mut self, amount: usize) -> Option<Vec<ItemEntityId>> {
|
||||
if amount <= self.count() {
|
||||
Some(self.entity_ids.drain(..amount).collect())
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -126,6 +135,26 @@ impl BankItem {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct BankItemHandle<'a> {
|
||||
bank: &'a mut CharacterBank,
|
||||
index: usize
|
||||
}
|
||||
|
||||
impl<'a> BankItemHandle<'a> {
|
||||
pub fn item(&'a self) -> Option<&'a BankItem> {
|
||||
self.bank.items.get(self.index)
|
||||
}
|
||||
|
||||
pub fn item_mut(&mut self) -> Option<&mut BankItem> {
|
||||
self.bank.items.get_mut(self.index)
|
||||
}
|
||||
|
||||
pub fn remove_from_bank(self) {
|
||||
self.bank.items.remove(self.index);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CharacterBank {
|
||||
item_id_counter: u32,
|
||||
items: Vec<BankItem>
|
||||
@ -147,6 +176,19 @@ impl CharacterBank {
|
||||
self.item_id_counter = base_item_id + self.items.len() as u32 + 1;
|
||||
}
|
||||
|
||||
pub fn get_item_handle_by_id<'a>(&'a mut self, item_id: ClientItemId) -> Option<BankItemHandle<'a>> {
|
||||
let (index, _) = self.items.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, item)| {
|
||||
item.item_id() == item_id
|
||||
})
|
||||
.nth(0)?;
|
||||
Some(BankItemHandle {
|
||||
bank: self,
|
||||
index: index,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_client_bank_items(&self) -> character::Bank {
|
||||
self.items.iter()
|
||||
.enumerate()
|
||||
|
@ -3,9 +3,11 @@ use thiserror::Error;
|
||||
use libpso::character::character;//::InventoryItem;
|
||||
use crate::entity::item::{ItemEntityId, ItemDetail, ItemType};
|
||||
use crate::entity::item::tool::Tool;
|
||||
use crate::ship::items::ClientItemId;
|
||||
use crate::ship::items::{ClientItemId, BankItem, BankItemHandle};
|
||||
use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem};
|
||||
|
||||
const INVENTORY_CAPACITY: usize = 30;
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InventorySlot(pub usize);
|
||||
@ -233,15 +235,15 @@ pub struct InventoryItemHandle<'a> {
|
||||
|
||||
impl<'a> InventoryItemHandle<'a> {
|
||||
pub fn item(&'a self) -> Option<&'a InventoryItem> {
|
||||
self.inventory.0.get(self.slot)
|
||||
self.inventory.items.get(self.slot)
|
||||
}
|
||||
|
||||
pub fn item_mut(&mut self) -> Option<&mut InventoryItem> {
|
||||
self.inventory.0.get_mut(self.slot)
|
||||
self.inventory.items.get_mut(self.slot)
|
||||
}
|
||||
|
||||
pub fn remove_from_inventory(self) {
|
||||
self.inventory.0.remove(self.slot);
|
||||
self.inventory.items.remove(self.slot);
|
||||
}
|
||||
|
||||
pub fn consume(self, amount: usize) -> Result<ConsumedItem, InventoryItemConsumeError> {
|
||||
@ -250,7 +252,7 @@ impl<'a> InventoryItemHandle<'a> {
|
||||
Partial(Tool),
|
||||
}
|
||||
|
||||
let inventory_item = self.inventory.0.get(self.slot).ok_or(InventoryItemConsumeError::InconsistentState)?;
|
||||
let inventory_item = self.inventory.items.get(self.slot).ok_or(InventoryItemConsumeError::InconsistentState)?;
|
||||
let remove_method = match inventory_item {
|
||||
InventoryItem::Individual(individual_inventory_item) => {
|
||||
RemoveMethod::EntireThing(ConsumedItem::Individual(IndividualConsumedItem {
|
||||
@ -278,11 +280,11 @@ impl<'a> InventoryItemHandle<'a> {
|
||||
|
||||
match remove_method {
|
||||
RemoveMethod::EntireThing(consumed_item) => {
|
||||
self.inventory.0.remove(self.slot);
|
||||
self.inventory.items.remove(self.slot);
|
||||
Ok(consumed_item)
|
||||
},
|
||||
RemoveMethod::Partial(tool) => {
|
||||
let entity_ids = self.inventory.0.get_mut(self.slot)
|
||||
let entity_ids = self.inventory.items.get_mut(self.slot)
|
||||
.and_then(|item| {
|
||||
if let InventoryItem::Stacked(stacked_inventory_item) = item {
|
||||
Some(stacked_inventory_item.entity_ids.drain(..amount).collect::<Vec<_>>())
|
||||
@ -305,21 +307,28 @@ impl<'a> InventoryItemHandle<'a> {
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CharacterInventory(Vec<InventoryItem>);
|
||||
pub struct CharacterInventory {
|
||||
item_id_counter: u32,
|
||||
items: Vec<InventoryItem>,
|
||||
}
|
||||
|
||||
impl CharacterInventory {
|
||||
pub fn new(items: Vec<InventoryItem>) -> CharacterInventory {
|
||||
CharacterInventory(items)
|
||||
}
|
||||
|
||||
pub fn initialize_item_ids(&mut self, base_item_id: u32) {
|
||||
for (i, item) in self.0.iter_mut().enumerate() {
|
||||
item.set_item_id(ClientItemId(base_item_id + i as u32));
|
||||
CharacterInventory{
|
||||
item_id_counter: 0,
|
||||
items: items,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize_item_ids(&mut self, base_item_id: u32) {
|
||||
for (i, item) in self.items.iter_mut().enumerate() {
|
||||
item.set_item_id(ClientItemId(base_item_id + i as u32));
|
||||
}
|
||||
self.item_id_counter = base_item_id + self.items.len() as u32 + 1;
|
||||
}
|
||||
|
||||
pub fn as_client_inventory_items(&self) -> [character::InventoryItem; 30] {
|
||||
self.0.iter()
|
||||
self.items.iter()
|
||||
.enumerate()
|
||||
.fold([character::InventoryItem::default(); 30], |mut inventory, (slot, item)| {
|
||||
let bytes = item.as_client_bytes();
|
||||
@ -335,15 +344,15 @@ impl CharacterInventory {
|
||||
}
|
||||
|
||||
pub fn slot(&self, slot: usize) -> Option<&InventoryItem> {
|
||||
self.0.get(slot)
|
||||
self.items.get(slot)
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize {
|
||||
self.0.len()
|
||||
self.items.len()
|
||||
}
|
||||
|
||||
pub fn get_item_handle_by_id<'a>(&'a mut self, item_id: ClientItemId) -> Option<InventoryItemHandle<'a>> {
|
||||
let (slot, _) = self.0.iter()
|
||||
let (slot, _) = self.items.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, item)| {
|
||||
item.item_id() == item_id
|
||||
@ -356,7 +365,7 @@ impl CharacterInventory {
|
||||
}
|
||||
|
||||
pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&InventoryItem> {
|
||||
self.0.iter()
|
||||
self.items.iter()
|
||||
.filter(|item| {
|
||||
item.item_id() == item_id
|
||||
})
|
||||
@ -364,14 +373,14 @@ impl CharacterInventory {
|
||||
}
|
||||
|
||||
pub fn take_item_by_id(&mut self, item_id: ClientItemId) -> Option<InventoryItem> {
|
||||
self.0
|
||||
self.items
|
||||
.drain_filter(|i| i.item_id() == item_id)
|
||||
.nth(0)
|
||||
}
|
||||
|
||||
pub fn add_item(&mut self, item: InventoryItem) -> Result<(), ()> { // TODO: errors
|
||||
// TODO: check slot conflict?
|
||||
self.0.push(item);
|
||||
self.items.push(item);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -381,14 +390,14 @@ impl CharacterInventory {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.0.push(InventoryItem::Individual(IndividualInventoryItem {
|
||||
self.items.push(InventoryItem::Individual(IndividualInventoryItem {
|
||||
entity_id: floor_item.entity_id,
|
||||
item_id: floor_item.item_id,
|
||||
item: floor_item.item.clone(),
|
||||
equipped: false,
|
||||
}));
|
||||
|
||||
if let Some(InventoryItem::Individual(new_item)) = self.0.last() {
|
||||
if let Some(InventoryItem::Individual(new_item)) = self.items.last() {
|
||||
Some((new_item, InventorySlot(self.count())))
|
||||
}
|
||||
else {
|
||||
@ -398,7 +407,7 @@ impl CharacterInventory {
|
||||
|
||||
// TODO: can be simplified using find instead of position
|
||||
pub fn pick_up_stacked_floor_item(&mut self, floor_item: &StackedFloorItem) -> Option<(&StackedInventoryItem, InventorySlot)> {
|
||||
let existing_stack_position = self.0.iter()
|
||||
let existing_stack_position = self.items.iter()
|
||||
.position(|inventory_item| {
|
||||
if let InventoryItem::Stacked(stacked_inventory_item) = inventory_item {
|
||||
if stacked_inventory_item.tool == floor_item.tool {
|
||||
@ -409,7 +418,7 @@ impl CharacterInventory {
|
||||
});
|
||||
|
||||
if let Some(existing_stack_position) = existing_stack_position {
|
||||
if let Some(InventoryItem::Stacked(stacked_item)) = self.0.get_mut(existing_stack_position) {
|
||||
if let Some(InventoryItem::Stacked(stacked_item)) = self.items.get_mut(existing_stack_position) {
|
||||
if stacked_item.count() + floor_item.count() <= stacked_item.tool.max_stack() {
|
||||
stacked_item.entity_ids.append(&mut floor_item.entity_ids.clone());
|
||||
Some((stacked_item, InventorySlot(existing_stack_position)))
|
||||
@ -429,8 +438,8 @@ impl CharacterInventory {
|
||||
tool: floor_item.tool,
|
||||
});
|
||||
|
||||
self.0.push(new_stacked_item);
|
||||
if let Some(InventoryItem::Stacked(new_item)) = self.0.last() {
|
||||
self.items.push(new_stacked_item);
|
||||
if let Some(InventoryItem::Stacked(new_item)) = self.items.last() {
|
||||
Some((new_item, InventorySlot(self.count())))
|
||||
}
|
||||
else {
|
||||
@ -438,5 +447,69 @@ impl CharacterInventory {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn withdraw_item(&mut self, mut bank_item: BankItemHandle, amount: usize) -> Option<(&InventoryItem, usize)> {
|
||||
let (remove, slot) = match bank_item.item_mut()? {
|
||||
BankItem::Individual(individual_bank_item) => {
|
||||
if self.items.len() >= INVENTORY_CAPACITY {
|
||||
return None
|
||||
}
|
||||
self.items.push(InventoryItem::Individual(IndividualInventoryItem {
|
||||
entity_id: individual_bank_item.entity_id,
|
||||
item_id: individual_bank_item.item_id,
|
||||
item: individual_bank_item.item.clone(),
|
||||
equipped: false,
|
||||
}));
|
||||
(true, self.count())
|
||||
},
|
||||
BankItem::Stacked(stacked_bank_item) => {
|
||||
let existing_inventory_item = self.items.iter_mut()
|
||||
.enumerate()
|
||||
.find_map(|(index, item)| {
|
||||
if let InventoryItem::Stacked(stacked_inventory_item) = item {
|
||||
if stacked_inventory_item.tool == stacked_inventory_item.tool {
|
||||
return Some((index, stacked_inventory_item))
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
let slot = match existing_inventory_item {
|
||||
Some((slot, stacked_inventory_item)) => {
|
||||
if stacked_inventory_item.count() + stacked_bank_item.count() > stacked_bank_item.tool.max_stack() {
|
||||
return None
|
||||
}
|
||||
|
||||
let mut withdrawn_entity_ids = stacked_bank_item.take_entity_ids(amount)?;
|
||||
stacked_inventory_item.entity_ids.append(&mut withdrawn_entity_ids);
|
||||
slot
|
||||
}
|
||||
None => {
|
||||
if self.items.len() >= INVENTORY_CAPACITY {
|
||||
return None
|
||||
}
|
||||
let withdrawn_entity_ids = stacked_bank_item.take_entity_ids(amount)?;
|
||||
|
||||
self.item_id_counter += 1; // oh no
|
||||
self.items.push(InventoryItem::Stacked(StackedInventoryItem {
|
||||
entity_ids: withdrawn_entity_ids,
|
||||
item_id: ClientItemId(self.item_id_counter),
|
||||
tool: stacked_bank_item.tool,
|
||||
}));
|
||||
self.count()
|
||||
}
|
||||
};
|
||||
(stacked_bank_item.count() == 0, slot)
|
||||
}
|
||||
};
|
||||
|
||||
if remove {
|
||||
bank_item.remove_from_bank();
|
||||
}
|
||||
|
||||
self.items.last().map(|item| {
|
||||
(item, slot)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,12 +558,41 @@ impl ItemManager {
|
||||
}
|
||||
|
||||
pub async fn player_withdraws_item<EG: EntityGateway>(&mut self,
|
||||
_entity_gateway: &mut EG,
|
||||
_character: &CharacterEntity,
|
||||
_item_id: ClientItemId,
|
||||
_amount: usize)
|
||||
-> Result<(), ItemManagerError> {
|
||||
entity_gateway: &mut EG,
|
||||
character: &CharacterEntity,
|
||||
item_id: ClientItemId,
|
||||
amount: usize)
|
||||
-> Result<&InventoryItem, ItemManagerError> {
|
||||
|
||||
Ok(())
|
||||
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
let bank = self.character_bank
|
||||
.get_mut(&character.id)
|
||||
.ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
|
||||
let item_to_withdraw = bank.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
||||
let inventory_item = inventory.withdraw_item(item_to_withdraw, amount).ok_or(ItemManagerError::Idunnoman)?;
|
||||
|
||||
match inventory_item {
|
||||
(InventoryItem::Individual(individual_inventory_item), slot) => {
|
||||
entity_gateway.change_item_location(&individual_inventory_item.entity_id,
|
||||
ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
slot: slot,
|
||||
equipped: false,
|
||||
}).await;
|
||||
},
|
||||
(InventoryItem::Stacked(stacked_inventory_item), slot) => {
|
||||
for entity_id in &stacked_inventory_item.entity_ids {
|
||||
entity_gateway.change_item_location(entity_id,
|
||||
ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
slot: slot,
|
||||
equipped: false,
|
||||
}).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(inventory_item.0)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use libpso::packet::messages::*;
|
||||
use libpso::packet::ship::*;
|
||||
use crate::common::leveltable::CharacterStats;
|
||||
use crate::ship::ship::{ShipError};
|
||||
use crate::ship::items::{ClientItemId, StackedFloorItem, FloorItem, CharacterBank};
|
||||
use crate::ship::items::{ClientItemId, InventoryItem, StackedFloorItem, FloorItem, CharacterBank};
|
||||
use crate::ship::location::AreaClient;
|
||||
use std::convert::TryInto;
|
||||
|
||||
@ -37,6 +37,18 @@ pub fn create_item(area_client: AreaClient, item: &FloorItem) -> Result<CreateIt
|
||||
})
|
||||
}
|
||||
|
||||
pub fn create_withdrawn_inventory_item(area_client: AreaClient, item: &InventoryItem) -> Result<CreateItem, ShipError> {
|
||||
let bytes = item.as_client_bytes();
|
||||
Ok(CreateItem {
|
||||
client: area_client.local_client.id(),
|
||||
target: 0,
|
||||
item_data: bytes[0..12].try_into()?,
|
||||
item_id: item.item_id().0,
|
||||
item_data2: bytes[12..16].try_into()?,
|
||||
unknown: 0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove_item_from_floor(area_client: AreaClient, item: &FloorItem) -> Result<RemoveItemFromFloor, ShipError> {
|
||||
Ok(RemoveItemFromFloor {
|
||||
client: area_client.local_client.id(),
|
||||
|
@ -249,8 +249,9 @@ where
|
||||
Vec::new()
|
||||
}
|
||||
else {
|
||||
item_manager.player_withdraws_item(entity_gateway, &client.character, ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as usize).await?;
|
||||
Vec::new()
|
||||
let item_added_to_inventory = item_manager.player_withdraws_item(entity_gateway, &client.character, ClientItemId(bank_interaction.item_id), bank_interaction.item_amount as usize).await?;
|
||||
let item_created = builder::message::create_withdrawn_inventory_item(area_client, &item_added_to_inventory)?;
|
||||
vec![SendShipPacket::Message(Message::new(GameMessage::CreateItem(item_created)))]
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
|
@ -41,7 +41,7 @@ async fn test_bank_items_sent_in_character_login() {
|
||||
menu: BLOCK_MENU_ID,
|
||||
item: 1,
|
||||
})).await.unwrap().collect::<Vec<_>>();
|
||||
|
||||
|
||||
assert!(matches!(&packets[0], (_, SendShipPacket::FullCharacter(fc)) if fc.character.bank.items[0].data1[0..3] == [0x00, 0x08, 0x04] ));
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ async fn test_deposit_individual_item() {
|
||||
if player_no_longer_has_item.item_id == 0x10001
|
||||
&& player_no_longer_has_item.amount == 0
|
||||
));
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -345,7 +345,7 @@ async fn test_deposit_stacked_item() {
|
||||
if player_no_longer_has_item.item_id == 0x10000
|
||||
&& player_no_longer_has_item.amount == 3
|
||||
));
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -412,7 +412,7 @@ async fn test_deposit_partial_stacked_item() {
|
||||
if player_no_longer_has_item.item_id == 0x10000
|
||||
&& player_no_longer_has_item.amount == 2
|
||||
));
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -505,7 +505,7 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() {
|
||||
if player_no_longer_has_item.item_id == 0x10000
|
||||
&& player_no_longer_has_item.amount == 2
|
||||
));
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -579,7 +579,7 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() {
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -671,7 +671,7 @@ async fn test_deposit_individual_item_in_full_bank() {
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -761,7 +761,7 @@ async fn test_deposit_stacked_item_in_full_bank() {
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
@ -995,7 +995,774 @@ async fn test_deposit_meseta_when_bank_is_maxed() {
|
||||
|
||||
let characters = entity_gateway.get_characters_by_user(&user1).await;
|
||||
let char = characters[0].as_ref().unwrap();
|
||||
println!("meseta {}", char.meseta);
|
||||
assert!(char.meseta == 300);
|
||||
assert!(char.bank_meseta == 999999);
|
||||
}
|
||||
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_individual_item() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
||||
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Saber,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".to_string())
|
||||
}
|
||||
}).await;
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
join_lobby(&mut ship, ClientId(2)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
join_room(&mut ship, ClientId(2), 0).await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 0,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().collect::<Vec<_>>();
|
||||
|
||||
assert!(packets.len() == 1);
|
||||
assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
|
||||
if create_item.item_id == 0x20000
|
||||
));
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory{..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids == vec![item::ItemEntityId(1)]);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_stacked_item() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
||||
|
||||
for _ in 0..3 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".to_string())
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
join_lobby(&mut ship, ClientId(2)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
join_room(&mut ship, ClientId(2), 0).await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 3,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().collect::<Vec<_>>();
|
||||
|
||||
assert!(packets.len() == 1);
|
||||
assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
|
||||
if create_item.item_id == 0x10002
|
||||
));
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_partial_stacked_item() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
||||
|
||||
for _ in 0..3 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".into())
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
join_lobby(&mut ship, ClientId(2)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
join_room(&mut ship, ClientId(2), 0).await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 2,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().collect::<Vec<_>>();
|
||||
|
||||
assert!(packets.len() == 1);
|
||||
assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
|
||||
if create_item.item_id == 0x10002
|
||||
));
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Bank {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(bank_item_ids == vec![item::ItemEntityId(3)]);
|
||||
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
||||
|
||||
for _ in 0..2 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: 0,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".into()),
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
join_lobby(&mut ship, ClientId(2)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
join_room(&mut ship, ClientId(2), 0).await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 2,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().collect::<Vec<_>>();
|
||||
|
||||
assert!(packets.len() == 1);
|
||||
assert!(matches!(&packets[0], (ClientId(2), SendShipPacket::Message(Message {msg: GameMessage::CreateItem(create_item)}))
|
||||
if create_item.item_id == 0x10000
|
||||
));
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)]);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
for _ in 0..2 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".into()),
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
for _ in 0..10 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: 0,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 2,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Bank {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
|
||||
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids.len() == 10);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_individual_item_in_full_inventory() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Vulcan,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".to_string())
|
||||
}
|
||||
}).await;
|
||||
|
||||
for i in 0..30 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Vulcan,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: i,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 0,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Bank {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(bank_item_ids == vec![item::ItemEntityId(1)]);
|
||||
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids.len() == 30);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_stacked_item_in_full_inventory() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
for _ in 0..2 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".to_string())
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
for i in 0..30 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Vulcan,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: i,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 2,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await;
|
||||
|
||||
assert!(packets.is_err());
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Bank {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
|
||||
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids.len() == 30);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
for _ in 0..2 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
character_id: char1.id,
|
||||
name: item::BankName("".to_string())
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
for i in 0..29 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Vulcan,
|
||||
grind: 0,
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: i,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
for _ in 0..2 {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
slot: 29,
|
||||
equipped: false,
|
||||
}
|
||||
}).await;
|
||||
}
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x20000,
|
||||
action: 1,
|
||||
item_amount: 2,
|
||||
meseta_amount: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let items = entity_gateway.get_items_by_character(&char1).await;
|
||||
let bank_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Bank {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(bank_item_ids.len() == 0);
|
||||
|
||||
let inventory_item_ids = items.iter()
|
||||
.filter_map(|item| {
|
||||
if let item::ItemLocation::Inventory {..} = item.location {
|
||||
Some(item.id)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert!(inventory_item_ids.len() == 33);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_meseta() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
char1.bank_meseta = 300;
|
||||
entity_gateway.save_character(&char1).await;
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0xFFFFFFFF,
|
||||
action: 1,
|
||||
item_amount: 0,
|
||||
meseta_amount: 23,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let characters = entity_gateway.get_characters_by_user(&user1).await;
|
||||
let char = characters[0].as_ref().unwrap();
|
||||
assert!(char.meseta == 23);
|
||||
assert!(char.bank_meseta == 277);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_too_much_meseta() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
char1.meseta = 999980;
|
||||
char1.bank_meseta = 300;
|
||||
entity_gateway.save_character(&char1).await;
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0xFFFFFFFF,
|
||||
action: 1,
|
||||
item_amount: 0,
|
||||
meseta_amount: 23,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let characters = entity_gateway.get_characters_by_user(&user1).await;
|
||||
let char = characters[0].as_ref().unwrap();
|
||||
assert!(char.meseta == 999980);
|
||||
assert!(char.bank_meseta == 300);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_withdraw_meseta_inventory_is_maxed() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
char1.meseta = 999999;
|
||||
char1.bank_meseta = 300;
|
||||
entity_gateway.save_character(&char1).await;
|
||||
|
||||
let mut ship = ShipServerState::new(entity_gateway.clone());
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankRequest(BankRequest {
|
||||
client: 0,
|
||||
target: 0,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::BankInteraction(BankInteraction {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0xFFFFFFFF,
|
||||
action: 1,
|
||||
item_amount: 0,
|
||||
meseta_amount: 23,
|
||||
unknown: 0,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let characters = entity_gateway.get_characters_by_user(&user1).await;
|
||||
let char = characters[0].as_ref().unwrap();
|
||||
assert!(char.meseta == 999999);
|
||||
assert!(char.bank_meseta == 300);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user