Skip to content

Commit 109b1e1

Browse files
authored
Merge #114: Change world-specific Resources to world Components
Change world-specific Resources to world Components Implements #78
2 parents 53d11cc + 439abea commit 109b1e1

16 files changed

Lines changed: 172 additions & 113 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/meloncraft_default_commands/src/teleport.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,25 @@
33
44
use bevy::ecs::entity::Entity;
55
use bevy::ecs::message::{MessageReader, MessageWriter};
6+
use bevy::ecs::query::With;
67
use bevy::ecs::system::Query;
78
use bevy::math::DVec3;
89
use meloncraft_command::raw::RawCommand;
910
use meloncraft_entity::position::EntityPosition;
1011
use meloncraft_entity::position::flags::EntityPositionFlags;
1112
use meloncraft_entity::position::teleport::TeleportEntity;
12-
use meloncraft_player::GameProfile;
13+
use meloncraft_player::{GameProfile, PlayerMarker};
1314

1415
pub fn cmd_teleport(
1516
mut raw_command_mr: MessageReader<RawCommand>,
1617
player_profile_q: Query<(Entity, &GameProfile)>,
18+
player_position_q: Query<&EntityPosition, With<PlayerMarker>>,
1719
mut teleport_entity_mw: MessageWriter<TeleportEntity>,
1820
) {
1921
for raw_command in raw_command_mr.read() {
22+
// world is relative to *executor*, for now:
23+
let world = player_position_q.get(raw_command.executor).unwrap().world;
24+
2025
if raw_command.name != "teleport" && raw_command.name != "tp" {
2126
return; // we don't care about other commands
2227
}
@@ -32,6 +37,7 @@ pub fn cmd_teleport(
3237
let entity = get_player_entity_by_name(player_name, player_profile_q).unwrap();
3338
let new_position = EntityPosition {
3439
location: DVec3::new(new_x, new_y, new_z),
40+
world,
3541
flags: EntityPositionFlags {
3642
on_ground: false,
3743
pushing_against_wall: false,

src/meloncraft_entity/src/position/flags.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ pub struct EntityPositionFlags {
2222
pub pushing_against_wall: bool,
2323
}
2424

25+
impl Default for EntityPositionFlags {
26+
fn default() -> Self {
27+
// these defaults may change in the future
28+
return EntityPositionFlags {
29+
on_ground: true,
30+
pushing_against_wall: false,
31+
};
32+
}
33+
}
34+
2535
impl From<u8> for EntityPositionFlags {
2636
fn from(value: u8) -> Self {
2737
return Self {

src/meloncraft_entity/src/position/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Module for struct [`EntityPosition`] and submodules related to it.
22
33
use bevy::ecs::component::Component;
4+
use bevy::ecs::entity::Entity;
45
use bevy::math::DVec3;
56

67
pub mod current_chunk;
@@ -26,6 +27,9 @@ pub struct EntityPosition {
2627
/// Stored as a bevy [`DVec3`].
2728
pub location: DVec3,
2829

30+
/// The entity which represents the world the entity is currently in.
31+
pub world: Entity,
32+
2933
/// Extra metadata about the entity's position, such as whether the entity is on the ground or
3034
/// pushing against a wall. See [`EntityPositionFlags`] for more information about the flags
3135
/// stored in this field.

src/meloncraft_packets/src/serverbound/play/set_player_position.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
use crate::ServerboundPacket;
22
use crate::network_messages::ServerboundNetworkPacket;
3+
use bevy::math::DVec3;
34
use bevy::prelude::{Entity, Message};
45
use meloncraft_client::connection_state::ConnectionState;
5-
use meloncraft_entity::position::{EntityPosition, flags::EntityPositionFlags};
6+
use meloncraft_entity::position::flags::EntityPositionFlags;
67
use meloncraft_protocol_types::{ProtocolBuffer as _, ProtocolType as _};
78

89
#[derive(Message, Debug, Clone)]
910
pub struct ServerboundSetPlayerPosition {
1011
pub client: Entity,
11-
pub position: EntityPosition,
12+
pub location: DVec3,
13+
pub flags: EntityPositionFlags,
1214
}
1315

1416
impl ServerboundPacket for ServerboundSetPlayerPosition {
@@ -28,7 +30,8 @@ impl ServerboundPacket for ServerboundSetPlayerPosition {
2830

2931
return Some(Self {
3032
client,
31-
position: EntityPosition { location, flags },
33+
location,
34+
flags,
3235
});
3336
}
3437
}

src/meloncraft_player/src/marker.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ use bevy::ecs::component::Component;
66
/// have *finished* spawning into the world, in the **play** connection state.
77
#[derive(Component)]
88
pub struct PlayerMarker;
9+
10+
/// Marker to allow querying specifically for player entities. This is added to a client once the
11+
/// *library user* has added any components they need to add before they are acted upon (e.g. positions).
12+
#[derive(Component)]
13+
pub struct LoadedPlayer;

src/meloncraft_player_state/src/movement.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use bevy::prelude::{MessageReader, MessageWriter, Query, With};
33
use meloncraft_entity::position::EntityPosition;
44
use meloncraft_entity::position::moved::EntityMoved;
55
use meloncraft_entity::position::teleport::TeleportEntity;
6+
use meloncraft_logger::warnlog;
67
use meloncraft_packets::{ClientboundSynchronizePlayerPosition, ServerboundSetPlayerPosition};
78
use meloncraft_player::GameProfile;
89

@@ -21,14 +22,26 @@ pub fn fwd_player_moved(
2122
existing_positions: Query<&EntityPosition, With<GameProfile>>,
2223
) {
2324
for packet in set_position_pr.read() {
24-
let old_position = existing_positions.get(packet.client).map_or_else(
25-
|_| return packet.position.clone(),
26-
|old_position| return old_position.clone(),
27-
);
25+
let Ok(old_position) = existing_positions.get(packet.client) else {
26+
warnlog!(
27+
"Couldn't forward {}'s movement, as their old position was not defined. Please define the players movement when their PlayerMarker is added.",
28+
packet.client
29+
);
30+
continue;
31+
};
32+
33+
// For now, we'll set the player's world to the world they were in last tick (as we
34+
// don't have dimensions yet anyway):
35+
let new_position = EntityPosition {
36+
location: packet.location,
37+
world: old_position.world,
38+
flags: packet.flags,
39+
};
40+
2841
player_moved_mw.write(EntityMoved {
2942
entity: packet.client,
30-
old_position,
31-
new_position: packet.position.clone(),
43+
old_position: old_position.clone(),
44+
new_position,
3245
});
3346
}
3447
}

src/meloncraft_resource_forwarding/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ license.workspace = true
66

77
[dependencies]
88
bevy.workspace = true
9+
meloncraft_entity.workspace = true
910
meloncraft_player.workspace = true
1011
meloncraft_core.workspace = true
1112
meloncraft_packets.workspace = true
Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
//! Packet forwarders for [`Difficulty`] resource.
22
3-
use bevy::ecs::change_detection::DetectChanges as _;
43
use bevy::ecs::entity::Entity;
54
use bevy::ecs::message::MessageWriter;
6-
use bevy::ecs::query::{Added, With};
7-
use bevy::ecs::system::{Query, Res};
5+
use bevy::ecs::query::{Added, Changed, With};
6+
use bevy::ecs::system::Query;
7+
use meloncraft_entity::position::EntityPosition;
88
use meloncraft_packets::ClientboundChangeDifficulty;
99
use meloncraft_player::PlayerMarker;
1010
use meloncraft_server_info::difficulty::Difficulty;
1111

1212
pub fn send_difficulty_on_join(
13-
new_player_q: Query<Entity, Added<PlayerMarker>>,
14-
difficulty: Res<Difficulty>,
13+
new_player_q: Query<(Entity, &EntityPosition), Added<PlayerMarker>>,
14+
difficulty: Query<&Difficulty>,
1515
mut change_difficulty_pw: MessageWriter<ClientboundChangeDifficulty>,
1616
) {
17-
for client in new_player_q {
17+
for (client, player_position) in new_player_q {
18+
let difficulty = difficulty.get(player_position.world).unwrap();
1819
change_difficulty_pw.write(ClientboundChangeDifficulty {
1920
client,
2021
difficulty: *difficulty,
@@ -24,19 +25,20 @@ pub fn send_difficulty_on_join(
2425
}
2526

2627
pub fn send_difficulty_on_change(
27-
player_q: Query<Entity, With<PlayerMarker>>,
28-
difficulty: Res<Difficulty>,
28+
player_q: Query<(Entity, &EntityPosition), With<PlayerMarker>>,
29+
difficulty_q: Query<(Entity, &Difficulty), Changed<Difficulty>>,
2930
mut change_difficulty_pw: MessageWriter<ClientboundChangeDifficulty>,
3031
) {
31-
if !difficulty.is_changed() {
32-
return;
33-
}
34-
35-
for client in player_q {
36-
change_difficulty_pw.write(ClientboundChangeDifficulty {
37-
client,
38-
difficulty: *difficulty,
39-
difficulty_locked: false,
40-
});
32+
for (world, difficulty) in difficulty_q {
33+
for (client, player_position) in player_q {
34+
if player_position.world != world {
35+
continue;
36+
}
37+
change_difficulty_pw.write(ClientboundChangeDifficulty {
38+
client,
39+
difficulty: *difficulty,
40+
difficulty_locked: false,
41+
});
42+
}
4143
}
4244
}

0 commit comments

Comments
 (0)