2022-10-24 12:03:56 -04:00
|
|
|
use std::sync::Arc;
|
|
|
|
use std::sync::RwLock;
|
2022-09-24 04:46:44 -04:00
|
|
|
|
2016-03-26 18:21:47 -04:00
|
|
|
use super::*;
|
2018-11-04 14:48:03 -05:00
|
|
|
use crate::ecs;
|
|
|
|
use crate::render;
|
|
|
|
use crate::shared::Position as BPos;
|
2020-06-21 15:17:24 -04:00
|
|
|
use crate::world;
|
2018-10-27 21:11:26 -04:00
|
|
|
use cgmath::InnerSpace;
|
2022-10-24 12:04:54 -04:00
|
|
|
use log::debug;
|
2022-09-24 04:46:44 -04:00
|
|
|
use steven_protocol::protocol;
|
2022-10-24 12:03:56 -04:00
|
|
|
use steven_protocol::protocol::Conn;
|
2016-03-26 18:21:47 -04:00
|
|
|
|
|
|
|
pub struct ApplyVelocity {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
position: ecs::Key<Position>,
|
|
|
|
velocity: ecs::Key<Velocity>,
|
|
|
|
movement: ecs::Key<super::player::PlayerMovement>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ApplyVelocity {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> ApplyVelocity {
|
|
|
|
let position = m.get_key();
|
|
|
|
let velocity = m.get_key();
|
|
|
|
ApplyVelocity {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(position).with(velocity),
|
2018-11-04 16:43:30 -05:00
|
|
|
position,
|
|
|
|
velocity,
|
2016-03-26 18:21:47 -04:00
|
|
|
movement: m.get_key(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for ApplyVelocity {
|
2016-03-27 09:25:34 -04:00
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:45:12 -04:00
|
|
|
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
2016-03-26 18:21:47 -04:00
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
if m.get_component(e, self.movement).is_some() {
|
2021-07-18 12:12:42 -04:00
|
|
|
// Player's handle their own physics
|
2016-03-26 18:21:47 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let pos = m.get_component_mut(e, self.position).unwrap();
|
|
|
|
let vel = m.get_component(e, self.velocity).unwrap();
|
2020-06-30 22:03:59 -04:00
|
|
|
pos.position += vel.velocity;
|
2016-03-26 18:21:47 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ApplyGravity {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
velocity: ecs::Key<Velocity>,
|
|
|
|
movement: ecs::Key<super::player::PlayerMovement>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ApplyGravity {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> ApplyGravity {
|
|
|
|
let gravity = m.get_key::<Gravity>();
|
|
|
|
let velocity = m.get_key();
|
|
|
|
ApplyGravity {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(gravity).with(velocity),
|
2018-11-04 16:43:30 -05:00
|
|
|
velocity,
|
2016-03-26 18:21:47 -04:00
|
|
|
movement: m.get_key(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for ApplyGravity {
|
2016-03-27 09:25:34 -04:00
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:45:12 -04:00
|
|
|
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
2016-03-26 18:21:47 -04:00
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
if m.get_component(e, self.movement).is_some() {
|
2021-07-18 12:12:42 -04:00
|
|
|
// Player's handle their own physics
|
2016-03-26 18:21:47 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let vel = m.get_component_mut(e, self.velocity).unwrap();
|
|
|
|
|
|
|
|
vel.velocity.y -= 0.03;
|
|
|
|
if vel.velocity.y < -0.3 {
|
|
|
|
vel.velocity.y = -0.3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct UpdateLastPosition {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
position: ecs::Key<Position>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UpdateLastPosition {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> UpdateLastPosition {
|
|
|
|
let position = m.get_key();
|
|
|
|
UpdateLastPosition {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(position),
|
2018-11-04 16:43:30 -05:00
|
|
|
position,
|
2016-03-26 18:21:47 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for UpdateLastPosition {
|
2016-03-27 09:25:34 -04:00
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:45:12 -04:00
|
|
|
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
2016-03-26 18:21:47 -04:00
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
let pos = m.get_component_mut(e, self.position).unwrap();
|
|
|
|
|
2018-10-27 21:11:26 -04:00
|
|
|
pos.moved = (pos.position - pos.last_position).magnitude2() > 0.01;
|
2016-03-26 18:21:47 -04:00
|
|
|
pos.last_position = pos.position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-07 14:30:42 -04:00
|
|
|
|
|
|
|
pub struct LerpPosition {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
position: ecs::Key<Position>,
|
|
|
|
target_position: ecs::Key<TargetPosition>,
|
|
|
|
game_info: ecs::Key<GameInfo>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LerpPosition {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> LerpPosition {
|
|
|
|
let position = m.get_key();
|
|
|
|
let target_position = m.get_key();
|
|
|
|
LerpPosition {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(position).with(target_position),
|
2018-11-04 16:43:30 -05:00
|
|
|
position,
|
|
|
|
target_position,
|
2016-04-07 14:30:42 -04:00
|
|
|
game_info: m.get_key(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for LerpPosition {
|
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
|
|
|
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
|
|
|
let world_entity = m.get_world();
|
2020-06-21 15:17:24 -04:00
|
|
|
let delta = m
|
|
|
|
.get_component_mut(world_entity, self.game_info)
|
|
|
|
.unwrap()
|
|
|
|
.delta
|
|
|
|
.min(5.0);
|
2016-04-07 14:30:42 -04:00
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
let pos = m.get_component_mut(e, self.position).unwrap();
|
|
|
|
let target_pos = m.get_component(e, self.target_position).unwrap();
|
|
|
|
|
2020-06-21 15:17:24 -04:00
|
|
|
pos.position = pos.position
|
|
|
|
+ (target_pos.position - pos.position) * delta * target_pos.lerp_amount;
|
|
|
|
let len = (pos.position - target_pos.position).magnitude2();
|
2020-12-31 12:51:46 -05:00
|
|
|
if !(0.001..=100.0 * 100.0).contains(&len) {
|
2016-04-08 12:45:05 -04:00
|
|
|
pos.position = target_pos.position;
|
|
|
|
}
|
2016-04-07 14:30:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct LerpRotation {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
rotation: ecs::Key<Rotation>,
|
|
|
|
target_rotation: ecs::Key<TargetRotation>,
|
|
|
|
game_info: ecs::Key<GameInfo>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LerpRotation {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> LerpRotation {
|
|
|
|
let rotation = m.get_key();
|
|
|
|
let target_rotation = m.get_key();
|
|
|
|
LerpRotation {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(rotation).with(target_rotation),
|
2018-11-04 16:43:30 -05:00
|
|
|
rotation,
|
|
|
|
target_rotation,
|
2016-04-07 14:30:42 -04:00
|
|
|
game_info: m.get_key(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for LerpRotation {
|
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
|
|
|
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
|
|
|
|
use std::f64::consts::PI;
|
|
|
|
let world_entity = m.get_world();
|
2020-06-21 15:17:24 -04:00
|
|
|
let delta = m
|
|
|
|
.get_component_mut(world_entity, self.game_info)
|
|
|
|
.unwrap()
|
|
|
|
.delta
|
|
|
|
.min(5.0);
|
2016-04-07 14:30:42 -04:00
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
let rot = m.get_component_mut(e, self.rotation).unwrap();
|
|
|
|
let target_rot = m.get_component_mut(e, self.target_rotation).unwrap();
|
2020-06-21 15:17:24 -04:00
|
|
|
target_rot.yaw = (PI * 2.0 + target_rot.yaw) % (PI * 2.0);
|
|
|
|
target_rot.pitch = (PI * 2.0 + target_rot.pitch) % (PI * 2.0);
|
2016-04-07 14:30:42 -04:00
|
|
|
|
|
|
|
let mut delta_yaw = target_rot.yaw - rot.yaw;
|
|
|
|
let mut delta_pitch = target_rot.pitch - rot.pitch;
|
|
|
|
|
|
|
|
if delta_yaw.abs() > PI {
|
|
|
|
delta_yaw = (PI - delta_yaw.abs()) * delta_yaw.signum();
|
|
|
|
}
|
|
|
|
if delta_pitch.abs() > PI {
|
|
|
|
delta_pitch = (PI - delta_pitch.abs()) * delta_pitch.signum();
|
|
|
|
}
|
|
|
|
|
|
|
|
rot.yaw += delta_yaw * 0.2 * delta;
|
|
|
|
rot.pitch += delta_pitch * 0.2 * delta;
|
2020-06-21 15:17:24 -04:00
|
|
|
rot.yaw = (PI * 2.0 + rot.yaw) % (PI * 2.0);
|
|
|
|
rot.pitch = (PI * 2.0 + rot.pitch) % (PI * 2.0);
|
2016-04-07 14:30:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-08 06:08:21 -04:00
|
|
|
|
|
|
|
pub struct LightEntity {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
position: ecs::Key<Position>,
|
|
|
|
bounds: ecs::Key<Bounds>,
|
2020-06-21 15:17:24 -04:00
|
|
|
light: ecs::Key<Light>,
|
2016-04-08 06:08:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl LightEntity {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> LightEntity {
|
|
|
|
let position = m.get_key();
|
|
|
|
let bounds = m.get_key();
|
|
|
|
let light = m.get_key();
|
|
|
|
LightEntity {
|
2020-06-21 15:17:24 -04:00
|
|
|
filter: ecs::Filter::new().with(position).with(bounds).with(light),
|
2018-11-04 16:43:30 -05:00
|
|
|
position,
|
|
|
|
bounds,
|
|
|
|
light,
|
2016-04-08 06:08:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for LightEntity {
|
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
|
|
|
fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, _: &mut render::Renderer) {
|
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
let pos = m.get_component(e, self.position).unwrap();
|
|
|
|
let bounds = m.get_component(e, self.bounds).unwrap();
|
|
|
|
let light = m.get_component_mut(e, self.light).unwrap();
|
|
|
|
let mut count = 0.0;
|
|
|
|
let mut block_light = 0.0;
|
|
|
|
let mut sky_light = 0.0;
|
|
|
|
|
|
|
|
let min_x = (pos.position.x + bounds.bounds.min.x).floor() as i32;
|
|
|
|
let min_y = (pos.position.y + bounds.bounds.min.y).floor() as i32;
|
|
|
|
let min_z = (pos.position.z + bounds.bounds.min.z).floor() as i32;
|
|
|
|
let max_x = (pos.position.x + bounds.bounds.max.x).ceil() as i32 + 1;
|
|
|
|
let max_y = (pos.position.y + bounds.bounds.max.y).ceil() as i32 + 1;
|
|
|
|
let max_z = (pos.position.z + bounds.bounds.max.z).ceil() as i32 + 1;
|
|
|
|
|
2018-10-27 21:11:26 -04:00
|
|
|
let length = (bounds.bounds.max - bounds.bounds.min).magnitude() as f32;
|
2016-04-08 06:08:21 -04:00
|
|
|
|
2020-06-21 15:17:24 -04:00
|
|
|
for y in min_y..max_y {
|
|
|
|
for z in min_z..max_z {
|
|
|
|
for x in min_x..max_x {
|
|
|
|
let dist = length
|
|
|
|
- (((x as f32 + 0.5) - pos.position.x as f32).powi(2)
|
2016-04-08 06:08:21 -04:00
|
|
|
+ ((y as f32 + 0.5) - pos.position.y as f32).powi(2)
|
2020-06-21 15:17:24 -04:00
|
|
|
+ ((z as f32 + 0.5) - pos.position.z as f32).powi(2))
|
2016-04-08 06:08:21 -04:00
|
|
|
.sqrt()
|
|
|
|
.min(length);
|
|
|
|
let dist = dist / length;
|
|
|
|
count += dist;
|
|
|
|
block_light += world.get_block_light(BPos::new(x, y, z)) as f32 * dist;
|
|
|
|
sky_light += world.get_sky_light(BPos::new(x, y, z)) as f32 * dist;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if count <= 0.01 {
|
|
|
|
light.block_light = 0.0;
|
|
|
|
light.sky_light = 0.0;
|
|
|
|
} else {
|
|
|
|
light.block_light = block_light / count;
|
|
|
|
light.sky_light = sky_light / count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-24 04:46:44 -04:00
|
|
|
|
|
|
|
pub struct ApplyDigging {
|
|
|
|
filter: ecs::Filter,
|
|
|
|
mouse_buttons: ecs::Key<MouseButtons>,
|
|
|
|
digging: ecs::Key<Digging>,
|
2022-10-24 12:03:56 -04:00
|
|
|
conn: ecs::Key<Arc<RwLock<Option<Conn>>>>,
|
2022-09-24 04:46:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ApplyDigging {
|
|
|
|
pub fn new(m: &mut ecs::Manager) -> Self {
|
|
|
|
let mouse_buttons = m.get_key();
|
|
|
|
let digging = m.get_key();
|
|
|
|
Self {
|
|
|
|
filter: ecs::Filter::new().with(mouse_buttons).with(digging),
|
|
|
|
mouse_buttons,
|
|
|
|
digging,
|
2022-10-24 12:03:56 -04:00
|
|
|
conn: m.get_key(),
|
2022-09-24 04:46:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-24 12:08:30 -04:00
|
|
|
fn send_packet(&self, conn: &mut Conn, target: &DiggingState, state: i32) {
|
2022-09-24 04:46:44 -04:00
|
|
|
match state {
|
2022-10-24 12:04:54 -04:00
|
|
|
0 => debug!("Send start dig packet {:?}", target),
|
|
|
|
1 => debug!("Send cancel dig packet {:?}", target),
|
|
|
|
2 => debug!("Send finish dig packet {:?}", target),
|
2022-09-24 04:46:44 -04:00
|
|
|
n => panic!("Invalid dig state {}", n),
|
|
|
|
}
|
|
|
|
|
2022-10-24 12:03:56 -04:00
|
|
|
match conn.protocol_version {
|
|
|
|
// 1.7.10
|
2022-10-24 12:08:30 -04:00
|
|
|
5 => conn
|
|
|
|
.write_packet(packet::play::serverbound::PlayerDigging_u8_u8y {
|
|
|
|
status: state as u8,
|
|
|
|
x: target.position.x,
|
|
|
|
y: target.position.y as u8,
|
|
|
|
z: target.position.z,
|
|
|
|
face: target.face.index() as u8,
|
|
|
|
})
|
|
|
|
.unwrap(),
|
2022-10-24 12:03:56 -04:00
|
|
|
// 1.8.9 or v15w39c
|
2022-10-24 12:08:30 -04:00
|
|
|
47 | 74 => conn
|
|
|
|
.write_packet(packet::play::serverbound::PlayerDigging_u8 {
|
|
|
|
status: state as u8,
|
|
|
|
location: target.position,
|
|
|
|
face: target.face.index() as u8,
|
|
|
|
})
|
|
|
|
.unwrap(),
|
2022-10-24 12:03:56 -04:00
|
|
|
// 1.9+
|
2022-10-24 12:08:30 -04:00
|
|
|
_ => conn
|
|
|
|
.write_packet(packet::play::serverbound::PlayerDigging {
|
|
|
|
status: protocol::VarInt(state),
|
|
|
|
location: target.position,
|
|
|
|
face: target.face.index() as u8,
|
|
|
|
})
|
|
|
|
.unwrap(),
|
2022-10-24 12:03:56 -04:00
|
|
|
}
|
2022-09-24 04:46:44 -04:00
|
|
|
}
|
|
|
|
|
2022-10-24 12:08:30 -04:00
|
|
|
fn next_state(
|
|
|
|
&self,
|
2022-09-24 04:46:44 -04:00
|
|
|
last: &Option<DiggingState>,
|
|
|
|
mouse_buttons: &MouseButtons,
|
2022-10-24 12:08:30 -04:00
|
|
|
target: Option<(
|
|
|
|
shared::Position,
|
|
|
|
block::Block,
|
|
|
|
shared::Direction,
|
|
|
|
Vector3<f64>,
|
|
|
|
)>,
|
2022-09-24 04:46:44 -04:00
|
|
|
) -> Option<DiggingState> {
|
|
|
|
// Figure out the next state
|
|
|
|
if !mouse_buttons.left {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
match (last, target) {
|
|
|
|
// Started digging
|
|
|
|
(None, Some((position, block, face, _))) => Some(DiggingState {
|
2022-10-24 12:08:30 -04:00
|
|
|
block,
|
|
|
|
face,
|
|
|
|
position,
|
2022-09-24 04:46:44 -04:00
|
|
|
start: std::time::Instant::now(),
|
|
|
|
finished: false,
|
|
|
|
}),
|
|
|
|
(Some(current), Some((position, block, face, _))) => {
|
|
|
|
// Continue digging
|
|
|
|
if position == current.position {
|
|
|
|
return last.clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start digging a different block.
|
|
|
|
Some(DiggingState {
|
2022-10-24 12:08:30 -04:00
|
|
|
block,
|
|
|
|
face,
|
|
|
|
position,
|
2022-09-24 04:46:44 -04:00
|
|
|
start: std::time::Instant::now(),
|
|
|
|
finished: false,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
// Not pointing at any target
|
|
|
|
(_, None) => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_finished(&self, state: &DiggingState) -> bool {
|
|
|
|
let mining_time = state.block.get_mining_time(&None);
|
|
|
|
match mining_time {
|
|
|
|
Some(mining_time) => {
|
|
|
|
let finish_time = state.start + mining_time;
|
|
|
|
finish_time > std::time::Instant::now()
|
2022-10-24 12:08:30 -04:00
|
|
|
}
|
2022-09-24 04:46:44 -04:00
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ecs::System for ApplyDigging {
|
|
|
|
fn filter(&self) -> &ecs::Filter {
|
|
|
|
&self.filter
|
|
|
|
}
|
|
|
|
|
2022-10-24 12:08:30 -04:00
|
|
|
fn update(
|
|
|
|
&mut self,
|
|
|
|
m: &mut ecs::Manager,
|
|
|
|
world: &mut world::World,
|
|
|
|
renderer: &mut render::Renderer,
|
|
|
|
) {
|
|
|
|
use crate::server::target::{test_block, trace_ray};
|
2022-09-24 04:46:44 -04:00
|
|
|
use cgmath::EuclideanSpace;
|
|
|
|
|
2022-10-24 12:03:56 -04:00
|
|
|
let world_entity = m.get_world();
|
2022-10-24 12:08:30 -04:00
|
|
|
let mut conn = m
|
|
|
|
.get_component(world_entity, self.conn)
|
|
|
|
.unwrap()
|
|
|
|
.write()
|
|
|
|
.unwrap();
|
2022-10-24 12:03:56 -04:00
|
|
|
let conn = match conn.as_mut() {
|
|
|
|
Some(conn) => conn,
|
|
|
|
// Don't keep processing digging operations if the connection was
|
|
|
|
// closed.
|
|
|
|
None => return,
|
|
|
|
};
|
|
|
|
|
2022-09-24 04:46:44 -04:00
|
|
|
let target = trace_ray(
|
|
|
|
world,
|
|
|
|
4.0,
|
|
|
|
renderer.camera.pos.to_vec(),
|
|
|
|
renderer.view_vector.cast().unwrap(),
|
|
|
|
test_block,
|
|
|
|
);
|
|
|
|
|
|
|
|
for e in m.find(&self.filter) {
|
|
|
|
let mouse_buttons = m.get_component(e, self.mouse_buttons).unwrap();
|
|
|
|
let digging = m.get_component_mut(e, self.digging).unwrap();
|
|
|
|
|
|
|
|
// Update last and current state
|
|
|
|
std::mem::swap(&mut digging.last, &mut digging.current);
|
|
|
|
digging.current = self.next_state(&digging.last, mouse_buttons, target);
|
|
|
|
|
|
|
|
// Handle digging packets
|
|
|
|
match (&digging.last, &mut digging.current) {
|
|
|
|
// Start the new digging operation.
|
2022-10-24 12:03:56 -04:00
|
|
|
(None, Some(current)) => self.send_packet(conn, current, 0),
|
2022-09-24 04:46:44 -04:00
|
|
|
// Cancel the previous digging operation.
|
2022-10-24 12:03:56 -04:00
|
|
|
(Some(last), None) if !last.finished => self.send_packet(conn, last, 1),
|
2022-09-24 04:46:44 -04:00
|
|
|
// Move to digging a new block
|
|
|
|
(Some(last), Some(current)) if last.position != current.position => {
|
|
|
|
// Cancel the previous digging operation.
|
|
|
|
if !current.finished {
|
2022-10-24 12:03:56 -04:00
|
|
|
self.send_packet(conn, last, 1);
|
2022-09-24 04:46:44 -04:00
|
|
|
}
|
|
|
|
// Start the new digging operation.
|
2022-10-24 12:03:56 -04:00
|
|
|
self.send_packet(conn, current, 0);
|
2022-10-24 12:08:30 -04:00
|
|
|
}
|
2022-09-24 04:46:44 -04:00
|
|
|
// Finish the new digging operation.
|
|
|
|
(Some(_), Some(current)) if !self.is_finished(current) && !current.finished => {
|
2022-10-24 12:03:56 -04:00
|
|
|
self.send_packet(conn, current, 2);
|
2022-09-24 04:46:44 -04:00
|
|
|
current.finished = true;
|
2022-10-24 12:08:30 -04:00
|
|
|
}
|
|
|
|
_ => {}
|
2022-09-24 04:46:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-10-24 12:08:30 -04:00
|
|
|
}
|