enemy drop refactor
This commit is contained in:
parent
07fd5955a8
commit
8655082e9e
@ -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
|
||||
}
|
||||
|
@ -1214,10 +1214,15 @@ impl FloorState {
|
||||
&self.shared.0[self.shared.0.len()-1]
|
||||
}
|
||||
|
||||
pub fn add_item(&mut self, floor_item: FloorItem) -> &FloorItem {
|
||||
pub fn add_shared_item(&mut self, floor_item: FloorItem) -> &FloorItem {
|
||||
self.shared.0.push(floor_item);
|
||||
&self.shared.0[self.shared.0.len()-1]
|
||||
}
|
||||
|
||||
pub fn add_local_item(&mut self, floor_item: FloorItem) -> &FloorItem {
|
||||
self.local.0.push(floor_item);
|
||||
&self.local.0[self.local.0.len()-1]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,19 +12,19 @@ use std::convert::TryInto;
|
||||
use crate::ship::shops::ShopItem;
|
||||
|
||||
|
||||
pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result<ItemDrop, ShipError> {
|
||||
pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem2) -> Result<ItemDrop, ShipError> {
|
||||
let item_bytes = item_drop.as_client_bytes();
|
||||
Ok(ItemDrop {
|
||||
client,
|
||||
target,
|
||||
map_area: item_drop.map_area().area_value(),
|
||||
map_area: item_drop.map_area.area_value(),
|
||||
variety: 0,
|
||||
unknown: 0,
|
||||
x: item_drop.x(),
|
||||
z: item_drop.z(),
|
||||
y: item_drop.y(),
|
||||
x: item_drop.x,
|
||||
z: item_drop.z,
|
||||
y: item_drop.y,
|
||||
item_bytes: item_bytes[0..12].try_into()?,
|
||||
item_id: item_drop.item_id().0,
|
||||
item_id: item_drop.item_id.0,
|
||||
item_bytes2: item_bytes[12..16].try_into()?,
|
||||
unknown2: 0,
|
||||
})
|
||||
|
@ -15,7 +15,7 @@ use libpso::utf8_to_utf16_array;
|
||||
use crate::ship::packet::builder;
|
||||
use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem};
|
||||
use crate::ship::items::state::{ItemState, FloorType, FloorItemDetail};
|
||||
use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, TriggerCreateItem};
|
||||
use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, TriggerCreateItem};
|
||||
|
||||
const BANK_ACTION_DEPOSIT: u8 = 0;
|
||||
const BANK_ACTION_WITHDRAW: u8 = 1;
|
||||
@ -76,7 +76,7 @@ pub async fn request_item<EG>(id: ClientId,
|
||||
client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
rooms: &mut Rooms,
|
||||
item_manager: &mut ItemManager)
|
||||
item_state: &mut ItemState)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||
where
|
||||
EG: EntityGateway
|
||||
@ -117,8 +117,8 @@ where
|
||||
item: item_drop,
|
||||
};
|
||||
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
|
||||
let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?;
|
||||
let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, floor_item)?;
|
||||
let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?;
|
||||
let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?;
|
||||
|
||||
item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))));
|
||||
}
|
||||
@ -201,7 +201,7 @@ pub async fn request_box_item<EG>(id: ClientId,
|
||||
client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
rooms: &mut Rooms,
|
||||
item_manager: &mut ItemManager)
|
||||
item_state: &mut ItemState)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||
where
|
||||
EG: EntityGateway
|
||||
@ -236,8 +236,8 @@ EG: EntityGateway
|
||||
item: item_drop,
|
||||
};
|
||||
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
|
||||
let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?; // TODO: unwrap
|
||||
let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, floor_item)?;
|
||||
let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?;
|
||||
let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?;
|
||||
item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))))
|
||||
}
|
||||
|
||||
|
@ -550,13 +550,13 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients)
|
||||
},
|
||||
GameMessage::RequestItem(request_item) => {
|
||||
handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_manager).await?
|
||||
handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await?
|
||||
},
|
||||
GameMessage::PickupItem(pickup_item) => {
|
||||
handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await?
|
||||
},
|
||||
GameMessage::BoxDropRequest(box_drop_request) => {
|
||||
handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_manager).await?
|
||||
handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await?
|
||||
},
|
||||
GameMessage::BankRequest(_bank_request) => {
|
||||
handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await?
|
||||
|
Loading…
x
Reference in New Issue
Block a user