Move stay position to agent

This commit is contained in:
TelepathicWalrus 2023-05-21 10:42:44 +01:00 committed by Maxicarlos08
parent 2cb8e2ca84
commit 4bdbb3ff6b
No known key found for this signature in database
11 changed files with 26 additions and 62 deletions

View File

@ -54,7 +54,6 @@ hud-mine-needs_unhandled_case = Needs ???
hud-talk = Talk hud-talk = Talk
hud-trade = Trade hud-trade = Trade
hud-mount = Mount hud-mount = Mount
hud-stay = Stay hud-stay-follow = Stay/Follow
hud-follow = Follow
hud-sit = Sit hud-sit = Sit
hud-steer = Steer hud-steer = Steer

View File

@ -46,7 +46,6 @@ macro_rules! synced_components {
beam_segment: BeamSegment, beam_segment: BeamSegment,
alignment: Alignment, alignment: Alignment,
stance: Stance, stance: Stance,
pet_state: PetState,
// TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum // TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum
// from other entities (e.g. just keys needed to show appearance // from other entities (e.g. just keys needed to show appearance
// based on their loadout). Also, it looks like this actually has // based on their loadout). Also, it looks like this actually has
@ -74,7 +73,6 @@ macro_rules! reexport_comps {
($($name:ident: $type:ident,)*) => { ($($name:ident: $type:ident,)*) => {
mod inner { mod inner {
pub use common::comp::*; pub use common::comp::*;
pub use common::comp::pet::PetState;
use common::link::Is; use common::link::Is;
use common::mounting::{Mount, Rider, VolumeRider}; use common::mounting::{Mount, Rider, VolumeRider};
// We alias these because the identifier used for the // We alias these because the identifier used for the
@ -106,11 +104,6 @@ synced_components!(reexport_comps);
use crate::sync::{NetSync, SyncFrom}; use crate::sync::{NetSync, SyncFrom};
// These are synced from any entity within range.
impl NetSync for PetState {
const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity;
}
impl NetSync for Body { impl NetSync for Body {
const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity; const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity;
} }

View File

@ -594,6 +594,7 @@ pub struct Agent {
/// required and reset each time the flee timer is reset. /// required and reset each time the flee timer is reset.
pub flee_from_pos: Option<Pos>, pub flee_from_pos: Option<Pos>,
pub awareness: Awareness, pub awareness: Awareness,
pub stay_pos: Option<Pos>,
/// Inputs sent up to rtsim /// Inputs sent up to rtsim
pub rtsim_outbox: Option<VecDeque<NpcInput>>, pub rtsim_outbox: Option<VecDeque<NpcInput>>,
} }
@ -699,6 +700,7 @@ impl Agent {
sounds_heard: Vec::new(), sounds_heard: Vec::new(),
position_pid_controller: None, position_pid_controller: None,
flee_from_pos: None, flee_from_pos: None,
stay_pos: None,
awareness: Awareness::new(0.0), awareness: Awareness::new(0.0),
rtsim_outbox: None, rtsim_outbox: None,
} }

View File

@ -1,7 +1,6 @@
use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small, Pos}; use crate::comp::{body::Body, phys::Mass, quadruped_medium, quadruped_small};
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use serde::{Deserialize, Serialize}; use specs::Component;
use specs::{Component, DerefFlaggedStorage};
use std::{num::NonZeroU64, sync::Arc}; use std::{num::NonZeroU64, sync::Arc};
pub type PetId = AtomicCell<Option<NonZeroU64>>; pub type PetId = AtomicCell<Option<NonZeroU64>>;
@ -108,12 +107,3 @@ impl Component for Pet {
// isn't worth using `DenseVecStorage` here. // isn't worth using `DenseVecStorage` here.
type Storage = specs::VecStorage<Self>; type Storage = specs::VecStorage<Self>;
} }
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct PetState {
pub stay_pos: Option<Pos>,
}
impl Component for PetState {
type Storage = DerefFlaggedStorage<Self>;
}

View File

@ -203,7 +203,6 @@ impl State {
ecs.register::<Is<Mount>>(); ecs.register::<Is<Mount>>();
ecs.register::<Is<Rider>>(); ecs.register::<Is<Rider>>();
ecs.register::<Is<VolumeRider>>(); ecs.register::<Is<VolumeRider>>();
ecs.register::<comp::pet::PetState>();
ecs.register::<comp::Mass>(); ecs.register::<comp::Mass>();
ecs.register::<comp::Density>(); ecs.register::<comp::Density>();
ecs.register::<comp::Collider>(); ecs.register::<comp::Collider>();

View File

@ -12,7 +12,6 @@ use common::{
}, },
slot::EquipSlot, slot::EquipSlot,
}, },
pet::PetState,
ActiveAbilities, Alignment, Body, CharacterState, Combo, Energy, Health, Inventory, ActiveAbilities, Alignment, Body, CharacterState, Combo, Energy, Health, Inventory,
LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Presence, Scale, SkillSet, Stance, LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Presence, Scale, SkillSet, Stance,
Stats, Vel, Stats, Vel,
@ -53,7 +52,6 @@ pub struct AgentData<'a> {
pub light_emitter: Option<&'a LightEmitter>, pub light_emitter: Option<&'a LightEmitter>,
pub glider_equipped: bool, pub glider_equipped: bool,
pub is_gliding: bool, pub is_gliding: 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,
@ -349,7 +347,6 @@ pub struct ReadData<'a> {
pub is_mounts: ReadStorage<'a, Is<Mount>>, pub is_mounts: ReadStorage<'a, Is<Mount>>,
pub is_riders: ReadStorage<'a, Is<Rider>>, pub is_riders: ReadStorage<'a, Is<Rider>>,
pub is_volume_riders: ReadStorage<'a, Is<VolumeRider>>, pub is_volume_riders: ReadStorage<'a, Is<VolumeRider>>,
pub pet_states: ReadStorage<'a, PetState>,
pub time_of_day: Read<'a, TimeOfDay>, pub time_of_day: Read<'a, TimeOfDay>,
pub light_emitter: ReadStorage<'a, LightEmitter>, pub light_emitter: ReadStorage<'a, LightEmitter>,
#[cfg(feature = "worldgen")] #[cfg(feature = "worldgen")]

