Compare commits

...

3 Commits

@ -53,6 +53,7 @@ fn main() {
commands::command_suggestor,
player::fall_damage,
player::death,
player::respawn,
)
.in_schedule(EventLoopSchedule),
)

@ -7,7 +7,7 @@ use once_cell::sync::Lazy;
use valence::{
entity::{living::Health, player::PlayerEntityBundle, EntityId},
packet::WritePacket,
prelude::{event::PlayerMove, *},
prelude::{event::PerformRespawn, *},
};
use valence_protocol::{
packet::s2c::play::{
@ -23,63 +23,6 @@ use crate::PLAYER_COUNT;
static PLAYER_HEIGHT_HISTORY: Lazy<Mutex<HashMap<i32, f64>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
pub fn fall_damage(
mut clients: Query<
(
&mut Client,
&OnGround,
&mut EntityId,
&mut Health,
&GameMode,
&Position,
),
Changed<Position>,
>,
mut instances: Query<&Instance>,
) {
let instance = instances.single();
for (client, on_ground, id, mut health, gamemode, position) in &mut clients {
let current_block = instance
.block(BlockPos {
x: position.0.x.floor() as i32,
y: position.0.y.floor() as i32 - 1,
z: position.0.z.floor() as i32,
})
.unwrap();
let mut hashmap = PLAYER_HEIGHT_HISTORY.lock().unwrap();
if *gamemode == GameMode::Survival {
// hack that potentially makes water not apply fall damage?
if current_block.state().to_kind() == BlockKind::Vine
|| current_block.state().to_kind() == BlockKind::SlimeBlock
|| current_block.state().is_liquid()
{
hashmap.insert(id.get(), position.0.y);
}
let old_position = hashmap.get(&id.get()).unwrap_or(&-1.0);
let delta_y = old_position - position.0.y;
if on_ground.0 {
if delta_y > 3.0 {
health.0 -= (delta_y - 3.0) as f32;
}
hashmap.insert(id.get(), position.0.y);
} else if delta_y < 0.0 {
hashmap.insert(id.get(), position.0.y);
}
}
}
}
pub fn death(mut healths: Query<(&mut Client, &Health, &Username), Changed<Health>>) {
for (mut client, health, username) in &mut healths {
if health.0 <= 0.0 {
tracing::debug!("Trying to kill player {}", username);
client.kill(None, format!("{} fell from a high place.", username));
}
}
}
pub fn init_clients(
mut new_clients: Query<
(
@ -155,6 +98,63 @@ pub fn init_clients(
}
}
pub fn fall_damage(
mut clients: Query<
(
&mut Client,
&OnGround,
&EntityId,
&mut Health,
&GameMode,
&Position,
),
Changed<Position>,
>,
instances: Query<&Instance>,
) {
let instance = instances.single();
for (_client, on_ground, id, mut health, gamemode, position) in &mut clients {
let current_block = instance
.block(BlockPos {
x: position.0.x.floor() as i32,
y: position.0.y.floor() as i32 - 1,
z: position.0.z.floor() as i32,
})
.unwrap();
let mut hashmap = PLAYER_HEIGHT_HISTORY.lock().unwrap();
if *gamemode == GameMode::Survival {
// hack that potentially makes water not apply fall damage?
if current_block.state().to_kind() == BlockKind::Vine
|| current_block.state().to_kind() == BlockKind::SlimeBlock
|| current_block.state().is_liquid()
{
hashmap.insert(id.get(), position.0.y);
}
let old_position = hashmap.get(&id.get()).unwrap_or(&-1.0);
let delta_y = old_position - position.0.y;
if on_ground.0 {
if delta_y > 3.0 {
health.0 -= (delta_y - 3.0) as f32;
}
hashmap.insert(id.get(), position.0.y);
} else if delta_y < 0.0 {
hashmap.insert(id.get(), position.0.y);
}
}
}
}
pub fn death(mut healths: Query<(&mut Client, &Health, &Username), Changed<Health>>) {
for (mut client, health, username) in &mut healths {
if health.0 <= 0.0 {
tracing::debug!("Trying to kill player {}", username);
client.kill(None, format!("{} fell from a high place.", username));
}
}
}
pub fn despawn_disconnected_clients(
mut commands: Commands,
mut disconnected_clients: RemovedComponents<Client>,
@ -166,3 +166,22 @@ pub fn despawn_disconnected_clients(
}
}
}
pub fn respawn(
mut clients: Query<(&mut Position, &mut Look, &mut Location)>,
mut events: EventReader<PerformRespawn>,
instances: Query<Entity, With<Instance>>,
) {
for event in events.iter() {
if let Ok((mut pos, mut look, mut loc)) = clients.get_mut(event.client) {
pos.set(DVec3 {
x: -214.0,
y: 83.0,
z: 276.0,
});
look.yaw = 0.0;
look.pitch = 0.0;
loc.0 = instances.single();
}
}
}

Loading…
Cancel
Save