bare minimum item usage stuff
This commit is contained in:
parent
eb23cc2dfd
commit
faf00a904a
@ -7,7 +7,10 @@ use crate::ship::map::MapArea;
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId};
|
||||
use crate::entity::gateway::{EntityGateway, EntityGatewayTransaction};
|
||||
use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, ItemAction, ItemStateError, FloorItem, InventoryItem, AddItemResult, FloorItemDetail,
|
||||
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail};
|
||||
StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail};
|
||||
use crate::ship::items::apply_item::apply_item;
|
||||
use crate::entity::item::ItemDetail;
|
||||
use crate::entity::item::tool::Tool;
|
||||
|
||||
|
||||
|
||||
@ -597,3 +600,50 @@ where
|
||||
Ok((transaction, result))
|
||||
}).await
|
||||
}
|
||||
|
||||
|
||||
fn use_consumed_item(character: CharacterEntity)
|
||||
-> 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>>
|
||||
{
|
||||
move |(mut item_state, mut transaction), inventory_item| {
|
||||
let mut character = character.clone();
|
||||
Box::pin(async move {
|
||||
let mut transaction = inventory_item.with_entity_id(Ok(transaction), |mut transaction: Result<_, ItemStateError>, entity_id| {
|
||||
async move {
|
||||
if let Ok(transaction) = &mut transaction {
|
||||
transaction.gateway().add_item_note(&entity_id, ItemNote::Consumed).await?;
|
||||
}
|
||||
transaction
|
||||
}}).await?;
|
||||
|
||||
apply_item(&mut item_state, transaction.gateway(), &mut character, inventory_item).await?;
|
||||
|
||||
Ok(((item_state, transaction), character))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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(consume_inventory_tool(character.id, *item_id, 1))
|
||||
.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
|
||||
}
|
||||
|
219
src/ship/items/apply_item.rs
Normal file
219
src/ship/items/apply_item.rs
Normal file
@ -0,0 +1,219 @@
|
||||
use thiserror::Error;
|
||||
use crate::entity::gateway::{EntityGateway, GatewayError};
|
||||
use crate::entity::character::CharacterEntity;
|
||||
use crate::entity::item::mag::MagCell;
|
||||
use crate::entity::item::tool::ToolType;
|
||||
use crate::entity::item::ItemDetail;
|
||||
use crate::ship::items::state::{ItemStateProxy, InventoryState, InventoryItem, InventoryItemDetail};
|
||||
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ApplyItemError {
|
||||
#[error("no character")]
|
||||
NoCharacter,
|
||||
#[error("item not equipped")]
|
||||
ItemNotEquipped,
|
||||
#[error("invalid item")]
|
||||
InvalidItem,
|
||||
#[error("gateway error {0}")]
|
||||
GatewayError(#[from] GatewayError),
|
||||
}
|
||||
|
||||
// TODO: make all these functions not-pub
|
||||
pub async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.power += 1;
|
||||
entity_gateway.save_character(character).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.mind += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.evade += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.def += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.luck += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.hp += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
|
||||
character.materials.tp += 1;
|
||||
entity_gateway.save_character(character).await.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*
|
||||
async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), ApplyItemError> {
|
||||
let mut mag_handle = inventory.get_equipped_mag_handle().ok_or(ApplyItemError::ItemNotEquipped)?;
|
||||
let mag_item = mag_handle.item_mut()
|
||||
.ok_or(ApplyItemError::InvalidItem)?;
|
||||
let actual_mag = mag_item
|
||||
.individual_mut()
|
||||
.ok_or(ApplyItemError::InvalidItem)?
|
||||
.mag_mut()
|
||||
.ok_or(ApplyItemError::InvalidItem)?;
|
||||
actual_mag.apply_mag_cell(mag_cell_type);
|
||||
for mag_entity_id in mag_item.entity_ids() {
|
||||
for cell_entity_id in used_cell.entity_ids() {
|
||||
entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cell_of_mag_502<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag502).await
|
||||
}
|
||||
|
||||
pub async fn cell_of_mag_213<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag213).await
|
||||
}
|
||||
|
||||
pub async fn parts_of_robochao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PartsOfRobochao).await
|
||||
}
|
||||
|
||||
pub async fn heart_of_opaopa<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfOpaOpa).await
|
||||
}
|
||||
|
||||
pub async fn heart_of_pian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfPian).await
|
||||
}
|
||||
|
||||
pub async fn heart_of_chao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfChao).await
|
||||
}
|
||||
|
||||
pub async fn heart_of_angel<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfAngel).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_hamburger<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfHamburger).await
|
||||
}
|
||||
|
||||
pub async fn panthers_spirit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PanthersSpirit).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_mark3<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMark3).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_master_system<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMasterSystem).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_genesis<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfGenesis).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_sega_saturn<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfSegaSaturn).await
|
||||
}
|
||||
|
||||
pub async fn kit_of_dreamcast<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfDreamcast).await
|
||||
}
|
||||
|
||||
pub async fn tablet<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::Tablet).await
|
||||
}
|
||||
|
||||
pub async fn dragon_scale<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::DragonScale).await
|
||||
}
|
||||
|
||||
pub async fn heaven_striker_coat<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeavenStrikerCoat).await
|
||||
}
|
||||
|
||||
pub async fn pioneer_parts<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::PioneerParts).await
|
||||
}
|
||||
|
||||
pub async fn amities_memo<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::AmitiesMemo).await
|
||||
}
|
||||
|
||||
pub async fn heart_of_morolian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfMorolian).await
|
||||
}
|
||||
|
||||
pub async fn rappys_beak<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::RappysBeak).await
|
||||
}
|
||||
|
||||
pub async fn yahoos_engine<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::YahoosEngine).await
|
||||
}
|
||||
|
||||
pub async fn d_photon_core<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::DPhotonCore).await
|
||||
}
|
||||
|
||||
pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
|
||||
mag_cell(entity_gateway, used_cell, inventory, MagCell::LibertaKit).await
|
||||
}
|
||||
*/
|
||||
|
||||
async fn apply_tool<'a, EG: EntityGateway + ?Sized>(item_state: &mut ItemStateProxy<'a>, entity_gateway: &mut EG, character: &mut CharacterEntity, tool: ToolType) -> Result<(), ApplyItemError> {
|
||||
match tool {
|
||||
ToolType::PowerMaterial => power_material(entity_gateway, character).await,
|
||||
ToolType::MindMaterial => mind_material(entity_gateway, character).await,
|
||||
ToolType::EvadeMaterial => evade_material(entity_gateway, character).await,
|
||||
ToolType::DefMaterial => def_material(entity_gateway, character).await,
|
||||
ToolType::LuckMaterial => luck_material(entity_gateway, character).await,
|
||||
ToolType::HpMaterial => hp_material(entity_gateway, character).await,
|
||||
ToolType::TpMaterial => tp_material(entity_gateway, character).await,
|
||||
ToolType::Monomate => Ok(()),
|
||||
ToolType::Dimate => Ok(()),
|
||||
ToolType::Trimate => Ok(()),
|
||||
ToolType::Monofluid => Ok(()),
|
||||
ToolType::Difluid => Ok(()),
|
||||
ToolType::Trifluid => Ok(()),
|
||||
ToolType::HuntersReport => Ok(()),
|
||||
// TODO: rest of these
|
||||
_ => Err(ApplyItemError::InvalidItem)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub async fn apply_item<'a, EG: EntityGateway + ?Sized>(item_state: &mut ItemStateProxy<'a>, entity_gateway: &mut EG, character: &mut CharacterEntity, item: InventoryItem) -> Result<(), ApplyItemError> {
|
||||
let item_detail = match item.item {
|
||||
InventoryItemDetail::Individual(individual_item) => {
|
||||
individual_item.item
|
||||
},
|
||||
InventoryItemDetail::Stacked(stacked_item) => {
|
||||
ItemDetail::Tool(stacked_item.tool)
|
||||
},
|
||||
};
|
||||
|
||||
match item_detail {
|
||||
ItemDetail::Tool(tool) => apply_tool(item_state, entity_gateway, character, tool.tool).await,
|
||||
_ => Err(ApplyItemError::InvalidItem)
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ pub mod transaction;
|
||||
pub mod use_tool;
|
||||
pub mod state;
|
||||
pub mod actions;
|
||||
pub mod apply_item;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, derive_more::Display)]
|
||||
|
@ -24,6 +24,9 @@ pub enum ItemStateError {
|
||||
#[error("floor item {0} not found")]
|
||||
NoFloorItem(ClientItemId),
|
||||
|
||||
#[error("expected {0} to be a tool")]
|
||||
NotATool(ClientItemId),
|
||||
|
||||
#[error("bank item {0} not found")]
|
||||
NoBankItem(ClientItemId),
|
||||
|
||||
@ -50,6 +53,9 @@ pub enum ItemStateError {
|
||||
|
||||
#[error("stacked item")]
|
||||
StackedItemError(Vec<ItemEntity>),
|
||||
|
||||
#[error("apply item {0}")]
|
||||
ApplyItemError(#[from] crate::ship::items::apply_item::ApplyItemError),
|
||||
}
|
||||
|
||||
pub enum FloorType {
|
||||
|
@ -8,7 +8,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||
use crate::ship::items::{ItemManager, ClientItemId};
|
||||
use crate::ship::packet::builder;
|
||||
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 crate::ship::items::actions::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item};
|
||||
|
||||
pub async fn request_exp<EG: EntityGateway>(id: ClientId,
|
||||
request_exp: &RequestExp,
|
||||
@ -278,20 +278,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn use_item<EG>(id: ClientId,
|
||||
pub async fn player_uses_item<EG>(id: ClientId,
|
||||
player_use_tool: &PlayerUseItem,
|
||||
entity_gateway: &mut EG,
|
||||
_client_location: &ClientLocation,
|
||||
clients: &mut Clients,
|
||||
item_manager: &mut ItemManager)
|
||||
item_state: &mut ItemState)
|
||||
-> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
|
||||
where
|
||||
EG: EntityGateway
|
||||
{
|
||||
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||
let item_used_type = item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?;
|
||||
|
||||
item_manager.use_item(item_used_type, entity_gateway, &mut client.character).await?;
|
||||
use_item(item_state, entity_gateway, &mut client.character, &ClientItemId(player_use_tool.item_id), 1).await?;
|
||||
Ok(Box::new(None.into_iter())) // TODO: should probably tell other players we used an item
|
||||
}
|
||||
|
||||
|
@ -502,7 +502,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
|
||||
},
|
||||
GameMessage::PlayerUseItem(player_use_item) => {
|
||||
let block = self.blocks.with_client(id, &self.clients)?;
|
||||
handler::message::use_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_manager).await?
|
||||
handler::message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await?
|
||||
},
|
||||
GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => {
|
||||
handler::message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await?
|
||||
|
@ -164,7 +164,7 @@ async fn test_use_nonstackable_tool() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::MagicStoneIritista,
|
||||
tool: item::tool::ToolType::HuntersReport,
|
||||
}
|
||||
),
|
||||
}).await.unwrap());
|
||||
@ -251,6 +251,9 @@ async fn test_use_materials() {
|
||||
assert!(char.materials.luck == 2);
|
||||
}
|
||||
|
||||
// TODO: tests for ALL ITEMS WOW
|
||||
|
||||
/*
|
||||
#[async_std::test]
|
||||
pub async fn test_learn_new_tech() {}
|
||||
|
||||
@ -268,3 +271,4 @@ pub async fn test_char_cannot_learn_high_level_tech() {}
|
||||
|
||||
#[async_std::test]
|
||||
pub async fn test_android_cannot_learn_tech() {}
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user