|
|
@ -10,9 +10,11 @@ use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, Item |
|
|
|
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail};
|
|
|
|
use crate::ship::items::apply_item::apply_item;
|
|
|
|
use crate::entity::item::{ItemDetail, NewItemEntity, TradeId};
|
|
|
|
use crate::entity::item::tool::Tool;
|
|
|
|
use crate::ship::shops::ShopItem;
|
|
|
|
use crate::ship::trade::TradeItem;
|
|
|
|
use crate::ship::location::{AreaClient, RoomId};
|
|
|
|
use crate::ship::drops::{ItemDrop, ItemDropType};
|
|
|
|
|
|
|
|
pub enum TriggerCreateItem {
|
|
|
|
Yes,
|
|
|
@ -239,7 +241,7 @@ fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_ |
|
|
|
};
|
|
|
|
|
|
|
|
let mut floor = item_state.floor(&character_id)?;
|
|
|
|
let floor_item = floor.add_item(floor_item).clone();
|
|
|
|
let floor_item = floor.add_shared_item(floor_item).clone();
|
|
|
|
item_state.set_floor(floor);
|
|
|
|
|
|
|
|
Ok(((item_state, transaction), floor_item))
|
|
|
@ -1145,3 +1147,137 @@ where |
|
|
|
Ok((transaction, ()))
|
|
|
|
}).await
|
|
|
|
}
|
|
|
|
|
|
|
|
fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: ItemDrop)
|
|
|
|
-> 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
|
|
|
|
{
|
|
|
|
move |(mut item_state, mut transaction), _| {
|
|
|
|
let item_drop = item_drop.clone();
|
|
|
|
Box::pin(async move {
|
|
|
|
enum ItemOrMeseta {
|
|
|
|
Individual(ItemDetail),
|
|
|
|
Stacked(Tool),
|
|
|
|
Meseta(Meseta)
|
|
|
|
}
|
|
|
|
|
|
|
|
let item = match item_drop.item {
|
|
|
|
ItemDropType::Weapon(w) => ItemOrMeseta::Individual(ItemDetail::Weapon(w)),
|
|
|
|
ItemDropType::Armor(w) => ItemOrMeseta::Individual(ItemDetail::Armor(w)),
|
|
|
|
ItemDropType::Shield(w) => ItemOrMeseta::Individual(ItemDetail::Shield(w)),
|
|
|
|
ItemDropType::Unit(w) => ItemOrMeseta::Individual(ItemDetail::Unit(w)),
|
|
|
|
ItemDropType::TechniqueDisk(w) => ItemOrMeseta::Individual(ItemDetail::TechniqueDisk(w)),
|
|
|
|
ItemDropType::Mag(w) => ItemOrMeseta::Individual(ItemDetail::Mag(w)),
|
|
|
|
ItemDropType::Tool(t) => {
|
|
|
|
if t.tool.is_stackable() {
|
|
|
|
ItemOrMeseta::Stacked(t)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ItemOrMeseta::Individual(ItemDetail::Tool(t))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ItemDropType::Meseta(m) => ItemOrMeseta::Meseta(Meseta(m)),
|
|
|
|
};
|
|
|
|
|
|
|
|
let item_id = item_state.new_item_id()?;
|
|
|
|
|
|
|
|
let floor_item = match item {
|
|
|
|
ItemOrMeseta::Individual(item_detail) => {
|
|
|
|
let entity = transaction.gateway().create_item(NewItemEntity {
|
|
|
|
item: item_detail.clone(),
|
|
|
|
}).await?;
|
|
|
|
transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop {
|
|
|
|
character_id,
|
|
|
|
map_area: item_drop.map_area,
|
|
|
|
x: item_drop.x,
|
|
|
|
y: item_drop.y,
|
|
|
|
z: item_drop.z,
|
|
|
|
}).await?;
|
|
|
|
FloorItem {
|
|
|
|
item_id,
|
|
|
|
item: FloorItemDetail::Individual(IndividualItemDetail {
|
|
|
|
entity_id: entity.id,
|
|
|
|
item: item_detail,
|
|
|
|
}),
|
|
|
|
map_area: item_drop.map_area,
|
|
|
|
x: item_drop.x,
|
|
|
|
y: item_drop.y,
|
|
|
|
z: item_drop.z,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ItemOrMeseta::Stacked(tool) => {
|
|
|
|
let entity = transaction.gateway().create_item(NewItemEntity {
|
|
|
|
item: ItemDetail::Tool(tool),
|
|
|
|
}).await?;
|
|
|
|
transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop {
|
|
|
|
character_id,
|
|
|
|
map_area: item_drop.map_area,
|
|
|
|
x: item_drop.x,
|
|
|
|
y: item_drop.y,
|
|
|
|
z: item_drop.z,
|
|
|
|
}).await?;
|
|
|
|
FloorItem {
|
|
|
|
item_id,
|
|
|
|
item: FloorItemDetail::Stacked(StackedItemDetail{
|
|
|
|
entity_ids: vec![entity.id],
|
|
|
|
tool,
|
|
|
|
}),
|
|
|
|
map_area: item_drop.map_area,
|
|
|
|
x: item_drop.x,
|
|
|
|
y: item_drop.y,
|
|
|
|
z: item_drop.z,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ItemOrMeseta::Meseta(meseta) => {
|
|
|
|
FloorItem {
|
|
|
|
item_id,
|
|
|
|
item: FloorItemDetail::Meseta(meseta),
|
|
|
|
map_area: item_drop.map_area,
|
|
|
|
x: item_drop.x,
|
|
|
|
y: item_drop.y,
|
|
|
|
z: item_drop.z,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(((item_state, transaction), floor_item))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_item_to_local_floor(character_id: CharacterEntityId)
|
|
|
|
-> 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>>
|
|
|
|
{
|
|
|
|
move |(mut item_state, transaction) , floor_item| {
|
|
|
|
Box::pin(async move {
|
|
|
|
let mut floor = item_state.floor(&character_id)?;
|
|
|
|
let item = floor.add_local_item(floor_item).clone();
|
|
|
|
item_state.set_floor(floor);
|
|
|
|
|
|
|
|
Ok(((item_state, transaction), item))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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(|mut 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
|
|
|
|
}
|