You can now leave a stance by using the corresponding ability input

This commit is contained in:
Sam 2022-09-10 22:47:16 -04:00
parent a2242b28f4
commit 5974646a3c
4 changed files with 44 additions and 13 deletions

View File

@ -765,6 +765,15 @@ impl CharacterState {
}),
}
}
// Determines if a character state should be returned to when using another
// ability from that character state
pub fn should_be_returned_to(&self) -> bool {
match self {
CharacterState::ComboMelee2(data) => data.static_data.is_stance,
_ => false,
}
}
}
#[derive(Default, Copy, Clone)]

View File

@ -56,6 +56,8 @@ pub trait CharacterBehavior {
fn talk(&self, data: &JoinData, _output_events: &mut OutputEvents) -> StateUpdate {
StateUpdate::from(data)
}
// start_input has custom implementation in the following character states that may also need to be modified when changes are made here:
// ComboMelee2
fn start_input(
&self,
data: &JoinData,

View File

@ -1,15 +1,17 @@
use crate::{
comp::{
character_state::OutputEvents, tool::Stats, CharacterState, InputKind, Melee,
MeleeConstructor, StateUpdate,
MeleeConstructor, StateUpdate, InputAttr
},
states::{
behavior::{CharacterBehavior, JoinData},
utils::*,
},
uid::Uid,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use vek::*;
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
@ -243,6 +245,26 @@ impl CharacterBehavior for Data {
update
}
fn start_input(
&self,
data: &JoinData,
input: InputKind,
target_entity: Option<Uid>,
select_pos: Option<Vec3<f32>>,
) -> StateUpdate {
let mut update = StateUpdate::from(data);
if matches!(data.character, CharacterState::ComboMelee2(data) if data.static_data.ability_info.input == input && input != InputKind::Primary) {
end_ability(data, &mut update);
} else {
update.queued_inputs.insert(input, InputAttr {
select_pos,
target_entity,
});
}
update
}
}
impl Data {

View File

@ -1203,6 +1203,10 @@ pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool {
data.controller.queued_inputs.contains_key(&input)
}
pub fn input_just_pressed(update: &StateUpdate, input: InputKind) -> bool {
update.queued_inputs.contains_key(&input)
}
/// Checked `Duration` addition. Computes `timer` + `dt`, applying relevant stat
/// attack modifiers and `other_modifiers`, returning None if overflow occurred.
pub fn checked_tick_attack(
@ -1307,19 +1311,12 @@ impl AbilityInfo {
.zip(data.active_abilities)
.map(|(i, a)| a.get_ability(i, data.inventory, Some(data.skill_set)));
let return_ability = {
let should_return = match data.character {
CharacterState::ComboMelee2(data) => data.static_data.is_stance,
_ => false,
};
if should_return {
data.character.ability_info().map(|info| info.input)
} else {
None
}
let return_ability = if data.character.should_be_returned_to() {
data.character.ability_info().map(|info| info.input)
} else {
None
};
Self {
tool,
hand,
@ -1333,7 +1330,8 @@ impl AbilityInfo {
}
pub fn end_ability(data: &JoinData<'_>, update: &mut StateUpdate) {
if let Some(return_ability) = data.character.ability_info().and_then(|info| info.return_ability) {
// If an ability has a return ability specified, and is not itself an ability that should be returned to (to prevent bouncing between two abilities), return to the specified ability, otherwise return to wield or idle depending on whether or not leaving a wield state
if let Some(return_ability) = (!data.character.should_be_returned_to()).then_some(data.character.ability_info().and_then(|info| info.return_ability)).flatten() {
handle_ability(data, update, return_ability);
} else if data.character.is_wield() || data.character.was_wielded() {
update.character =