enemy drop refactor
This commit is contained in:
parent
2775f81cc9
commit
ff072ca026
@ -10,9 +10,11 @@ use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, Item
|
|||||||
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail};
|
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail};
|
||||||
use crate::ship::items::apply_item::apply_item;
|
use crate::ship::items::apply_item::apply_item;
|
||||||
use crate::entity::item::{ItemDetail, NewItemEntity, TradeId};
|
use crate::entity::item::{ItemDetail, NewItemEntity, TradeId};
|
||||||
|
use crate::entity::item::tool::Tool;
|
||||||
use crate::ship::shops::ShopItem;
|
use crate::ship::shops::ShopItem;
|
||||||
use crate::ship::trade::TradeItem;
|
use crate::ship::trade::TradeItem;
|
||||||
use crate::ship::location::{AreaClient, RoomId};
|
use crate::ship::location::{AreaClient, RoomId};
|
||||||
|
use crate::ship::drops::{ItemDrop, ItemDropType};
|
||||||
|
|
||||||
pub enum TriggerCreateItem {
|
pub enum TriggerCreateItem {
|
||||||
Yes,
|
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 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);
|
item_state.set_floor(floor);
|
||||||
|
|
||||||
Ok(((item_state, transaction), floor_item))
|
Ok(((item_state, transaction), floor_item))
|
||||||
@ -1145,3 +1147,137 @@ where
|
|||||||
Ok((transaction, ()))
|
Ok((transaction, ()))
|
||||||
}).await
|
}).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]
|
&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.push(floor_item);
|
||||||
&self.shared.0[self.shared.0.len()-1]
|
&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;
|
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();
|
let item_bytes = item_drop.as_client_bytes();
|
||||||
Ok(ItemDrop {
|
Ok(ItemDrop {
|
||||||
client,
|
client,
|
||||||
target,
|
target,
|
||||||
map_area: item_drop.map_area().area_value(),
|
map_area: item_drop.map_area.area_value(),
|
||||||
variety: 0,
|
variety: 0,
|
||||||
unknown: 0,
|
unknown: 0,
|
||||||
x: item_drop.x(),
|
x: item_drop.x,
|
||||||
z: item_drop.z(),
|
z: item_drop.z,
|
||||||
y: item_drop.y(),
|
y: item_drop.y,
|
||||||
item_bytes: item_bytes[0..12].try_into()?,
|
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()?,
|
item_bytes2: item_bytes[12..16].try_into()?,
|
||||||
unknown2: 0,
|
unknown2: 0,
|
||||||
})
|
})
|
||||||
|
@ -15,7 +15,7 @@ use libpso::utf8_to_utf16_array;
|
|||||||
use crate::ship::packet::builder;
|
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, FloorType, FloorItemDetail};
|
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_DEPOSIT: u8 = 0;
|
||||||
const BANK_ACTION_WITHDRAW: u8 = 1;
|
const BANK_ACTION_WITHDRAW: u8 = 1;
|
||||||
@ -76,7 +76,7 @@ pub async fn request_item<EG>(id: ClientId,
|
|||||||
client_location: &ClientLocation,
|
client_location: &ClientLocation,
|
||||||
clients: &mut Clients,
|
clients: &mut Clients,
|
||||||
rooms: &mut Rooms,
|
rooms: &mut Rooms,
|
||||||
item_manager: &mut ItemManager)
|
item_state: &mut ItemState)
|
||||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
where
|
where
|
||||||
EG: EntityGateway
|
EG: EntityGateway
|
||||||
@ -111,8 +111,8 @@ where
|
|||||||
item: item_drop,
|
item: item_drop,
|
||||||
};
|
};
|
||||||
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
|
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 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)?;
|
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)))));
|
item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))));
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ pub async fn request_box_item<EG>(id: ClientId,
|
|||||||
client_location: &ClientLocation,
|
client_location: &ClientLocation,
|
||||||
clients: &mut Clients,
|
clients: &mut Clients,
|
||||||
rooms: &mut Rooms,
|
rooms: &mut Rooms,
|
||||||
item_manager: &mut ItemManager)
|
item_state: &mut ItemState)
|
||||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||||
where
|
where
|
||||||
EG: EntityGateway
|
EG: EntityGateway
|
||||||
@ -230,8 +230,8 @@ EG: EntityGateway
|
|||||||
item: item_drop,
|
item: item_drop,
|
||||||
};
|
};
|
||||||
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
|
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 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)?;
|
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)))))
|
item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,13 +548,13 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
|||||||
handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients)
|
handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients)
|
||||||
},
|
},
|
||||||
GameMessage::RequestItem(request_item) => {
|
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) => {
|
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?
|
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) => {
|
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) => {
|
GameMessage::BankRequest(_bank_request) => {
|
||||||
handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await?
|
handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user