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:
TelepathicWalrus 2023-05-01 11:24:32 +01:00 committed by Maxicarlos08
parent 9597810e3d
commit d9d364fe79
No known key found for this signature in database
8 changed files with 50 additions and 30 deletions

View File

@ -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 {

View File

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

View File

@ -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,

View File

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

View File

@ -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,

View File

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

View File

@ -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(),

View File

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