Skip to content

Commit 85afb91

Browse files
committed
basic ender pearl implementation
1 parent 3fe2c94 commit 85afb91

File tree

15 files changed

+229
-36
lines changed

15 files changed

+229
-36
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::block::Block;
2+
use crate::types::aabb::AABB;
3+
use crate::{World, WorldExtension};
4+
use glam::dvec3;
5+
6+
pub fn check_block_collisions<W : WorldExtension + 'static>(world: &World<W>, aabb: &AABB) -> bool {
7+
let min_x = aabb.min.x.floor() as i32;
8+
let min_y = aabb.min.y.floor() as i32;
9+
let min_z = aabb.min.z.floor() as i32;
10+
let max_x = aabb.max.x.ceil() as i32;
11+
let max_y = aabb.max.y.ceil() as i32;
12+
let max_z = aabb.max.z.ceil() as i32;
13+
14+
for x in min_x..max_x {
15+
for y in min_y..max_y {
16+
for z in min_z..max_z {
17+
let block = world.chunk_grid.get_block_at(x, y, z);
18+
let (shapes, len) = block_collision(block);
19+
for shape in &shapes[..len] {
20+
let shifted = shape.offset(dvec3(x as f64, y as f64, z as f64));
21+
if aabb.intersects(&shifted) {
22+
return true;
23+
}
24+
}
25+
}
26+
}
27+
}
28+
29+
false
30+
}
31+
32+
pub fn block_collision(block: Block) -> ([AABB; 1], usize) {
33+
let length = if block == Block::Air { 0 } else { 1 };
34+
([AABB::new(dvec3(0.0, 0.0, 0.0), dvec3(1.0, 1.0, 1.0))], length)
35+
}

server/src/block/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ pub mod block_parameter;
22
pub mod blocks;
33
pub mod metadata;
44
pub mod rotatable;
5+
pub mod block_collision;
56

67
pub use blocks::Block;

