mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Support for canceling an input. Boost state hooked up to system.
This commit is contained in:
parent
c6d8daaae3
commit
19c81f1528
@ -998,7 +998,7 @@ impl Client {
|
||||
target: None,
|
||||
});
|
||||
} else {
|
||||
self.control_action(ControlAction::CancelInput);
|
||||
self.control_action(ControlAction::CancelInput(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1156,8 +1156,10 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
||||
static_data: boost::StaticData {
|
||||
movement_duration: Duration::from_secs_f32(*movement_duration),
|
||||
only_up: *only_up,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
end: false,
|
||||
}),
|
||||
CharacterAbility::DashMelee {
|
||||
energy_cost: _,
|
||||
|
@ -18,6 +18,7 @@ pub struct StateUpdate {
|
||||
pub energy: Energy,
|
||||
pub swap_equipped_weapons: bool,
|
||||
pub queued_inputs: BTreeSet<InputKind>,
|
||||
pub removed_inputs: Vec<InputKind>,
|
||||
pub local_events: VecDeque<LocalEvent>,
|
||||
pub server_events: VecDeque<ServerEvent>,
|
||||
}
|
||||
@ -32,6 +33,7 @@ impl From<&JoinData<'_>> for StateUpdate {
|
||||
swap_equipped_weapons: false,
|
||||
character: data.character.clone(),
|
||||
queued_inputs: BTreeSet::new(),
|
||||
removed_inputs: Vec::new(),
|
||||
local_events: VecDeque::new(),
|
||||
server_events: VecDeque::new(),
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ pub enum ControlAction {
|
||||
ability: InputKind,
|
||||
target: Option<Uid>,
|
||||
},
|
||||
CancelInput,
|
||||
CancelInput(InputKind),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Ord, PartialOrd)]
|
||||
|
@ -34,7 +34,11 @@ pub trait CharacterBehavior {
|
||||
update.queued_inputs.insert(input);
|
||||
update
|
||||
}
|
||||
fn cancel_input(&self, data: &JoinData) -> StateUpdate { StateUpdate::from(data) }
|
||||
fn cancel_input(&self, data: &JoinData, input: InputKind) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
update.removed_inputs.push(input);
|
||||
update
|
||||
}
|
||||
fn handle_event(&self, data: &JoinData, event: ControlAction) -> StateUpdate {
|
||||
match event {
|
||||
ControlAction::SwapEquippedWeapons => self.swap_equipped_weapons(data),
|
||||
@ -50,7 +54,7 @@ pub trait CharacterBehavior {
|
||||
ControlAction::StartInput { ability, target } => {
|
||||
self.handle_input(data, ability, target)
|
||||
},
|
||||
ControlAction::CancelInput => self.cancel_input(data),
|
||||
ControlAction::CancelInput(input) => self.cancel_input(data, input),
|
||||
}
|
||||
}
|
||||
// fn init(data: &JoinData) -> CharacterState;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
comp::{CharacterState, StateUpdate},
|
||||
comp::{CharacterState, InputKind, StateUpdate},
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
utils::*,
|
||||
@ -13,6 +13,7 @@ use std::time::Duration;
|
||||
pub struct StaticData {
|
||||
pub movement_duration: Duration,
|
||||
pub only_up: bool,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -22,6 +23,8 @@ pub struct Data {
|
||||
pub static_data: StaticData,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// Whether or not the state should end
|
||||
pub end: bool,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
@ -46,9 +49,31 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
update.character = CharacterState::Wielding;
|
||||
if self.end || self.static_data.ability_info.input.is_none() {
|
||||
update.character = CharacterState::Wielding;
|
||||
} else {
|
||||
reset_state(self, &mut update);
|
||||
}
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
|
||||
fn cancel_input(&self, data: &JoinData, input: InputKind) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
update.removed_inputs.push(input);
|
||||
|
||||
if Some(input) == self.static_data.ability_info.input {
|
||||
update.character = CharacterState::Boost(Data { end: true, ..*self });
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_state(data: &Data, update: &mut StateUpdate) {
|
||||
update.character = CharacterState::Boost(Data {
|
||||
timer: Duration::default(),
|
||||
..*data
|
||||
})
|
||||
}
|
||||
|
@ -434,7 +434,12 @@ pub fn handle_jump(data: &JoinData, update: &mut StateUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_ability_pressed(data: &JoinData, update: &mut StateUpdate, ability_key: AbilityKey) {
|
||||
fn handle_ability_pressed(
|
||||
data: &JoinData,
|
||||
update: &mut StateUpdate,
|
||||
ability_key: AbilityKey,
|
||||
input: Option<InputKind>,
|
||||
) {
|
||||
let hands = |equip_slot| match data.inventory.equipped(equip_slot).map(|i| i.kind()) {
|
||||
Some(ItemKind::Tool(tool)) => Some(tool.hands),
|
||||
_ => None,
|
||||
@ -484,7 +489,12 @@ fn handle_ability_pressed(data: &JoinData, update: &mut StateUpdate, ability_key
|
||||
{
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, ability_key, matches!(equip_slot, EquipSlot::Offhand)),
|
||||
AbilityInfo::from_key(
|
||||
data,
|
||||
ability_key,
|
||||
matches!(equip_slot, EquipSlot::Offhand),
|
||||
input,
|
||||
),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -493,7 +503,7 @@ fn handle_ability_pressed(data: &JoinData, update: &mut StateUpdate, ability_key
|
||||
|
||||
pub fn handle_input(data: &JoinData, update: &mut StateUpdate, input: InputKind) {
|
||||
match input {
|
||||
InputKind::Primary => handle_ability_pressed(data, update, AbilityKey::Mouse1),
|
||||
InputKind::Primary => handle_ability_pressed(data, update, AbilityKey::Mouse1, Some(input)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,19 +515,19 @@ pub fn handle_input(data: &JoinData, update: &mut StateUpdate, input: InputKind)
|
||||
|
||||
pub fn handle_ability2_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.secondary.is_pressed() {
|
||||
handle_ability_pressed(data, update, AbilityKey::Mouse2);
|
||||
handle_ability_pressed(data, update, AbilityKey::Mouse2, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.ability3.is_pressed() {
|
||||
handle_ability_pressed(data, update, AbilityKey::Skill1);
|
||||
handle_ability_pressed(data, update, AbilityKey::Skill1, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ability4_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.ability4.is_pressed() {
|
||||
handle_ability_pressed(data, update, AbilityKey::Skill2);
|
||||
handle_ability_pressed(data, update, AbilityKey::Skill2, None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,7 +549,7 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if let CharacterState::ComboMelee(c) = data.character {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false, None),
|
||||
)
|
||||
.into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
@ -549,7 +559,7 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
} else if data.character.is_wield() {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false, None),
|
||||
)
|
||||
.into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
@ -558,7 +568,7 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
} else if data.character.is_stealthy() {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false, None),
|
||||
)
|
||||
.into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
@ -567,7 +577,7 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
} else {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false, None),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -687,10 +697,16 @@ pub struct AbilityInfo {
|
||||
pub tool: Option<ToolKind>,
|
||||
pub hand: Option<HandInfo>,
|
||||
pub key: AbilityKey,
|
||||
pub input: Option<InputKind>,
|
||||
}
|
||||
|
||||
impl AbilityInfo {
|
||||
pub fn from_key(data: &JoinData, key: AbilityKey, from_offhand: bool) -> Self {
|
||||
pub fn from_key(
|
||||
data: &JoinData,
|
||||
key: AbilityKey,
|
||||
from_offhand: bool,
|
||||
input: Option<InputKind>,
|
||||
) -> Self {
|
||||
let tool_data = if from_offhand {
|
||||
unwrap_tool_data(data, EquipSlot::Offhand)
|
||||
} else {
|
||||
@ -705,7 +721,12 @@ impl AbilityInfo {
|
||||
)
|
||||
};
|
||||
|
||||
Self { tool, hand, key }
|
||||
Self {
|
||||
tool,
|
||||
hand,
|
||||
key,
|
||||
input,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ use common::{
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use std::time::Duration;
|
||||
|
||||
fn incorporate_update(join: &mut JoinStruct, state_update: StateUpdate) {
|
||||
fn incorporate_update(join: &mut JoinStruct, mut state_update: StateUpdate) {
|
||||
// TODO: if checking equality is expensive use optional field in StateUpdate
|
||||
if join.char_state.get_unchecked() != &state_update.character {
|
||||
*join.char_state.get_mut_unchecked() = state_update.character
|
||||
@ -35,6 +35,12 @@ fn incorporate_update(join: &mut JoinStruct, state_update: StateUpdate) {
|
||||
if join.energy.get_unchecked() != &state_update.energy {
|
||||
*join.energy.get_mut_unchecked() = state_update.energy
|
||||
};
|
||||
join.controller
|
||||
.queued_inputs
|
||||
.append(&mut state_update.queued_inputs);
|
||||
for input in state_update.removed_inputs {
|
||||
join.controller.queued_inputs.remove(&input);
|
||||
}
|
||||
if state_update.swap_equipped_weapons {
|
||||
let mut inventory = join.inventory.get_mut_unchecked();
|
||||
let inventory = &mut *inventory;
|
||||
@ -350,10 +356,11 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
local_emitter.append(&mut state_update.local_events);
|
||||
server_emitter.append(&mut state_update.server_events);
|
||||
join_struct
|
||||
.controller
|
||||
.queued_inputs
|
||||
.append(&mut state_update.queued_inputs);
|
||||
// join_struct
|
||||
// .controller
|
||||
// .queued_inputs
|
||||
// .append(&mut state_update.queued_inputs);
|
||||
// join_struct.controller.queued_inputs.
|
||||
incorporate_update(&mut join_struct, state_update);
|
||||
}
|
||||
}
|
||||
|
@ -1638,7 +1638,9 @@ impl<'a> AgentData<'a> {
|
||||
Tactic::TailSlap => {
|
||||
if dist_sqrd < (1.5 * min_attack_dist * self.scale).powi(2) {
|
||||
if agent.action_timer > 4.0 {
|
||||
controller.actions.push(ControlAction::CancelInput);
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::CancelInput(InputKind::Primary));
|
||||
//controller.inputs.primary.set_state(false);
|
||||
agent.action_timer = 0.0;
|
||||
} else if agent.action_timer > 1.0 {
|
||||
|
Loading…
Reference in New Issue
Block a user