Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ members = [
"quill/example-plugins/plugin-message",
"quill/example-plugins/query-entities",
"quill/example-plugins/simple",
"quill/example-plugins/observe-creativemode-flight-event",

# Feather (common and server)
"feather/utils",
Expand Down
7 changes: 5 additions & 2 deletions feather/common/src/entities/player.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use anyhow::bail;
use base::EntityKind;
use ecs::{EntityBuilder, SysResult};
use quill_common::entities::Player;
use quill_common::{components::CreativeFlying, entities::Player};

pub fn build_default(builder: &mut EntityBuilder) {
super::build_default(builder);
builder.add(Player).add(EntityKind::Player);
builder
.add(Player)
.add(CreativeFlying(false))
.add(EntityKind::Player);
}

/// The hotbar slot a player's cursor is currently on
Expand Down
5 changes: 4 additions & 1 deletion feather/server/src/packet_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ pub fn handle_packet(

ClientPlayPacket::ClientSettings(packet) => handle_client_settings(server, player, packet),

ClientPlayPacket::PlayerAbilities(packet) => {
movement::handle_player_abilities(game, player_id, packet)
}

ClientPlayPacket::TeleportConfirm(_)
| ClientPlayPacket::QueryBlockNbt(_)
| ClientPlayPacket::SetDifficulty(_)
Expand All @@ -84,7 +88,6 @@ pub fn handle_packet(
| ClientPlayPacket::SteerBoat(_)
| ClientPlayPacket::PickItem(_)
| ClientPlayPacket::CraftRecipeRequest(_)
| ClientPlayPacket::PlayerAbilities(_)
| ClientPlayPacket::EntityAction(_)
| ClientPlayPacket::SteerVehicle(_)
| ClientPlayPacket::SetDisplayedRecipe(_)
Expand Down
53 changes: 50 additions & 3 deletions feather/server/src/packet_handlers/movement.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use base::Position;
use ecs::{EntityRef, SysResult};
use common::Game;
use ecs::{Entity, EntityRef, SysResult};
use protocol::packets::client::{
PlayerMovement, PlayerPosition, PlayerPositionAndRotation, PlayerRotation,
PlayerAbilities, PlayerMovement, PlayerPosition, PlayerPositionAndRotation, PlayerRotation,
};
use quill_common::{
components::{CreativeFlying, OnGround},
events::CreativeFlyingEvent,
};
use quill_common::components::OnGround;

use crate::{ClientId, Server};

Expand Down Expand Up @@ -89,3 +93,46 @@ fn update_client_position(server: &Server, player: EntityRef, pos: Position) ->
}
Ok(())
}

/// Handles the PlayerAbilities packet that signals, if the client wants to
/// start/stop flying (like in creative mode).
pub fn handle_player_abilities(
game: &mut Game,
player: Entity,
packet: PlayerAbilities,
) -> SysResult {
let flying = game.ecs.get_mut::<CreativeFlying>(player)?.0;

match packet.flags {
0 => {
// Flying stopped
if flying {
// Then it used to fly, therefor we need to trigger a event
// The vanilla client is actually quite good at keeping track of sending
// this packet only when there is a change, so this if should basically
// always trigger.
game.ecs
.insert_entity_event(player, CreativeFlyingEvent::new(false))?;

game.ecs.get_mut::<CreativeFlying>(player)?.0 = false;
}
}
2 => {
// Flying started
if !flying {
// Then it used to not fly, therefor we need to trigger a event.
// The vanilla client is actually quite good at keeping track of sending
// this packet only when there is a change, so this if should basically
// always trigger.
game.ecs
.insert_entity_event(player, CreativeFlyingEvent::new(true))?;
game.ecs.get_mut::<CreativeFlying>(player)?.0 = true;
}
}
err => {
log::error!("Got a unexpected flag in the PlayerAbilities packet. The value was: {} and not 0 or 2.", err)
}
}

Ok(())
}
14 changes: 13 additions & 1 deletion quill/common/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ host_component_enum! {
Particle = 1005,
InteractEntityEvent = 1006,
BlockPlacementEvent = 1007,
BlockInteractEvent = 1008
BlockInteractEvent = 1008,
CreativeFlying = 1009,
CreativeFlyingEvent = 1010,

}
}

Expand Down Expand Up @@ -303,6 +306,14 @@ macro_rules! pod_component_impl {

pod_component_impl!(Position);

/**
If you are using this macro and you get the error:
```
error[E0599]: no variant or associated item named `...` found for enum `HostComponent` in the current scope.
```
Then you need to go to the top of the file were this macro is defined. There you find the HostCompoent enum, that
you need to add your component to.
*/
macro_rules! bincode_component_impl {
($type:ident) => {
unsafe impl crate::Component for $type {
Expand Down Expand Up @@ -336,3 +347,4 @@ bincode_component_impl!(Particle);
bincode_component_impl!(InteractEntityEvent);
bincode_component_impl!(BlockPlacementEvent);
bincode_component_impl!(BlockInteractEvent);
bincode_component_impl!(CreativeFlyingEvent);
6 changes: 6 additions & 0 deletions quill/common/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,9 @@ impl Display for CustomName {
self.0.fmt(f)
}
}

/// Whether an entity is flying (like in creative mode)
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CreativeFlying(pub bool);

bincode_component_impl!(CreativeFlying);
2 changes: 2 additions & 0 deletions quill/common/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod block_interact;
mod change;
mod interact_entity;

pub use block_interact::{BlockInteractEvent, BlockPlacementEvent};
pub use change::CreativeFlyingEvent;
pub use interact_entity::InteractEntityEvent;
13 changes: 13 additions & 0 deletions quill/common/src/events/change.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CreativeFlyingEvent {
pub is_flying: bool,
}

impl CreativeFlyingEvent {
pub fn new(changed_to: bool) -> Self {
Self {
is_flying: changed_to,
}
}
}
11 changes: 11 additions & 0 deletions quill/example-plugins/observe-creativemode-flight-event/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "observe-creativemode-flight-event"
version = "0.1.0"
authors = ["Miro Andrin <[email protected]>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
quill = { path = "../../api" }
29 changes: 29 additions & 0 deletions quill/example-plugins/observe-creativemode-flight-event/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
This plugin observers the CreativeFlightEvent printing a msg when someone starts
flying.
*/

use quill::{events::CreativeFlyingEvent, Game, Plugin, Setup};

quill::plugin!(FlightPlugin);

struct FlightPlugin {}

impl Plugin for FlightPlugin {
fn enable(_game: &mut Game, setup: &mut Setup<Self>) -> Self {
setup.add_system(flight_observer_system);
FlightPlugin {}
}

fn disable(self, _game: &mut Game) {}
}

fn flight_observer_system(_plugin: &mut FlightPlugin, game: &mut Game) {
for (entity, change) in game.query::<&CreativeFlyingEvent>() {
if change.is_flying {
entity.send_message("Enjoy your flight!");
} else {
entity.send_message("Hope you enjoyed your flight.");
}
}
}