Browse Source

split actions into actions+tasks

kill_counters
jake 2 years ago
committed by andy
parent
commit
cb00ce67c6
  1. 534
      src/ship/items/actions.rs
  2. 1
      src/ship/items/mod.rs
  3. 2
      src/ship/items/state.rs
  4. 500
      src/ship/items/tasks.rs
  5. 3
      src/ship/packet/handler/direct_message.rs
  6. 2
      src/ship/packet/handler/message.rs
  7. 2
      src/ship/packet/handler/trade.rs

534
src/ship/items/actions.rs

@ -1,5 +1,4 @@
// TODO: replace various u32s and usizes denoting item amounts for ItemAmount(u32) for consistency // TODO: replace various u32s and usizes denoting item amounts for ItemAmount(u32) for consistency
use crate::ship::items::ClientItemId; use crate::ship::items::ClientItemId;
use crate::entity::item::{Meseta, ItemNote}; use crate::entity::item::{Meseta, ItemNote};
use std::future::Future; use std::future::Future;
@ -7,10 +6,9 @@ use std::pin::Pin;
use crate::ship::map::MapArea; use crate::ship::map::MapArea;
use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::character::{CharacterEntity, CharacterEntityId};
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction};
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail};
use crate::entity::gateway::EntityGatewayTransaction;
use crate::ship::items::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail};
use crate::ship::items::bank::{BankItem, BankItemDetail}; use crate::ship::items::bank::{BankItem, BankItemDetail};
use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction};
use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail}; use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
use crate::ship::items::floor::{FloorItem, FloorItemDetail}; use crate::ship::items::floor::{FloorItem, FloorItemDetail};
use crate::ship::items::apply_item::apply_item; use crate::ship::items::apply_item::apply_item;
@ -18,8 +16,6 @@ use crate::entity::item::{ItemDetail, NewItemEntity, TradeId};
use crate::entity::item::tool::Tool; use crate::entity::item::tool::Tool;
use crate::entity::item::ItemModifier; use crate::entity::item::ItemModifier;
use crate::ship::shops::ShopItem; use crate::ship::shops::ShopItem;
use crate::ship::trade::TradeItem;
use crate::ship::location::AreaClient;
use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::drops::{ItemDrop, ItemDropType};
pub enum TriggerCreateItem { pub enum TriggerCreateItem {
@ -27,7 +23,7 @@ pub enum TriggerCreateItem {
No No
} }
fn take_item_from_floor(character_id: CharacterEntityId, item_id: ClientItemId)
pub(super) fn take_item_from_floor(character_id: CharacterEntityId, item_id: ClientItemId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
{ {
@ -42,7 +38,7 @@ fn take_item_from_floor(character_id: CharacterEntityId, item_id: ClientItemId)
} }
} }
fn add_floor_item_to_inventory(character: &CharacterEntity)
pub(super) fn add_floor_item_to_inventory(character: &CharacterEntity)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), TriggerCreateItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), TriggerCreateItem), ItemStateError>> + Send + 'a>>
{ {
@ -84,28 +80,8 @@ fn add_floor_item_to_inventory(character: &CharacterEntity)
} }
pub async fn pick_up_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId)
-> Result<TriggerCreateItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_floor(character.id, *item_id))
.act(add_floor_item_to_inventory(character))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn take_item_from_inventory(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
pub(super) fn take_item_from_inventory(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
{ {
@ -123,7 +99,7 @@ fn take_item_from_inventory(character_id: CharacterEntityId, item_id: ClientItem
} }
fn add_inventory_item_to_shared_floor(character_id: CharacterEntityId, map_area: MapArea, drop_position: (f32, f32, f32))
pub(super) fn add_inventory_item_to_shared_floor(character_id: CharacterEntityId, map_area: MapArea, drop_position: (f32, f32, f32))
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
{ {
@ -150,55 +126,8 @@ fn add_inventory_item_to_shared_floor(character_id: CharacterEntityId, map_area:
} }
} }
pub async fn drop_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
map_area: MapArea,
drop_position: (f32, f32, f32))
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, *item_id, 0))
.act(add_inventory_item_to_shared_floor(character.id, map_area, drop_position))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn drop_partial_item<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, *item_id, amount))
.act(add_inventory_item_to_shared_floor(character.id, map_area, (drop_position.0, 0.0, drop_position.1)))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn take_meseta_from_inventory(character_id: CharacterEntityId, amount: u32)
pub(super) fn take_meseta_from_inventory(character_id: CharacterEntityId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -214,7 +143,7 @@ fn take_meseta_from_inventory(character_id: CharacterEntityId, amount: u32)
} }
} }
fn add_meseta_to_inventory(character_id: CharacterEntityId, amount: u32)
pub(super) fn add_meseta_to_inventory(character_id: CharacterEntityId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -230,7 +159,7 @@ fn add_meseta_to_inventory(character_id: CharacterEntityId, amount: u32)
} }
} }
fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_area: MapArea, drop_position: (f32, f32))
pub(super) fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_area: MapArea, drop_position: (f32, f32))
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
{ {
@ -255,31 +184,7 @@ fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_
} }
} }
pub async fn drop_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_meseta_from_inventory(character.id, amount))
.act(add_meseta_to_shared_floor(character.id, amount, map_area, drop_position))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn take_meseta_from_bank(character_id: CharacterEntityId, amount: u32)
pub(super) fn take_meseta_from_bank(character_id: CharacterEntityId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -294,7 +199,7 @@ fn take_meseta_from_bank(character_id: CharacterEntityId, amount: u32)
} }
} }
fn add_meseta_from_bank_to_inventory(character_id: CharacterEntityId, amount: u32)
pub(super) fn add_meseta_from_bank_to_inventory(character_id: CharacterEntityId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -310,28 +215,7 @@ fn add_meseta_from_bank_to_inventory(character_id: CharacterEntityId, amount: u3
} }
pub async fn withdraw_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_meseta_from_bank(character.id, amount))
.act(add_meseta_from_bank_to_inventory(character.id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn add_meseta_to_bank(character_id: CharacterEntityId, amount: u32)
pub(super) fn add_meseta_to_bank(character_id: CharacterEntityId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -346,28 +230,8 @@ fn add_meseta_to_bank(character_id: CharacterEntityId, amount: u32)
} }
} }
pub async fn deposit_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(take_meseta_from_inventory(character.id, amount))
.act(add_meseta_to_bank(character.id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
fn take_item_from_bank(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
pub(super) fn take_item_from_bank(character_id: CharacterEntityId, item_id: ClientItemId, amount: u32)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem), ItemStateError>> + Send + 'a>>
{ {
@ -383,7 +247,7 @@ fn take_item_from_bank(character_id: CharacterEntityId, item_id: ClientItemId, a
} }
} }
fn add_bank_item_to_inventory(character: &CharacterEntity)
pub(super) fn add_bank_item_to_inventory(character: &CharacterEntity)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), BankItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
{ {
@ -429,31 +293,8 @@ fn add_bank_item_to_inventory(character: &CharacterEntity)
} }
} }
pub async fn withdraw_item<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_bank(character.id, *item_id, amount))
//.act(bank_item_to_inventory_item)
//.act(add_item_to_inventory)
.act(add_bank_item_to_inventory(character))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn add_inventory_item_to_bank(character_id: CharacterEntityId)
pub(super) fn add_inventory_item_to_bank(character_id: CharacterEntityId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -482,29 +323,8 @@ fn add_inventory_item_to_bank(character_id: CharacterEntityId)
} }
} }
pub async fn deposit_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, *item_id, amount))
.act(add_inventory_item_to_bank(character.id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn equip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId, equip_slot: u8)
pub(super) fn equip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId, equip_slot: u8)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -520,29 +340,8 @@ fn equip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId,
} }
} }
pub async fn equip_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
equip_slot: u8,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(equip_inventory_item(character.id, *item_id, equip_slot))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn unequip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId)
pub(super) fn unequip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -558,28 +357,9 @@ fn unequip_inventory_item(character_id: CharacterEntityId, item_id: ClientItemId
} }
} }
pub async fn unequip_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(unequip_inventory_item(character.id, *item_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Vec<ClientItemId>)
pub(super) fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Vec<ClientItemId>)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()), ItemStateError>> + Send + 'a>>
{ {
@ -596,28 +376,8 @@ fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Vec<ClientIte
} }
} }
pub async fn sort_inventory<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_ids: Vec<ClientItemId>,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(sort_inventory_items(character.id, item_ids))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn use_consumed_item(character: CharacterEntity)
pub(super) fn use_consumed_item(character: CharacterEntity)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>>
{ {
@ -637,30 +397,8 @@ fn use_consumed_item(character: CharacterEntity)
} }
} }
pub async fn use_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &mut CharacterEntity,
item_id: &ClientItemId,
amount: u32,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), new_character) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, *item_id, amount))
.act(use_consumed_item(character.clone()))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
*character = new_character;
Ok((transaction, ()))
}).await
}
fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemId)
pub(super) fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), CharacterEntity), ItemStateError>> + Send + 'a>>
{ {
@ -707,30 +445,7 @@ fn feed_mag_item(character: CharacterEntity, mag_item_id: ClientItemId)
} }
pub async fn feed_mag<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
mag_item_id: &ClientItemId,
tool_item_id: &ClientItemId,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, *tool_item_id, 1))
.act(feed_mag_item(character.clone(), *mag_item_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
pub(super) fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
shop_item: &'a (dyn ShopItem + Send + Sync), shop_item: &'a (dyn ShopItem + Send + Sync),
item_id: ClientItemId, item_id: ClientItemId,
amount: u32) amount: u32)
@ -790,34 +505,8 @@ fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
} }
} }
pub async fn buy_shop_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
shop_item: &'a (dyn ShopItem + Send + Sync),
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
let item_price = shop_item.price() as u32 * amount;
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_meseta_from_inventory(character.id, item_price))
//.act(bought_item_to_inventory_item)
//.act(add_item_to_inventory)
.act(add_bought_item_to_inventory(character.id, shop_item, item_id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
fn sell_inventory_item<'a>(character_id: CharacterEntityId)
pub(super) fn sell_inventory_item<'a>(character_id: CharacterEntityId)
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
{ {
@ -839,27 +528,6 @@ fn sell_inventory_item<'a>(character_id: CharacterEntityId)
} }
} }
pub async fn sell_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, item_id, amount))
.act(sell_inventory_item(character.id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
#[async_recursion::async_recursion] #[async_recursion::async_recursion]
async fn iterate_inner<'a, I, O, T, F, FR>(state: (ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), async fn iterate_inner<'a, I, O, T, F, FR>(state: (ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>),
@ -890,7 +558,7 @@ where
Ok((state, output)) Ok((state, output))
} }
pub fn iterate<'k, I, O, T, F, FR>(
pub(super) fn iterate<'k, I, O, T, F, FR>(
input: Vec<I>, input: Vec<I>,
func: F) func: F)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T)
@ -942,7 +610,7 @@ where
Ok((state, output)) Ok((state, output))
} }
pub fn foreach<'k, O, T, F>(func: F)
pub(super) fn foreach<'k, O, T, F>(func: F)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<T>) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<T>)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<O>), ItemStateError>> + Send + 'a>>
where where
@ -963,7 +631,7 @@ where
} }
} }
fn insert<'a, T: Send + Clone + 'a>(element: T)
pub(super) fn insert<'a, T: Send + Clone + 'a>(element: T)
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), T), ItemStateError>> + Send + 'a>>
{ {
@ -975,7 +643,7 @@ fn insert<'a, T: Send + Clone + 'a>(element: T)
} }
} }
fn add_item_to_inventory(character: CharacterEntity)
pub(super) fn add_item_to_inventory(character: CharacterEntity)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone
{ {
@ -999,7 +667,7 @@ fn add_item_to_inventory(character: CharacterEntity)
} }
} }
fn record_trade(trade_id: TradeId, character_to: CharacterEntityId, character_from: CharacterEntityId)
pub(super) fn record_trade(trade_id: TradeId, character_to: CharacterEntityId, character_from: CharacterEntityId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>), ItemStateError>> + Send + 'a>> + Clone -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), Vec<InventoryItem>), ItemStateError>> + Send + 'a>> + Clone
{ {
@ -1022,7 +690,7 @@ fn record_trade(trade_id: TradeId, character_to: CharacterEntityId, character_fr
} }
fn assign_new_item_id()
pub(super) fn assign_new_item_id()
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> + Clone
{ {
@ -1034,98 +702,8 @@ fn assign_new_item_id()
} }
} }
pub async fn trade_items<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta),
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta))
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), ItemStateError>
where
EG: EntityGateway,
{
let p1_trade_items = p1.2
.iter()
.map(|item| {
match item {
TradeItem::Individual(item_id) => (*item_id, 1),
TradeItem::Stacked(item_id, amount) => (*item_id, *amount as u32),
}
})
.collect();
let p2_trade_items = p2.2
.iter()
.map(|item| {
match item {
TradeItem::Individual(item_id) => (*item_id, 1),
TradeItem::Stacked(item_id, amount) => (*item_id, *amount as u32),
}
})
.collect();
entity_gateway.with_transaction(|mut transaction| async move {
let p1_id = p1.1.id;
let p2_id = p2.1.id;
let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?;
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), p1_removed_items) = ItemStateAction::default()
.act(iterate(p1_trade_items, move |p1_trade_item| take_item_from_inventory(p1_id, p1_trade_item.0, p1_trade_item.1) ))
.act(foreach(assign_new_item_id()))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p2_removed_items) = ItemStateAction::default()
.act(iterate(p2_trade_items, move |p2_trade_item| take_item_from_inventory(p2_id, p2_trade_item.0, p2_trade_item.1) ))
.act(foreach(assign_new_item_id()))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p2_new_items) = ItemStateAction::default()
.act(insert(p1_removed_items))
.act(foreach(add_item_to_inventory(p2.1.clone())))
.act(record_trade(trade.id, p1_id, p2_id))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p1_new_items) = ItemStateAction::default()
.act(insert(p2_removed_items))
.act(foreach(add_item_to_inventory(p1.1.clone())))
.act(record_trade(trade.id, p2_id, p1_id))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(take_meseta_from_inventory(p1_id, p1.3.0))
.act(take_meseta_from_inventory(p2_id, p2.3.0))
.act(add_meseta_to_inventory(p1_id, p2.3.0))
.act(add_meseta_to_inventory(p2_id, p1.3.0))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, (p1_new_items, p2_new_items)))
}).await
}
pub async fn take_meseta<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character_id: &CharacterEntityId,
meseta: Meseta)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(take_meseta_from_inventory(*character_id, meseta.0))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: ItemDrop)
pub(super) fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: ItemDrop)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> + Clone -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> + Clone
{ {
@ -1222,7 +800,7 @@ fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: I
} }
} }
fn add_item_to_local_floor(character_id: CharacterEntityId)
pub(super) fn add_item_to_local_floor(character_id: CharacterEntityId)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>>
{ {
@ -1237,29 +815,7 @@ fn add_item_to_local_floor(character_id: CharacterEntityId)
} }
} }
pub async fn enemy_drops_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character_id: CharacterEntityId,
item_drop: ItemDrop)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default()
.act(convert_item_drop_to_floor_item(character_id, item_drop))
.act(add_item_to_local_floor(character_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, floor_item))
}).await
}
fn apply_modifier_to_inventory_item(modifier: ItemModifier)
pub(super) fn apply_modifier_to_inventory_item(modifier: ItemModifier)
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
{ {
@ -1279,7 +835,7 @@ fn apply_modifier_to_inventory_item(modifier: ItemModifier)
} }
} }
fn as_individual_item()
pub(super) fn as_individual_item()
-> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem) -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem)
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), IndividualItemDetail), ItemStateError>> + Send + 'a>> -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), IndividualItemDetail), ItemStateError>> + Send + 'a>>
{ {
@ -1294,29 +850,3 @@ fn as_individual_item()
}) })
} }
} }
pub async fn apply_modifier<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: ClientItemId,
modifier: ItemModifier)
-> Result<IndividualItemDetail, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), item) = ItemStateAction::default()
.act(take_item_from_inventory(character.id, item_id, 1))
.act(apply_modifier_to_inventory_item(modifier))
.act(add_item_to_inventory(character.clone()))
.act(as_individual_item())
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, item))
}).await
}

