Restructured logic for staff AI

This commit is contained in:
Knightress Paladin 2021-07-17 23:55:22 -07:00
parent a1e22df944
commit 38432cc880
4 changed files with 72 additions and 28 deletions

View File

@ -11,4 +11,6 @@ EntityConfig (
])),
meta: [],
loadout_asset: None,
skillset_asset: Some("common.skillset.dungeon.tier-5.warlock"),
)

View 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))),
])

View File

@ -0,0 +1,5 @@
([
// Gather all warlock skills
Tree("common.skillset.dungeon.tier-5.bow"),
Tree("common.skillset.dungeon.tier-5.staff"),
])

View File

@ -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);
}
}