View File

@ -10,7 +10,7 @@ use common::{
inventory::slot::EquipSlot, inventory::slot::EquipSlot,
item::{flatten_counted_items, MaterialStatManifest}, item::{flatten_counted_items, MaterialStatManifest},
loot_owner::LootOwnerKind, loot_owner::LootOwnerKind,
pet::{is_mountable, PetState}, pet::is_mountable,
tool::{AbilityMap, ToolKind}, tool::{AbilityMap, ToolKind},
Inventory, LootOwner, Pos, SkillGroupKind, Inventory, LootOwner, Pos, SkillGroupKind,
}, },
@ -134,7 +134,7 @@ pub fn handle_mount(server: &mut Server, rider: EcsEntity, mount: EcsEntity) {
let is_stay = state let is_stay = state
.ecs() .ecs()
.read_storage::<PetState>() .read_storage::<comp::Agent>()
.get(mount) .get(mount)
.and_then(|x| x.stay_pos) .and_then(|x| x.stay_pos)
.is_some(); .is_some();
@ -225,7 +225,7 @@ pub fn handle_toggle_stay(server: &mut Server, command_giver: EcsEntity, pet: Ec
} }
let prev_pet_pos = state let prev_pet_pos = state
.ecs() .ecs()
.read_storage::<PetState>() .read_storage::<comp::Agent>()
.get(pet) .get(pet)
.and_then(|s| s.stay_pos); .and_then(|s| s.stay_pos);
let mut new_pet_pos = None; let mut new_pet_pos = None;
@ -236,12 +236,11 @@ pub fn handle_toggle_stay(server: &mut Server, command_giver: EcsEntity, pet: Ec
&& within_mounting_range(positions.get(command_giver), positions.get(pet)) && within_mounting_range(positions.get(command_giver), positions.get(pet))
&& state.ecs().read_storage::<Is<Mount>>().get(pet).is_none() && state.ecs().read_storage::<Is<Mount>>().get(pet).is_none()
{ {
let _ = state state
.ecs() .ecs()
.write_storage::<PetState>() .write_storage::<comp::Agent>()
.insert(pet, PetState { .get_mut(pet)
stay_pos: new_pet_pos, .map(|s| s.stay_pos = new_pet_pos);
});
} }
} }

