mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Yeti AI
This commit is contained in:
parent
93f90d514c
commit
74b7039219
@ -1,11 +1,11 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.4,
|
||||
recover_duration: 0.25,
|
||||
beam_duration: 0.5,
|
||||
beam_duration: 0.25,
|
||||
damage: 50,
|
||||
tick_rate: 1.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
max_angle: 30.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Frozen,
|
||||
dur_secs: 3.0,
|
||||
|
@ -3,15 +3,15 @@ Shockwave(
|
||||
buildup_duration: 0.6,
|
||||
swing_duration: 0.12,
|
||||
recover_duration: 1.2,
|
||||
damage: 300,
|
||||
poise_damage: 30,
|
||||
knockback: (strength: 40.0, direction: Up),
|
||||
damage: 200,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 30.0, direction: Up),
|
||||
shockwave_angle: 90.0,
|
||||
shockwave_vertical_angle: 15.0,
|
||||
shockwave_speed: 25.0,
|
||||
shockwave_duration: 1.0,
|
||||
requires_ground: false,
|
||||
move_efficiency: 0.0,
|
||||
shockwave_speed: 50.0,
|
||||
shockwave_duration: 0.5,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.5,
|
||||
damage_kind: Piercing,
|
||||
specifier: IceSpikes,
|
||||
)
|
@ -5,7 +5,7 @@ BasicMelee(
|
||||
recover_duration: 0.5,
|
||||
base_damage: 150,
|
||||
base_poise_damage: 50,
|
||||
knockback: ( strength: 100.0, direction: Away),
|
||||
knockback: ( strength: 50.0, direction: Away),
|
||||
range: 4.0,
|
||||
max_angle: 20.0,
|
||||
damage_effect: None,
|
||||
|
@ -471,7 +471,7 @@ impl Body {
|
||||
biped_large::Species::Dullahan => 3000,
|
||||
biped_large::Species::Mindflayer => 12500,
|
||||
biped_large::Species::Tidalwarrior => 16000,
|
||||
biped_large::Species::Yeti => 4000,
|
||||
biped_large::Species::Yeti => 12000,
|
||||
biped_large::Species::Minotaur => 30000,
|
||||
biped_large::Species::Harvester => 3000,
|
||||
biped_large::Species::Blueoni => 2400,
|
||||
@ -586,7 +586,7 @@ impl Body {
|
||||
biped_large::Species::Wendigo => 80,
|
||||
biped_large::Species::Troll => 60,
|
||||
biped_large::Species::Dullahan => 120,
|
||||
biped_large::Species::Yeti => 80,
|
||||
biped_large::Species::Yeti => 0,
|
||||
biped_large::Species::Harvester => 80,
|
||||
// Boss enemies have their health set, not adjusted by level.
|
||||
biped_large::Species::Mindflayer => 0,
|
||||
@ -650,6 +650,7 @@ impl Body {
|
||||
biped_large::Species::Mindflayer => 4.8,
|
||||
biped_large::Species::Minotaur => 3.2,
|
||||
biped_large::Species::Tidalwarrior => 2.25,
|
||||
biped_large::Species::Yeti => 2.0,
|
||||
_ => 1.0,
|
||||
},
|
||||
Body::Golem(g) => match g.species {
|
||||
|
@ -119,6 +119,7 @@ pub enum Tactic {
|
||||
Minotaur,
|
||||
ClayGolem,
|
||||
TidalWarrior,
|
||||
Yeti,
|
||||
}
|
||||
|
||||
#[derive(SystemData)]
|
||||
@ -1609,6 +1610,7 @@ impl<'a> AgentData<'a> {
|
||||
"Clay Golem" => Tactic::ClayGolem,
|
||||
"Tidal Warrior" => Tactic::TidalWarrior,
|
||||
"Tidal Totem" => Tactic::RadialTurret,
|
||||
"Yeti" => Tactic::Yeti,
|
||||
_ => Tactic::Melee,
|
||||
},
|
||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||
@ -1697,6 +1699,18 @@ impl<'a> AgentData<'a> {
|
||||
),
|
||||
)
|
||||
},
|
||||
Tactic::Yeti if matches!(self.char_state, CharacterState::BasicRanged(_)) => {
|
||||
const SNOWBALL_SPEED: f32 = 60.0;
|
||||
aim_projectile(
|
||||
SNOWBALL_SPEED,
|
||||
Vec3::new(self.pos.0.x, self.pos.0.y, self.pos.0.z + eye_offset),
|
||||
Vec3::new(
|
||||
tgt_data.pos.0.x,
|
||||
tgt_data.pos.0.y,
|
||||
tgt_data.pos.0.z + tgt_eye_offset,
|
||||
),
|
||||
)
|
||||
},
|
||||
_ => Dir::from_unnormalized(
|
||||
Vec3::new(
|
||||
tgt_data.pos.0.x,
|
||||
@ -1865,6 +1879,9 @@ impl<'a> AgentData<'a> {
|
||||
&tgt_data,
|
||||
&read_data,
|
||||
),
|
||||
Tactic::Yeti => {
|
||||
self.handle_yeti_attack(agent, controller, &attack_data, &tgt_data, &read_data)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -3476,6 +3493,65 @@ impl<'a> AgentData<'a> {
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, None);
|
||||
}
|
||||
|
||||
fn handle_yeti_attack(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
) {
|
||||
const ICE_SPIKES_RANGE: f32 = 20.0;
|
||||
const ICE_BREATH_RANGE: f32 = 15.0;
|
||||
const ICE_BREATH_TIMER: f32 = 5.0;
|
||||
const SNOWBALL_MAX_RANGE: f32 = 50.0;
|
||||
|
||||
agent.action_state.counter += read_data.dt.0;
|
||||
|
||||
if attack_data.dist_sqrd < ICE_BREATH_RANGE.powi(2) && attack_data.angle < 60.0 {
|
||||
if matches!(self.char_state, CharacterState::BasicBeam(c) if c.timer < Duration::from_secs(1))
|
||||
{
|
||||
// Keep using ice breath until a second has passed
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||
} else if agent.action_state.counter > ICE_BREATH_TIMER {
|
||||
// Use ice breath if timer has gone for long enough
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||
|
||||
if matches!(self.char_state, CharacterState::BasicBeam(_)) {
|
||||
// Resets action counter when using beam
|
||||
agent.action_state.counter = 0.0;
|
||||
}
|
||||
} else if attack_data.in_min_range() {
|
||||
// Basic attack if on top of them
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
} else {
|
||||
// Use ice spikes if too far for other abilities
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||
}
|
||||
} else if attack_data.dist_sqrd < ICE_SPIKES_RANGE.powi(2) && attack_data.angle < 60.0 {
|
||||
// Use ice spikes if in range
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||
} else if attack_data.dist_sqrd < SNOWBALL_MAX_RANGE.powi(2) && attack_data.angle < 60.0 {
|
||||
// Otherwise, chuck all the snowballs
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(1)));
|
||||
}
|
||||
|
||||
// Always attempt to path towards target
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, None);
|
||||
}
|
||||
|
||||
fn follow(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
|
Loading…
Reference in New Issue
Block a user