mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Cleaving stance AI
This commit is contained in:
parent
5358016ba0
commit
df9ef691fd
@ -13,7 +13,7 @@ LeapMelee(
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
forward_leap_strength: 20.0,
|
||||
vertical_leap_strength: 8.0,
|
||||
|
@ -11,7 +11,7 @@ SpinMelee(
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_cost: 10.0,
|
||||
is_infinite: true,
|
||||
|
@ -13,7 +13,7 @@ LeapMelee(
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 180.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
forward_leap_strength: 40.0,
|
||||
vertical_leap_strength: 7.5,
|
||||
|
@ -12,7 +12,7 @@ BasicMelee(
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 45.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ BasicMelee(
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 60.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -10,7 +10,7 @@ SpinMelee(
|
||||
),
|
||||
range: 16.0,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_cost: 0.0,
|
||||
is_infinite: true,
|
||||
|
@ -21,7 +21,7 @@ DashMelee(
|
||||
strength: DamageFraction(0.3),
|
||||
chance: 0.25,
|
||||
))),
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_drain: 0,
|
||||
forward_speed: 5.0,
|
||||
|
@ -16,7 +16,7 @@ ChargedMelee(
|
||||
)),
|
||||
range: 5.0,
|
||||
angle: 45.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
charge_duration: 4.5,
|
||||
swing_duration: 0.1,
|
||||
|
@ -18,7 +18,7 @@ BasicMelee(
|
||||
strength: Value(0.5),
|
||||
chance: 1.0,
|
||||
))),
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -16,7 +16,7 @@ ChargedMelee(
|
||||
)),
|
||||
range: 6.0,
|
||||
angle: 90.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
charge_duration: 3.2,
|
||||
swing_duration: 0.7,
|
||||
|
@ -13,7 +13,7 @@ LeapMelee(
|
||||
),
|
||||
range: 6.75,
|
||||
angle: 180.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
forward_leap_strength: 45.0,
|
||||
vertical_leap_strength: 10.0,
|
||||
|
@ -13,7 +13,7 @@ LeapMelee(
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 180.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
forward_leap_strength: 20.0,
|
||||
vertical_leap_strength: 5.0,
|
||||
|
@ -11,7 +11,7 @@ SpinMelee(
|
||||
),
|
||||
range: 7.5,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_cost: 0,
|
||||
is_infinite: false,
|
||||
|
@ -12,7 +12,7 @@ BasicMelee(
|
||||
),
|
||||
range: 5.0,
|
||||
angle: 60.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -15,7 +15,7 @@ DashMelee(
|
||||
)),
|
||||
range: 5.0,
|
||||
angle: 90.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_drain: 0,
|
||||
forward_speed: 10.0,
|
||||
|
@ -11,7 +11,7 @@ SpinMelee(
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
energy_cost: 0,
|
||||
is_infinite: true,
|
||||
|
@ -12,7 +12,7 @@ BasicMelee(
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 20.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -16,7 +16,7 @@ ChargedMelee(
|
||||
)),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
charge_duration: 1.0,
|
||||
swing_duration: 0.12,
|
||||
|
@ -13,7 +13,7 @@ LeapMelee(
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
forward_leap_strength: 20.0,
|
||||
vertical_leap_strength: 8.0,
|
||||
|
@ -6,11 +6,11 @@ ComboMelee2(
|
||||
damage: 6,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 3,
|
||||
energy_regen: 7,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.1,
|
||||
@ -29,11 +29,11 @@ ComboMelee2(
|
||||
damage: 8,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 5,
|
||||
energy_regen: 8,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.15,
|
||||
|
@ -1,6 +1,6 @@
|
||||
DiveMelee(
|
||||
energy_cost: 20,
|
||||
vertical_speed: 15,
|
||||
vertical_speed: 10,
|
||||
movement_duration: 5,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.3,
|
||||
@ -19,7 +19,7 @@ DiveMelee(
|
||||
)),
|
||||
range: 6.0,
|
||||
angle: 15.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
meta: (
|
||||
kind: Some(Sword(Cleaving)),
|
||||
|
@ -12,7 +12,7 @@ FinisherMelee(
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 15.0,
|
||||
damage_effect: Some(ResetMelee),
|
||||
multi_target: Some(Scaling(0.5)),
|
||||
),
|
||||
scaling: Some((
|
||||
target: Buff,
|
||||
|
@ -10,7 +10,7 @@ ComboMelee2(
|
||||
),
|
||||
range: 6.0,
|
||||
angle: 360.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.1,
|
||||
swing_duration: 0.3,
|
||||
|
@ -10,7 +10,7 @@ ComboMelee2(
|
||||
),
|
||||
range: 8.0,
|
||||
angle: 10.0,
|
||||
multi_target: true,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.1,
|
||||
|
@ -430,18 +430,6 @@ impl Attack {
|
||||
});
|
||||
}
|
||||
},
|
||||
CombatEffect::ResetMelee => {
|
||||
if let Some(attacker_entity) = attacker.map(|a| a.entity) {
|
||||
if target
|
||||
.health
|
||||
.map_or(false, |h| accumulated_damage > h.current())
|
||||
{
|
||||
emit(ServerEvent::ResetMelee {
|
||||
entity: attacker_entity,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
CombatEffect::BuildupsVulnerable => {
|
||||
if target.char_state.map_or(false, |cs| {
|
||||
matches!(cs.stage_section(), Some(StageSection::Buildup))
|
||||
@ -604,18 +592,6 @@ impl Attack {
|
||||
});
|
||||
}
|
||||
},
|
||||
CombatEffect::ResetMelee => {
|
||||
if let Some(attacker_entity) = attacker.map(|a| a.entity) {
|
||||
if target
|
||||
.health
|
||||
.map_or(false, |h| accumulated_damage > h.current())
|
||||
{
|
||||
emit(ServerEvent::ResetMelee {
|
||||
entity: attacker_entity,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
// Only has an effect when attached to a damage
|
||||
CombatEffect::BuildupsVulnerable => {},
|
||||
}
|
||||
@ -749,8 +725,6 @@ pub enum CombatEffect {
|
||||
Lifesteal(f32),
|
||||
Poise(f32),
|
||||
Combo(i32),
|
||||
// If the attack kills the target, reset the melee attack
|
||||
ResetMelee,
|
||||
// If the attack hits the target while they are in the buildup portion of a character state,
|
||||
// deal double damage Only has an effect when attached to a damage, otherwise does nothing
|
||||
// if only attached to the attack TODO: Maybe try to make it do something if tied to
|
||||
|
@ -732,7 +732,7 @@ impl Default for CharacterAbility {
|
||||
scaled: None,
|
||||
range: 3.5,
|
||||
angle: 15.0,
|
||||
multi_target: false,
|
||||
multi_target: None,
|
||||
damage_effect: None,
|
||||
},
|
||||
ori_modifier: 1.0,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::DamageSource;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::{comp, consts::HP_PER_LEVEL};
|
||||
use crate::{uid::Uid, DamageSource};
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::convert::TryFrom;
|
||||
@ -193,6 +193,12 @@ impl Health {
|
||||
.map(|(damage_contrib, (damage, _))| (damage_contrib, damage))
|
||||
}
|
||||
|
||||
pub fn recent_damagers(&self) -> impl Iterator<Item = (Uid, Time)> + '_ {
|
||||
self.damage_contributors
|
||||
.iter()
|
||||
.map(|(contrib, (_, time))| (contrib.uid(), *time))
|
||||
}
|
||||
|
||||
pub fn should_die(&self) -> bool { self.current == 0 }
|
||||
|
||||
pub fn kill(&mut self) { self.current = 0; }
|
||||
|
@ -20,10 +20,16 @@ pub struct Melee {
|
||||
pub max_angle: f32,
|
||||
pub applied: bool,
|
||||
pub hit_count: u32,
|
||||
pub multi_target: bool,
|
||||
pub multi_target: Option<MultiTarget>,
|
||||
pub break_block: Option<(Vec3<i32>, Option<ToolKind>)>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum MultiTarget {
|
||||
Normal,
|
||||
Scaling(f32),
|
||||
}
|
||||
|
||||
impl Melee {
|
||||
#[must_use]
|
||||
pub fn with_block_breaking(
|
||||
@ -47,8 +53,7 @@ pub struct MeleeConstructor {
|
||||
pub scaled: Option<MeleeConstructorKind>,
|
||||
pub range: f32,
|
||||
pub angle: f32,
|
||||
#[serde(default)]
|
||||
pub multi_target: bool,
|
||||
pub multi_target: Option<MultiTarget>,
|
||||
pub damage_effect: Option<CombatEffect>,
|
||||
}
|
||||
|
||||
|
@ -226,9 +226,6 @@ pub enum ServerEvent {
|
||||
entity: EcsEntity,
|
||||
update: comp::MapMarkerChange,
|
||||
},
|
||||
ResetMelee {
|
||||
entity: EcsEntity,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct EventBus<E> {
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
combat::{Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement},
|
||||
comp::{
|
||||
character_state::OutputEvents,
|
||||
tool::{Stats, ToolKind},
|
||||
tool::{Stats, ToolKind}, melee::MultiTarget,
|
||||
CharacterState, Melee, StateUpdate,
|
||||
},
|
||||
states::{
|
||||
@ -279,7 +279,7 @@ impl CharacterBehavior for Data {
|
||||
hit_count: 0,
|
||||
// TODO: Evaluate if we want to leave this true. State will be removed at
|
||||
// some point anyways and this does preserve behavior
|
||||
multi_target: true,
|
||||
multi_target: Some(MultiTarget::Normal),
|
||||
break_block: data
|
||||
.inputs
|
||||
.break_block_pos
|
||||
|
@ -278,7 +278,7 @@ fn create_test_melee(static_data: StaticData) -> Melee {
|
||||
scaled: None,
|
||||
range: static_data.melee_constructor.range,
|
||||
angle: static_data.melee_constructor.angle,
|
||||
multi_target: false,
|
||||
multi_target: None,
|
||||
damage_effect: None,
|
||||
};
|
||||
melee.create_melee((0.0, 0.0), 0.0)
|
||||
|
@ -74,6 +74,8 @@ impl CharacterBehavior for Data {
|
||||
let crit_data = get_crit_data(data, self.static_data.ability_info);
|
||||
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
||||
let scaling = self.max_vertical_speed / self.static_data.vertical_speed;
|
||||
// TODO: Remove when server authoritative physics
|
||||
let scaling = scaling.max(2.0);
|
||||
|
||||
data.updater.insert(
|
||||
data.entity,
|
||||
|
@ -2,6 +2,7 @@ use common::{
|
||||
combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo},
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
melee::MultiTarget,
|
||||
Alignment, Body, CharacterState, Combo, Energy, Group, Health, Inventory, Melee, Ori,
|
||||
Player, Pos, Scale, Stats,
|
||||
},
|
||||
@ -116,7 +117,7 @@ impl<'a> System<'a> for Sys {
|
||||
{
|
||||
// Unless the melee attack can hit multiple targets, stop the attack if it has
|
||||
// already hit 1 target
|
||||
if !melee_attack.multi_target && melee_attack.hit_count > 0 {
|
||||
if melee_attack.multi_target.is_none() && melee_attack.hit_count > 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -197,12 +198,19 @@ impl<'a> System<'a> for Sys {
|
||||
target_group,
|
||||
};
|
||||
|
||||
let strength =
|
||||
if let Some(MultiTarget::Scaling(scaling)) = melee_attack.multi_target {
|
||||
1.0 + melee_attack.hit_count as f32 * scaling
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
let is_applied = melee_attack.attack.apply_attack(
|
||||
attacker_info,
|
||||
target_info,
|
||||
dir,
|
||||
attack_options,
|
||||
1.0,
|
||||
strength,
|
||||
AttackSource::Melee,
|
||||
*read_data.time,
|
||||
|e| server_emitter.emit(e),
|
||||
|
@ -18,6 +18,7 @@ use common::{
|
||||
vol::ReadVol,
|
||||
};
|
||||
use rand::Rng;
|
||||
use specs::saveload::MarkerAllocator;
|
||||
use std::{f32::consts::PI, time::Duration};
|
||||
use vek::*;
|
||||
|
||||
@ -474,16 +475,31 @@ impl<'a> AgentData<'a> {
|
||||
.map_or(false, |buffs| !buffs.contains(self.buff))
|
||||
}
|
||||
}
|
||||
struct DiveMeleeData {
|
||||
range: f32,
|
||||
angle: f32,
|
||||
energy: f32,
|
||||
}
|
||||
impl DiveMeleeData {
|
||||
fn npc_should_use_hack(&self, agent_data: &AgentData, tgt_data: &TargetData) -> bool {
|
||||
let dist_sqrd_2d = agent_data.pos.0.xy().distance_squared(tgt_data.pos.0.xy());
|
||||
agent_data.energy.current() > self.energy
|
||||
&& agent_data.physics_state.on_ground.is_some()
|
||||
&& agent_data.pos.0.z >= tgt_data.pos.0.z
|
||||
&& dist_sqrd_2d > (self.range / 2.0).powi(2)
|
||||
&& dist_sqrd_2d < (self.range + 5.0).powi(2)
|
||||
}
|
||||
}
|
||||
use ability::SwordStance;
|
||||
let stance = |stance| match stance {
|
||||
1 => SwordStance::Offensive,
|
||||
2 => SwordStance::Defensive,
|
||||
3 => SwordStance::Mobility,
|
||||
4 => SwordStance::Crippling,
|
||||
5 => SwordStance::Cleaving,
|
||||
6 => SwordStance::Parrying,
|
||||
7 => SwordStance::Heavy,
|
||||
8 => SwordStance::Reaching,
|
||||
5 => SwordStance::Parrying,
|
||||
6 => SwordStance::Heavy,
|
||||
7 => SwordStance::Reaching,
|
||||
8 => SwordStance::Cleaving,
|
||||
_ => SwordStance::Balanced,
|
||||
};
|
||||
if !agent.action_state.initialized {
|
||||
@ -495,8 +511,12 @@ impl<'a> AgentData<'a> {
|
||||
.skill_set
|
||||
.has_skill(Skill::Sword(SwordSkill::CripplingFinisher))
|
||||
{
|
||||
// Hack to make cleaving stance come up less often because agents cannot use it
|
||||
// effectively due to only considering a single target
|
||||
// Remove when agents properly consider multiple targets
|
||||
// 4 + rng.gen_range(0..13) / 3
|
||||
// rng.gen_range(4..9)
|
||||
4
|
||||
5
|
||||
} else if self
|
||||
.skill_set
|
||||
.has_skill(Skill::Sword(SwordSkill::OffensiveFinisher))
|
||||
@ -569,8 +589,8 @@ impl<'a> AgentData<'a> {
|
||||
set_sword_ability(2, 10);
|
||||
// Cleaving dive
|
||||
set_sword_ability(3, 11);
|
||||
// Offensive finisher
|
||||
set_sword_ability(4, 2);
|
||||
// Offensive advance
|
||||
set_sword_ability(4, 3);
|
||||
},
|
||||
SwordStance::Parrying => {
|
||||
// Parrying combo
|
||||
@ -1021,8 +1041,6 @@ impl<'a> AgentData<'a> {
|
||||
if self.energy.current() < DESIRED_ENERGY {
|
||||
fallback_tactics(agent, controller);
|
||||
} else if !in_stance(SwordStance::Crippling) {
|
||||
// controller.push_basic_input(InputKind::Jump);
|
||||
// agent.action_state.initialized = false;
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
} else if CRIPPLING_FINISHER.could_use(attack_data, self)
|
||||
&& CRIPPLING_FINISHER.use_desirable(tgt_data, self)
|
||||
@ -1080,7 +1098,121 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
},
|
||||
SwordStance::Cleaving => {
|
||||
fallback_tactics(agent, controller);
|
||||
// TODO: Rewrite cleaving stance tactics when agents can consider multiple
|
||||
// targets at once. Remove hack to make cleaving AI appear less frequently above
|
||||
// when doing so.
|
||||
const CLEAVING_COMBO: ComboMeleeData = ComboMeleeData {
|
||||
min_range: 0.0,
|
||||
max_range: 2.5,
|
||||
angle: 35.0,
|
||||
energy: 10.0,
|
||||
};
|
||||
const CLEAVING_FINISHER: FinisherMeleeData = FinisherMeleeData {
|
||||
range: 2.0,
|
||||
angle: 10.0,
|
||||
energy: 40.0,
|
||||
combo: 10,
|
||||
};
|
||||
const CLEAVING_SPIN: ComboMeleeData = ComboMeleeData {
|
||||
min_range: 0.0,
|
||||
max_range: 5.0,
|
||||
angle: 360.0,
|
||||
energy: 15.0,
|
||||
};
|
||||
const CLEAVING_DIVE: DiveMeleeData = DiveMeleeData {
|
||||
range: 5.0,
|
||||
angle: 10.0,
|
||||
energy: 20.0,
|
||||
};
|
||||
const DESIRED_ENERGY: f32 = 50.0;
|
||||
|
||||
// TODO: Remove when agents actually have multiple targets
|
||||
// Hacky check for multiple nearby melee range targets
|
||||
let are_nearby_targets = || {
|
||||
if let Some(health) = self.health {
|
||||
health
|
||||
.recent_damagers()
|
||||
.filter(|(_, time)| read_data.time.0 - time.0 < 5.0)
|
||||
.filter_map(|(uid, _)| {
|
||||
read_data.uid_allocator.retrieve_entity_internal(uid.0)
|
||||
})
|
||||
.filter(|e| {
|
||||
read_data.positions.get(*e).map_or(false, |pos| {
|
||||
pos.0.distance_squared(self.pos.0) < 10_f32.powi(2)
|
||||
})
|
||||
})
|
||||
.count()
|
||||
> 1
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
if matches!(self.char_state, CharacterState::Roll(_)) {
|
||||
agent.action_state.condition = true;
|
||||
}
|
||||
|
||||
if agent.action_state.condition {
|
||||
if self.physics_state.on_ground.is_some() {
|
||||
controller.push_basic_input(InputKind::Jump);
|
||||
} else {
|
||||
controller.push_basic_input(InputKind::Ability(3));
|
||||
}
|
||||
agent.action_state.timer += read_data.dt.0;
|
||||
if agent.action_state.timer > 2.0 {
|
||||
agent.action_state.timer = 0.0;
|
||||
agent.action_state.condition = false;
|
||||
}
|
||||
advance(agent, controller, CLEAVING_DIVE.range, CLEAVING_DIVE.angle);
|
||||
} else if self.energy.current() < DESIRED_ENERGY {
|
||||
fallback_tactics(agent, controller);
|
||||
} else if !in_stance(SwordStance::Cleaving) {
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
} else if CLEAVING_FINISHER.could_use(attack_data, self)
|
||||
&& CLEAVING_FINISHER.use_desirable(tgt_data, self)
|
||||
{
|
||||
controller.push_basic_input(InputKind::Ability(1));
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
CLEAVING_FINISHER.range,
|
||||
CLEAVING_FINISHER.angle,
|
||||
);
|
||||
} else if CLEAVING_SPIN.could_use(attack_data, self) && are_nearby_targets() {
|
||||
controller.push_basic_input(InputKind::Ability(2));
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
CLEAVING_SPIN.max_range,
|
||||
CLEAVING_SPIN.angle,
|
||||
);
|
||||
} else if CLEAVING_DIVE.npc_should_use_hack(self, tgt_data) {
|
||||
controller.push_basic_input(InputKind::Roll);
|
||||
advance(agent, controller, CLEAVING_DIVE.range, CLEAVING_DIVE.angle);
|
||||
} else if CLEAVING_COMBO.could_use(attack_data, self) {
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
CLEAVING_COMBO.max_range,
|
||||
CLEAVING_COMBO.angle,
|
||||
);
|
||||
} else if OFFENSIVE_ADVANCE.could_use(attack_data, self) {
|
||||
controller.push_basic_input(InputKind::Ability(4));
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
OFFENSIVE_ADVANCE.max_range,
|
||||
OFFENSIVE_ADVANCE.angle,
|
||||
);
|
||||
} else {
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
CLEAVING_COMBO.max_range,
|
||||
CLEAVING_COMBO.angle,
|
||||
);
|
||||
}
|
||||
},
|
||||
SwordStance::Parrying => {
|
||||
fallback_tactics(agent, controller);
|
||||
|
@ -1417,12 +1417,3 @@ pub fn handle_update_map_marker(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_reset_melee(server: &Server, entity: EcsEntity) {
|
||||
let ecs = &server.state.ecs();
|
||||
|
||||
if let Some(mut melee) = ecs.write_storage::<comp::Melee>().get_mut(entity) {
|
||||
melee.applied = false;
|
||||
melee.hit_count = 0;
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,7 @@ use entity_manipulation::{
|
||||
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
||||
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
||||
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground,
|
||||
handle_parry_hook, handle_poise, handle_reset_melee, handle_respawn, handle_teleport_to,
|
||||
handle_update_map_marker,
|
||||
handle_parry_hook, handle_poise, handle_respawn, handle_teleport_to, handle_update_map_marker,
|
||||
};
|
||||
use group_manip::handle_group;
|
||||
use information::handle_site_info;
|
||||
@ -287,7 +286,6 @@ impl Server {
|
||||
ServerEvent::UpdateMapMarker { entity, update } => {
|
||||
handle_update_map_marker(self, entity, update)
|
||||
},
|
||||
ServerEvent::ResetMelee { entity } => handle_reset_melee(self, entity),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ fn maps_basic_melee() {
|
||||
range: 3.5,
|
||||
angle: 15.0,
|
||||
damage_effect: None,
|
||||
multi_target: false,
|
||||
multi_target: None,
|
||||
},
|
||||
ori_modifier: 1.0,
|
||||
ability_info: empty_ability_info(),
|
||||
|
Loading…
Reference in New Issue
Block a user