mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add stay position to PetState
Pets will now stay within 10 voxels of where they were told to stay Added MAX_STAY_DISTANCE constant Fixed being able to tell pet to stay when mounted
This commit is contained in:
parent
9597810e3d
commit
d9d364fe79
@ -1,4 +1,4 @@
|
|||||||
use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small};
|
use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small, Pos};
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
@ -109,15 +109,10 @@ impl Component for Pet {
|
|||||||
type Storage = specs::VecStorage<Self>;
|
type Storage = specs::VecStorage<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum StayFollow {
|
|
||||||
Stay,
|
|
||||||
Follow,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
|
||||||
pub struct PetState {
|
pub struct PetState {
|
||||||
pub stay: bool,
|
pub stay: bool,
|
||||||
|
pub stay_pos: Option<Pos>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for PetState {
|
impl Component for PetState {
|
||||||
|
@ -3,6 +3,7 @@ pub const FLEE_DURATION: f32 = 3.0;
|
|||||||
pub const NPC_PICKUP_RANGE: f32 = 2.5;
|
pub const NPC_PICKUP_RANGE: f32 = 2.5;
|
||||||
pub const MAX_PATROL_DIST: f32 = 50.0;
|
pub const MAX_PATROL_DIST: f32 = 50.0;
|
||||||
pub const MAX_PATH_DIST: f32 = 170.0;
|
pub const MAX_PATH_DIST: f32 = 170.0;
|
||||||
|
pub const MAX_STAY_DISTANCE: f32 = 10.0;
|
||||||
pub const PARTIAL_PATH_DIST: f32 = 50.0;
|
pub const PARTIAL_PATH_DIST: f32 = 50.0;
|
||||||
pub const SEPARATION_DIST: f32 = 10.0;
|
pub const SEPARATION_DIST: f32 = 10.0;
|
||||||
pub const SEPARATION_BIAS: f32 = 0.8;
|
pub const SEPARATION_BIAS: f32 = 0.8;
|
||||||
|
@ -54,6 +54,7 @@ pub struct AgentData<'a> {
|
|||||||
pub glider_equipped: bool,
|
pub glider_equipped: bool,
|
||||||
pub is_gliding: bool,
|
pub is_gliding: bool,
|
||||||
pub is_stay: bool,
|
pub is_stay: bool,
|
||||||
|
pub stay_pos: Option<Pos>,
|
||||||
pub health: Option<&'a Health>,
|
pub health: Option<&'a Health>,
|
||||||
pub char_state: &'a CharacterState,
|
pub char_state: &'a CharacterState,
|
||||||
pub active_abilities: &'a ActiveAbilities,
|
pub active_abilities: &'a ActiveAbilities,
|
||||||
|
@ -213,12 +213,19 @@ pub fn handle_toggle_stay(server: &mut Server, pet: EcsEntity) {
|
|||||||
let _ = state
|
let _ = state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<PetState>()
|
.write_storage::<PetState>()
|
||||||
.insert(pet, PetState { stay: false });
|
.insert(pet, PetState {
|
||||||
|
stay: false,
|
||||||
|
stay_pos: None,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
let current_pos = state.ecs().read_storage::<Pos>().get(pet).copied();
|
||||||
let _ = state
|
let _ = state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<PetState>()
|
.write_storage::<PetState>()
|
||||||
.insert(pet, PetState { stay: true });
|
.insert(pet, PetState {
|
||||||
|
stay: true,
|
||||||
|
stay_pos: current_pos,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +160,11 @@ impl<'a> System<'a> for Sys {
|
|||||||
.map_or(false, |item| {
|
.map_or(false, |item| {
|
||||||
matches!(&*item.kind(), comp::item::ItemKind::Glider)
|
matches!(&*item.kind(), comp::item::ItemKind::Glider)
|
||||||
});
|
});
|
||||||
|
|
||||||
let is_stay = pet_state.map_or(false, |s| s.stay);
|
let is_stay = pet_state.map_or(false, |s| s.stay);
|
||||||
|
|
||||||
|
let stay_pos = pet_state.and_then(|s| s.stay_pos);
|
||||||
|
|
||||||
let is_gliding = matches!(
|
let is_gliding = matches!(
|
||||||
read_data.char_states.get(entity),
|
read_data.char_states.get(entity),
|
||||||
Some(CharacterState::GlideWield(_) | CharacterState::Glide(_))
|
Some(CharacterState::GlideWield(_) | CharacterState::Glide(_))
|
||||||
@ -233,6 +236,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
glider_equipped,
|
glider_equipped,
|
||||||
is_gliding,
|
is_gliding,
|
||||||
is_stay,
|
is_stay,
|
||||||
|
stay_pos,
|
||||||
health: read_data.healths.get(entity),
|
health: read_data.healths.get(entity),
|
||||||
char_state,
|
char_state,
|
||||||
active_abilities,
|
active_abilities,
|
||||||
|
@ -25,7 +25,7 @@ use self::interaction::{
|
|||||||
use super::{
|
use super::{
|
||||||
consts::{
|
consts::{
|
||||||
DAMAGE_MEMORY_DURATION, FLEE_DURATION, HEALING_ITEM_THRESHOLD, MAX_PATROL_DIST,
|
DAMAGE_MEMORY_DURATION, FLEE_DURATION, HEALING_ITEM_THRESHOLD, MAX_PATROL_DIST,
|
||||||
NORMAL_FLEE_DIR_DIST, NPC_PICKUP_RANGE, RETARGETING_THRESHOLD_SECONDS,
|
MAX_STAY_DISTANCE, NORMAL_FLEE_DIR_DIST, NPC_PICKUP_RANGE, RETARGETING_THRESHOLD_SECONDS,
|
||||||
STD_AWARENESS_DECAY_RATE,
|
STD_AWARENESS_DECAY_RATE,
|
||||||
},
|
},
|
||||||
data::{AgentData, ReadData, TargetData},
|
data::{AgentData, ReadData, TargetData},
|
||||||
@ -406,9 +406,20 @@ fn do_pickup_loot(bdata: &mut BehaviorData) -> bool {
|
|||||||
fn follow_if_far_away(bdata: &mut BehaviorData) -> bool {
|
fn follow_if_far_away(bdata: &mut BehaviorData) -> bool {
|
||||||
if let Some(Target { target, .. }) = bdata.agent.target {
|
if let Some(Target { target, .. }) = bdata.agent.target {
|
||||||
if let Some(tgt_pos) = bdata.read_data.positions.get(target) {
|
if let Some(tgt_pos) = bdata.read_data.positions.get(target) {
|
||||||
let dist_sqrd = bdata.agent_data.pos.0.distance_squared(tgt_pos.0);
|
|
||||||
let stay = bdata.agent_data.is_stay;
|
let stay = bdata.agent_data.is_stay;
|
||||||
if dist_sqrd > (MAX_PATROL_DIST * bdata.agent.psyche.idle_wander_factor).powi(2) && !stay {
|
if stay {
|
||||||
|
let stay_pos = bdata.agent_data.stay_pos.map_or(Pos(Vec3::zero()), |v| v);
|
||||||
|
let distance_from_stay = stay_pos.0.distance_squared(bdata.agent_data.pos.0);
|
||||||
|
|
||||||
|
if distance_from_stay > (MAX_STAY_DISTANCE).powi(2) {
|
||||||
|
bdata
|
||||||
|
.agent_data
|
||||||
|
.follow(bdata.agent, bdata.controller, bdata.read_data, &stay_pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let dist_sqrd = bdata.agent_data.pos.0.distance_squared(tgt_pos.0);
|
||||||
|
if dist_sqrd > (MAX_PATROL_DIST * bdata.agent.psyche.idle_wander_factor).powi(2) {
|
||||||
bdata
|
bdata
|
||||||
.agent_data
|
.agent_data
|
||||||
.follow(bdata.agent, bdata.controller, bdata.read_data, tgt_pos);
|
.follow(bdata.agent, bdata.controller, bdata.read_data, tgt_pos);
|
||||||
@ -416,6 +427,7 @@ fn follow_if_far_away(bdata: &mut BehaviorData) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2432,7 +2432,6 @@ impl Hud {
|
|||||||
i18n.get_msg("hud-mount").to_string(),
|
i18n.get_msg("hud-mount").to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
let pet_stay = is_stay.get(entity).map(|st| st.stay);
|
let pet_stay = is_stay.get(entity).map(|st| st.stay);
|
||||||
match pet_stay {
|
match pet_stay {
|
||||||
Some(false) => options.push((
|
Some(false) => options.push((
|
||||||
@ -2448,6 +2447,7 @@ impl Hud {
|
|||||||
i18n.get_msg("hud-stay").to_string(),
|
i18n.get_msg("hud-stay").to_string(),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
options
|
options
|
||||||
},
|
},
|
||||||
_ => Vec::new(),
|
_ => Vec::new(),
|
||||||
|
@ -963,7 +963,7 @@ impl PlayState for SessionState {
|
|||||||
*dist_sqr < MAX_MOUNT_RANGE.powi(2)
|
*dist_sqr < MAX_MOUNT_RANGE.powi(2)
|
||||||
})
|
})
|
||||||
.min_by_key(|(_, dist_sqr)| OrderedFloat(*dist_sqr));
|
.min_by_key(|(_, dist_sqr)| OrderedFloat(*dist_sqr));
|
||||||
if let Some((pet_entity, _)) = closest_pet {
|
if let Some((pet_entity, _)) = closest_pet && client.state().read_storage::<Is<Mount>>().get(pet_entity).is_none() {
|
||||||
client.toggle_stay(pet_entity);
|
client.toggle_stay(pet_entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user