View File

@ -72,7 +72,6 @@ impl<'a> System<'a> for Sys {
!&read_data.is_mounts, !&read_data.is_mounts,
read_data.is_riders.maybe(), read_data.is_riders.maybe(),
read_data.is_volume_riders.maybe(), read_data.is_volume_riders.maybe(),
read_data.pet_states.maybe(),
), ),
) )
.par_join() .par_join()
@ -96,7 +95,7 @@ impl<'a> System<'a> for Sys {
light_emitter, light_emitter,
group, group,
rtsim_entity, rtsim_entity,
(_, is_rider, is_volume_rider, pet_state), (_, is_rider, is_volume_rider),
)| { )| {
let mut event_emitter = event_bus.emitter(); let mut event_emitter = event_bus.emitter();
let mut rng = thread_rng(); let mut rng = thread_rng();
@ -160,8 +159,6 @@ impl<'a> System<'a> for Sys {
matches!(&*item.kind(), comp::item::ItemKind::Glider) matches!(&*item.kind(), comp::item::ItemKind::Glider)
}); });
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(_))
@ -232,7 +229,6 @@ impl<'a> System<'a> for Sys {
light_emitter, light_emitter,
glider_equipped, glider_equipped,
is_gliding, is_gliding,
stay_pos,
health: read_data.healths.get(entity), health: read_data.healths.get(entity),
char_state, char_state,
active_abilities, active_abilities,

View File

@ -406,11 +406,11 @@ 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 stay = bdata.agent_data.stay_pos.is_some(); let stay = bdata.agent.stay_pos.is_some();
if stay { if stay {
let stay_pos = bdata.agent_data.stay_pos.map_or(Pos(Vec3::zero()), |v| v); let stay_pos = bdata.agent.stay_pos.map_or(Pos(Vec3::zero()), |v| v);
let distance_from_stay = stay_pos.0.distance_squared(bdata.agent_data.pos.0); let distance_from_stay = stay_pos.0.distance_squared(bdata.agent_data.pos.0);
bdata.controller.push_action(ControlAction::Sit);
if distance_from_stay > (MAX_STAY_DISTANCE).powi(2) { if distance_from_stay > (MAX_STAY_DISTANCE).powi(2) {
bdata.agent_data.follow( bdata.agent_data.follow(
bdata.agent, bdata.agent,
@ -421,6 +421,7 @@ fn follow_if_far_away(bdata: &mut BehaviorData) -> bool {
return true; return true;
} }
} else { } else {
bdata.controller.push_action(ControlAction::Stand);
let dist_sqrd = bdata.agent_data.pos.0.distance_squared(tgt_pos.0); 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) { if dist_sqrd > (MAX_PATROL_DIST * bdata.agent.psyche.idle_wander_factor).powi(2) {
bdata.agent_data.follow( bdata.agent_data.follow(
@ -449,7 +450,7 @@ fn attack_if_owner_hurt(bdata: &mut BehaviorData) -> bool {
} else { } else {
false false
}; };
let stay = bdata.agent_data.stay_pos.is_some(); let stay = bdata.agent.stay_pos.is_some();
if owner_recently_attacked && !stay { if owner_recently_attacked && !stay {
bdata.agent_data.attack_target_attacker( bdata.agent_data.attack_target_attacker(
bdata.agent, bdata.agent,

View File

@ -1,5 +1,5 @@
use common::{ use common::{
comp::{pet::PetState, Alignment, Pet, PhysicsState, Pos}, comp::{Agent, Alignment, Pet, PhysicsState, Pos},
terrain::TerrainGrid, terrain::TerrainGrid,
uid::IdMaps, uid::IdMaps,
}; };
@ -16,7 +16,7 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Pos>, WriteStorage<'a, Pos>,
ReadStorage<'a, Alignment>, ReadStorage<'a, Alignment>,
ReadStorage<'a, Pet>, ReadStorage<'a, Pet>,
ReadStorage<'a, PetState>, ReadStorage<'a, Agent>,
ReadStorage<'a, PhysicsState>, ReadStorage<'a, PhysicsState>,
Read<'a, IdMaps>, Read<'a, IdMaps>,
); );
@ -27,7 +27,7 @@ impl<'a> System<'a> for Sys {
fn run( fn run(
_job: &mut Job<Self>, _job: &mut Job<Self>,
(entities, terrain, mut positions, alignments, pets, pet_state, physics, id_maps): Self::SystemData, (entities, terrain, mut positions, alignments, pets, agn, physics, id_maps): Self::SystemData,
) { ) {
const LOST_PET_DISTANCE_THRESHOLD: f32 = 200.0; const LOST_PET_DISTANCE_THRESHOLD: f32 = 200.0;
@ -58,10 +58,7 @@ impl<'a> System<'a> for Sys {
.collect(); .collect();
for (pet_entity, owner_pos) in lost_pets.iter() { for (pet_entity, owner_pos) in lost_pets.iter() {
let stay = pet_state let stay = agn.get(*pet_entity).and_then(|x| x.stay_pos).is_some();
.get(*pet_entity)
.and_then(|f| f.stay_pos)
.is_some();
if let Some(mut pet_pos) = positions.get_mut(*pet_entity) && !stay{ if let Some(mut pet_pos) = positions.get_mut(*pet_entity) && !stay{
// Move the pets to their owner's position // Move the pets to their owner's position
// TODO: Create a teleportation event to handle this instead of // TODO: Create a teleportation event to handle this instead of

View File

@ -1504,7 +1504,6 @@ impl Hud {
let alignments = ecs.read_storage::<comp::Alignment>(); let alignments = ecs.read_storage::<comp::Alignment>();
let is_mounts = ecs.read_storage::<Is<Mount>>(); let is_mounts = ecs.read_storage::<Is<Mount>>();
let is_riders = ecs.read_storage::<Is<Rider>>(); let is_riders = ecs.read_storage::<Is<Rider>>();
let pet_state = ecs.read_storage::<comp::pet::PetState>();
let stances = ecs.read_storage::<comp::Stance>(); let stances = ecs.read_storage::<comp::Stance>();
let time = ecs.read_resource::<Time>(); let time = ecs.read_resource::<Time>();
@ -2426,24 +2425,16 @@ impl Hud {
)); ));
if !client.is_riding() if !client.is_riding()
&& is_mountable(body, bodies.get(client.entity())) && is_mountable(body, bodies.get(client.entity()))
&& pet_state.get(entity).and_then(|st| st.stay_pos).is_none()
{ {
options.push(( options.push((
GameInput::Mount, GameInput::Mount,
i18n.get_msg("hud-mount").to_string(), i18n.get_msg("hud-mount").to_string(),
)); ));
} }
if pet_state.get(entity).and_then(|st| st.stay_pos).is_some() {
options.push(( options.push((
GameInput::StayFollow, GameInput::StayFollow,
i18n.get_msg("hud-follow").to_string(), i18n.get_msg("hud-stay-follow").to_string(),
)); ));
} else {
options.push((
GameInput::StayFollow,
i18n.get_msg("hud-stay").to_string(),
));
}
} }
options options
}, },