mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Heavy stance AI
This commit is contained in:
@ -5,7 +5,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
ability::{self, AbilityKind, ActiveAbilities, AuxiliaryAbility, Capability},
|
ability::{self, Ability, AbilityKind, ActiveAbilities, AuxiliaryAbility, Capability},
|
||||||
buff::BuffKind,
|
buff::BuffKind,
|
||||||
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill},
|
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill},
|
||||||
AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, ControlEvent,
|
AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, ControlEvent,
|
||||||
@ -529,7 +529,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Remove when agents properly consider multiple targets
|
// Remove when agents properly consider multiple targets
|
||||||
// 4 + rng.gen_range(0..13) / 3
|
// 4 + rng.gen_range(0..13) / 3
|
||||||
// rng.gen_range(4..9)
|
// rng.gen_range(4..9)
|
||||||
5
|
6
|
||||||
} else if self
|
} else if self
|
||||||
.skill_set
|
.skill_set
|
||||||
.has_skill(Skill::Sword(SwordSkill::OffensiveFinisher))
|
.has_skill(Skill::Sword(SwordSkill::OffensiveFinisher))
|
||||||
@ -728,6 +728,10 @@ impl<'a> AgentData<'a> {
|
|||||||
angle: 35.0,
|
angle: 35.0,
|
||||||
energy: 10.0,
|
energy: 10.0,
|
||||||
};
|
};
|
||||||
|
const DEFENSIVE_BULWARK: SelfBuffData = SelfBuffData {
|
||||||
|
buff: BuffKind::ProtectingWard,
|
||||||
|
energy: 40.0,
|
||||||
|
};
|
||||||
|
|
||||||
match stance(agent.action_state.int_counter) {
|
match stance(agent.action_state.int_counter) {
|
||||||
SwordStance::Balanced => {
|
SwordStance::Balanced => {
|
||||||
@ -833,10 +837,6 @@ impl<'a> AgentData<'a> {
|
|||||||
angle: 35.0,
|
angle: 35.0,
|
||||||
energy: 5.0,
|
energy: 5.0,
|
||||||
};
|
};
|
||||||
const DEFENSIVE_BULWARK: SelfBuffData = SelfBuffData {
|
|
||||||
buff: BuffKind::ProtectingWard,
|
|
||||||
energy: 40.0,
|
|
||||||
};
|
|
||||||
const BASIC_BLOCK: BlockData = BlockData {
|
const BASIC_BLOCK: BlockData = BlockData {
|
||||||
angle: 55.0,
|
angle: 55.0,
|
||||||
range: 5.0,
|
range: 5.0,
|
||||||
@ -1371,7 +1371,85 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Heavy => {
|
SwordStance::Heavy => {
|
||||||
fallback_tactics(agent, controller);
|
const HEAVY_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
|
min_range: 0.0,
|
||||||
|
max_range: 2.5,
|
||||||
|
angle: 35.0,
|
||||||
|
energy: 5.0,
|
||||||
|
};
|
||||||
|
const HEAVY_FINISHER: FinisherMeleeData = FinisherMeleeData {
|
||||||
|
range: 2.5,
|
||||||
|
angle: 10.0,
|
||||||
|
energy: 40.0,
|
||||||
|
combo: 10,
|
||||||
|
};
|
||||||
|
const HEAVY_POMMELSTRIKE: ComboMeleeData = ComboMeleeData {
|
||||||
|
min_range: 0.0,
|
||||||
|
max_range: 3.0,
|
||||||
|
angle: 3.0,
|
||||||
|
energy: 10.0,
|
||||||
|
};
|
||||||
|
const HEAVY_FORTITUDE: SelfBuffData = SelfBuffData {
|
||||||
|
buff: BuffKind::Fortitude,
|
||||||
|
energy: 40.0,
|
||||||
|
};
|
||||||
|
const DESIRED_ENERGY: f32 = 50.0;
|
||||||
|
|
||||||
|
agent.action_state.condition = self
|
||||||
|
.poise
|
||||||
|
.map_or(false, |p| p.current() < p.maximum() * 0.8);
|
||||||
|
if matches!(
|
||||||
|
self.char_state.ability_info().and_then(|info| info.ability),
|
||||||
|
Some(Ability::MainWeaponAux(21))
|
||||||
|
) {
|
||||||
|
agent.action_state.timer = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.energy.current() < DESIRED_ENERGY {
|
||||||
|
fallback_tactics(agent, controller);
|
||||||
|
} else if !agent.action_state.condition
|
||||||
|
&& DEFENSIVE_BULWARK.could_use(self)
|
||||||
|
&& DEFENSIVE_BULWARK.use_desirable(self)
|
||||||
|
{
|
||||||
|
if in_stance(SwordStance::Heavy) {
|
||||||
|
controller.push_basic_input(InputKind::Ability(0));
|
||||||
|
} else {
|
||||||
|
controller.push_basic_input(InputKind::Ability(4));
|
||||||
|
}
|
||||||
|
} else if !in_stance(SwordStance::Heavy) {
|
||||||
|
controller.push_basic_input(InputKind::Ability(0));
|
||||||
|
} else if HEAVY_FORTITUDE.could_use(self)
|
||||||
|
&& HEAVY_FORTITUDE.use_desirable(self)
|
||||||
|
&& agent.action_state.condition
|
||||||
|
{
|
||||||
|
controller.push_basic_input(InputKind::Ability(3));
|
||||||
|
} else if HEAVY_FINISHER.could_use(attack_data, self)
|
||||||
|
&& HEAVY_FINISHER.use_desirable(tgt_data, self)
|
||||||
|
{
|
||||||
|
controller.push_basic_input(InputKind::Ability(1));
|
||||||
|
advance(
|
||||||
|
agent,
|
||||||
|
controller,
|
||||||
|
HEAVY_FINISHER.range,
|
||||||
|
HEAVY_FINISHER.angle,
|
||||||
|
);
|
||||||
|
} else if HEAVY_POMMELSTRIKE.could_use(attack_data, self)
|
||||||
|
&& rng.gen::<f32>()
|
||||||
|
< agent.action_state.timer * self.poise.map_or(0.5, |p| p.fraction())
|
||||||
|
{
|
||||||
|
controller.push_basic_input(InputKind::Ability(2));
|
||||||
|
advance(
|
||||||
|
agent,
|
||||||
|
controller,
|
||||||
|
HEAVY_POMMELSTRIKE.max_range,
|
||||||
|
HEAVY_POMMELSTRIKE.angle,
|
||||||
|
);
|
||||||
|
} else if HEAVY_COMBO.could_use(attack_data, self) {
|
||||||
|
controller.push_basic_input(InputKind::Primary);
|
||||||
|
advance(agent, controller, HEAVY_COMBO.max_range, HEAVY_COMBO.angle);
|
||||||
|
} else {
|
||||||
|
advance(agent, controller, HEAVY_COMBO.max_range, HEAVY_COMBO.angle);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Reaching => {
|
SwordStance::Reaching => {
|
||||||
fallback_tactics(agent, controller);
|
fallback_tactics(agent, controller);
|
||||||
|
@ -2,7 +2,7 @@ use common::{
|
|||||||
comp::{
|
comp::{
|
||||||
buff::Buffs, group, item::MaterialStatManifest, ActiveAbilities, Alignment, Body,
|
buff::Buffs, group, item::MaterialStatManifest, ActiveAbilities, Alignment, Body,
|
||||||
CharacterState, Combo, Energy, Health, Inventory, LightEmitter, LootOwner, Ori,
|
CharacterState, Combo, Energy, Health, Inventory, LightEmitter, LootOwner, Ori,
|
||||||
PhysicsState, Pos, Scale, SkillSet, Stats, Vel,
|
PhysicsState, Poise, Pos, Scale, SkillSet, Stats, Vel,
|
||||||
},
|
},
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::Mount,
|
mounting::Mount,
|
||||||
@ -43,6 +43,7 @@ pub struct AgentData<'a> {
|
|||||||
pub active_abilities: &'a ActiveAbilities,
|
pub active_abilities: &'a ActiveAbilities,
|
||||||
pub combo: Option<&'a Combo>,
|
pub combo: Option<&'a Combo>,
|
||||||
pub buffs: Option<&'a Buffs>,
|
pub buffs: Option<&'a Buffs>,
|
||||||
|
pub poise: Option<&'a Poise>,
|
||||||
pub cached_spatial_grid: &'a common::CachedSpatialGrid,
|
pub cached_spatial_grid: &'a common::CachedSpatialGrid,
|
||||||
pub msm: &'a MaterialStatManifest,
|
pub msm: &'a MaterialStatManifest,
|
||||||
}
|
}
|
||||||
@ -171,6 +172,7 @@ pub struct ReadData<'a> {
|
|||||||
pub active_abilities: ReadStorage<'a, ActiveAbilities>,
|
pub active_abilities: ReadStorage<'a, ActiveAbilities>,
|
||||||
pub loot_owners: ReadStorage<'a, LootOwner>,
|
pub loot_owners: ReadStorage<'a, LootOwner>,
|
||||||
pub msm: ReadExpect<'a, MaterialStatManifest>,
|
pub msm: ReadExpect<'a, MaterialStatManifest>,
|
||||||
|
pub poises: ReadStorage<'a, Poise>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Path {
|
pub enum Path {
|
||||||
|
@ -201,6 +201,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
buffs: read_data.buffs.get(entity),
|
buffs: read_data.buffs.get(entity),
|
||||||
cached_spatial_grid: &read_data.cached_spatial_grid,
|
cached_spatial_grid: &read_data.cached_spatial_grid,
|
||||||
msm: &read_data.msm,
|
msm: &read_data.msm,
|
||||||
|
poise: read_data.poises.get(entity),
|
||||||
};
|
};
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Behavior tree
|
// Behavior tree
|
||||||
|
Reference in New Issue
Block a user