1
src/ship/items/mod.rs

@ -5,6 +5,7 @@ pub mod itemstateaction;
pub mod inventory; pub mod inventory;
pub mod floor; pub mod floor;
pub mod bank; pub mod bank;
pub mod tasks;
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, derive_more::Display)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, derive_more::Display)]
pub struct ClientItemId(pub u32); pub struct ClientItemId(pub u32);

2
src/ship/items/state.rs

@ -14,8 +14,6 @@ use crate::ship::items::inventory::{Inventory, InventoryItem, InventoryItemDetai
use crate::ship::items::floor::{FloorState, FloorItem, LocalFloor, SharedFloor, FloorType}; use crate::ship::items::floor::{FloorState, FloorItem, LocalFloor, SharedFloor, FloorType};
use crate::ship::items::bank::{Bank, BankState, BankItem, BankItemDetail, BankError}; use crate::ship::items::bank::{Bank, BankState, BankItem, BankItemDetail, BankError};
// TODO: Commit trait that ItemStateProxy and EntityTransaction implement that .commit requires and acts on upon everything succeeding (like 3 less lines of code!)
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum ItemStateError { pub enum ItemStateError {
#[error("character {0} not found")] #[error("character {0} not found")]

500
src/ship/items/tasks.rs

@ -0,0 +1,500 @@
use crate::ship::items::ClientItemId;
use crate::entity::item::Meseta;
use crate::ship::map::MapArea;
use crate::entity::character::{CharacterEntity, CharacterEntityId};
use crate::entity::gateway::EntityGateway;
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateError, IndividualItemDetail};
use crate::ship::items::itemstateaction::{ItemStateAction, ItemAction};
use crate::ship::items::inventory::InventoryItem;
use crate::ship::items::floor::FloorItem;
use crate::entity::item::ItemModifier;
use crate::ship::shops::ShopItem;
use crate::ship::trade::TradeItem;
use crate::ship::location::AreaClient;
use crate::ship::drops::ItemDrop;
use crate::ship::items::actions;
pub async fn pick_up_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId)
-> Result<actions::TriggerCreateItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_floor(character.id, *item_id))
.act(actions::add_floor_item_to_inventory(character))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn drop_item<EG>(
item_state: &mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
map_area: MapArea,
drop_position: (f32, f32, f32))
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, 0))
.act(actions::add_inventory_item_to_shared_floor(character.id, map_area, drop_position))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn drop_partial_item<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
.act(actions::add_inventory_item_to_shared_floor(character.id, map_area, (drop_position.0, 0.0, drop_position.1)))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn drop_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
map_area: MapArea,
drop_position: (f32, f32),
amount: u32)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, amount))
.act(actions::add_meseta_to_shared_floor(character.id, amount, map_area, drop_position))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn withdraw_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_bank(character.id, amount))
.act(actions::add_meseta_from_bank_to_inventory(character.id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn deposit_meseta<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, amount))
.act(actions::add_meseta_to_bank(character.id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
pub async fn withdraw_item<'a, EG>(
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_bank(character.id, *item_id, amount))
//.act(bank_item_to_inventory_item)
//.act(add_item_to_inventory)
.act(actions::add_bank_item_to_inventory(character))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn deposit_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
amount: u32)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
.act(actions::add_inventory_item_to_bank(character.id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn equip_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
equip_slot: u8,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::equip_inventory_item(character.id, *item_id, equip_slot))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn unequip_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: &ClientItemId,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::unequip_inventory_item(character.id, *item_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn sort_inventory<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_ids: Vec<ClientItemId>,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::sort_inventory_items(character.id, item_ids))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn use_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &mut CharacterEntity,
item_id: &ClientItemId,
amount: u32,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), new_character) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *item_id, amount))
.act(actions::use_consumed_item(character.clone()))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
*character = new_character;
Ok((transaction, ()))
}).await
}
pub async fn feed_mag<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
mag_item_id: &ClientItemId,
tool_item_id: &ClientItemId,
) -> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, *tool_item_id, 1))
.act(actions::feed_mag_item(character.clone(), *mag_item_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
pub async fn buy_shop_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
shop_item: &'a (dyn ShopItem + Send + Sync),
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
let item_price = shop_item.price() as u32 * amount;
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(character.id, item_price))
//.act(bought_item_to_inventory_item)
//.act(add_item_to_inventory)
.act(actions::add_bought_item_to_inventory(character.id, shop_item, item_id, amount))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn sell_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: ClientItemId,
amount: u32,
) -> Result<InventoryItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), result) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, item_id, amount))
.act(actions::sell_inventory_item(character.id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, result))
}).await
}
pub async fn trade_items<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
p1: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta),
p2: (&AreaClient, &CharacterEntity, &Vec<TradeItem>, Meseta))
-> Result<(Vec<InventoryItem>, Vec<InventoryItem>), ItemStateError>
where
EG: EntityGateway,
{
let p1_trade_items = p1.2
.iter()
.map(|item| {
match item {
TradeItem::Individual(item_id) => (*item_id, 1),
TradeItem::Stacked(item_id, amount) => (*item_id, *amount as u32),
}
})
.collect();
let p2_trade_items = p2.2
.iter()
.map(|item| {
match item {
TradeItem::Individual(item_id) => (*item_id, 1),
TradeItem::Stacked(item_id, amount) => (*item_id, *amount as u32),
}
})
.collect();
entity_gateway.with_transaction(|mut transaction| async move {
let p1_id = p1.1.id;
let p2_id = p2.1.id;
let trade = transaction.gateway().create_trade(&p1_id, &p2_id).await?;
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), p1_removed_items) = ItemStateAction::default()
.act(actions::iterate(p1_trade_items, move |p1_trade_item| actions::take_item_from_inventory(p1_id, p1_trade_item.0, p1_trade_item.1) ))
.act(actions::foreach(actions::assign_new_item_id()))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p2_removed_items) = ItemStateAction::default()
.act(actions::iterate(p2_trade_items, move |p2_trade_item| actions::take_item_from_inventory(p2_id, p2_trade_item.0, p2_trade_item.1) ))
.act(actions::foreach(actions::assign_new_item_id()))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p2_new_items) = ItemStateAction::default()
.act(actions::insert(p1_removed_items))
.act(actions::foreach(actions::add_item_to_inventory(p2.1.clone())))
.act(actions::record_trade(trade.id, p1_id, p2_id))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), p1_new_items) = ItemStateAction::default()
.act(actions::insert(p2_removed_items))
.act(actions::foreach(actions::add_item_to_inventory(p1.1.clone())))
.act(actions::record_trade(trade.id, p2_id, p1_id))
.commit((item_state_proxy, transaction))
.await?;
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(p1_id, p1.3.0))
.act(actions::take_meseta_from_inventory(p2_id, p2.3.0))
.act(actions::add_meseta_to_inventory(p1_id, p2.3.0))
.act(actions::add_meseta_to_inventory(p2_id, p1.3.0))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, (p1_new_items, p2_new_items)))
}).await
}
pub async fn take_meseta<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character_id: &CharacterEntityId,
meseta: Meseta)
-> Result<(), ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), _) = ItemStateAction::default()
.act(actions::take_meseta_from_inventory(*character_id, meseta.0))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, ()))
}).await
}
pub async fn enemy_drops_item<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character_id: CharacterEntityId,
item_drop: ItemDrop)
-> Result<FloorItem, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), floor_item) = ItemStateAction::default()
.act(actions::convert_item_drop_to_floor_item(character_id, item_drop))
.act(actions::add_item_to_local_floor(character_id))
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, floor_item))
}).await
}
pub async fn apply_modifier<'a, EG> (
item_state: &'a mut ItemState,
entity_gateway: &mut EG,
character: &CharacterEntity,
item_id: ClientItemId,
modifier: ItemModifier)
-> Result<IndividualItemDetail, ItemStateError>
where
EG: EntityGateway,
{
entity_gateway.with_transaction(|transaction| async move {
let item_state_proxy = ItemStateProxy::new(item_state);
let ((item_state_proxy, transaction), item) = ItemStateAction::default()
.act(actions::take_item_from_inventory(character.id, item_id, 1))
.act(actions::apply_modifier_to_inventory_item(modifier))
.act(actions::add_item_to_inventory(character.clone()))
.act(actions::as_individual_item())
.commit((item_state_proxy, transaction))
.await?;
item_state_proxy.commit();
Ok((transaction, item))
}).await
}

