mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improve NPC aiming and humanoid hitboxes
This commit is contained in:
parent
7ad330af4c
commit
6085edaa34
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Flight
|
||||
- Roll dodges melee attacks, and reduces the height of your hitbox
|
||||
- Persistent waypoints (start from the last camp fire you visited)
|
||||
- NPCs use all three weapon skills in combat
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -140,7 +140,7 @@ impl Body {
|
||||
pub fn radius(&self) -> f32 {
|
||||
// TODO: Improve these values (some might be reliant on more info in inner type)
|
||||
match self {
|
||||
Body::Humanoid(body) => 0.35 * body.scale(),
|
||||
Body::Humanoid(body) => 0.5 * body.scale(),
|
||||
Body::QuadrupedSmall(_) => 0.4,
|
||||
Body::QuadrupedMedium(body) => match body.species {
|
||||
quadruped_medium::Species::Grolgar => 1.9,
|
||||
@ -172,12 +172,7 @@ impl Body {
|
||||
|
||||
pub fn height(&self) -> f32 {
|
||||
match self {
|
||||
Body::Humanoid(humanoid) => match humanoid.species {
|
||||
humanoid::Species::Danari => 1.5 * humanoid.scale(),
|
||||
humanoid::Species::Dwarf => 1.55 * humanoid.scale(),
|
||||
humanoid::Species::Orc => 1.95 * humanoid.scale(),
|
||||
_ => 1.8 * humanoid.scale(),
|
||||
},
|
||||
Body::Humanoid(body) => 1.9 * body.scale(),
|
||||
Body::QuadrupedSmall(body) => match body.species {
|
||||
quadruped_small::Species::Dodarock => 1.5,
|
||||
quadruped_small::Species::Holladon => 1.5,
|
||||
|
@ -308,7 +308,7 @@ impl<'a> System<'a> for Sys {
|
||||
Axe,
|
||||
Hammer,
|
||||
Sword,
|
||||
RangedPowerup,
|
||||
Bow,
|
||||
Staff,
|
||||
StoneGolemBoss,
|
||||
}
|
||||
@ -320,7 +320,7 @@ impl<'a> System<'a> for Sys {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
Some(ToolKind::Bow) => Tactic::RangedPowerup,
|
||||
Some(ToolKind::Bow) => Tactic::Bow,
|
||||
Some(ToolKind::Staff) => Tactic::Staff,
|
||||
Some(ToolKind::Hammer) => Tactic::Hammer,
|
||||
Some(ToolKind::Sword) => Tactic::Sword,
|
||||
@ -341,10 +341,42 @@ impl<'a> System<'a> for Sys {
|
||||
.unwrap_or(Alignment::Wild),
|
||||
),
|
||||
) {
|
||||
if let Some(dir) = Dir::from_unnormalized(tgt_pos.0 - pos.0) {
|
||||
controller.actions.push(ControlAction::Wield);
|
||||
|
||||
let eye_offset = match body {
|
||||
Some(body) => match body {
|
||||
Body::Humanoid(body) => body.eye_height(),
|
||||
_ => 0.4 * body.height(),
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
let tgt_eye_offset = match bodies.get(*target) {
|
||||
Some(body) => match body {
|
||||
Body::Humanoid(body) => body.eye_height(),
|
||||
_ => 0.4 * body.height(),
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
let distance_offset = match tactic {
|
||||
Tactic::Bow => 0.0004 * pos.0.distance_squared(tgt_pos.0),
|
||||
Tactic::Staff => 0.0015 * pos.0.distance_squared(tgt_pos.0),
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
if let Some(dir) = Dir::from_unnormalized(
|
||||
Vec3::new(
|
||||
tgt_pos.0.x,
|
||||
tgt_pos.0.y,
|
||||
tgt_pos.0.z + tgt_eye_offset + distance_offset,
|
||||
) - Vec3::new(pos.0.x, pos.0.y, pos.0.z + eye_offset),
|
||||
) {
|
||||
inputs.look_dir = dir;
|
||||
}
|
||||
|
||||
//if let Some(dir) = Dir::from_unnormalized(tgt_pos.0 - pos.0) {
|
||||
// inputs.look_dir = dir;
|
||||
//}
|
||||
|
||||
// Don't attack entities we are passive towards
|
||||
// TODO: This is here, it's a bit of a hack
|
||||
if let Some(alignment) = alignment {
|
||||
@ -388,7 +420,7 @@ impl<'a> System<'a> for Sys {
|
||||
inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
||||
* speed
|
||||
* 0.2; //Let small/slow animals flee slower than the player
|
||||
* 0.4; //Let small/slow animals flee slower than the player
|
||||
inputs.jump.set_state(bearing.z > 1.5);
|
||||
inputs.move_z = bearing.z;
|
||||
}
|
||||
@ -407,14 +439,27 @@ impl<'a> System<'a> for Sys {
|
||||
* 0.1;
|
||||
|
||||
match tactic {
|
||||
Tactic::Sword
|
||||
| Tactic::Melee
|
||||
| Tactic::Hammer
|
||||
| Tactic::StoneGolemBoss => inputs.primary.set_state(true),
|
||||
Tactic::Melee | Tactic::StoneGolemBoss => {
|
||||
inputs.primary.set_state(true)
|
||||
},
|
||||
Tactic::Hammer => {
|
||||
if *powerup > 4.0 {
|
||||
inputs.secondary.set_state(false);
|
||||
*powerup = 0.0;
|
||||
} else if *powerup > 2.0 {
|
||||
inputs.secondary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else if energy.current() > 700 {
|
||||
inputs.ability3.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else {
|
||||
inputs.primary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
}
|
||||
},
|
||||
Tactic::Staff => {
|
||||
// Kind of arbitrary values, but feel right in game
|
||||
if energy.current() > 800 && thread_rng().gen::<f32>() > 0.8
|
||||
{
|
||||
if energy.current() > 800 && thread_rng().gen_bool(0.2) {
|
||||
inputs.ability3.set_state(true)
|
||||
} else if energy.current() > 10 {
|
||||
inputs.secondary.set_state(true)
|
||||
@ -422,19 +467,35 @@ impl<'a> System<'a> for Sys {
|
||||
inputs.primary.set_state(true)
|
||||
}
|
||||
},
|
||||
Tactic::Sword => {
|
||||
if *powerup < 2.0 && energy.current() > 500 {
|
||||
inputs.ability3.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else if *powerup > 2.0 {
|
||||
*powerup = 0.0;
|
||||
} else {
|
||||
inputs.primary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
}
|
||||
},
|
||||
Tactic::Axe => {
|
||||
if *powerup > 6.0 {
|
||||
inputs.secondary.set_state(false);
|
||||
*powerup = 0.0;
|
||||
} else if *powerup > 4.0 && energy.current() > 10 {
|
||||
} else if *powerup > 4.0 && energy.current() > 100 {
|
||||
inputs.secondary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else if energy.current() > 800
|
||||
&& thread_rng().gen_bool(0.5)
|
||||
{
|
||||
inputs.ability3.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else {
|
||||
inputs.primary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
}
|
||||
},
|
||||
Tactic::RangedPowerup => inputs.roll.set_state(true),
|
||||
Tactic::Bow => inputs.roll.set_state(true),
|
||||
}
|
||||
} else if dist_sqrd < MAX_CHASE_DIST.powf(2.0)
|
||||
|| (dist_sqrd < SIGHT_DIST.powf(2.0)
|
||||
@ -449,37 +510,54 @@ impl<'a> System<'a> for Sys {
|
||||
>= dist_sqrd;
|
||||
|
||||
if can_see_tgt {
|
||||
if let Tactic::RangedPowerup = tactic {
|
||||
if *powerup > 1.5 {
|
||||
inputs.primary.set_state(false);
|
||||
match tactic {
|
||||
Tactic::Bow => {
|
||||
if *powerup > 4.0 {
|
||||
inputs.secondary.set_state(false);
|
||||
*powerup = 0.0;
|
||||
} else if *powerup > 2.0 && energy.current() > 300 {
|
||||
inputs.secondary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else if energy.current() > 400
|
||||
&& thread_rng().gen_bool(0.8)
|
||||
{
|
||||
inputs.secondary.set_state(false);
|
||||
inputs.ability3.set_state(true);
|
||||
*powerup += dt.0;
|
||||
} else {
|
||||
inputs.secondary.set_state(false);
|
||||
inputs.primary.set_state(true);
|
||||
*powerup += dt.0;
|
||||
}
|
||||
} else if let Tactic::Sword = tactic {
|
||||
},
|
||||
Tactic::Sword => {
|
||||
if *powerup > 4.0 {
|
||||
inputs.secondary.set_state(true);
|
||||
*powerup = 0.0;
|
||||
} else {
|
||||
*powerup += dt.0;
|
||||
}
|
||||
} else if let Tactic::Staff = tactic {
|
||||
},
|
||||
Tactic::Staff => {
|
||||
inputs.primary.set_state(true);
|
||||
} else if let Tactic::Hammer = tactic {
|
||||
},
|
||||
Tactic::Hammer => {
|
||||
if *powerup > 5.0 {
|
||||
inputs.ability3.set_state(true);
|
||||
*powerup = 0.0;
|
||||
} else {
|
||||
*powerup += dt.0;
|
||||
}
|
||||
} else if let Tactic::StoneGolemBoss = tactic {
|
||||
},
|
||||
Tactic::StoneGolemBoss => {
|
||||
if *powerup > 5.0 {
|
||||
inputs.secondary.set_state(true);
|
||||
*powerup = 0.0;
|
||||
} else {
|
||||
*powerup += dt.0;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,7 +580,7 @@ impl<'a> System<'a> for Sys {
|
||||
) {
|
||||
if can_see_tgt {
|
||||
match tactic {
|
||||
Tactic::RangedPowerup => {
|
||||
Tactic::Bow => {
|
||||
inputs.move_dir = bearing
|
||||
.xy()
|
||||
.rotated_z(thread_rng().gen_range(0.5, 1.57))
|
||||
|
Loading…
Reference in New Issue
Block a user