From d567c502166c5961b2a8a067fdb733182f2a6bba Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 7 Sep 2020 08:02:12 -0600 Subject: [PATCH] mag cells --- src/entity/gateway/entitygateway.rs | 4 + src/entity/gateway/inmemory.rs | 16 ++++ src/entity/item/mag.rs | 117 ++++++++++++++++++++++++++++ src/ship/items/inventory.rs | 29 +++++++ src/ship/items/manager.rs | 12 ++- src/ship/items/use_tool.rs | 35 ++++++++- 6 files changed, 208 insertions(+), 5 deletions(-) diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 168c870..9cf4d4d 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -68,6 +68,10 @@ pub trait EntityGateway: Send + Sync + Clone { unimplemented!(); } + async fn use_mag_cell(&mut self, _mag_item_id: &ItemEntityId, _mag_cell_id: &ItemEntityId) { + unimplemented!(); + } + async fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec { unimplemented!(); } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index f263ece..5620cb6 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::convert::TryInto; use crate::entity::account::*; use crate::entity::character::*; @@ -183,6 +184,13 @@ impl EntityGateway for InMemoryGateway { .push(mag::MagModifier::OwnerChange(character.char_class, character.section_id)); } + async fn use_mag_cell(&mut self, mag_item_id: &ItemEntityId, mag_cell_id: &ItemEntityId) { + self.mag_modifiers.lock().unwrap() + .entry(*mag_item_id) + .or_insert(Vec::new()) + .push(mag::MagModifier::MagCell(mag_cell_id.clone())); + } + async fn get_items_by_character(&self, character: &CharacterEntity) -> Vec { let items = self.items.lock().unwrap(); items @@ -214,6 +222,14 @@ impl EntityGateway for InMemoryGateway { mag::MagModifier::OwnerChange(class, section_id) => { mag.change_owner(*class, *section_id) }, + mag::MagModifier::MagCell(mag_cell_id) => { + items.get(&mag_cell_id).map(|mag_cell| { + match mag_cell.item { + ItemDetail::Tool(mag_cell) => mag.apply_mag_cell(mag_cell.tool.try_into().unwrap()), + _ => {} + } + }); + }, _ => {} } } diff --git a/src/entity/item/mag.rs b/src/entity/item/mag.rs index 55b2f00..e9870b3 100644 --- a/src/entity/item/mag.rs +++ b/src/entity/item/mag.rs @@ -390,6 +390,78 @@ impl MagType { } } +pub enum MagCell { + CellOfMag502, + CellOfMag213, + PartsOfRobochao, + HeartOfOpaOpa, + HeartOfPian, + HeartOfChao, + HeartOfAngel, + HeartOfDevil, + KitOfHamburger, + PanthersSpirit, + KitOfMark3, + KitOfMasterSystem, + KitOfGenesis, + KitOfSegaSaturn, + KitOfDreamcast, + Tablet, + DragonScale, + HeavenStrikerCoat, + PioneerParts, + AmitiesMemo, + HeartOfMorolian, + RappysBeak, + YahoosEngine, + DPhotonCore, + LibertaKit, + CellOfMag0503, + CellOfMag0504, + CellOfMag0505, + CellOfMag0506, + CellOfMag0507, +} + +impl std::convert::TryFrom for MagCell { + type Error = (); + + fn try_from(tool: ToolType) -> Result { + match tool { + ToolType::CellOfMag502 => Ok(MagCell::CellOfMag502), + ToolType::CellOfMag213 => Ok(MagCell::CellOfMag213), + ToolType::PartsOfRobochao => Ok(MagCell::PartsOfRobochao), + ToolType::HeartOfOpaOpa => Ok(MagCell::HeartOfOpaOpa), + ToolType::HeartOfPian => Ok(MagCell::HeartOfPian), + ToolType::HeartOfChao => Ok(MagCell::HeartOfChao), + ToolType::HeartOfAngel => Ok(MagCell::HeartOfAngel), + ToolType::HeartOfDevil => Ok(MagCell::HeartOfDevil), + ToolType::KitOfHamburger => Ok(MagCell::KitOfHamburger), + ToolType::PanthersSpirit => Ok(MagCell::PanthersSpirit), + ToolType::KitOfMark3 => Ok(MagCell::KitOfMark3), + ToolType::KitOfMasterSystem => Ok(MagCell::KitOfMasterSystem), + ToolType::KitOfGenesis => Ok(MagCell::KitOfGenesis), + ToolType::KitOfSegaSaturn => Ok(MagCell::KitOfSegaSaturn), + ToolType::KitOfDreamcast => Ok(MagCell::KitOfDreamcast), + ToolType::Tablet => Ok(MagCell::Tablet), + ToolType::DragonScale => Ok(MagCell::DragonScale), + ToolType::HeavenStrikerCoat => Ok(MagCell::HeavenStrikerCoat), + ToolType::PioneerParts => Ok(MagCell::PioneerParts), + ToolType::AmitiesMemo => Ok(MagCell::AmitiesMemo), + ToolType::HeartOfMorolian => Ok(MagCell::HeartOfMorolian), + ToolType::RappysBeak => Ok(MagCell::RappysBeak), + ToolType::YahoosEngine => Ok(MagCell::YahoosEngine), + ToolType::DPhotonCore => Ok(MagCell::DPhotonCore), + ToolType::LibertaKit => Ok(MagCell::LibertaKit), + ToolType::CellOfMag0503 => Ok(MagCell::CellOfMag0503), + ToolType::CellOfMag0504 => Ok(MagCell::CellOfMag0504), + ToolType::CellOfMag0505 => Ok(MagCell::CellOfMag0505), + ToolType::CellOfMag0506 => Ok(MagCell::CellOfMag0506), + ToolType::CellOfMag0507 => Ok(MagCell::CellOfMag0507), + _ => Err(()), + } + } +} enum MagAttribute { //Def, @@ -981,6 +1053,51 @@ impl Mag { pub fn bank(&mut self) { // what is the truncation logic anyway } + + pub fn apply_mag_cell(&mut self, mag_cell: MagCell) { + self.mag = match mag_cell { + MagCell::CellOfMag502 => { + match self.id { + SectionID::Viridia | SectionID::Skyly | SectionID::Purplenum | SectionID::Redria | SectionID::Yellowboze => { + MagType::Soniti + }, + SectionID::Greenill | SectionID::Bluefull | SectionID::Pinkal | SectionID::Oran | SectionID::Whitill => { + MagType::Pitri + } + } + } + //MagCell::CellOfMag213 => , + MagCell::PartsOfRobochao => MagType::Robochao, + //MagCell::HeartOfOpaOpa => , + //MagCell::HeartOfPian => , + //MagCell::HeartOfChao => , + //MagCell::HeartOfAngel => , + //MagCell::HeartOfDevil => , + //MagCell::KitOfHamburger => , + //MagCell::PanthersSpirit => , + //MagCell::KitOfMark3 => , + //MagCell::KitOfMasterSystem => , + //MagCell::KitOfGenesis => , + //MagCell::KitOfSegaSaturn => , + //MagCell::KitOfDreamcast => , + //MagCell::Tablet => , + //MagCell::DragonScale => , + //MagCell::HeavenStrikerCoat => , + //MagCell::PioneerParts => , + //MagCell::AmitiesMemo => , + //MagCell::HeartOfMorolian => , + //MagCell::RappysBeak => , + //MagCell::YahoosEngine => , + //MagCell::DPhotonCore => , + //MagCell::LibertaKit => , + //MagCell::CellOfMag0503 => , + //MagCell::CellOfMag0504 => , + //MagCell::CellOfMag0505 => , + //MagCell::CellOfMag0506 => , + //MagCell::CellOfMag0507 => , + _ => panic!() + } + } } diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index 024a2ca..4cbd57d 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -74,6 +74,17 @@ pub enum InventoryItemAddToError { } impl InventoryItem { + pub fn entity_ids(&self) -> Vec { + match self { + InventoryItem::Individual(individual_inventory_item) => { + vec![individual_inventory_item.entity_id] + }, + InventoryItem::Stacked(stacked_inventory_item) => { + stacked_inventory_item.entity_ids.clone() + } + } + } + pub fn item_id(&self) -> ClientItemId { match self { InventoryItem::Individual(individual_inventory_item) => { @@ -388,6 +399,24 @@ impl CharacterInventory { }) } + pub fn get_equipped_mag_handle<'a>(&'a mut self) -> Option> { + let (slot, _) = self.items.iter() + .enumerate() + .filter(|(_, item)| { + if let InventoryItem::Individual(individual_inventory_item) = item { + if let ItemDetail::Mag(_) = &individual_inventory_item.item { + return individual_inventory_item.equipped + } + } + false + }) + .nth(0)?; + Some(InventoryItemHandle { + inventory: self, + slot: slot, + }) + } + pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&InventoryItem> { self.items.iter() .filter(|item| { diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 9537bb4..025e85f 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -513,7 +513,7 @@ impl ItemManager { character: &CharacterEntity, item_id: ClientItemId, amount: usize) - -> Result { + -> Result { let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; let used_item = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; let consumed_item = used_item.consume(amount)?; @@ -523,7 +523,7 @@ impl ItemManager { ItemLocation::Consumed).await; } - Ok(consumed_item.item()) + Ok(consumed_item) } pub async fn player_deposits_item(&mut self, @@ -640,10 +640,11 @@ impl ItemManager { pub async fn use_item(&mut self, - used_item: ItemDetail, + used_item: ConsumedItem, entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ItemManagerError> { - match used_item { + let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + match &used_item.item() { ItemDetail::Weapon(_w) => { // something like when items are used to combine/transform them? //_ => {} @@ -671,6 +672,9 @@ impl ItemManager { ToolType::TpMaterial => { use_tool::tp_material(entity_gateway, character).await; }, + ToolType::CellOfMag502 => { + use_tool::cell_of_mag_502(entity_gateway, &used_item, inventory).await; + }, _ => {} } } diff --git a/src/ship/items/use_tool.rs b/src/ship/items/use_tool.rs index 30a016e..b2812af 100644 --- a/src/ship/items/use_tool.rs +++ b/src/ship/items/use_tool.rs @@ -1,8 +1,10 @@ use thiserror::Error; use crate::entity::gateway::EntityGateway; use crate::entity::character::CharacterEntity; -use crate::entity::item::ItemDetail; +use crate::entity::item::{ItemEntityId, ItemDetail}; use crate::entity::item::tool::ToolType; +use crate::entity::item::mag::MagCell; +use crate::ship::items::{ItemManager, ClientItemId, CharacterInventory, ConsumedItem}; @@ -12,6 +14,8 @@ use crate::entity::item::tool::ToolType; #[error("")] pub enum UseItemError { NoCharacter, + ItemNotEquipped, + InvalidItem, } @@ -54,3 +58,32 @@ pub async fn tp_material(entity_gateway: &mut EG, character: character.materials.tp += 1; entity_gateway.save_character(character).await; } + + + + + +async fn mag_cell(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), UseItemError> { + let mut mag_handle = inventory.get_equipped_mag_handle().ok_or(UseItemError::ItemNotEquipped)?; + let mag_item = mag_handle.item_mut() + .ok_or(UseItemError::InvalidItem)?; + let actual_mag = mag_item + .individual() + .ok_or(UseItemError::InvalidItem)? + .mag_mut() + .ok_or(UseItemError::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; + } + } + + Ok(()) +} + + +pub async fn cell_of_mag_502(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), UseItemError> { + println!("used a 502!"); + mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag502).await +}