mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Remove write to Body from Buff.
Also fix tests and add an inner PhysicsState type that is Copy, to make it easier to facilitate reading Last<PhysicsState> and read deltas.
This commit is contained in:
parent
8383a72818
commit
338b377ef4
@ -655,7 +655,7 @@ impl CharacterAbility {
|
|||||||
pub fn requirements_paid(&self, data: &JoinData, update: &mut StateUpdate) -> bool {
|
pub fn requirements_paid(&self, data: &JoinData, update: &mut StateUpdate) -> bool {
|
||||||
match self {
|
match self {
|
||||||
CharacterAbility::Roll { energy_cost, .. } => {
|
CharacterAbility::Roll { energy_cost, .. } => {
|
||||||
data.physics.on_ground.is_some()
|
data.physics.state.on_ground.is_some()
|
||||||
&& data.inputs.move_dir.magnitude_squared() > 0.25
|
&& data.inputs.move_dir.magnitude_squared() > 0.25
|
||||||
&& update.energy.try_change_by(-*energy_cost).is_ok()
|
&& update.energy.try_change_by(-*energy_cost).is_ok()
|
||||||
},
|
},
|
||||||
|
@ -100,8 +100,8 @@ pub use self::{
|
|||||||
ori::Ori,
|
ori::Ori,
|
||||||
pet::Pet,
|
pet::Pet,
|
||||||
phys::{
|
phys::{
|
||||||
Collider, Density, ForceUpdate, Immovable, Mass, PhysicsState, Pos, PosVelOriDefer,
|
Collider, Density, ForceUpdate, Immovable, Mass, PhysicsState, PhysicsStateFast, Pos,
|
||||||
PreviousPhysCache, Scale, Sticky, Vel,
|
PosVelOriDefer, PreviousPhysCache, Scale, Sticky, Vel,
|
||||||
},
|
},
|
||||||
player::DisconnectReason,
|
player::DisconnectReason,
|
||||||
player::{AliasError, Player, MAX_ALIAS_LEN},
|
player::{AliasError, Player, MAX_ALIAS_LEN},
|
||||||
|
@ -170,13 +170,13 @@ impl Component for Immovable {
|
|||||||
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
|
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PhysicsState
|
/// Cheaply copyable components of PhysicsState used for most delta
|
||||||
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
/// computations.
|
||||||
pub struct PhysicsState {
|
#[derive(Clone, Copy, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PhysicsStateFast {
|
||||||
pub on_ground: Option<Block>,
|
pub on_ground: Option<Block>,
|
||||||
pub on_ceiling: bool,
|
pub on_ceiling: bool,
|
||||||
pub on_wall: Option<Vec3<f32>>,
|
pub on_wall: Option<Vec3<f32>>,
|
||||||
pub touch_entities: HashSet<Uid>,
|
|
||||||
pub in_fluid: Option<Fluid>,
|
pub in_fluid: Option<Fluid>,
|
||||||
pub ground_vel: Vec3<f32>,
|
pub ground_vel: Vec3<f32>,
|
||||||
pub footwear: Friction,
|
pub footwear: Friction,
|
||||||
@ -184,6 +184,13 @@ pub struct PhysicsState {
|
|||||||
pub skating_active: bool,
|
pub skating_active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PhysicsState
|
||||||
|
#[derive(Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PhysicsState {
|
||||||
|
pub state: PhysicsStateFast,
|
||||||
|
pub touch_entities: HashSet<Uid>,
|
||||||
|
}
|
||||||
|
|
||||||
impl PhysicsState {
|
impl PhysicsState {
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
// Avoid allocation overhead!
|
// Avoid allocation overhead!
|
||||||
@ -191,12 +198,17 @@ impl PhysicsState {
|
|||||||
touch_entities.clear();
|
touch_entities.clear();
|
||||||
*self = Self {
|
*self = Self {
|
||||||
touch_entities,
|
touch_entities,
|
||||||
ground_vel: self.ground_vel, /* Preserved, since it's the velocity of the last
|
state: PhysicsStateFast {
|
||||||
* contact point */
|
ground_vel: self.state.ground_vel, /* Preserved, since it's the velocity of the
|
||||||
..Self::default()
|
* last
|
||||||
|
* contact point */
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PhysicsStateFast {
|
||||||
pub fn on_surface(&self) -> Option<Vec3<f32>> {
|
pub fn on_surface(&self) -> Option<Vec3<f32>> {
|
||||||
self.on_ground
|
self.on_ground
|
||||||
.map(|_| -Vec3::unit_z())
|
.map(|_| -Vec3::unit_z())
|
||||||
|
@ -226,6 +226,11 @@ pub enum ServerEvent {
|
|||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
update: comp::MapMarkerChange,
|
update: comp::MapMarkerChange,
|
||||||
},
|
},
|
||||||
|
/// FIXME: Remove this hack! It is only used for dousing flames.
|
||||||
|
UpdateBody {
|
||||||
|
entity: EcsEntity,
|
||||||
|
new_body: comp::Body,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -164,14 +164,14 @@ impl CharacterBehavior for Data {
|
|||||||
.prerotated(pitch)
|
.prerotated(pitch)
|
||||||
};
|
};
|
||||||
// Velocity relative to the current ground
|
// Velocity relative to the current ground
|
||||||
let rel_vel = data.vel.0 - data.physics.ground_vel;
|
let rel_vel = data.vel.0 - data.physics.state.ground_vel;
|
||||||
// Gets offsets
|
// Gets offsets
|
||||||
let body_offsets = beam_offsets(
|
let body_offsets = beam_offsets(
|
||||||
data.body,
|
data.body,
|
||||||
data.inputs.look_dir,
|
data.inputs.look_dir,
|
||||||
data.ori.look_vec(),
|
data.ori.look_vec(),
|
||||||
rel_vel,
|
rel_vel,
|
||||||
data.physics.on_ground,
|
data.physics.state.on_ground,
|
||||||
);
|
);
|
||||||
let pos = Pos(data.pos.0 + body_offsets);
|
let pos = Pos(data.pos.0 + body_offsets);
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ impl CharacterBehavior for Data {
|
|||||||
|
|
||||||
// If no wall is in front of character or we stopped climbing;
|
// If no wall is in front of character or we stopped climbing;
|
||||||
let (wall_dir, climb) = if let (Some(wall_dir), Some(climb), None) = (
|
let (wall_dir, climb) = if let (Some(wall_dir), Some(climb), None) = (
|
||||||
data.physics.on_wall,
|
data.physics.state.on_wall,
|
||||||
data.inputs.climb,
|
data.inputs.climb,
|
||||||
data.physics.on_ground,
|
data.physics.state.on_ground,
|
||||||
) {
|
) {
|
||||||
(wall_dir, climb)
|
(wall_dir, climb)
|
||||||
} else {
|
} else {
|
||||||
@ -102,7 +102,7 @@ impl CharacterBehavior for Data {
|
|||||||
// Smooth orientation
|
// Smooth orientation
|
||||||
data.ori.slerped_towards(
|
data.ori.slerped_towards(
|
||||||
Ori::from(ori_dir),
|
Ori::from(ori_dir),
|
||||||
if data.physics.on_ground.is_some() {
|
if data.physics.state.on_ground.is_some() {
|
||||||
9.0
|
9.0
|
||||||
} else {
|
} else {
|
||||||
2.0
|
2.0
|
||||||
|
@ -19,7 +19,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if data.physics.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
if data.physics.state.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||||
update.character = CharacterState::Idle(idle::Data::default());
|
update.character = CharacterState::Idle(idle::Data::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,11 +79,11 @@ impl CharacterBehavior for Data {
|
|||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
// If player is on ground, end glide
|
// If player is on ground, end glide
|
||||||
if data.physics.on_ground.is_some()
|
if data.physics.state.on_ground.is_some()
|
||||||
&& (data.vel.0 - data.physics.ground_vel).magnitude_squared() < 2_f32.powi(2)
|
&& (data.vel.0 - data.physics.state.ground_vel).magnitude_squared() < 2_f32.powi(2)
|
||||||
{
|
{
|
||||||
update.character = CharacterState::GlideWield(glide_wield::Data::from(data));
|
update.character = CharacterState::GlideWield(glide_wield::Data::from(data));
|
||||||
} else if data.physics.in_liquid().is_some()
|
} else if data.physics.state.in_liquid().is_some()
|
||||||
|| data
|
|| data
|
||||||
.inventory
|
.inventory
|
||||||
.and_then(|inv| inv.equipped(EquipSlot::Glider))
|
.and_then(|inv| inv.equipped(EquipSlot::Glider))
|
||||||
@ -93,6 +93,7 @@ impl CharacterBehavior for Data {
|
|||||||
} else if !handle_climb(data, &mut update) {
|
} else if !handle_climb(data, &mut update) {
|
||||||
let air_flow = data
|
let air_flow = data
|
||||||
.physics
|
.physics
|
||||||
|
.state
|
||||||
.in_fluid
|
.in_fluid
|
||||||
.map(|fluid| fluid.relative_flow(data.vel))
|
.map(|fluid| fluid.relative_flow(data.vel))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
@ -171,7 +172,7 @@ impl CharacterBehavior for Data {
|
|||||||
Quaternion::rotation_3d(
|
Quaternion::rotation_3d(
|
||||||
PI / 2.0
|
PI / 2.0
|
||||||
* accel_factor
|
* accel_factor
|
||||||
* if data.physics.on_ground.is_some() {
|
* if data.physics.state.on_ground.is_some() {
|
||||||
-1.0
|
-1.0
|
||||||
} else {
|
} else {
|
||||||
1.0
|
1.0
|
||||||
|
@ -49,7 +49,7 @@ impl CharacterBehavior for Data {
|
|||||||
// If still in this state, do the things
|
// If still in this state, do the things
|
||||||
if matches!(update.character, CharacterState::GlideWield(_)) {
|
if matches!(update.character, CharacterState::GlideWield(_)) {
|
||||||
// If not on the ground while wielding glider enter gliding state
|
// If not on the ground while wielding glider enter gliding state
|
||||||
update.character = if data.physics.on_ground.is_none() {
|
update.character = if data.physics.state.on_ground.is_none() {
|
||||||
CharacterState::Glide(glide::Data::new(
|
CharacterState::Glide(glide::Data::new(
|
||||||
self.span_length,
|
self.span_length,
|
||||||
self.chord_length,
|
self.chord_length,
|
||||||
@ -60,7 +60,7 @@ impl CharacterBehavior for Data {
|
|||||||
.inventory
|
.inventory
|
||||||
.and_then(|inv| inv.equipped(EquipSlot::Glider))
|
.and_then(|inv| inv.equipped(EquipSlot::Glider))
|
||||||
.is_some()
|
.is_some()
|
||||||
&& data.physics.in_liquid().map_or(true, |depth| depth < 0.5)
|
&& data.physics.state.in_liquid().map_or(true, |depth| depth < 0.5)
|
||||||
{
|
{
|
||||||
CharacterState::GlideWield(Self {
|
CharacterState::GlideWield(Self {
|
||||||
// Glider tilt follows look dir
|
// Glider tilt follows look dir
|
||||||
|
@ -30,7 +30,7 @@ impl CharacterBehavior for Data {
|
|||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if self.is_sneaking
|
if self.is_sneaking
|
||||||
&& (data.physics.on_ground.is_none() || data.physics.in_liquid().is_some())
|
&& (data.physics.state.on_ground.is_none() || data.physics.state.in_liquid().is_some())
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Idle(Data {
|
update.character = CharacterState::Idle(Data {
|
||||||
is_sneaking: false,
|
is_sneaking: false,
|
||||||
|
@ -90,7 +90,7 @@ impl CharacterBehavior for Data {
|
|||||||
timer: tick_attack_or_default(data, self.timer, None),
|
timer: tick_attack_or_default(data, self.timer, None),
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else if data.physics.on_ground.is_some() | data.physics.in_liquid().is_some() {
|
} else if data.physics.state.on_ground.is_some() | data.physics.state.in_liquid().is_some() {
|
||||||
// Transitions to swing portion of state upon hitting ground
|
// Transitions to swing portion of state upon hitting ground
|
||||||
update.character = CharacterState::LeapMelee(Data {
|
update.character = CharacterState::LeapMelee(Data {
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
@ -19,7 +19,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
// Try to Fall/Stand up/Move
|
// Try to Fall/Stand up/Move
|
||||||
if data.physics.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
if data.physics.state.on_ground.is_none() || data.inputs.move_dir.magnitude_squared() > 0.0 {
|
||||||
update.character = CharacterState::Idle(idle::Data::default());
|
update.character = CharacterState::Idle(idle::Data::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_wield(data, &mut update);
|
handle_wield(data, &mut update);
|
||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
if !data.physics.skating_active {
|
if !data.physics.state.skating_active {
|
||||||
update.character = CharacterState::Idle(idle::Data {
|
update.character = CharacterState::Idle(idle::Data {
|
||||||
is_sneaking: false,
|
is_sneaking: false,
|
||||||
footwear: Some(self.footwear),
|
footwear: Some(self.footwear),
|
||||||
|
@ -62,7 +62,7 @@ impl CharacterBehavior for Data {
|
|||||||
match self.static_data.movement_behavior {
|
match self.static_data.movement_behavior {
|
||||||
MovementBehavior::ForwardGround | MovementBehavior::Stationary => {},
|
MovementBehavior::ForwardGround | MovementBehavior::Stationary => {},
|
||||||
MovementBehavior::AxeHover => {
|
MovementBehavior::AxeHover => {
|
||||||
update.movement = update.movement.with_movement(if data.physics.on_ground.is_some() {
|
update.movement = update.movement.with_movement(if data.physics.state.on_ground.is_some() {
|
||||||
// TODO: Just remove axehover entirely with axe rework, it's really janky
|
// TODO: Just remove axehover entirely with axe rework, it's really janky
|
||||||
// TODO: Should 5 even be used here, or should body accel be used? Maybe just call handle_move?
|
// TODO: Should 5 even be used here, or should body accel be used? Maybe just call handle_move?
|
||||||
let dir = Dir::from_unnormalized(data.inputs.move_dir.with_z(0.0));
|
let dir = Dir::from_unnormalized(data.inputs.move_dir.with_z(0.0));
|
||||||
|
@ -327,7 +327,7 @@ pub fn handle_skating(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
footwear,
|
footwear,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if data.physics.skating_active {
|
if data.physics.state.skating_active {
|
||||||
update.character =
|
update.character =
|
||||||
CharacterState::Skate(skate::Data::new(data, footwear.unwrap_or(Friction::Normal)));
|
CharacterState::Skate(skate::Data::new(data, footwear.unwrap_or(Friction::Normal)));
|
||||||
}
|
}
|
||||||
@ -338,16 +338,17 @@ pub fn handle_skating(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
pub fn handle_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32) {
|
pub fn handle_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32) {
|
||||||
let submersion = data
|
let submersion = data
|
||||||
.physics
|
.physics
|
||||||
|
.state
|
||||||
.in_liquid()
|
.in_liquid()
|
||||||
.map(|depth| depth / data.body.height());
|
.map(|depth| depth / data.body.height());
|
||||||
|
|
||||||
if input_is_pressed(data, InputKind::Fly)
|
if input_is_pressed(data, InputKind::Fly)
|
||||||
&& submersion.map_or(true, |sub| sub < 1.0)
|
&& submersion.map_or(true, |sub| sub < 1.0)
|
||||||
&& (data.physics.on_ground.is_none() || data.body.jump_impulse().is_none())
|
&& (data.physics.state.on_ground.is_none() || data.body.jump_impulse().is_none())
|
||||||
&& data.body.fly_thrust().is_some()
|
&& data.body.fly_thrust().is_some()
|
||||||
{
|
{
|
||||||
fly_move(data, update, efficiency);
|
fly_move(data, update, efficiency);
|
||||||
} else if let Some(submersion) = (data.physics.on_ground.is_none()
|
} else if let Some(submersion) = (data.physics.state.on_ground.is_none()
|
||||||
&& data.body.swim_thrust().is_some())
|
&& data.body.swim_thrust().is_some())
|
||||||
.then_some(submersion)
|
.then_some(submersion)
|
||||||
.flatten()
|
.flatten()
|
||||||
@ -362,7 +363,7 @@ pub fn handle_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f3
|
|||||||
fn basic_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32) {
|
fn basic_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32) {
|
||||||
let efficiency = efficiency * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
let efficiency = efficiency * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
||||||
|
|
||||||
let accel = if let Some(block) = data.physics.on_ground {
|
let accel = if let Some(block) = data.physics.state.on_ground {
|
||||||
// FRIC_GROUND temporarily used to normalize things around expected values
|
// FRIC_GROUND temporarily used to normalize things around expected values
|
||||||
data.body.base_accel() * block.get_traction() * block.get_friction() / FRIC_GROUND
|
data.body.base_accel() * block.get_traction() * block.get_friction() / FRIC_GROUND
|
||||||
} else {
|
} else {
|
||||||
@ -409,7 +410,7 @@ pub fn handle_forced_movement(
|
|||||||
match movement {
|
match movement {
|
||||||
ForcedMovement::Forward { strength } => {
|
ForcedMovement::Forward { strength } => {
|
||||||
let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier;
|
||||||
if let Some(accel) = data.physics.on_ground.map(|block| {
|
if let Some(accel) = data.physics.state.on_ground.map(|block| {
|
||||||
// FRIC_GROUND temporarily used to normalize things around expected values
|
// FRIC_GROUND temporarily used to normalize things around expected values
|
||||||
data.body.base_accel() * block.get_traction() * block.get_friction() / FRIC_GROUND
|
data.body.base_accel() * block.get_traction() * block.get_friction() / FRIC_GROUND
|
||||||
}) {
|
}) {
|
||||||
@ -474,7 +475,7 @@ pub fn handle_orientation(
|
|||||||
// unit is multiples of 180°
|
// unit is multiples of 180°
|
||||||
let half_turns_per_tick = data.body.base_ori_rate()
|
let half_turns_per_tick = data.body.base_ori_rate()
|
||||||
* efficiency
|
* efficiency
|
||||||
* if data.physics.on_ground.is_some() {
|
* if data.physics.state.on_ground.is_some() {
|
||||||
1.0
|
1.0
|
||||||
} else {
|
} else {
|
||||||
0.2
|
0.2
|
||||||
@ -579,7 +580,7 @@ pub fn fly_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32)
|
|||||||
Density((update.density.0 + data.dt.0 * rate * change).clamp(min, max))
|
Density((update.density.0 + data.dt.0 * rate * change).clamp(min, max))
|
||||||
};
|
};
|
||||||
let def_density = ship.density().0;
|
let def_density = ship.density().0;
|
||||||
if data.physics.in_liquid().is_some() {
|
if data.physics.state.in_liquid().is_some() {
|
||||||
let hull_density = ship.hull_density().0;
|
let hull_density = ship.hull_density().0;
|
||||||
update.density.0 =
|
update.density.0 =
|
||||||
regulate_density(def_density * 0.6, hull_density, hull_density, 25.0).0;
|
regulate_density(def_density * 0.6, hull_density, hull_density, 25.0).0;
|
||||||
@ -660,25 +661,25 @@ pub fn attempt_wield(data: &JoinData<'_>, update: &mut StateUpdate) {
|
|||||||
|
|
||||||
/// Checks that player can `Sit` and updates `CharacterState` if so
|
/// Checks that player can `Sit` and updates `CharacterState` if so
|
||||||
pub fn attempt_sit(data: &JoinData<'_>, update: &mut StateUpdate) {
|
pub fn attempt_sit(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground.is_some() {
|
if data.physics.state.on_ground.is_some() {
|
||||||
update.character = CharacterState::Sit;
|
update.character = CharacterState::Sit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_dance(data: &JoinData<'_>, update: &mut StateUpdate) {
|
pub fn attempt_dance(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground.is_some() && data.body.is_humanoid() {
|
if data.physics.state.on_ground.is_some() && data.body.is_humanoid() {
|
||||||
update.character = CharacterState::Dance;
|
update.character = CharacterState::Dance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_talk(data: &JoinData<'_>, update: &mut StateUpdate) {
|
pub fn attempt_talk(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground.is_some() {
|
if data.physics.state.on_ground.is_some() {
|
||||||
update.character = CharacterState::Talk;
|
update.character = CharacterState::Talk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attempt_sneak(data: &JoinData<'_>, update: &mut StateUpdate) {
|
pub fn attempt_sneak(data: &JoinData<'_>, update: &mut StateUpdate) {
|
||||||
if data.physics.on_ground.is_some() && data.body.is_humanoid() {
|
if data.physics.state.on_ground.is_some() && data.body.is_humanoid() {
|
||||||
update.character = Idle(idle::Data {
|
update.character = Idle(idle::Data {
|
||||||
is_sneaking: true,
|
is_sneaking: true,
|
||||||
footwear: data.character.footwear(),
|
footwear: data.character.footwear(),
|
||||||
@ -689,10 +690,11 @@ pub fn attempt_sneak(data: &JoinData<'_>, update: &mut StateUpdate) {
|
|||||||
/// Checks that player can `Climb` and updates `CharacterState` if so
|
/// Checks that player can `Climb` and updates `CharacterState` if so
|
||||||
pub fn handle_climb(data: &JoinData<'_>, update: &mut StateUpdate) -> bool {
|
pub fn handle_climb(data: &JoinData<'_>, update: &mut StateUpdate) -> bool {
|
||||||
if data.inputs.climb.is_some()
|
if data.inputs.climb.is_some()
|
||||||
&& data.physics.on_wall.is_some()
|
&& data.physics.state.on_wall.is_some()
|
||||||
&& data.physics.on_ground.is_none()
|
&& data.physics.state.on_ground.is_none()
|
||||||
&& !data
|
&& !data
|
||||||
.physics
|
.physics
|
||||||
|
.state
|
||||||
.in_liquid()
|
.in_liquid()
|
||||||
.map(|depth| depth > 1.0)
|
.map(|depth| depth > 1.0)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
@ -708,9 +710,9 @@ pub fn handle_climb(data: &JoinData<'_>, update: &mut StateUpdate) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_wallrun(data: &JoinData<'_>, update: &mut StateUpdate) -> bool {
|
pub fn handle_wallrun(data: &JoinData<'_>, update: &mut StateUpdate) -> bool {
|
||||||
if data.physics.on_wall.is_some()
|
if data.physics.state.on_wall.is_some()
|
||||||
&& data.physics.on_ground.is_none()
|
&& data.physics.state.on_ground.is_none()
|
||||||
&& data.physics.in_liquid().is_none()
|
&& data.physics.state.in_liquid().is_none()
|
||||||
&& data.body.can_climb()
|
&& data.body.can_climb()
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Wallrun(wallrun::Data);
|
update.character = CharacterState::Wallrun(wallrun::Data);
|
||||||
@ -895,6 +897,7 @@ pub fn attempt_glide_wield(
|
|||||||
.is_some()
|
.is_some()
|
||||||
&& !data
|
&& !data
|
||||||
.physics
|
.physics
|
||||||
|
.state
|
||||||
.in_liquid()
|
.in_liquid()
|
||||||
.map(|depth| depth > 1.0)
|
.map(|depth| depth > 1.0)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
@ -916,7 +919,7 @@ pub fn handle_jump(
|
|||||||
_update: &mut StateUpdate,
|
_update: &mut StateUpdate,
|
||||||
strength: f32,
|
strength: f32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
(input_is_pressed(data, InputKind::Jump) && data.physics.on_ground.is_some())
|
(input_is_pressed(data, InputKind::Jump) && data.physics.state.on_ground.is_some())
|
||||||
.then(|| data.body.jump_impulse())
|
.then(|| data.body.jump_impulse())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|impulse| {
|
.map(|impulse| {
|
||||||
|
@ -33,9 +33,9 @@ impl CharacterBehavior for Data {
|
|||||||
// fall off wall, hit ground, or enter water
|
// fall off wall, hit ground, or enter water
|
||||||
// TODO: Rugged way to determine when state change occurs and we need to leave
|
// TODO: Rugged way to determine when state change occurs and we need to leave
|
||||||
// this state
|
// this state
|
||||||
if data.physics.on_wall.is_none()
|
if data.physics.state.on_wall.is_none()
|
||||||
|| data.physics.on_ground.is_some()
|
|| data.physics.state.on_ground.is_some()
|
||||||
|| data.physics.in_liquid().is_some()
|
|| data.physics.state.in_liquid().is_some()
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Idle(idle::Data::default());
|
update.character = CharacterState::Idle(idle::Data::default());
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ impl CharacterBehavior for Data {
|
|||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
if self.is_sneaking
|
if self.is_sneaking
|
||||||
&& (data.physics.on_ground.is_none() || data.physics.in_liquid().is_some())
|
&& (data.physics.state.on_ground.is_none() || data.physics.state.in_liquid().is_some())
|
||||||
{
|
{
|
||||||
update.character = CharacterState::Wielding(Data { is_sneaking: false });
|
update.character = CharacterState::Wielding(Data { is_sneaking: false });
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ impl CharacterBehavior for Data {
|
|||||||
|
|
||||||
fn sneak(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
fn sneak(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
|
||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
if data.physics.on_ground.is_some() && data.body.is_humanoid() {
|
if data.physics.state.on_ground.is_some() && data.body.is_humanoid() {
|
||||||
update.character = CharacterState::Wielding(Data { is_sneaking: true });
|
update.character = CharacterState::Wielding(Data { is_sneaking: true });
|
||||||
}
|
}
|
||||||
update
|
update
|
||||||
|
@ -575,7 +575,8 @@ impl State {
|
|||||||
match event {
|
match event {
|
||||||
LocalEvent::Jump(entity, impulse) => {
|
LocalEvent::Jump(entity, impulse) => {
|
||||||
if let Some(vel) = velocities.get_mut(entity) {
|
if let Some(vel) = velocities.get_mut(entity) {
|
||||||
vel.0.z = impulse + physics.get(entity).map_or(0.0, |ps| ps.ground_vel.z);
|
vel.0.z =
|
||||||
|
impulse + physics.get(entity).map_or(0.0, |ps| ps.state.ground_vel.z);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LocalEvent::ApplyImpulse { entity, impulse } => {
|
LocalEvent::ApplyImpulse { entity, impulse } => {
|
||||||
|
@ -31,6 +31,7 @@ pub struct ReadData<'a> {
|
|||||||
entities: Entities<'a>,
|
entities: Entities<'a>,
|
||||||
dt: Read<'a, DeltaTime>,
|
dt: Read<'a, DeltaTime>,
|
||||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||||
|
bodies: ReadStorage<'a, Body>,
|
||||||
inventories: ReadStorage<'a, Inventory>,
|
inventories: ReadStorage<'a, Inventory>,
|
||||||
healths: ReadStorage<'a, Health>,
|
healths: ReadStorage<'a, Health>,
|
||||||
energies: ReadStorage<'a, Energy>,
|
energies: ReadStorage<'a, Energy>,
|
||||||
@ -48,7 +49,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadData<'a>,
|
ReadData<'a>,
|
||||||
WriteStorage<'a, Buffs>,
|
WriteStorage<'a, Buffs>,
|
||||||
WriteStorage<'a, Stats>,
|
WriteStorage<'a, Stats>,
|
||||||
WriteStorage<'a, Body>,
|
|
||||||
WriteStorage<'a, LightEmitter>,
|
WriteStorage<'a, LightEmitter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
job: &mut Job<Self>,
|
job: &mut Job<Self>,
|
||||||
(read_data, mut buffs, mut stats, mut bodies, mut light_emitters): Self::SystemData,
|
(read_data, mut buffs, mut stats, mut light_emitters): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
let mut server_emitter = read_data.server_bus.emitter();
|
let mut server_emitter = read_data.server_bus.emitter();
|
||||||
let dt = read_data.dt.0;
|
let dt = read_data.dt.0;
|
||||||
@ -74,7 +74,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
prof_span!(guard_, "buff campfire deactivate");
|
prof_span!(guard_, "buff campfire deactivate");
|
||||||
(
|
(
|
||||||
&read_data.entities,
|
&read_data.entities,
|
||||||
&mut bodies,
|
&read_data.bodies,
|
||||||
&read_data.physics_states,
|
&read_data.physics_states,
|
||||||
light_emitters_mask, //to improve iteration speed
|
light_emitters_mask, //to improve iteration speed
|
||||||
)
|
)
|
||||||
@ -82,16 +82,19 @@ impl<'a> System<'a> for Sys {
|
|||||||
.filter(|(_, body, physics_state, _)| {
|
.filter(|(_, body, physics_state, _)| {
|
||||||
matches!(&**body, Body::Object(object::Body::CampfireLit))
|
matches!(&**body, Body::Object(object::Body::CampfireLit))
|
||||||
&& matches!(
|
&& matches!(
|
||||||
physics_state.in_fluid,
|
physics_state.state.in_fluid,
|
||||||
Some(Fluid::Liquid {
|
Some(Fluid::Liquid {
|
||||||
kind: LiquidKind::Water,
|
kind: LiquidKind::Water,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.for_each(|(e, mut body, _, _)| {
|
.for_each(|(entity, _, _, _)| {
|
||||||
*body = Body::Object(object::Body::Campfire);
|
server_emitter.emit(ServerEvent::UpdateBody {
|
||||||
light_emitters.remove(e);
|
entity,
|
||||||
|
new_body: Body::Object(object::Body::Campfire),
|
||||||
|
});
|
||||||
|
light_emitters.remove(entity);
|
||||||
});
|
});
|
||||||
drop(guard_);
|
drop(guard_);
|
||||||
|
|
||||||
@ -108,7 +111,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Apply buffs to entity based off of their current physics_state
|
// Apply buffs to entity based off of their current physics_state
|
||||||
if let Some(physics_state) = physics_state {
|
if let Some(physics_state) = physics_state {
|
||||||
if matches!(
|
if matches!(
|
||||||
physics_state.on_ground.and_then(|b| b.get_sprite()),
|
physics_state.state.on_ground.and_then(|b| b.get_sprite()),
|
||||||
Some(SpriteKind::EnsnaringVines) | Some(SpriteKind::EnsnaringWeb)
|
Some(SpriteKind::EnsnaringVines) | Some(SpriteKind::EnsnaringWeb)
|
||||||
) {
|
) {
|
||||||
// If on ensnaring vines, apply ensnared debuff
|
// If on ensnaring vines, apply ensnared debuff
|
||||||
@ -123,7 +126,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if matches!(
|
if matches!(
|
||||||
physics_state.on_ground.and_then(|b| b.get_sprite()),
|
physics_state.state.on_ground.and_then(|b| b.get_sprite()),
|
||||||
Some(SpriteKind::SeaUrchin)
|
Some(SpriteKind::SeaUrchin)
|
||||||
) {
|
) {
|
||||||
// If touching Sea Urchin apply Bleeding buff
|
// If touching Sea Urchin apply Bleeding buff
|
||||||
@ -138,7 +141,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if matches!(
|
if matches!(
|
||||||
physics_state.in_fluid,
|
physics_state.state.in_fluid,
|
||||||
Some(Fluid::Liquid {
|
Some(Fluid::Liquid {
|
||||||
kind: LiquidKind::Lava,
|
kind: LiquidKind::Lava,
|
||||||
..
|
..
|
||||||
@ -155,7 +158,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
physics_state.in_fluid,
|
physics_state.state.in_fluid,
|
||||||
Some(Fluid::Liquid {
|
Some(Fluid::Liquid {
|
||||||
kind: LiquidKind::Water,
|
kind: LiquidKind::Water,
|
||||||
..
|
..
|
||||||
|
@ -4,7 +4,8 @@ use common::{
|
|||||||
fluid_dynamics::{Fluid, LiquidKind, Wings},
|
fluid_dynamics::{Fluid, LiquidKind, Wings},
|
||||||
inventory::item::armor::Friction,
|
inventory::item::armor::Friction,
|
||||||
Body, CharacterState, Collider, Density, Immovable, Mass, MovementState, Ori, PhysicsState,
|
Body, CharacterState, Collider, Density, Immovable, Mass, MovementState, Ori, PhysicsState,
|
||||||
Pos, PosVelOriDefer, PreviousPhysCache, Projectile, Scale, Stats, Sticky, Vel,
|
PhysicsStateFast, Pos, PosVelOriDefer, PreviousPhysCache, Projectile, Scale, Stats, Sticky,
|
||||||
|
Vel,
|
||||||
},
|
},
|
||||||
consts::{AIR_DENSITY, FRIC_GROUND, GRAVITY},
|
consts::{AIR_DENSITY, FRIC_GROUND, GRAVITY},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
@ -388,7 +389,7 @@ impl<'a> PhysicsRead<'a> {
|
|||||||
)| {
|
)| {
|
||||||
let is_sticky = sticky.is_some();
|
let is_sticky = sticky.is_some();
|
||||||
let is_immovable = immovable.is_some();
|
let is_immovable = immovable.is_some();
|
||||||
let is_mid_air = physics.on_surface().is_none();
|
let is_mid_air = physics.state.on_surface().is_none();
|
||||||
let mut entity_entity_collision_checks = 0;
|
let mut entity_entity_collision_checks = 0;
|
||||||
let mut entity_entity_collisions = 0;
|
let mut entity_entity_collisions = 0;
|
||||||
|
|
||||||
@ -667,7 +668,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// Apply physics only if in a loaded chunk
|
// Apply physics only if in a loaded chunk
|
||||||
if in_loaded_chunk
|
if in_loaded_chunk
|
||||||
// And not already stuck on a block (e.g., for arrows)
|
// And not already stuck on a block (e.g., for arrows)
|
||||||
&& !(physics_state.on_surface().is_some() && sticky.is_some())
|
&& !(physics_state.state.on_surface().is_some() && sticky.is_some())
|
||||||
{
|
{
|
||||||
// Clamp dt to an effective 10 TPS, to prevent gravity
|
// Clamp dt to an effective 10 TPS, to prevent gravity
|
||||||
// from slamming the players into the floor when
|
// from slamming the players into the floor when
|
||||||
@ -675,7 +676,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// to lag (as observed in the 0.9 release party).
|
// to lag (as observed in the 0.9 release party).
|
||||||
let dt = DeltaTime(read.dt.0.min(0.1));
|
let dt = DeltaTime(read.dt.0.min(0.1));
|
||||||
|
|
||||||
match physics_state.in_fluid {
|
match physics_state.state.in_fluid {
|
||||||
None => {
|
None => {
|
||||||
vel.0.z -= dt.0 * GRAVITY;
|
vel.0.z -= dt.0 * GRAVITY;
|
||||||
},
|
},
|
||||||
@ -814,8 +815,8 @@ impl<'a> PhysicsData<'a> {
|
|||||||
|
|
||||||
if let Some(state) = character_state {
|
if let Some(state) = character_state {
|
||||||
let footwear = state.footwear().unwrap_or(Friction::Normal);
|
let footwear = state.footwear().unwrap_or(Friction::Normal);
|
||||||
if footwear != physics_state.footwear {
|
if footwear != physics_state.state.footwear {
|
||||||
physics_state.footwear = footwear;
|
physics_state.state.footwear = footwear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +850,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// velocities or entirely broken position snapping.
|
// velocities or entirely broken position snapping.
|
||||||
let mut tgt_pos = pos.0 + pos_delta;
|
let mut tgt_pos = pos.0 + pos_delta;
|
||||||
|
|
||||||
let was_on_ground = physics_state.on_ground.is_some();
|
let was_on_ground = physics_state.state.on_ground.is_some();
|
||||||
let block_snap =
|
let block_snap =
|
||||||
body.map_or(false, |b| !matches!(b, Body::Object(_) | Body::Ship(_)));
|
body.map_or(false, |b| !matches!(b, Body::Object(_) | Body::Ship(_)));
|
||||||
let climbing =
|
let climbing =
|
||||||
@ -876,7 +877,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
&mut cpos,
|
&mut cpos,
|
||||||
tgt_pos,
|
tgt_pos,
|
||||||
&mut vel,
|
&mut vel,
|
||||||
physics_state,
|
&mut physics_state.state,
|
||||||
Vec3::zero(),
|
Vec3::zero(),
|
||||||
&read.dt,
|
&read.dt,
|
||||||
was_on_ground,
|
was_on_ground,
|
||||||
@ -909,7 +910,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
&mut cpos,
|
&mut cpos,
|
||||||
tgt_pos,
|
tgt_pos,
|
||||||
&mut vel,
|
&mut vel,
|
||||||
physics_state,
|
&mut physics_state.state,
|
||||||
Vec3::zero(),
|
Vec3::zero(),
|
||||||
&read.dt,
|
&read.dt,
|
||||||
was_on_ground,
|
was_on_ground,
|
||||||
@ -921,8 +922,8 @@ impl<'a> PhysicsData<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Sticky things shouldn't move when on a surface
|
// Sticky things shouldn't move when on a surface
|
||||||
if physics_state.on_surface().is_some() && sticky.is_some() {
|
if physics_state.state.on_surface().is_some() && sticky.is_some() {
|
||||||
vel.0 = physics_state.ground_vel;
|
vel.0 = physics_state.state.ground_vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgt_pos = cpos.0;
|
tgt_pos = cpos.0;
|
||||||
@ -982,13 +983,13 @@ impl<'a> PhysicsData<'a> {
|
|||||||
> block_rpos.xy().map(|e| e.abs()).reduce_partial_max()
|
> block_rpos.xy().map(|e| e.abs()).reduce_partial_max()
|
||||||
{
|
{
|
||||||
if block_rpos.z > 0.0 {
|
if block_rpos.z > 0.0 {
|
||||||
physics_state.on_ground = block.copied();
|
physics_state.state.on_ground = block.copied();
|
||||||
} else {
|
} else {
|
||||||
physics_state.on_ceiling = true;
|
physics_state.state.on_ceiling = true;
|
||||||
}
|
}
|
||||||
vel.0.z = 0.0;
|
vel.0.z = 0.0;
|
||||||
} else {
|
} else {
|
||||||
physics_state.on_wall =
|
physics_state.state.on_wall =
|
||||||
Some(if block_rpos.x.abs() > block_rpos.y.abs() {
|
Some(if block_rpos.x.abs() > block_rpos.y.abs() {
|
||||||
vel.0.x = 0.0;
|
vel.0.x = 0.0;
|
||||||
Vec3::unit_x() * -block_rpos.x.signum()
|
Vec3::unit_x() * -block_rpos.x.signum()
|
||||||
@ -1000,11 +1001,11 @@ impl<'a> PhysicsData<'a> {
|
|||||||
|
|
||||||
// Sticky things shouldn't move
|
// Sticky things shouldn't move
|
||||||
if sticky.is_some() {
|
if sticky.is_some() {
|
||||||
vel.0 = physics_state.ground_vel;
|
vel.0 = physics_state.state.ground_vel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
physics_state.in_fluid = read
|
physics_state.state.in_fluid = read
|
||||||
.terrain
|
.terrain
|
||||||
.get(pos.0.map(|e| e.floor() as i32))
|
.get(pos.0.map(|e| e.floor() as i32))
|
||||||
.ok()
|
.ok()
|
||||||
@ -1015,7 +1016,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
vel: Vel::zero(),
|
vel: Vel::zero(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.or_else(|| match physics_state.in_fluid {
|
.or_else(|| match physics_state.state.in_fluid {
|
||||||
Some(Fluid::Liquid { .. }) | None => Some(Fluid::Air {
|
Some(Fluid::Liquid { .. }) | None => Some(Fluid::Air {
|
||||||
elevation: pos.0.z,
|
elevation: pos.0.z,
|
||||||
vel: Vel::default(),
|
vel: Vel::default(),
|
||||||
@ -1113,7 +1114,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut physics_state_delta = physics_state.clone();
|
let mut physics_state_delta = physics_state.state;
|
||||||
// deliberately don't use scale yet here, because the
|
// deliberately don't use scale yet here, because the
|
||||||
// 11.0/0.8 thing is
|
// 11.0/0.8 thing is
|
||||||
// in the comp::Scale for visual reasons
|
// in the comp::Scale for visual reasons
|
||||||
@ -1191,7 +1192,7 @@ impl<'a> PhysicsData<'a> {
|
|||||||
// based on the most
|
// based on the most
|
||||||
// recent terrain that collision was attempted with
|
// recent terrain that collision was attempted with
|
||||||
if physics_state_delta.on_ground.is_some() {
|
if physics_state_delta.on_ground.is_some() {
|
||||||
physics_state.ground_vel = vel_other;
|
physics_state.state.ground_vel = vel_other;
|
||||||
|
|
||||||
// Rotate if on ground
|
// Rotate if on ground
|
||||||
ori = ori.rotated(
|
ori = ori.rotated(
|
||||||
@ -1199,16 +1200,16 @@ impl<'a> PhysicsData<'a> {
|
|||||||
* previous_cache_other.ori.inverse(),
|
* previous_cache_other.ori.inverse(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
physics_state.on_ground =
|
physics_state.state.on_ground =
|
||||||
physics_state.on_ground.or(physics_state_delta.on_ground);
|
physics_state.state.on_ground.or(physics_state_delta.on_ground);
|
||||||
physics_state.on_ceiling |= physics_state_delta.on_ceiling;
|
physics_state.state.on_ceiling |= physics_state_delta.on_ceiling;
|
||||||
physics_state.on_wall = physics_state.on_wall.or_else(|| {
|
physics_state.state.on_wall = physics_state.state.on_wall.or_else(|| {
|
||||||
physics_state_delta
|
physics_state_delta
|
||||||
.on_wall
|
.on_wall
|
||||||
.map(|dir| ori_from.mul_direction(dir))
|
.map(|dir| ori_from.mul_direction(dir))
|
||||||
});
|
});
|
||||||
physics_state.in_fluid = match (
|
physics_state.state.in_fluid = match (
|
||||||
physics_state.in_fluid,
|
physics_state.state.in_fluid,
|
||||||
physics_state_delta.in_fluid,
|
physics_state_delta.in_fluid,
|
||||||
) {
|
) {
|
||||||
(Some(x), Some(y)) => x
|
(Some(x), Some(y)) => x
|
||||||
@ -1467,7 +1468,7 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
pos: &mut Pos,
|
pos: &mut Pos,
|
||||||
tgt_pos: Vec3<f32>,
|
tgt_pos: Vec3<f32>,
|
||||||
vel: &mut Vel,
|
vel: &mut Vel,
|
||||||
physics_state: &mut PhysicsState,
|
physics_state: &mut PhysicsStateFast,
|
||||||
ground_vel: Vec3<f32>,
|
ground_vel: Vec3<f32>,
|
||||||
dt: &DeltaTime,
|
dt: &DeltaTime,
|
||||||
was_on_ground: bool,
|
was_on_ground: bool,
|
||||||
|
@ -86,7 +86,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into()));
|
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into()));
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
if physics.on_surface().is_none() && rng.gen_bool(0.05) {
|
if physics.state.on_surface().is_none() && rng.gen_bool(0.05) {
|
||||||
server_emitter.emit(ServerEvent::Sound {
|
server_emitter.emit(ServerEvent::Sound {
|
||||||
sound: Sound::new(SoundKind::Projectile, pos.0, 4.0, read_data.time.0),
|
sound: Sound::new(SoundKind::Projectile, pos.0, 4.0, read_data.time.0),
|
||||||
});
|
});
|
||||||
@ -162,7 +162,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if physics.on_surface().is_some() {
|
if physics.state.on_surface().is_some() {
|
||||||
let projectile_write = &mut *projectile_write;
|
let projectile_write = &mut *projectile_write;
|
||||||
for effect in projectile_write.hit_solid.drain(..) {
|
for effect in projectile_write.hit_solid.drain(..) {
|
||||||
match effect {
|
match effect {
|
||||||
|
@ -182,7 +182,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
arc_strip.collides_with_circle(Disk::new(pos_b2, rad_b))
|
arc_strip.collides_with_circle(Disk::new(pos_b2, rad_b))
|
||||||
}
|
}
|
||||||
&& (pos_b_ground - pos.0).angle_between(pos_b.0 - pos.0) < max_angle
|
&& (pos_b_ground - pos.0).angle_between(pos_b.0 - pos.0) < max_angle
|
||||||
&& (!shockwave.requires_ground || physics_state_b.on_ground.is_some());
|
&& (!shockwave.requires_ground || physics_state_b.state.on_ground.is_some());
|
||||||
|
|
||||||
if hit {
|
if hit {
|
||||||
let dir = Dir::from_unnormalized(pos_b.0 - pos.0).unwrap_or(look_dir);
|
let dir = Dir::from_unnormalized(pos_b.0 - pos.0).unwrap_or(look_dir);
|
||||||
|
@ -23,6 +23,7 @@ const POISE_REGEN_ACCEL: f32 = 2.0;
|
|||||||
#[derive(SystemData)]
|
#[derive(SystemData)]
|
||||||
pub struct ReadData<'a> {
|
pub struct ReadData<'a> {
|
||||||
entities: Entities<'a>,
|
entities: Entities<'a>,
|
||||||
|
stats: ReadStorage<'a, Stats>,
|
||||||
dt: Read<'a, DeltaTime>,
|
dt: Read<'a, DeltaTime>,
|
||||||
time: Read<'a, Time>,
|
time: Read<'a, Time>,
|
||||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||||
@ -39,7 +40,6 @@ pub struct Sys;
|
|||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
type SystemData = (
|
type SystemData = (
|
||||||
ReadData<'a>,
|
ReadData<'a>,
|
||||||
WriteStorage<'a, Stats>,
|
|
||||||
WriteStorage<'a, SkillSet>,
|
WriteStorage<'a, SkillSet>,
|
||||||
WriteStorage<'a, Health>,
|
WriteStorage<'a, Health>,
|
||||||
WriteStorage<'a, Poise>,
|
WriteStorage<'a, Poise>,
|
||||||
@ -56,7 +56,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
_job: &mut Job<Self>,
|
_job: &mut Job<Self>,
|
||||||
(
|
(
|
||||||
read_data,
|
read_data,
|
||||||
stats,
|
|
||||||
mut skill_sets,
|
mut skill_sets,
|
||||||
mut healths,
|
mut healths,
|
||||||
mut poises,
|
mut poises,
|
||||||
@ -72,7 +71,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Update stats
|
// Update stats
|
||||||
for (entity, stats, mut health, pos, mut energy, inventory) in (
|
for (entity, stats, mut health, pos, mut energy, inventory) in (
|
||||||
&read_data.entities,
|
&read_data.entities,
|
||||||
&stats,
|
&read_data.stats,
|
||||||
&mut healths,
|
&mut healths,
|
||||||
&read_data.positions,
|
&read_data.positions,
|
||||||
&mut energies,
|
&mut energies,
|
||||||
|
@ -3,7 +3,7 @@ mod tests {
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
item::MaterialStatManifest, skills::GeneralSkill, CharacterState, Controller, Energy,
|
item::MaterialStatManifest, skills::GeneralSkill, CharacterState, Controller, Energy,
|
||||||
Ori, PhysicsState, Poise, Pos, Skill, Stats, Vel,
|
MovementState, Ori, PhysicsState, Poise, Pos, Skill, Stats, Vel,
|
||||||
},
|
},
|
||||||
resources::{DeltaTime, GameMode, Time},
|
resources::{DeltaTime, GameMode, Time},
|
||||||
terrain::{MapSizeLg, TerrainChunk},
|
terrain::{MapSizeLg, TerrainChunk},
|
||||||
@ -51,6 +51,7 @@ mod tests {
|
|||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.create_entity()
|
.create_entity()
|
||||||
.with(CharacterState::Idle(common::states::idle::Data::default()))
|
.with(CharacterState::Idle(common::states::idle::Data::default()))
|
||||||
|
.with(MovementState::default())
|
||||||
.with(Pos(Vec3::zero()))
|
.with(Pos(Vec3::zero()))
|
||||||
.with(Vel::default())
|
.with(Vel::default())
|
||||||
.with(ori)
|
.with(ori)
|
||||||
@ -105,11 +106,22 @@ mod tests {
|
|||||||
Ori::from_unnormalized_vec(testcases[i].0).unwrap_or_default(),
|
Ori::from_unnormalized_vec(testcases[i].0).unwrap_or_default(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
tick(&mut state, Duration::from_secs_f32(0.033));
|
let dt = 0.033;
|
||||||
let results = state.ecs().read_storage::<Ori>();
|
tick(&mut state, Duration::from_secs_f32(dt));
|
||||||
|
let movement = state.ecs().read_storage::<MovementState>();
|
||||||
|
let pos = state.ecs().read_storage::<Pos>();
|
||||||
|
let vel = state.ecs().read_storage::<Vel>();
|
||||||
|
let ori = state.ecs().read_storage::<Ori>();
|
||||||
|
let dt = DeltaTime(dt);
|
||||||
for i in 0..TESTCASES {
|
for i in 0..TESTCASES {
|
||||||
if let Some(e) = entities[i] {
|
if let Some(e) = entities[i] {
|
||||||
let result = Dir::from(*results.get(e).expect("Ori missing"));
|
let mut pos = *pos.get(e).expect("Pos missing");
|
||||||
|
let mut vel = *vel.get(e).expect("Vel missing");
|
||||||
|
let mut ori = *ori.get(e).expect("Ori missing");
|
||||||
|
if let Some(movement) = movement.get(e) {
|
||||||
|
movement.handle_movement(&dt, &mut pos, &mut vel, &mut ori);
|
||||||
|
}
|
||||||
|
let result = Dir::from(ori);
|
||||||
assert!(result.abs_diff_eq(&testcases[i].1, 0.0005));
|
assert!(result.abs_diff_eq(&testcases[i].1, 0.0005));
|
||||||
// println!("{:?}", result);
|
// println!("{:?}", result);
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ use common::{
|
|||||||
comp::{
|
comp::{
|
||||||
inventory::item::MaterialStatManifest,
|
inventory::item::MaterialStatManifest,
|
||||||
skills::{GeneralSkill, Skill},
|
skills::{GeneralSkill, Skill},
|
||||||
Auras, Buffs, CharacterState, Collider, Combo, Controller, Energy, Health, Ori, Pos, Stats,
|
Auras, Buffs, CharacterState, Collider, Combo, Controller, Energy, Health, MovementState,
|
||||||
Vel,
|
Ori, Pos, Stats, Vel,
|
||||||
},
|
},
|
||||||
resources::{DeltaTime, GameMode, Time},
|
resources::{DeltaTime, GameMode, Time},
|
||||||
skillset_builder::SkillSetBuilder,
|
skillset_builder::SkillSetBuilder,
|
||||||
|
slowjob::SlowJobPool,
|
||||||
terrain::{
|
terrain::{
|
||||||
Block, BlockKind, MapSizeLg, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainGrid,
|
Block, BlockKind, MapSizeLg, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainGrid,
|
||||||
},
|
},
|
||||||
@ -42,6 +43,10 @@ pub fn setup() -> State {
|
|||||||
Arc::new(TerrainChunk::water(0)),
|
Arc::new(TerrainChunk::water(0)),
|
||||||
);
|
);
|
||||||
state.ecs_mut().insert(MaterialStatManifest::with_empty());
|
state.ecs_mut().insert(MaterialStatManifest::with_empty());
|
||||||
|
state
|
||||||
|
.ecs_mut()
|
||||||
|
.write_resource::<SlowJobPool>()
|
||||||
|
.configure("CHUNK_DROP", |_n| 1);
|
||||||
state.ecs_mut().read_resource::<Time>();
|
state.ecs_mut().read_resource::<Time>();
|
||||||
state.ecs_mut().read_resource::<DeltaTime>();
|
state.ecs_mut().read_resource::<DeltaTime>();
|
||||||
for x in 0..2 {
|
for x in 0..2 {
|
||||||
@ -117,6 +122,7 @@ pub fn create_player(state: &mut State) -> Entity {
|
|||||||
.with(body)
|
.with(body)
|
||||||
.with(Controller::default())
|
.with(Controller::default())
|
||||||
.with(CharacterState::default())
|
.with(CharacterState::default())
|
||||||
|
.with(MovementState::default())
|
||||||
.with(Buffs::default())
|
.with(Buffs::default())
|
||||||
.with(Combo::default())
|
.with(Combo::default())
|
||||||
.with(Auras::default())
|
.with(Auras::default())
|
||||||
|
@ -966,8 +966,8 @@ impl<'a> AgentData<'a> {
|
|||||||
controller.inputs.look_dir,
|
controller.inputs.look_dir,
|
||||||
self.ori.look_vec(),
|
self.ori.look_vec(),
|
||||||
// Try to match animation by getting some context
|
// Try to match animation by getting some context
|
||||||
self.vel.0 - self.physics_state.ground_vel,
|
self.vel.0 - self.physics_state.state.ground_vel,
|
||||||
self.physics_state.on_ground,
|
self.physics_state.state.on_ground,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let aim_to = Vec3::new(
|
let aim_to = Vec3::new(
|
||||||
|
@ -106,7 +106,7 @@ pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3<f32>)
|
|||||||
if let Some(physics) = ecs.read_storage::<PhysicsState>().get(entity) {
|
if let Some(physics) = ecs.read_storage::<PhysicsState>().get(entity) {
|
||||||
//Check if the entity is on a surface. If it is not, reduce knockback.
|
//Check if the entity is on a surface. If it is not, reduce knockback.
|
||||||
let mut impulse = impulse
|
let mut impulse = impulse
|
||||||
* if physics.on_surface().is_some() {
|
* if physics.state.on_surface().is_some() {
|
||||||
1.0
|
1.0
|
||||||
} else {
|
} else {
|
||||||
0.4
|
0.4
|
||||||
@ -1359,3 +1359,11 @@ pub fn handle_update_map_marker(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FIXME: Remove this hack! It should only be used for dousing flames from
|
||||||
|
/// campfires.
|
||||||
|
pub fn handle_update_body(server: &mut Server, entity: EcsEntity, new_body: comp::Body) {
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.write_component_ignore_entity_dead(entity, new_body);
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@ use entity_manipulation::{
|
|||||||
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
||||||
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
||||||
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground, handle_parry,
|
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground, handle_parry,
|
||||||
handle_poise, handle_respawn, handle_teleport_to, handle_update_map_marker,
|
handle_poise, handle_respawn, handle_teleport_to, handle_update_body, handle_update_map_marker,
|
||||||
};
|
};
|
||||||
use group_manip::handle_group;
|
use group_manip::handle_group;
|
||||||
use information::handle_site_info;
|
use information::handle_site_info;
|
||||||
@ -287,6 +287,9 @@ impl Server {
|
|||||||
ServerEvent::UpdateMapMarker { entity, update } => {
|
ServerEvent::UpdateMapMarker { entity, update } => {
|
||||||
handle_update_map_marker(self, entity, update)
|
handle_update_map_marker(self, entity, update)
|
||||||
},
|
},
|
||||||
|
ServerEvent::UpdateBody { entity, new_body } => {
|
||||||
|
handle_update_body(self, entity, new_body)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
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(_))
|
||||||
) && physics_state.on_ground.is_none();
|
) && physics_state.state.on_ground.is_none();
|
||||||
|
|
||||||
if let Some(pid) = agent.position_pid_controller.as_mut() {
|
if let Some(pid) = agent.position_pid_controller.as_mut() {
|
||||||
pid.add_measurement(read_data.time.0, pos.0);
|
pid.add_measurement(read_data.time.0, pos.0);
|
||||||
@ -150,8 +150,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
let traversal_config = TraversalConfig {
|
let traversal_config = TraversalConfig {
|
||||||
node_tolerance,
|
node_tolerance,
|
||||||
slow_factor,
|
slow_factor,
|
||||||
on_ground: physics_state.on_ground.is_some(),
|
on_ground: physics_state.state.on_ground.is_some(),
|
||||||
in_liquid: physics_state.in_liquid().is_some(),
|
in_liquid: physics_state.state.in_liquid().is_some(),
|
||||||
min_tgt_dist: 1.0,
|
min_tgt_dist: 1.0,
|
||||||
can_climb: body.map_or(false, Body::can_climb),
|
can_climb: body.map_or(false, Body::can_climb),
|
||||||
can_fly: body.map_or(false, |b| b.fly_thrust().is_some()),
|
can_fly: body.map_or(false, |b| b.fly_thrust().is_some()),
|
||||||
|
@ -184,7 +184,7 @@ fn react_if_on_fire(bdata: &mut BehaviorData) -> bool {
|
|||||||
|
|
||||||
if is_on_fire
|
if is_on_fire
|
||||||
&& bdata.agent_data.body.map_or(false, |b| b.is_humanoid())
|
&& bdata.agent_data.body.map_or(false, |b| b.is_humanoid())
|
||||||
&& bdata.agent_data.physics_state.on_ground.is_some()
|
&& bdata.agent_data.physics_state.state.on_ground.is_some()
|
||||||
&& bdata
|
&& bdata
|
||||||
.rng
|
.rng
|
||||||
.gen_bool((2.0 * bdata.read_data.dt.0).clamp(0.0, 1.0) as f64)
|
.gen_bool((2.0 * bdata.read_data.dt.0).clamp(0.0, 1.0) as f64)
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
{
|
{
|
||||||
match object {
|
match object {
|
||||||
Object::Bomb { owner } => {
|
Object::Bomb { owner } => {
|
||||||
if physics.on_surface().is_some() {
|
if physics.state.on_surface().is_some() {
|
||||||
server_emitter.emit(ServerEvent::Delete(entity));
|
server_emitter.emit(ServerEvent::Delete(entity));
|
||||||
server_emitter.emit(ServerEvent::Explosion {
|
server_emitter.emit(ServerEvent::Explosion {
|
||||||
pos: pos.0,
|
pos: pos.0,
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.filter(|(_, owner_pos, owner_physics, pet_pos)| {
|
.filter(|(_, owner_pos, owner_physics, pet_pos)| {
|
||||||
// Don't teleport pets to the player if they're in the air, nobody wants
|
// Don't teleport pets to the player if they're in the air, nobody wants
|
||||||
// pets to go splat :(
|
// pets to go splat :(
|
||||||
owner_physics.on_ground.is_some()
|
owner_physics.state.on_ground.is_some()
|
||||||
&& owner_pos.0.distance_squared(pet_pos.0) > LOST_PET_DISTANCE_THRESHOLD.powi(2)
|
&& owner_pos.0.distance_squared(pet_pos.0) > LOST_PET_DISTANCE_THRESHOLD.powi(2)
|
||||||
})
|
})
|
||||||
.map(|(entity, owner_pos, _, _)| (entity, *owner_pos))
|
.map(|(entity, owner_pos, _, _)| (entity, *owner_pos))
|
||||||
|
@ -55,7 +55,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
if physics.map_or(true, |ps| ps.on_ground.is_some()) && velocity.0.z >= 0.0 {
|
if physics.map_or(true, |ps| ps.state.on_ground.is_some()) && velocity.0.z >= 0.0 {
|
||||||
for (waypoint_pos, waypoint_area) in (&positions, &waypoint_areas).join() {
|
for (waypoint_pos, waypoint_area) in (&positions, &waypoint_areas).join() {
|
||||||
if player_pos.0.distance_squared(waypoint_pos.0)
|
if player_pos.0.distance_squared(waypoint_pos.0)
|
||||||
< waypoint_area.radius().powi(2)
|
< waypoint_area.radius().powi(2)
|
||||||
|
@ -706,17 +706,17 @@ fn selected_entity_window(
|
|||||||
.spacing([40.0, 4.0])
|
.spacing([40.0, 4.0])
|
||||||
.striped(true)
|
.striped(true)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
two_col_row(ui, "On Ground", physics_state.on_ground.map_or("None".to_owned(), |x| format!("{:?}", x)));
|
two_col_row(ui, "On Ground", physics_state.state.on_ground.map_or("None".to_owned(), |x| format!("{:?}", x)));
|
||||||
two_col_row(ui, "On Ceiling", (if physics_state.on_ceiling { "True" } else { "False " }).to_string());
|
two_col_row(ui, "On Ceiling", (if physics_state.state.on_ceiling { "True" } else { "False " }).to_string());
|
||||||
two_col_row(ui, "On Wall", physics_state.on_wall.map_or("-".to_owned(), |x| format!("{:.1},{:.1},{:.1}", x.x, x.y, x.z )));
|
two_col_row(ui, "On Wall", physics_state.state.on_wall.map_or("-".to_owned(), |x| format!("{:.1},{:.1},{:.1}", x.x, x.y, x.z )));
|
||||||
two_col_row(ui, "Touching Entities", physics_state.touch_entities.len().to_string());
|
two_col_row(ui, "Touching Entities", physics_state.touch_entities.len().to_string());
|
||||||
two_col_row(ui, "In Fluid", match physics_state.in_fluid {
|
two_col_row(ui, "In Fluid", match physics_state.state.in_fluid {
|
||||||
|
|
||||||
Some(Fluid::Air { elevation, .. }) => format!("Air (Elevation: {:.1})", elevation),
|
Some(Fluid::Air { elevation, .. }) => format!("Air (Elevation: {:.1})", elevation),
|
||||||
Some(Fluid::Liquid { depth, kind, .. }) => format!("{:?} (Depth: {:.1})", kind, depth),
|
Some(Fluid::Liquid { depth, kind, .. }) => format!("{:?} (Depth: {:.1})", kind, depth),
|
||||||
_ => "None".to_owned() });
|
_ => "None".to_owned() });
|
||||||
});
|
});
|
||||||
two_col_row(ui, "Footwear", match physics_state.footwear{ Friction::Ski => "Ski", Friction::Skate => "Skate", /* Friction::Snowshoe => "Snowshoe", Friction::Spikes => "Spikes", */ Friction::Normal=>"Normal",}.to_string());
|
two_col_row(ui, "Footwear", match physics_state.state.footwear{ Friction::Ski => "Ski", Friction::Skate => "Skate", /* Friction::Snowshoe => "Snowshoe", Friction::Spikes => "Spikes", */ Friction::Normal=>"Normal",}.to_string());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
comp::{Body, CharacterState, PhysicsState, Pos, Vel},
|
comp::{Body, CharacterState, PhysicsState, PhysicsStateFast, Pos, Vel},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
terrain::{BlockKind, TerrainChunk},
|
terrain::{BlockKind, TerrainChunk},
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
@ -72,6 +72,7 @@ impl EventMapper for MovementEventMapper {
|
|||||||
.join()
|
.join()
|
||||||
.filter(|(_, e_pos, ..)| (e_pos.0.distance_squared(cam_pos)) < SFX_DIST_LIMIT_SQR)
|
.filter(|(_, e_pos, ..)| (e_pos.0.distance_squared(cam_pos)) < SFX_DIST_LIMIT_SQR)
|
||||||
{
|
{
|
||||||
|
let physics = &physics.state;
|
||||||
if let Some(character) = character {
|
if let Some(character) = character {
|
||||||
let internal_state = self.event_history.entry(entity).or_default();
|
let internal_state = self.event_history.entry(entity).or_default();
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ impl MovementEventMapper {
|
|||||||
/// `SfxEvent`'s which we attach sounds to
|
/// `SfxEvent`'s which we attach sounds to
|
||||||
fn map_movement_event(
|
fn map_movement_event(
|
||||||
character_state: &CharacterState,
|
character_state: &CharacterState,
|
||||||
physics_state: &PhysicsState,
|
physics_state: &PhysicsStateFast,
|
||||||
previous_state: &PreviousEntityState,
|
previous_state: &PreviousEntityState,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
underfoot_block_kind: BlockKind,
|
underfoot_block_kind: BlockKind,
|
||||||
@ -228,7 +229,7 @@ impl MovementEventMapper {
|
|||||||
|
|
||||||
/// Maps a limited set of movements for other non-humanoid entities
|
/// Maps a limited set of movements for other non-humanoid entities
|
||||||
fn map_non_humanoid_movement_event(
|
fn map_non_humanoid_movement_event(
|
||||||
physics_state: &PhysicsState,
|
physics_state: &PhysicsStateFast,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
underfoot_block_kind: BlockKind,
|
underfoot_block_kind: BlockKind,
|
||||||
) -> SfxEvent {
|
) -> SfxEvent {
|
||||||
@ -250,7 +251,7 @@ impl MovementEventMapper {
|
|||||||
|
|
||||||
/// Maps a limited set of movements for quadruped entities
|
/// Maps a limited set of movements for quadruped entities
|
||||||
fn map_quadruped_movement_event(
|
fn map_quadruped_movement_event(
|
||||||
physics_state: &PhysicsState,
|
physics_state: &PhysicsStateFast,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
underfoot_block_kind: BlockKind,
|
underfoot_block_kind: BlockKind,
|
||||||
) -> SfxEvent {
|
) -> SfxEvent {
|
||||||
|
@ -3,7 +3,7 @@ use crate::audio::sfx::SfxEvent;
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
bird_large, humanoid, quadruped_medium, quadruped_small, Body, CharacterState, InputKind,
|
bird_large, humanoid, quadruped_medium, quadruped_small, Body, CharacterState, InputKind,
|
||||||
Ori, PhysicsState,
|
Ori, PhysicsStateFast,
|
||||||
},
|
},
|
||||||
states,
|
states,
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
@ -94,7 +94,7 @@ fn same_previous_event_elapsed_emits() {
|
|||||||
fn maps_idle() {
|
fn maps_idle() {
|
||||||
let result = MovementEventMapper::map_movement_event(
|
let result = MovementEventMapper::map_movement_event(
|
||||||
&CharacterState::Idle(states::idle::Data::default()),
|
&CharacterState::Idle(states::idle::Data::default()),
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -116,7 +116,7 @@ fn maps_idle() {
|
|||||||
fn maps_run_with_sufficient_velocity() {
|
fn maps_run_with_sufficient_velocity() {
|
||||||
let result = MovementEventMapper::map_movement_event(
|
let result = MovementEventMapper::map_movement_event(
|
||||||
&CharacterState::Idle(states::idle::Data::default()),
|
&CharacterState::Idle(states::idle::Data::default()),
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -138,7 +138,7 @@ fn maps_run_with_sufficient_velocity() {
|
|||||||
fn does_not_map_run_with_insufficient_velocity() {
|
fn does_not_map_run_with_insufficient_velocity() {
|
||||||
let result = MovementEventMapper::map_movement_event(
|
let result = MovementEventMapper::map_movement_event(
|
||||||
&CharacterState::Idle(states::idle::Data::default()),
|
&CharacterState::Idle(states::idle::Data::default()),
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -193,7 +193,7 @@ fn maps_roll() {
|
|||||||
is_sneaking: false,
|
is_sneaking: false,
|
||||||
was_combo: None,
|
was_combo: None,
|
||||||
}),
|
}),
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -215,7 +215,7 @@ fn maps_roll() {
|
|||||||
fn maps_land_on_ground_to_run() {
|
fn maps_land_on_ground_to_run() {
|
||||||
let result = MovementEventMapper::map_movement_event(
|
let result = MovementEventMapper::map_movement_event(
|
||||||
&CharacterState::Idle(states::idle::Data::default()),
|
&CharacterState::Idle(states::idle::Data::default()),
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -255,7 +255,7 @@ fn maps_glide() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn maps_quadrupeds_running() {
|
fn maps_quadrupeds_running() {
|
||||||
let result = MovementEventMapper::map_non_humanoid_movement_event(
|
let result = MovementEventMapper::map_non_humanoid_movement_event(
|
||||||
&PhysicsState {
|
&PhysicsStateFast {
|
||||||
on_ground: Some(Block::empty()),
|
on_ground: Some(Block::empty()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -767,6 +767,7 @@ impl FigureMgr {
|
|||||||
.join()
|
.join()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
|
let physics = &physics.state;
|
||||||
// Velocity relative to the current ground
|
// Velocity relative to the current ground
|
||||||
let rel_vel = anim::vek::Vec3::<f32>::from(vel.0 - physics.ground_vel);
|
let rel_vel = anim::vek::Vec3::<f32>::from(vel.0 - physics.ground_vel);
|
||||||
|
|
||||||
|
@ -528,7 +528,7 @@ impl Scene {
|
|||||||
let on_ground = ecs
|
let on_ground = ecs
|
||||||
.read_storage::<comp::PhysicsState>()
|
.read_storage::<comp::PhysicsState>()
|
||||||
.get(scene_data.viewpoint_entity)
|
.get(scene_data.viewpoint_entity)
|
||||||
.map(|p| p.on_ground.is_some());
|
.map(|p| p.state.on_ground.is_some());
|
||||||
|
|
||||||
let (viewpoint_height, viewpoint_eye_height) = scene_data
|
let (viewpoint_height, viewpoint_eye_height) = scene_data
|
||||||
.state
|
.state
|
||||||
|
@ -1061,6 +1061,7 @@ impl PlayState for SessionState {
|
|||||||
let fluid = ecs
|
let fluid = ecs
|
||||||
.read_storage::<comp::PhysicsState>()
|
.read_storage::<comp::PhysicsState>()
|
||||||
.get(entity)?
|
.get(entity)?
|
||||||
|
.state
|
||||||
.in_fluid?;
|
.in_fluid?;
|
||||||
ecs.read_storage::<Vel>()
|
ecs.read_storage::<Vel>()
|
||||||
.get(entity)
|
.get(entity)
|
||||||
@ -1220,7 +1221,7 @@ impl PlayState for SessionState {
|
|||||||
let in_fluid = ecs
|
let in_fluid = ecs
|
||||||
.read_storage::<comp::PhysicsState>()
|
.read_storage::<comp::PhysicsState>()
|
||||||
.get(entity)
|
.get(entity)
|
||||||
.and_then(|state| state.in_fluid);
|
.and_then(|state| state.state.in_fluid);
|
||||||
let character_state = ecs
|
let character_state = ecs
|
||||||
.read_storage::<comp::CharacterState>()
|
.read_storage::<comp::CharacterState>()
|
||||||
.get(entity)
|
.get(entity)
|
||||||
|
Loading…
Reference in New Issue
Block a user