mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-10 06:41:30 +11:00
Fix bug with respawn position
This commit is contained in:
parent
abf9064901
commit
a5387af324
|
@ -22,7 +22,7 @@ fn setup(
|
||||||
dimensions: Query<&DimensionType>,
|
dimensions: Query<&DimensionType>,
|
||||||
biomes: Query<&Biome>,
|
biomes: Query<&Biome>,
|
||||||
) {
|
) {
|
||||||
for block in [BlockState::GRASS_BLOCK, BlockState::DEEPSLATE] {
|
for block in [BlockState::GRASS_BLOCK, BlockState::DEEPSLATE, BlockState::MAGMA_BLOCK] {
|
||||||
let mut instance = Instance::new(ident!("overworld"), &dimensions, &biomes, &server);
|
let mut instance = Instance::new(ident!("overworld"), &dimensions, &biomes, &server);
|
||||||
|
|
||||||
for z in -5..5 {
|
for z in -5..5 {
|
||||||
|
@ -42,21 +42,12 @@ fn setup(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_clients(
|
fn init_clients(
|
||||||
mut clients: Query<
|
mut clients: Query<(&mut Client, &mut Location, &mut Position), Added<Client>>,
|
||||||
(
|
|
||||||
&mut Client,
|
|
||||||
&mut Location,
|
|
||||||
&mut Position,
|
|
||||||
&mut HasRespawnScreen,
|
|
||||||
),
|
|
||||||
Added<Client>,
|
|
||||||
>,
|
|
||||||
instances: Query<Entity, With<Instance>>,
|
instances: Query<Entity, With<Instance>>,
|
||||||
) {
|
) {
|
||||||
for (mut client, mut loc, mut pos, mut has_respawn_screen) in &mut clients {
|
for (mut client, mut loc, mut pos) in &mut clients {
|
||||||
loc.0 = instances.iter().next().unwrap();
|
loc.0 = instances.iter().next().unwrap();
|
||||||
pos.set([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
|
pos.set([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
|
||||||
has_respawn_screen.0 = true;
|
|
||||||
|
|
||||||
client.send_message(
|
client.send_message(
|
||||||
"Welcome to Valence! Sneak to die in the game (but not in real life).".italic(),
|
"Welcome to Valence! Sneak to die in the game (but not in real life).".italic(),
|
||||||
|
@ -75,15 +66,13 @@ fn squat_and_die(mut clients: Query<&mut Client>, mut events: EventReader<Sneaki
|
||||||
}
|
}
|
||||||
|
|
||||||
fn necromancy(
|
fn necromancy(
|
||||||
mut clients: Query<(&mut Position, &mut Look, &mut Location)>,
|
mut clients: Query<(&mut Location, &mut RespawnPosition)>,
|
||||||
mut events: EventReader<Respawn>,
|
mut events: EventReader<Respawn>,
|
||||||
instances: Query<Entity, With<Instance>>,
|
instances: Query<Entity, With<Instance>>,
|
||||||
) {
|
) {
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
if let Ok((mut pos, mut look, mut loc)) = clients.get_mut(event.client) {
|
if let Ok((mut loc, mut spawn_pos)) = clients.get_mut(event.client) {
|
||||||
pos.set([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
|
spawn_pos.pos = BlockPos::new(0, SPAWN_Y, 0);
|
||||||
look.yaw = 0.0;
|
|
||||||
look.pitch = 0.0;
|
|
||||||
|
|
||||||
// make the client respawn in another instance
|
// make the client respawn in another instance
|
||||||
let idx = instances.iter().position(|i| i == loc.0).unwrap();
|
let idx = instances.iter().position(|i| i == loc.0).unwrap();
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub mod prelude {
|
||||||
pub use client::event_loop::{EventLoopSchedule, EventLoopSet};
|
pub use client::event_loop::{EventLoopSchedule, EventLoopSet};
|
||||||
pub use client::interact_entity::*;
|
pub use client::interact_entity::*;
|
||||||
pub use client::{
|
pub use client::{
|
||||||
despawn_disconnected_clients, Client, CompassPos, DeathLocation, HasRespawnScreen,
|
despawn_disconnected_clients, Client, RespawnPosition, DeathLocation, HasRespawnScreen,
|
||||||
HashedSeed, Ip, IsDebug, IsFlat, IsHardcore, OldView, OldViewDistance, OpLevel,
|
HashedSeed, Ip, IsDebug, IsFlat, IsHardcore, OldView, OldViewDistance, OpLevel,
|
||||||
PrevGameMode, Properties, ReducedDebugInfo, Username, View, ViewDistance,
|
PrevGameMode, Properties, ReducedDebugInfo, Username, View, ViewDistance,
|
||||||
};
|
};
|
||||||
|
|
|
@ -108,9 +108,9 @@ impl Plugin for ClientPlugin {
|
||||||
.after(WriteUpdatePacketsToInstancesSet)
|
.after(WriteUpdatePacketsToInstancesSet)
|
||||||
.after(update_chunk_load_dist),
|
.after(update_chunk_load_dist),
|
||||||
update_view.after(initial_join).after(read_data_in_old_view),
|
update_view.after(initial_join).after(read_data_in_old_view),
|
||||||
respawn.after(update_view),
|
update_respawn_position.after(update_view),
|
||||||
|
respawn.after(update_respawn_position),
|
||||||
remove_entities.after(update_view),
|
remove_entities.after(update_view),
|
||||||
update_spawn_position.after(update_view),
|
|
||||||
update_old_view_dist.after(update_view),
|
update_old_view_dist.after(update_view),
|
||||||
update_game_mode,
|
update_game_mode,
|
||||||
update_tracked_data.after(WriteUpdatePacketsToInstancesSet),
|
update_tracked_data.after(WriteUpdatePacketsToInstancesSet),
|
||||||
|
@ -154,7 +154,7 @@ pub struct ClientBundle {
|
||||||
pub username: Username,
|
pub username: Username,
|
||||||
pub ip: Ip,
|
pub ip: Ip,
|
||||||
pub properties: Properties,
|
pub properties: Properties,
|
||||||
pub compass_pos: CompassPos,
|
pub respawn_pos: RespawnPosition,
|
||||||
pub game_mode: GameMode,
|
pub game_mode: GameMode,
|
||||||
pub op_level: OpLevel,
|
pub op_level: OpLevel,
|
||||||
pub action_sequence: action::ActionSequence,
|
pub action_sequence: action::ActionSequence,
|
||||||
|
@ -187,7 +187,7 @@ impl ClientBundle {
|
||||||
username: Username(args.username),
|
username: Username(args.username),
|
||||||
ip: Ip(args.ip),
|
ip: Ip(args.ip),
|
||||||
properties: Properties(args.properties),
|
properties: Properties(args.properties),
|
||||||
compass_pos: CompassPos::default(),
|
respawn_pos: RespawnPosition::default(),
|
||||||
game_mode: GameMode::default(),
|
game_mode: GameMode::default(),
|
||||||
op_level: OpLevel::default(),
|
op_level: OpLevel::default(),
|
||||||
action_sequence: action::ActionSequence::default(),
|
action_sequence: action::ActionSequence::default(),
|
||||||
|
@ -589,9 +589,16 @@ impl Deref for Properties {
|
||||||
#[derive(Component, Clone, PartialEq, Eq, Debug)]
|
#[derive(Component, Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct Ip(pub IpAddr);
|
pub struct Ip(pub IpAddr);
|
||||||
|
|
||||||
/// The position that regular compass items will point to.
|
/// The position and angle that clients will respawn with. Also
|
||||||
#[derive(Component, Copy, Clone, PartialEq, Eq, Default, Debug)]
|
/// controls the position that compasses point towards.
|
||||||
pub struct CompassPos(pub BlockPos);
|
#[derive(Component, Copy, Clone, PartialEq, Default, Debug)]
|
||||||
|
pub struct RespawnPosition {
|
||||||
|
/// The position that clients will respawn at. This can be changed at any
|
||||||
|
/// time to set the position that compasses point towards.
|
||||||
|
pub pos: BlockPos,
|
||||||
|
/// The yaw angle that clients will respawn with (in degrees).
|
||||||
|
pub yaw: f32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Clone, PartialEq, Eq, Default, Debug)]
|
#[derive(Component, Clone, PartialEq, Eq, Default, Debug)]
|
||||||
pub struct OpLevel(u8);
|
pub struct OpLevel(u8);
|
||||||
|
@ -948,7 +955,7 @@ fn read_data_in_old_view(
|
||||||
&Position,
|
&Position,
|
||||||
&OldPosition,
|
&OldPosition,
|
||||||
&OldViewDistance,
|
&OldViewDistance,
|
||||||
Option<&PacketByteRange>,
|
&PacketByteRange,
|
||||||
)>,
|
)>,
|
||||||
instances: Query<&Instance>,
|
instances: Query<&Instance>,
|
||||||
entities: Query<(EntityInitQuery, &OldPosition)>,
|
entities: Query<(EntityInitQuery, &OldPosition)>,
|
||||||
|
@ -1010,17 +1017,14 @@ fn read_data_in_old_view(
|
||||||
// Send all data in the chunk's packet buffer to this client. This will update
|
// Send all data in the chunk's packet buffer to this client. This will update
|
||||||
// entities in the cell, spawn or update the chunk in the cell, or send any
|
// entities in the cell, spawn or update the chunk in the cell, or send any
|
||||||
// other packet data that was added here by users.
|
// other packet data that was added here by users.
|
||||||
match byte_range {
|
if pos == new_chunk_pos && loc == old_loc {
|
||||||
Some(byte_range) if pos == new_chunk_pos && loc == old_loc => {
|
|
||||||
// Skip range of bytes for the client's own entity.
|
// Skip range of bytes for the client's own entity.
|
||||||
client.write_packet_bytes(&cell.packet_buf[..byte_range.0.start]);
|
client.write_packet_bytes(&cell.packet_buf[..byte_range.0.start]);
|
||||||
client.write_packet_bytes(&cell.packet_buf[byte_range.0.end..]);
|
client.write_packet_bytes(&cell.packet_buf[byte_range.0.end..]);
|
||||||
}
|
} else {
|
||||||
_ => {
|
|
||||||
client.write_packet_bytes(&cell.packet_buf);
|
client.write_packet_bytes(&cell.packet_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1223,15 +1227,17 @@ fn update_old_view_dist(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the client's compass position.
|
/// Sets the client's respawn and compass position.
|
||||||
///
|
///
|
||||||
/// This also closes the "downloading terrain" screen when first joining, so
|
/// This also closes the "downloading terrain" screen when first joining, so
|
||||||
/// it should happen after the initial chunks are written.
|
/// it should happen after the initial chunks are written.
|
||||||
fn update_spawn_position(mut clients: Query<(&mut Client, &CompassPos), Changed<CompassPos>>) {
|
fn update_respawn_position(
|
||||||
for (mut client, compass_pos) in &mut clients {
|
mut clients: Query<(&mut Client, &RespawnPosition), Changed<RespawnPosition>>,
|
||||||
|
) {
|
||||||
|
for (mut client, respawn_pos) in &mut clients {
|
||||||
client.write_packet(&PlayerSpawnPositionS2c {
|
client.write_packet(&PlayerSpawnPositionS2c {
|
||||||
position: compass_pos.0,
|
position: respawn_pos.pos,
|
||||||
angle: 0.0, // TODO: does this do anything?
|
angle: respawn_pos.yaw,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,12 @@ use super::*;
|
||||||
use crate::event_loop::{EventLoopSchedule, EventLoopSet, PacketEvent};
|
use crate::event_loop::{EventLoopSchedule, EventLoopSet, PacketEvent};
|
||||||
|
|
||||||
pub(super) fn build(app: &mut App) {
|
pub(super) fn build(app: &mut App) {
|
||||||
app.add_system(teleport.after(update_view).in_set(UpdateClientsSet))
|
app.add_system(
|
||||||
|
teleport
|
||||||
|
.after(update_view)
|
||||||
|
.before(update_respawn_position)
|
||||||
|
.in_set(UpdateClientsSet),
|
||||||
|
)
|
||||||
.add_system(
|
.add_system(
|
||||||
handle_teleport_confirmations
|
handle_teleport_confirmations
|
||||||
.in_schedule(EventLoopSchedule)
|
.in_schedule(EventLoopSchedule)
|
||||||
|
@ -29,11 +34,12 @@ impl TeleportState {
|
||||||
Self {
|
Self {
|
||||||
teleport_id_counter: 0,
|
teleport_id_counter: 0,
|
||||||
pending_teleports: 0,
|
pending_teleports: 0,
|
||||||
synced_pos: DVec3::ZERO,
|
// Set initial synced pos and look to NaN so a teleport always happens when first
|
||||||
|
// joining.
|
||||||
|
synced_pos: DVec3::NAN,
|
||||||
synced_look: Look {
|
synced_look: Look {
|
||||||
// Client starts facing north.
|
yaw: f32::NAN,
|
||||||
yaw: 180.0,
|
pitch: f32::NAN,
|
||||||
pitch: 0.0,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue