mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix NaN in agent sys, stop pushback from turning player around, account for Scale in melee attack hit detection
This commit is contained in:
parent
8f7323f41b
commit
bfaa18e010
@ -17,7 +17,7 @@ opt-level = 2
|
||||
overflow-checks = true
|
||||
debug-assertions = true
|
||||
panic = "abort"
|
||||
# debug = false
|
||||
debug = false
|
||||
codegen-units = 8
|
||||
lto = false
|
||||
incremental = true
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::comp::{
|
||||
Agent, CharacterState, Controller, ControllerInputs, MountState, MovementState::Glide, Pos,
|
||||
Stats,
|
||||
Agent, CharacterState, Controller, MountState, MovementState::Glide, Pos, Stats,
|
||||
};
|
||||
use crate::pathfinding::WorldPath;
|
||||
use crate::terrain::TerrainGrid;
|
||||
@ -60,7 +59,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
controller.reset();
|
||||
|
||||
let mut inputs = ControllerInputs::default();
|
||||
let mut inputs = &mut controller.inputs;
|
||||
|
||||
match agent {
|
||||
Agent::Traveler { path } => {
|
||||
@ -147,10 +146,10 @@ impl<'a> System<'a> for Sys {
|
||||
let dist = Vec2::<f32>::from(target_pos.0 - pos.0).magnitude();
|
||||
if target_stats.is_dead {
|
||||
choose_new = true;
|
||||
} else if dist < MIN_ATTACK_DIST
|
||||
&& dist > 0.001
|
||||
&& rand::random::<f32>() < 0.3
|
||||
{
|
||||
} else if dist < 0.001 {
|
||||
// TODO: move back? (probably can only happen when entities are at a
|
||||
// different z-level due to repulsion)
|
||||
} else if dist < MIN_ATTACK_DIST {
|
||||
// Fight (and slowly move closer)
|
||||
inputs.move_dir =
|
||||
Vec2::<f32>::from(target_pos.0 - pos.0).normalized() * 0.01;
|
||||
@ -203,7 +202,8 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
|
||||
controller.inputs = inputs;
|
||||
debug_assert!(inputs.move_dir.map(|e| !e.is_nan()).reduce_and());
|
||||
debug_assert!(inputs.look_dir.map(|e| !e.is_nan()).reduce_and());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState::*, CharacterState, Controller, HealthChange, HealthSource, Item, ItemKind,
|
||||
Ori, Pos, Stats,
|
||||
Ori, Pos, Scale, Stats,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
state::DeltaTime,
|
||||
@ -13,7 +13,8 @@ use vek::*;
|
||||
|
||||
const BLOCK_EFFICIENCY: f32 = 0.9;
|
||||
|
||||
const ATTACK_RANGE: f32 = 4.0;
|
||||
const ATTACK_RANGE: f32 = 3.5;
|
||||
const ATTACK_ANGLE: f32 = 45.0;
|
||||
const BLOCK_ANGLE: f32 = 180.0;
|
||||
|
||||
/// This system is responsible for handling accepted inputs like moving or attacking
|
||||
@ -27,6 +28,7 @@ impl<'a> System<'a> for Sys {
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Pos>,
|
||||
ReadStorage<'a, Ori>,
|
||||
ReadStorage<'a, Scale>,
|
||||
ReadStorage<'a, Controller>,
|
||||
WriteStorage<'a, CharacterState>,
|
||||
WriteStorage<'a, Stats>,
|
||||
@ -42,6 +44,7 @@ impl<'a> System<'a> for Sys {
|
||||
uids,
|
||||
positions,
|
||||
orientations,
|
||||
scales,
|
||||
controllers,
|
||||
mut character_states,
|
||||
stats,
|
||||
@ -51,11 +54,12 @@ impl<'a> System<'a> for Sys {
|
||||
let mut _local_emitter = local_bus.emitter();
|
||||
|
||||
// Attacks
|
||||
for (entity, uid, pos, ori, _, stat) in (
|
||||
for (entity, uid, pos, ori, scale_maybe, _, stat) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
&orientations,
|
||||
scales.maybe(),
|
||||
&controllers,
|
||||
&stats,
|
||||
)
|
||||
@ -92,11 +96,12 @@ impl<'a> System<'a> for Sys {
|
||||
if deal_damage {
|
||||
if let Some(Attack { .. }) = &character_states.get(entity).map(|c| c.action) {
|
||||
// Go through all other entities
|
||||
for (b, uid_b, pos_b, ori_b, character_b, stat_b) in (
|
||||
for (b, uid_b, pos_b, ori_b, scale_b_maybe, character_b, stat_b) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
&orientations,
|
||||
scales.maybe(),
|
||||
&character_states,
|
||||
&stats,
|
||||
)
|
||||
@ -107,12 +112,18 @@ impl<'a> System<'a> for Sys {
|
||||
let pos_b2: Vec2<f32> = Vec2::from(pos_b.0);
|
||||
let ori2 = Vec2::from(ori.0);
|
||||
|
||||
// Scales
|
||||
let scale = scale_maybe.map_or(1.0, |s| s.0);
|
||||
let scale_b = scale_b_maybe.map_or(1.0, |s| s.0);
|
||||
// TODO: don't do this here
|
||||
let rad_b = 0.5 * scale_b;
|
||||
|
||||
// Check if it is a hit
|
||||
if entity != b
|
||||
&& !stat_b.is_dead
|
||||
&& pos.0.distance_squared(pos_b.0) < ATTACK_RANGE.powi(2)
|
||||
// TODO: Use size instead of 1.0
|
||||
&& ori2.angle_between(pos_b2 - pos2) < (2.0 / pos2.distance(pos_b2)).atan()
|
||||
// Spherical wedge shaped attack field
|
||||
&& pos.0.distance_squared(pos_b.0) < (rad_b + scale * ATTACK_RANGE).powi(2)
|
||||
&& ori2.angle_between(pos_b2 - pos2) < ATTACK_ANGLE.to_radians() / 2.0 + (rad_b / pos2.distance(pos_b2)).atan()
|
||||
{
|
||||
// Weapon gives base damage
|
||||
let mut dmg = if let Some(ItemKind::Tool { power, .. }) =
|
||||
@ -125,8 +136,8 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
// Block
|
||||
if character_b.action.is_block()
|
||||
&& ori_b.0.angle_between(pos.0 - pos_b.0).to_degrees()
|
||||
< BLOCK_ANGLE / 2.0
|
||||
&& ori_b.0.angle_between(pos.0 - pos_b.0)
|
||||
< BLOCK_ANGLE.to_radians() / 2.0
|
||||
{
|
||||
dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as i32
|
||||
}
|
||||
|
@ -173,10 +173,10 @@ impl<'a> System<'a> for Sys {
|
||||
if Vec2::<f32>::from(wall_dir).magnitude_squared() > 0.001 {
|
||||
Vec2::from(wall_dir).normalized()
|
||||
} else {
|
||||
Vec2::from(vel.0)
|
||||
Vec2::from(inputs.move_dir)
|
||||
}
|
||||
} else {
|
||||
Vec2::from(vel.0)
|
||||
Vec2::from(inputs.move_dir)
|
||||
};
|
||||
|
||||
if ori_dir.magnitude_squared() > 0.0001
|
||||
|
@ -102,6 +102,7 @@ impl<'a> System<'a> for Sys {
|
||||
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
||||
|
||||
// Basic collision with terrain
|
||||
// TODO: rename this, not just the player entity
|
||||
let player_rad = 0.3 * scale; // half-width of the player's AABB
|
||||
let player_height = 1.5 * scale;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user