From 3559ce580372635f7d8fa67cb664f226e7392bb8 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 24 Jun 2021 20:38:11 -0500 Subject: [PATCH] Added UseItem character state. --- common/src/comp/character_state.rs | 2 + common/src/states/mod.rs | 1 + common/src/states/use_item.rs | 123 +++++++++++++++++++++++ common/src/states/utils.rs | 9 +- common/systems/src/character_behavior.rs | 2 + common/systems/src/stats.rs | 3 +- 6 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 common/src/states/use_item.rs diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 87102015bb..1b8c1fd2d7 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -105,6 +105,8 @@ pub enum CharacterState { SelfBuff(self_buff::Data), /// Creates sprites around the caster SpriteSummon(sprite_summon::Data), + /// Handles logic for using an item so it is not simply instant + UseItem(use_item::Data), } impl CharacterState { diff --git a/common/src/states/mod.rs b/common/src/states/mod.rs index 0e63dd48d4..bc1777bfe8 100644 --- a/common/src/states/mod.rs +++ b/common/src/states/mod.rs @@ -29,5 +29,6 @@ pub mod spin_melee; pub mod sprite_summon; pub mod stunned; pub mod talk; +pub mod use_item; pub mod utils; pub mod wielding; diff --git a/common/src/states/use_item.rs b/common/src/states/use_item.rs new file mode 100644 index 0000000000..951f69a5d2 --- /dev/null +++ b/common/src/states/use_item.rs @@ -0,0 +1,123 @@ +use super::utils::*; +use crate::{ + comp::{ + inventory::{ + item::{ConsumableKind, ItemKind}, + slot::Slot, + }, + CharacterState, StateUpdate, + }, + states::behavior::{CharacterBehavior, JoinData}, +}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; + +/// Separated out to condense update portions of character state +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct StaticData { + /// Buildup to item use + pub buildup_duration: Duration, + /// Duration of item use + pub use_duration: Duration, + /// Recovery after item use + pub recover_duration: Duration, + /// Inventory slot to use item from + pub inv_slot: Slot, + /// Kind of item used + pub item_kind: ItemUseKind, +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Data { + /// Struct containing data that does not change over the course of the + /// character state + pub static_data: StaticData, + /// Timer for each stage + pub timer: Duration, + /// What section the character stage is in + pub stage_section: StageSection, + /// Had weapon + pub was_wielded: bool, + /// Was sneaking + pub was_sneak: bool, +} + +impl CharacterBehavior for Data { + fn behavior(&self, data: &JoinData) -> StateUpdate { + let mut update = StateUpdate::from(data); + + match self.stage_section { + StageSection::Buildup => { + if self.timer < self.static_data.buildup_duration { + // Build up + update.character = CharacterState::UseItem(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else { + // Transitions to use section of stage + update.character = CharacterState::UseItem(Data { + timer: Duration::default(), + stage_section: StageSection::Use, + ..*self + }); + } + }, + StageSection::Use => { + if self.timer < self.static_data.use_duration { + // Item use + update.character = CharacterState::UseItem(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else { + // Transitions to recover section of stage + update.character = CharacterState::UseItem(Data { + timer: Duration::default(), + stage_section: StageSection::Recover, + ..*self + }); + } + }, + StageSection::Recover => { + if self.timer < self.static_data.recover_duration { + // Recovery + update.character = CharacterState::UseItem(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else { + // Done + if self.was_wielded { + update.character = CharacterState::Wielding; + } else if self.was_sneak { + update.character = CharacterState::Sneak; + } else { + update.character = CharacterState::Idle; + } + } + }, + _ => { + // If it somehow ends up in an incorrect stage section + update.character = CharacterState::Idle; + }, + } + + update + } +} + +/// Used to control effects based off of the type of item used +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum ItemUseKind { + Consumable(ConsumableKind), +} + +impl From<&ItemKind> for Option { + fn from(item_kind: &ItemKind) -> Self { + match item_kind { + ItemKind::Consumable { kind, .. } => Some(ItemUseKind::Consumable(*kind)), + _ => None, + } + } +} diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index d18830cf56..dadb6b4c8d 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -836,12 +836,15 @@ pub fn tick_attack_or_default( #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum StageSection { Buildup, - Swing, Recover, Charge, - Cast, - Shoot, Movement, + // TODO: Consolidate these to `Action` + // Code reviewers: comment here to remind me to open beginner issue + Swing, + Shoot, + Cast, + Use, } #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index 1782ef693f..b54bf021e7 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -332,6 +332,7 @@ impl<'a> System<'a> for Sys { CharacterState::BasicSummon(data) => data.handle_event(&j, action), CharacterState::SelfBuff(data) => data.handle_event(&j, action), CharacterState::SpriteSummon(data) => data.handle_event(&j, action), + CharacterState::UseItem(data) => data.handle_event(&j, action), }; local_emitter.append(&mut state_update.local_events); server_emitter.append(&mut state_update.server_events); @@ -388,6 +389,7 @@ impl<'a> System<'a> for Sys { CharacterState::BasicSummon(data) => data.behavior(&j), CharacterState::SelfBuff(data) => data.behavior(&j), CharacterState::SpriteSummon(data) => data.behavior(&j), + CharacterState::UseItem(data) => data.behavior(&j), }; local_emitter.append(&mut state_update.local_events); diff --git a/common/systems/src/stats.rs b/common/systems/src/stats.rs index 50a7578e8c..f047902707 100644 --- a/common/systems/src/stats.rs +++ b/common/systems/src/stats.rs @@ -289,7 +289,8 @@ impl<'a> System<'a> for Sys { CharacterState::Roll { .. } | CharacterState::Climb { .. } | CharacterState::Stunned { .. } - | CharacterState::BasicBlock { .. } => {}, + | CharacterState::BasicBlock { .. } + | CharacterState::UseItem { .. } => {}, } }