server/src/constants/entity_variants.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub enum EntityVariant {
1111
#[repr(i8)]
1212
#[derive(Copy, Clone)]
1313
pub enum ObjectVariant {
14+
EnderPearl = 65,
1415
FallingBlock = 70
1516
}
1617

server/src/entity/entities.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ impl<W: WorldExtension + 'static> Entities<W> {
5959
// maybe rename, since this is what also ticks mc entity
6060
pub(crate) fn register_appearance_update<T: EntityAppearance<W>>(&mut self) {
6161
self.tick_systems.post.insert(|world| {
62-
let mut query = world.query::<(&mut MinecraftEntity<W>, &T)>();
63-
for (mut entity, appearance) in query.iter_mut(world) {
64-
entity.update(appearance);
62+
let mut query = world.query::<(&mut MinecraftEntity<W>, Entity, &T)>();
63+
for (mut entity, entity_id, appearance) in query.iter_mut(world) {
64+
entity.update(appearance, entity_id);
6565
}
6666
});
6767
}

server/src/entity/entity.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::network::protocol::play::clientbound::DestroyEntites;
55
use crate::world::chunk::get_chunk_position;
66
use crate::{Player, World, WorldExtension};
77
use bevy_ecs::component::Component;
8+
use bevy_ecs::entity::Entity;
89
use bevy_ecs::world::{EntityMut, EntityRef};
910
use glam::DVec3;
1011
use std::ptr::NonNull;
@@ -16,7 +17,7 @@ pub struct MinecraftEntity<W: WorldExtension> {
1617
pub id: MCEntityId,
1718

1819
pub position: DVec3,
19-
pub velocity: DVec3, // maybe seperate?
20+
pub velocity: DVec3,
2021
pub yaw: f32,
2122
pub pitch: f32,
2223

@@ -80,21 +81,34 @@ impl<W: WorldExtension + 'static> MinecraftEntity<W> {
8081
unsafe { self.world.as_mut() }
8182
}
8283

83-
pub(crate) fn update<T : EntityAppearance<W>>(&mut self, appearance: &T) {
84+
pub(crate) fn update<T : EntityAppearance<W>>(&mut self, appearance: &T, entity_id: Entity) {
8485
if self.position != self.last_position || self.yaw != self.last_yaw || self.pitch != self.last_pitch {
8586
let (chunk_x, chunk_z) = get_chunk_position(self.position);
8687
let Some(chunk) = self.world_mut().chunk_grid.get_chunk_mut(chunk_x, chunk_z) else {
8788
return;
8889
};
8990

91+
let (old_cx, old_cz) = get_chunk_position(self.last_position);
92+
if old_cx != chunk_x || old_cz != chunk_z {
93+
if let Some(chunk) = self.world_mut().chunk_grid.get_chunk_mut(old_cx, old_cz) {
94+
chunk.remove_entity(entity_id)
95+
}
96+
chunk.insert_entity(entity_id)
97+
}
98+
9099
appearance.update_position(self, &mut chunk.packet_buffer);
91100
self.last_position = self.position;
92101
self.last_yaw = self.yaw;
93102
self.last_pitch = self.pitch;
94103
}
95-
96104
self.ticks_existed += 1;
97105
}
106+
107+
pub fn destroy(&mut self) {
108+
let world = self.world_mut();
109+
let entity = world.entities.mc_id_to_entity(self.id).unwrap();
110+
world.remove_entity(*entity)
111+
}
98112
}
99113

100114

server/src/network/protocol/play/clientbound.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ packet_serializable! {
225225

226226
packet_serializable! {
227227
pub struct EntityVelocity {
228-
pub entity_id: VarInt,
229-
pub velocity_x: i16,
230-
pub velocity_y: i16,
231-
pub velocity_z: i16,
228+
pub entity_id: i32 => &VarInt(self.entity_id),
229+
pub velocity_x: f64 => &((self.velocity_x.clamp(-MOTION_CLAMP, MOTION_CLAMP) * 8000.0) as i16),
230+
pub velocity_y: f64 => &((self.velocity_y.clamp(-MOTION_CLAMP, MOTION_CLAMP) * 8000.0) as i16),
231+
pub velocity_z: f64 => &((self.velocity_z.clamp(-MOTION_CLAMP, MOTION_CLAMP) * 8000.0) as i16),
232232
}
233233
}
234234

server/src/player/player.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ impl<E : PlayerExtension> Player<E> {
341341
let container = unsafe { self.open_container.get().as_mut().unwrap() };
342342
container.sync_container(self);
343343
}
344+
345+
pub fn player_eye_position(&self) -> DVec3 {
346+
let mut position = self.position;
347+
position.y += 1.62;
348+
position
349+
}
344350

345351
pub fn rotation_vec(&self) -> Vec3 {
346352
let (yaw_sin, yaw_cos) = (-self.yaw.to_radians() - PI).sin_cos();

server/src/types/aabb.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ impl AABB {
4646
max: DVec3 { x: width / 2.0, y: height, z: width / 2.0 }
4747
}
4848
}
49+
50+
pub fn offset(self, dvec3: DVec3) -> AABB {
51+
AABB::new(self.min + dvec3, self.max + dvec3)
52+
}
4953
}

src/dungeon/door/door_entity.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::dungeon::dungeon::Dungeon;
22
use crate::dungeon::dungeon_player::DungeonPlayer;
3-
use bevy_ecs::entity::Entity;
43
use bevy_ecs::prelude::Component;
5-
use bevy_ecs::query::With;
64
use glam::{ivec3, DVec3};
75
use server::block::Block;
86
use server::constants::{EntityVariant, ObjectVariant};
@@ -18,28 +16,20 @@ use server::{Player, World};
1816
pub struct DoorBehaviour;
1917

2018
impl EntityBehaviour<Dungeon> for DoorBehaviour {
19+
fn tick(entity: &mut MinecraftEntity<Dungeon>, _: &mut Self) {
20+
entity.position.y -= 0.25;
2121

22-
fn tick(_: &mut MinecraftEntity<Dungeon>, _: &mut Self) {}
22+
if entity.ticks_existed == 20 {
23+
let world = entity.world_mut();
24+
let x = entity.position.x as i32;
25+
let z = entity.position.z as i32;
2326

24-
fn query(world: &mut bevy_ecs::prelude::World) {
25-
// need entity(id) from query,
26-
// without using macro IDK if there's a good way to define a nicer query with traits ,
27-
let mut query = world.query_filtered::<(Entity, &mut MinecraftEntity<Dungeon>), With<DoorBehaviour>>();
28-
for (entity_id, mut entity) in query.iter_mut(world) {
29-
entity.position.y -= 0.25;
30-
31-
if entity.ticks_existed == 20 {
32-
let world = entity.world_mut();
33-
let x = entity.position.x as i32;
34-
let z = entity.position.z as i32;
35-
36-
world.chunk_grid.fill_blocks(
37-
Block::Air,
38-
ivec3(x, 69, z),
39-
ivec3(x + 2, 72, z + 2),
40-
);
41-
world.remove_entity(entity_id);
42-
}
27+
world.chunk_grid.fill_blocks(
28+
Block::Air,
29+
ivec3(x, 69, z),
30+
ivec3(x + 2, 72, z + 2),
31+
);
32+
entity.destroy()
4333
}
4434
}
4535
}

src/dungeon/dungeon.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,11 @@ impl WorldExtension for Dungeon {
196196

197197
player.extension.sidebar.write_init_packets(&mut player.packet_buffer);
198198

199-
player.inventory.set_slot(37, Some(DungeonItem::Hyperion));
199+
player.inventory.set_slot(36, Some(DungeonItem::Hyperion));
200+
player.inventory.set_slot(37, Some(DungeonItem::AspectOfTheVoid));
201+
player.inventory.set_slot(38, Some(DungeonItem::EnderPearl));
200202
player.inventory.set_slot(39, Some(DungeonItem::Pickaxe));
201203
player.inventory.set_slot(42, Some(DungeonItem::TacticalInsertion));
202-
player.inventory.set_slot(43, Some(DungeonItem::AspectOfTheVoid));
203204
player.inventory.set_slot(44, Some(DungeonItem::SkyblockMenu));
204205
player.sync_inventory();
205206

0 commit comments

Comments
 (0)