You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
13 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. use thiserror::Error;
  2. use std::convert::TryInto;
  3. use crate::entity::gateway::{EntityGateway, GatewayError};
  4. use crate::entity::character::CharacterEntity;
  5. use crate::entity::item::mag::{MagCell, MagCellError};
  6. use crate::entity::item::tool::ToolType;
  7. use crate::entity::item::{ItemDetail, ItemEntityId};
  8. use crate::ship::items::state::{ItemStateProxy, ItemStateError};
  9. use crate::ship::items::inventory::{InventoryItem, InventoryItemDetail};
  10. #[derive(Error, Debug)]
  11. pub enum ApplyItemError {
  12. #[error("no character")]
  13. NoCharacter,
  14. #[error("item not equipped")]
  15. ItemNotEquipped,
  16. #[error("invalid item")]
  17. InvalidItem,
  18. #[error("gateway error {0}")]
  19. GatewayError(#[from] GatewayError),
  20. #[error("itemstate error {0}")]
  21. ItemStateError(Box<ItemStateError>),
  22. #[error("magcell error {0}")]
  23. MagCellError(#[from] MagCellError),
  24. }
  25. impl From<ItemStateError> for ApplyItemError {
  26. fn from(other: ItemStateError) -> ApplyItemError {
  27. ApplyItemError::ItemStateError(Box::new(other))
  28. }
  29. }
  30. // TODO: make all these functions not-pub
  31. pub async fn power_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  32. character.materials.power += 1;
  33. entity_gateway.save_character(character).await?;
  34. Ok(())
  35. }
  36. pub async fn mind_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  37. character.materials.mind += 1;
  38. entity_gateway.save_character(character).await.unwrap();
  39. Ok(())
  40. }
  41. pub async fn evade_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  42. character.materials.evade += 1;
  43. entity_gateway.save_character(character).await.unwrap();
  44. Ok(())
  45. }
  46. pub async fn def_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  47. character.materials.def += 1;
  48. entity_gateway.save_character(character).await.unwrap();
  49. Ok(())
  50. }
  51. pub async fn luck_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  52. character.materials.luck += 1;
  53. entity_gateway.save_character(character).await.unwrap();
  54. Ok(())
  55. }
  56. pub async fn hp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  57. character.materials.hp += 1;
  58. entity_gateway.save_character(character).await.unwrap();
  59. Ok(())
  60. }
  61. pub async fn tp_material<EG: EntityGateway + ?Sized>(entity_gateway: &mut EG, character: &mut CharacterEntity) -> Result<(), ApplyItemError> {
  62. character.materials.tp += 1;
  63. entity_gateway.save_character(character).await.unwrap();
  64. Ok(())
  65. }
  66. /*
  67. async fn mag_cell<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory, mag_cell_type: MagCell) -> Result<(), ApplyItemError> {
  68. let mut mag_handle = inventory.get_equipped_mag_handle().ok_or(ApplyItemError::ItemNotEquipped)?;
  69. let mag_item = mag_handle.item_mut()
  70. .ok_or(ApplyItemError::InvalidItem)?;
  71. let actual_mag = mag_item
  72. .individual_mut()
  73. .ok_or(ApplyItemError::InvalidItem)?
  74. .mag_mut()
  75. .ok_or(ApplyItemError::InvalidItem)?;
  76. actual_mag.apply_mag_cell(mag_cell_type);
  77. for mag_entity_id in mag_item.entity_ids() {
  78. for cell_entity_id in used_cell.entity_ids() {
  79. entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await.unwrap();
  80. }
  81. }
  82. Ok(())
  83. }
  84. */
  85. async fn mag_cell<'a, EG>(item_state: &mut ItemStateProxy<'a>,
  86. entity_gateway: &mut EG,
  87. character: &CharacterEntity,
  88. cell_entity_id: ItemEntityId,
  89. mag_cell_type: MagCell)
  90. -> Result<(), ApplyItemError>
  91. where
  92. EG: EntityGateway + ?Sized,
  93. {
  94. let mut inventory = item_state.inventory(&character.id)?;
  95. let (mag_entity_id, mag) = inventory.equipped_mag_mut()
  96. .ok_or(ApplyItemError::ItemNotEquipped)?;
  97. mag.apply_mag_cell(mag_cell_type)?;
  98. entity_gateway.use_mag_cell(&mag_entity_id, &cell_entity_id).await?;
  99. entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
  100. item_state.set_inventory(inventory);
  101. Ok(())
  102. }
  103. /*
  104. pub async fn cell_of_mag_502<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  105. mag_cell(entity_gateway, inventory, MagCell::CellOfMag502).await
  106. }
  107. pub async fn cell_of_mag_213<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  108. mag_cell(entity_gateway, used_cell, inventory, MagCell::CellOfMag213).await
  109. }
  110. pub async fn parts_of_robochao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  111. mag_cell(entity_gateway, used_cell, inventory, MagCell::PartsOfRobochao).await
  112. }
  113. pub async fn heart_of_opaopa<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  114. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfOpaOpa).await
  115. }
  116. pub async fn heart_of_pian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  117. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfPian).await
  118. }
  119. pub async fn heart_of_chao<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  120. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfChao).await
  121. }
  122. pub async fn heart_of_angel<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  123. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfAngel).await
  124. }
  125. pub async fn kit_of_hamburger<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  126. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfHamburger).await
  127. }
  128. pub async fn panthers_spirit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  129. mag_cell(entity_gateway, used_cell, inventory, MagCell::PanthersSpirit).await
  130. }
  131. pub async fn kit_of_mark3<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  132. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMark3).await
  133. }
  134. pub async fn kit_of_master_system<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  135. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfMasterSystem).await
  136. }
  137. pub async fn kit_of_genesis<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  138. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfGenesis).await
  139. }
  140. pub async fn kit_of_sega_saturn<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  141. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfSegaSaturn).await
  142. }
  143. pub async fn kit_of_dreamcast<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  144. mag_cell(entity_gateway, used_cell, inventory, MagCell::KitOfDreamcast).await
  145. }
  146. pub async fn tablet<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  147. mag_cell(entity_gateway, used_cell, inventory, MagCell::Tablet).await
  148. }
  149. pub async fn dragon_scale<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  150. mag_cell(entity_gateway, used_cell, inventory, MagCell::DragonScale).await
  151. }
  152. pub async fn heaven_striker_coat<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  153. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeavenStrikerCoat).await
  154. }
  155. pub async fn pioneer_parts<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  156. mag_cell(entity_gateway, used_cell, inventory, MagCell::PioneerParts).await
  157. }
  158. pub async fn amities_memo<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  159. mag_cell(entity_gateway, used_cell, inventory, MagCell::AmitiesMemo).await
  160. }
  161. pub async fn heart_of_morolian<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  162. mag_cell(entity_gateway, used_cell, inventory, MagCell::HeartOfMorolian).await
  163. }
  164. pub async fn rappys_beak<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  165. mag_cell(entity_gateway, used_cell, inventory, MagCell::RappysBeak).await
  166. }
  167. pub async fn yahoos_engine<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  168. mag_cell(entity_gateway, used_cell, inventory, MagCell::YahoosEngine).await
  169. }
  170. pub async fn d_photon_core<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  171. mag_cell(entity_gateway, used_cell, inventory, MagCell::DPhotonCore).await
  172. }
  173. pub async fn liberta_kit<EG: EntityGateway>(entity_gateway: &mut EG, used_cell: &ConsumedItem, inventory: &mut CharacterInventory) -> Result<(), ApplyItemError> {
  174. mag_cell(entity_gateway, used_cell, inventory, MagCell::LibertaKit).await
  175. }
  176. */
  177. async fn apply_tool<'a, EG>(item_state: &mut ItemStateProxy<'a>,
  178. entity_gateway: &mut EG,
  179. character: &mut CharacterEntity,
  180. entity_id: ItemEntityId,
  181. tool: ToolType)
  182. -> Result<(), ApplyItemError>
  183. where
  184. EG: EntityGateway + ?Sized,
  185. {
  186. match tool {
  187. ToolType::PowerMaterial => power_material(entity_gateway, character).await,
  188. ToolType::MindMaterial => mind_material(entity_gateway, character).await,
  189. ToolType::EvadeMaterial => evade_material(entity_gateway, character).await,
  190. ToolType::DefMaterial => def_material(entity_gateway, character).await,
  191. ToolType::LuckMaterial => luck_material(entity_gateway, character).await,
  192. ToolType::HpMaterial => hp_material(entity_gateway, character).await,
  193. ToolType::TpMaterial => tp_material(entity_gateway, character).await,
  194. ToolType::Monomate => Ok(()),
  195. ToolType::Dimate => Ok(()),
  196. ToolType::Trimate => Ok(()),
  197. ToolType::Monofluid => Ok(()),
  198. ToolType::Difluid => Ok(()),
  199. ToolType::Trifluid => Ok(()),
  200. ToolType::HuntersReport => Ok(()),
  201. ToolType::CellOfMag502
  202. | ToolType::CellOfMag213
  203. | ToolType::PartsOfRobochao
  204. | ToolType::HeartOfOpaOpa
  205. | ToolType::HeartOfPian
  206. | ToolType::HeartOfChao
  207. | ToolType::HeartOfAngel
  208. | ToolType::KitOfHamburger
  209. | ToolType::PanthersSpirit
  210. | ToolType::KitOfMark3
  211. | ToolType::KitOfMasterSystem
  212. | ToolType::KitOfGenesis
  213. | ToolType::KitOfSegaSaturn
  214. | ToolType::KitOfDreamcast
  215. | ToolType::Tablet
  216. | ToolType::DragonScale
  217. | ToolType::HeavenStrikerCoat
  218. | ToolType::PioneerParts
  219. | ToolType::AmitiesMemo
  220. | ToolType::HeartOfMorolian
  221. | ToolType::RappysBeak
  222. | ToolType::YahoosEngine
  223. | ToolType::DPhotonCore
  224. | ToolType::LibertaKit => {
  225. mag_cell(item_state, entity_gateway, character, entity_id, tool.try_into()?).await
  226. }
  227. // TODO: rest of these
  228. _ => Err(ApplyItemError::InvalidItem)
  229. }
  230. }
  231. 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> {
  232. match item.item {
  233. InventoryItemDetail::Individual(individual_item) => {
  234. match individual_item.item {
  235. ItemDetail::Tool(tool) => apply_tool(item_state, entity_gateway, character, individual_item.entity_id, tool.tool).await,
  236. _ => Err(ApplyItemError::InvalidItem)
  237. }
  238. },
  239. InventoryItemDetail::Stacked(stacked_item) => {
  240. for entity_id in stacked_item.entity_ids {
  241. apply_tool(item_state, entity_gateway, character, entity_id, stacked_item.tool.tool).await?
  242. }
  243. Ok(())
  244. },
  245. }
  246. }