3
src/ship/packet/handler/direct_message.rs

@ -16,7 +16,8 @@ use crate::ship::packet::builder;
use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem};
use crate::ship::items::state::{ItemState, ItemStateError}; use crate::ship::items::state::{ItemState, ItemStateError};
use crate::ship::items::floor::{FloorType, FloorItemDetail}; use crate::ship::items::floor::{FloorType, FloorItemDetail};
use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, take_meseta, apply_modifier, TriggerCreateItem};
use crate::ship::items::actions::TriggerCreateItem;
use crate::ship::items::tasks::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, take_meseta, apply_modifier};
const BANK_ACTION_DEPOSIT: u8 = 0; const BANK_ACTION_DEPOSIT: u8 = 0;
const BANK_ACTION_WITHDRAW: u8 = 1; const BANK_ACTION_WITHDRAW: u8 = 1;

2
src/ship/packet/handler/message.rs

@ -9,7 +9,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError};
use crate::ship::items::ClientItemId; use crate::ship::items::ClientItemId;
use crate::ship::packet::builder; use crate::ship::packet::builder;
use crate::ship::items::state::ItemState; use crate::ship::items::state::ItemState;
use crate::ship::items::actions::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta};
use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta};
pub async fn request_exp<EG: EntityGateway>(id: ClientId, pub async fn request_exp<EG: EntityGateway>(id: ClientId,
request_exp: &RequestExp, request_exp: &RequestExp,

2
src/ship/packet/handler/trade.rs

@ -10,7 +10,7 @@ use crate::ship::items::inventory::InventoryItemDetail;
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::ship::packet::builder; use crate::ship::packet::builder;
use crate::ship::items::actions::trade_items;
use crate::ship::items::tasks::trade_items;
use crate::ship::location::{AreaClient, RoomId}; use crate::ship::location::{AreaClient, RoomId};
use crate::entity::item::Meseta; use crate::entity::item::Meseta;

Loading…
Cancel
Save