mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added AbilityInfo struct to attack states
This commit is contained in:
parent
50cbe42b07
commit
18309fe4c6
@ -6,7 +6,7 @@ use crate::{
|
||||
},
|
||||
states::{
|
||||
behavior::JoinData,
|
||||
utils::{AbilityKey, StageSection},
|
||||
utils::{AbilityInfo, StageSection},
|
||||
*,
|
||||
},
|
||||
Knockback,
|
||||
@ -1060,8 +1060,8 @@ impl CharacterAbility {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
fn from((ability, key): (&CharacterAbility, AbilityKey)) -> Self {
|
||||
impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
||||
fn from((ability, ability_info): (&CharacterAbility, AbilityInfo)) -> Self {
|
||||
match ability {
|
||||
CharacterAbility::BasicMelee {
|
||||
buildup_duration,
|
||||
@ -1083,7 +1083,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
knockback: *knockback,
|
||||
range: *range,
|
||||
max_angle: *max_angle,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1109,7 +1109,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
projectile_gravity: *projectile_gravity,
|
||||
projectile_speed: *projectile_speed,
|
||||
can_continue: *can_continue,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1162,7 +1162,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
swing_duration: Duration::from_secs_f32(*swing_duration),
|
||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||
is_interruptible: *is_interruptible,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
auto_charge: false,
|
||||
timer: Duration::default(),
|
||||
@ -1212,7 +1212,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
max_speed_increase: *max_speed_increase,
|
||||
scales_from_combo: *scales_from_combo,
|
||||
is_interruptible: *is_interruptible,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
stage: 1,
|
||||
combo: 0,
|
||||
@ -1246,7 +1246,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
max_angle: *max_angle,
|
||||
forward_leap_strength: *forward_leap_strength,
|
||||
vertical_leap_strength: *vertical_leap_strength,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1281,7 +1281,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
is_interruptible: *is_interruptible,
|
||||
forward_speed: *forward_speed,
|
||||
num_spins: *num_spins,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
spins_remaining: *num_spins - 1,
|
||||
@ -1321,7 +1321,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
swing_duration: Duration::from_secs_f32(*swing_duration),
|
||||
hit_timing: *hit_timing,
|
||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
stage_section: StageSection::Charge,
|
||||
timer: Duration::default(),
|
||||
@ -1362,7 +1362,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
initial_projectile_speed: *initial_projectile_speed,
|
||||
scaled_projectile_speed: *scaled_projectile_speed,
|
||||
move_speed: *move_speed,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1393,7 +1393,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
projectile_light: *projectile_light,
|
||||
projectile_gravity: *projectile_gravity,
|
||||
projectile_speed: *projectile_speed,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Movement,
|
||||
@ -1427,7 +1427,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
shockwave_duration: Duration::from_secs_f32(*shockwave_duration),
|
||||
requires_ground: *requires_ground,
|
||||
move_efficiency: *move_efficiency,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
@ -1459,7 +1459,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
||||
energy_regen: *energy_regen,
|
||||
energy_cost: *energy_cost,
|
||||
energy_drain: *energy_drain,
|
||||
ability_key: key,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
|
@ -44,7 +44,7 @@ pub struct StaticData {
|
||||
/// Energy drained per
|
||||
pub energy_drain: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -68,7 +68,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 0.4);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::BasicBeam(_) => {},
|
||||
@ -78,11 +78,6 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
}
|
||||
|
||||
if unwrap_tool_data(data).is_none() {
|
||||
update.character = CharacterState::Idle;
|
||||
return update;
|
||||
}
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Buildup => {
|
||||
if self.timer < self.static_data.buildup_duration {
|
||||
@ -119,7 +114,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
},
|
||||
StageSection::Cast => {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
if ability_key_is_pressed(data, self.static_data.ability_info.key)
|
||||
&& (self.static_data.energy_drain <= f32::EPSILON
|
||||
|| update.energy.current() > 0)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ pub struct StaticData {
|
||||
/// Max angle (45.0 will give you a 90.0 angle window)
|
||||
pub max_angle: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -52,7 +52,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::BasicMelee(_) => {},
|
||||
|
@ -23,7 +23,7 @@ pub struct StaticData {
|
||||
pub projectile_gravity: Option<Gravity>,
|
||||
pub projectile_speed: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
/// Whether or not the ability can auto continue
|
||||
pub can_continue: bool,
|
||||
}
|
||||
@ -50,7 +50,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 0.3);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::BasicRanged(_) => {},
|
||||
@ -103,7 +103,7 @@ impl CharacterBehavior for Data {
|
||||
..*self
|
||||
});
|
||||
} else if self.timer < self.static_data.recover_duration {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
// Recovers
|
||||
update.character = CharacterState::BasicRanged(Data {
|
||||
timer: self
|
||||
|
@ -44,7 +44,7 @@ pub struct StaticData {
|
||||
/// How long the state has until exiting
|
||||
pub recover_duration: Duration,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -68,7 +68,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::ChargedMelee(_) => {},
|
||||
@ -80,7 +80,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Charge => {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
if ability_key_is_pressed(data, self.static_data.ability_info.key)
|
||||
&& update.energy.current() as f32 >= self.static_data.energy_cost
|
||||
&& self.timer < self.static_data.charge_duration
|
||||
{
|
||||
@ -107,7 +107,7 @@ impl CharacterBehavior for Data {
|
||||
* self.static_data.speed) as i32,
|
||||
source: EnergySource::Ability,
|
||||
});
|
||||
} else if ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
} else if ability_key_is_pressed(data, self.static_data.ability_info.key)
|
||||
&& update.energy.current() as f32 >= self.static_data.energy_cost
|
||||
{
|
||||
// Maintains charge
|
||||
|
@ -46,7 +46,7 @@ pub struct StaticData {
|
||||
/// Move speed efficiency
|
||||
pub move_speed: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -68,7 +68,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, self.static_data.move_speed);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::ChargedRanged(_) => {},
|
||||
@ -99,7 +99,7 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
},
|
||||
StageSection::Charge => {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) && !self.exhausted {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) && !self.exhausted {
|
||||
let charge_frac = (self.timer.as_secs_f32()
|
||||
/ self.static_data.charge_duration.as_secs_f32())
|
||||
.min(1.0);
|
||||
@ -156,7 +156,7 @@ impl CharacterBehavior for Data {
|
||||
..*self
|
||||
});
|
||||
} else if self.timer < self.static_data.charge_duration
|
||||
&& ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
&& ability_key_is_pressed(data, self.static_data.ability_info.key)
|
||||
{
|
||||
// Charges
|
||||
update.character = CharacterState::ChargedRanged(Data {
|
||||
@ -176,7 +176,7 @@ impl CharacterBehavior for Data {
|
||||
* self.static_data.speed) as i32,
|
||||
source: EnergySource::Ability,
|
||||
});
|
||||
} else if ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
} else if ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
// Holds charge
|
||||
update.character = CharacterState::ChargedRanged(Data {
|
||||
timer: self
|
||||
|
@ -98,7 +98,7 @@ pub struct StaticData {
|
||||
/// Whether the state can be interrupted by other abilities
|
||||
pub is_interruptible: bool,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
/// A sequence of attacks that can incrementally become faster and more
|
||||
/// damaging.
|
||||
@ -125,7 +125,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_orientation(data, &mut update, 1.0);
|
||||
handle_move(data, &mut update, 0.3);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
roll.was_combo = Some((self.stage, self.combo));
|
||||
@ -259,7 +259,7 @@ impl CharacterBehavior for Data {
|
||||
StageSection::Recover => {
|
||||
if self.timer < self.static_data.stage_data[stage_index].base_recover_duration {
|
||||
// Recovers
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
// Checks if state will transition to next stage after recover
|
||||
update.character = CharacterState::ComboMelee(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
|
@ -47,7 +47,7 @@ pub struct StaticData {
|
||||
/// Whether the state can be interrupted by other abilities
|
||||
pub is_interruptible: bool,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -73,7 +73,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_orientation(data, &mut update, 1.0);
|
||||
handle_move(data, &mut update, 0.1);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
match update.character {
|
||||
CharacterState::DashMelee(_) => {},
|
||||
@ -97,7 +97,7 @@ impl CharacterBehavior for Data {
|
||||
} else {
|
||||
// Transitions to charge section of stage
|
||||
update.character = CharacterState::DashMelee(Data {
|
||||
auto_charge: !ability_key_is_pressed(data, self.static_data.ability_key),
|
||||
auto_charge: !ability_key_is_pressed(data, self.static_data.ability_info.key),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Charge,
|
||||
..*self
|
||||
@ -107,7 +107,7 @@ impl CharacterBehavior for Data {
|
||||
StageSection::Charge => {
|
||||
if (self.static_data.infinite_charge
|
||||
|| self.timer < self.static_data.charge_duration)
|
||||
&& (ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
&& (ability_key_is_pressed(data, self.static_data.ability_info.key)
|
||||
|| (self.auto_charge && self.timer < self.static_data.charge_duration))
|
||||
&& update.energy.current() > 0
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ pub struct StaticData {
|
||||
/// Affects how high the player leaps
|
||||
pub vertical_leap_strength: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -58,7 +58,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 0.3);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::LeapMelee(_) => {},
|
||||
|
@ -31,7 +31,7 @@ pub struct StaticData {
|
||||
pub projectile_gravity: Option<Gravity>,
|
||||
pub projectile_speed: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -53,7 +53,7 @@ impl CharacterBehavior for Data {
|
||||
|
||||
handle_move(data, &mut update, 1.0);
|
||||
handle_jump(data, &mut update);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::RepeaterRanged(_) => {},
|
||||
|
@ -41,7 +41,7 @@ pub struct StaticData {
|
||||
/// Movement speed efficiency
|
||||
pub move_efficiency: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -60,7 +60,7 @@ impl CharacterBehavior for Data {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_move(data, &mut update, self.static_data.move_efficiency);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, false);
|
||||
match update.character {
|
||||
CharacterState::Shockwave(_) => {},
|
||||
|
@ -42,7 +42,7 @@ pub struct StaticData {
|
||||
/// Number of spins
|
||||
pub num_spins: u32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -75,7 +75,7 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
}
|
||||
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
match update.character {
|
||||
CharacterState::SpinMelee(_) => {},
|
||||
@ -176,7 +176,7 @@ impl CharacterBehavior for Data {
|
||||
} else if update.energy.current() as f32 >= self.static_data.energy_cost
|
||||
&& (self.spins_remaining != 0
|
||||
|| (self.static_data.is_infinite
|
||||
&& ability_key_is_pressed(data, self.static_data.ability_key)))
|
||||
&& ability_key_is_pressed(data, self.static_data.ability_info.key)))
|
||||
{
|
||||
let new_spins_remaining = if self.static_data.is_infinite {
|
||||
self.spins_remaining
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{Hands, ItemKind, Tool},
|
||||
item::{Hands, ItemKind, Tool, ToolKind},
|
||||
quadruped_low, quadruped_medium, theropod, Body, CharacterState, LoadoutManip, StateUpdate,
|
||||
},
|
||||
consts::{FRIC_GROUND, GRAVITY},
|
||||
@ -407,12 +407,12 @@ pub fn handle_ability1_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
.equipped(EquipSlot::Mainhand)
|
||||
.map(|i| &i.item_config_expect().abilities.primary)
|
||||
.map(|a| {
|
||||
let tool = unwrap_tool_data(data).map(|t| t.kind);
|
||||
let tool = unwrap_tool_data(data, EquipSlot::Mainhand).map(|t| t.kind);
|
||||
a.clone().adjusted_by_skills(&data.stats.skill_set, tool)
|
||||
})
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = (&ability, AbilityKey::Mouse1).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Mouse1, false)).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -450,12 +450,12 @@ pub fn handle_ability2_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
.equipped(equip_slot)
|
||||
.map(|i| &i.item_config_expect().abilities.secondary)
|
||||
.map(|a| {
|
||||
let tool = unwrap_tool_data(data).map(|t| t.kind);
|
||||
let tool = unwrap_tool_data(data, equip_slot).map(|t| t.kind);
|
||||
a.clone().adjusted_by_skills(&data.stats.skill_set, tool)
|
||||
})
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = (&ability, AbilityKey::Mouse2).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Mouse2, matches!(equip_slot, EquipSlot::Offhand))).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -472,12 +472,12 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
.then_some(a)
|
||||
})
|
||||
.map(|a| {
|
||||
let tool = unwrap_tool_data(data).map(|t| t.kind);
|
||||
let tool = unwrap_tool_data(data, EquipSlot::Mainhand).map(|t| t.kind);
|
||||
a.clone().adjusted_by_skills(&data.stats.skill_set, tool)
|
||||
})
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = (&ability, AbilityKey::Skill1).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Skill1, false)).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -519,12 +519,12 @@ pub fn handle_ability4_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
.then_some(a)
|
||||
})
|
||||
.map(|a| {
|
||||
let tool = unwrap_tool_data(data).map(|t| t.kind);
|
||||
let tool = unwrap_tool_data(data, equip_slot).map(|t| t.kind);
|
||||
a.clone().adjusted_by_skills(&data.stats.skill_set, tool)
|
||||
})
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = (&ability, AbilityKey::Skill1).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Skill2, matches!(equip_slot, EquipSlot::Offhand))).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -546,26 +546,26 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
if data.character.is_wield() {
|
||||
update.character = (&ability, AbilityKey::Dodge).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Dodge, false)).into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
roll.was_wielded = true;
|
||||
}
|
||||
} else if data.character.is_stealthy() {
|
||||
update.character = (&ability, AbilityKey::Dodge).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Dodge, false)).into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
roll.was_sneak = true;
|
||||
}
|
||||
} else {
|
||||
update.character = (&ability, AbilityKey::Dodge).into();
|
||||
update.character = (&ability, AbilityInfo::from_key(data, AbilityKey::Dodge, false)).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_tool_data<'a>(data: &'a JoinData) -> Option<&'a Tool> {
|
||||
pub fn unwrap_tool_data<'a>(data: &'a JoinData, equip_slot: EquipSlot) -> Option<&'a Tool> {
|
||||
if let Some(ItemKind::Tool(tool)) = data
|
||||
.inventory
|
||||
.equipped(EquipSlot::Mainhand)
|
||||
.equipped(equip_slot)
|
||||
.map(|i| i.kind())
|
||||
{
|
||||
Some(&tool)
|
||||
@ -658,3 +658,47 @@ impl MovementDirection {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct AbilityInfo {
|
||||
pub tool: Option<ToolKind>,
|
||||
pub hand: Option<HandInfo>,
|
||||
pub key: AbilityKey,
|
||||
}
|
||||
|
||||
impl AbilityInfo {
|
||||
pub fn from_key(data: &JoinData, key: AbilityKey, from_offhand: bool) -> Self {
|
||||
let tool_data = if from_offhand {
|
||||
unwrap_tool_data(data, EquipSlot::Offhand)
|
||||
} else {
|
||||
unwrap_tool_data(data, EquipSlot::Mainhand)
|
||||
};
|
||||
let (tool, hand) = if from_offhand {
|
||||
(tool_data.map(|t| t.kind), Some(HandInfo::OffHand))
|
||||
} else {
|
||||
(tool_data.map(|t| t.kind), tool_data.map(|t| HandInfo::from_main_tool(t)))
|
||||
};
|
||||
|
||||
Self {
|
||||
tool,
|
||||
hand,
|
||||
key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum HandInfo {
|
||||
TwoHanded,
|
||||
MainHand,
|
||||
OffHand,
|
||||
}
|
||||
|
||||
impl HandInfo {
|
||||
pub fn from_main_tool(tool: &Tool) -> Self {
|
||||
match tool.hands {
|
||||
Hands::TwoHand => Self::TwoHanded,
|
||||
Hands::OneHand => Self::MainHand,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user