|
|
@ -9,8 +9,9 @@ use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction}; |
|
|
|
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, ItemAction, ItemStateError, FloorItem, InventoryItem, AddItemResult, FloorItemDetail,
|
|
|
|
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail};
|
|
|
|
use crate::ship::items::apply_item::apply_item;
|
|
|
|
use crate::entity::item::ItemDetail;
|
|
|
|
use crate::entity::item::{ItemDetail, ItemEntity, NewItemEntity};
|
|
|
|
use crate::entity::item::tool::Tool;
|
|
|
|
use crate::ship::shops::ShopItem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -701,3 +702,88 @@ where |
|
|
|
Ok((transaction, ()))
|
|
|
|
}).await
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn add_bought_item_to_inventory<'a>(character_id: CharacterEntityId,
|
|
|
|
shop_item: &'a (dyn ShopItem + Send + Sync),
|
|
|
|
item_id: ClientItemId,
|
|
|
|
amount: u32)
|
|
|
|
-> impl Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ())
|
|
|
|
-> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), InventoryItem), ItemStateError>> + Send + 'a>>
|
|
|
|
{
|
|
|
|
move |(mut item_state, mut transaction), _| {
|
|
|
|
Box::pin(async move {
|
|
|
|
let mut inventory = item_state.inventory(&character_id)?;
|
|
|
|
let bought_item = shop_item.as_item();
|
|
|
|
|
|
|
|
let inventory_item = match bought_item {
|
|
|
|
ItemDetail::Tool(tool) if tool.is_stackable() => {
|
|
|
|
let mut item_entities = Vec::new();
|
|
|
|
for _ in 0..amount {
|
|
|
|
let item_entity = transaction.gateway().create_item(NewItemEntity {
|
|
|
|
item: ItemDetail::Tool(tool),
|
|
|
|
}).await?;
|
|
|
|
transaction.gateway().add_item_note(&item_entity.id, ItemNote::BoughtAtShop {
|
|
|
|
character_id: character_id,
|
|
|
|
}).await?;
|
|
|
|
item_entities.push(item_entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
let inventory_item = InventoryItem {
|
|
|
|
item_id,
|
|
|
|
item: InventoryItemDetail::Stacked(StackedItemDetail {
|
|
|
|
entity_ids: item_entities.into_iter().map(|i| i.id).collect(),
|
|
|
|
tool: tool,
|
|
|
|
})
|
|
|
|
};
|
|
|
|
inventory.add_item(inventory_item)?.1
|
|
|
|
},
|
|
|
|
item_detail => {
|
|
|
|
let item_entity = transaction.gateway().create_item(NewItemEntity {
|
|
|
|
item: item_detail.clone(),
|
|
|
|
}).await?;
|
|
|
|
transaction.gateway().add_item_note(&item_entity.id, ItemNote::BoughtAtShop {
|
|
|
|
character_id: character_id,
|
|
|
|
}).await?;
|
|
|
|
|
|
|
|
let inventory_item = InventoryItem {
|
|
|
|
item_id,
|
|
|
|
item: InventoryItemDetail::Individual(IndividualItemDetail {
|
|
|
|
entity_id: item_entity.id,
|
|
|
|
item: item_detail,
|
|
|
|
})
|
|
|
|
};
|
|
|
|
inventory.add_item(inventory_item)?.1
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?;
|
|
|
|
item_state.set_inventory(inventory);
|
|
|
|
Ok(((item_state, transaction), inventory_item))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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(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
|
|
|
|
}
|