mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Restructured logic for staff AI
This commit is contained in:
parent
a1e22df944
commit
38432cc880
@ -11,4 +11,6 @@ EntityConfig (
|
||||
])),
|
||||
|
||||
meta: [],
|
||||
loadout_asset: None,
|
||||
skillset_asset: Some("common.skillset.dungeon.tier-5.warlock"),
|
||||
)
|
||||
|
21
assets/common/skillset/dungeon/tier-5/staff.ron
Normal file
21
assets/common/skillset/dungeon/tier-5/staff.ron
Normal file
@ -0,0 +1,21 @@
|
||||
([
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(1))),
|
||||
Skill((Staff(BRegen), Some(1))),
|
||||
Skill((Staff(BRadius), Some(1))),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FDamage), Some(1))),
|
||||
Skill((Staff(FRange), Some(1))),
|
||||
Skill((Staff(FDrain), Some(1))),
|
||||
Skill((Staff(FVelocity), Some(1))),
|
||||
|
||||
// Shockwave
|
||||
Skill((Staff(UnlockShockwave), None)),
|
||||
Skill((Staff(SDamage), Some(1))),
|
||||
Skill((Staff(SKnockback), Some(1))),
|
||||
Skill((Staff(SRange), Some(1))),
|
||||
Skill((Staff(SCost), Some(1))),
|
||||
])
|
5
assets/common/skillset/dungeon/tier-5/warlock.ron
Normal file
5
assets/common/skillset/dungeon/tier-5/warlock.ron
Normal file
@ -0,0 +1,5 @@
|
||||
([
|
||||
// Gather all warlock skills
|
||||
Tree("common.skillset.dungeon.tier-5.bow"),
|
||||
Tree("common.skillset.dungeon.tier-5.staff"),
|
||||
])
|
@ -2443,40 +2443,37 @@ impl<'a> AgentData<'a> {
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
) {
|
||||
if self.body.map(|b| b.is_humanoid()).unwrap_or(false) && attack_data.in_min_range() {
|
||||
//TODO: minimum energy values for skills and rolls are hard coded from
|
||||
// approximate guesses
|
||||
if self.body.map(|b| b.is_humanoid()).unwrap_or(false)
|
||||
&& attack_data.in_min_range()
|
||||
&& self.energy.current() > 100
|
||||
{
|
||||
// if a humanoid, have enough stamina, and in melee range, emergency roll
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Roll));
|
||||
} else if attack_data.dist_sqrd < (5.0 * attack_data.min_attack_dist).powi(2)
|
||||
&& attack_data.angle < 15.0
|
||||
} else if !matches!(self.char_state, CharacterState::Shockwave(c) if !matches!(c.stage_section, StageSection::Recover))
|
||||
{
|
||||
if agent.action_state.timer < 1.5 {
|
||||
controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0)
|
||||
.xy()
|
||||
.rotated_z(0.47 * PI)
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec2::unit_y);
|
||||
agent.action_state.timer += read_data.dt.0;
|
||||
} else if agent.action_state.timer < 3.0 {
|
||||
controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0)
|
||||
.xy()
|
||||
.rotated_z(-0.47 * PI)
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec2::unit_y);
|
||||
agent.action_state.timer += read_data.dt.0;
|
||||
} else {
|
||||
agent.action_state.timer = 0.0;
|
||||
}
|
||||
// only try to use another ability if not already in recover and not casting
|
||||
// shockwave
|
||||
let target_approaching_speed = -agent
|
||||
.target
|
||||
.as_ref()
|
||||
.map(|t| t.target)
|
||||
.and_then(|e| read_data.velocities.get(e))
|
||||
.map_or(0.0, |v| v.0.dot(self.ori.look_vec()));
|
||||
if self
|
||||
.skill_set
|
||||
.has_skill(Skill::Staff(StaffSkill::UnlockShockwave))
|
||||
&& self.energy.current() > 800
|
||||
&& thread_rng().gen::<f32>() > 0.8
|
||||
&& target_approaching_speed > 20.0
|
||||
&& self.energy.current() > 200
|
||||
{
|
||||
// if enemy is closing distance quickly, use shockwave to knock back
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||
} else if self.energy.current() > 10 {
|
||||
} else if self.energy.current() > 100 && attack_data.dist_sqrd < 280.0 {
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||
@ -2485,7 +2482,26 @@ impl<'a> AgentData<'a> {
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
}
|
||||
// Logic to move. Intentionally kept separate from ability logic so duplicated
|
||||
// work is less necessary.
|
||||
if attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) {
|
||||
// Attempt to move away from target if too close
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*read_data.terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_data.pos.0,
|
||||
TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
controller.inputs.move_dir =
|
||||
-bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
}
|
||||
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
|
||||
// Else attempt to circle target if neither too close nor too far
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*read_data.terrain,
|
||||
self.pos.0,
|
||||
@ -2501,7 +2517,7 @@ impl<'a> AgentData<'a> {
|
||||
self.pos,
|
||||
tgt_data.pos,
|
||||
attack_data.dist_sqrd,
|
||||
) && attack_data.angle < 15.0
|
||||
) && attack_data.angle < 45.0
|
||||
{
|
||||
controller.inputs.move_dir = bearing
|
||||
.xy()
|
||||
@ -2509,25 +2525,25 @@ impl<'a> AgentData<'a> {
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec2::zero)
|
||||
* speed;
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
} else {
|
||||
// Unless cannot see target, then move towards them
|
||||
controller.inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
self.jump_if(controller, bearing.z > 1.5);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
// Sometimes try to roll
|
||||
if self.body.map(|b| b.is_humanoid()).unwrap_or(false)
|
||||
&& attack_data.dist_sqrd < 16.0f32.powi(2)
|
||||
&& thread_rng().gen::<f32>() < 0.02
|
||||
&& thread_rng().gen::<f32>() < 0.01
|
||||
{
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Roll));
|
||||
}
|
||||
} else {
|
||||
// If too far, move towards target
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user