Add PlayerAbilities

This commit is contained in:
Snowiiii 2024-08-26 22:21:02 +02:00
parent 80ffaff777
commit 65d8093694
2 changed files with 82 additions and 13 deletions

View File

@ -65,12 +65,19 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
let gamemode = parse_arg_gamemode(args)?; let gamemode = parse_arg_gamemode(args)?;
return if let Player(target) = sender { return if let Player(target) = sender {
target.set_gamemode(server, gamemode); dbg!("1");
target.send_system_message(TextComponent::text(&format!( if target.gamemode == gamemode {
"Game mode was set to {:?}", target.send_system_message(TextComponent::text(&format!(
gamemode "You already in {:?} gamemode",
))); gamemode
)));
} else {
target.set_gamemode(server, gamemode);
target.send_system_message(TextComponent::text(&format!(
"Game mode was set to {:?}",
gamemode
)));
}
Ok(()) Ok(())
} else { } else {
Err(InvalidRequirementError) Err(InvalidRequirementError)
@ -82,11 +89,18 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
let gamemode = parse_arg_gamemode(args)?; let gamemode = parse_arg_gamemode(args)?;
let target = parse_arg_player(sender, ARG_TARGET, args)?; let target = parse_arg_player(sender, ARG_TARGET, args)?;
target.set_gamemode(server, gamemode); if target.gamemode == gamemode {
target.send_system_message(TextComponent::text(&format!( target.send_system_message(TextComponent::text(&format!(
"Set own game mode to {:?}", "You already in {:?} gamemode",
gamemode gamemode
))); )));
} else {
target.set_gamemode(server, gamemode);
target.send_system_message(TextComponent::text(&format!(
"Game mode was set to {:?}",
gamemode
)));
}
Ok(()) Ok(())
}, },

View File

@ -8,8 +8,8 @@ use pumpkin_inventory::player::PlayerInventory;
use pumpkin_protocol::{ use pumpkin_protocol::{
bytebuf::{packet_id::Packet, DeserializerError}, bytebuf::{packet_id::Packet, DeserializerError},
client::play::{ client::play::{
CGameEvent, CPlayDisconnect, CPlayerInfoUpdate, CSyncPlayerPosition, CSystemChatMessage, CGameEvent, CPlayDisconnect, CPlayerAbilities, CPlayerInfoUpdate, CSyncPlayerPosition,
PlayerAction, CSystemChatMessage, PlayerAction,
}, },
position::WorldPosition, position::WorldPosition,
server::play::{ server::play::{
@ -25,6 +25,28 @@ use serde::{Deserialize, Serialize};
use crate::{client::Client, server::Server, util::boundingbox::BoundingBox}; use crate::{client::Client, server::Server, util::boundingbox::BoundingBox};
pub struct PlayerAbilities {
pub invulnerable: bool,
pub flying: bool,
pub allow_flying: bool,
pub creative: bool,
pub fly_speed: f32,
pub walk_speed_fov: f32,
}
impl Default for PlayerAbilities {
fn default() -> Self {
Self {
invulnerable: false,
flying: false,
allow_flying: false,
creative: false,
fly_speed: 0.5,
walk_speed_fov: 0.1,
}
}
}
pub struct Player { pub struct Player {
pub client: Client, pub client: Client,
pub entity: Entity, pub entity: Entity,
@ -35,6 +57,8 @@ pub struct Player {
pub food: i32, pub food: i32,
pub food_saturation: f32, pub food_saturation: f32,
pub inventory: PlayerInventory, pub inventory: PlayerInventory,
/// send `send_abilties_update` when changed
pub abilities: PlayerAbilities,
// Client side value, Should be not trusted // Client side value, Should be not trusted
pub on_ground: bool, pub on_ground: bool,
@ -70,6 +94,7 @@ impl Player {
velocity: Vector3::new(0.0, 0.0, 0.0), velocity: Vector3::new(0.0, 0.0, 0.0),
inventory: PlayerInventory::new(), inventory: PlayerInventory::new(),
teleport_id_count: 0, teleport_id_count: 0,
abilities: PlayerAbilities::default(),
gamemode, gamemode,
} }
} }
@ -100,6 +125,29 @@ impl Player {
); );
} }
pub fn send_abilties_update(&mut self) {
let mut b = 0i8;
let abilities = &self.abilities;
if abilities.invulnerable {
b |= 1;
}
if abilities.flying {
b |= 2;
}
if abilities.allow_flying {
b |= 4;
}
if abilities.creative {
b |= 8;
}
self.client.send_packet(&CPlayerAbilities::new(
b,
abilities.fly_speed,
abilities.walk_speed_fov,
));
}
pub fn teleport(&mut self, x: f64, y: f64, z: f64, yaw: f32, pitch: f32) { pub fn teleport(&mut self, x: f64, y: f64, z: f64, yaw: f32, pitch: f32) {
// this is the ultra special magic code used to create the teleport id // this is the ultra special magic code used to create the teleport id
self.teleport_id_count += 1; self.teleport_id_count += 1;
@ -163,7 +211,14 @@ impl Player {
} }
pub fn set_gamemode(&mut self, server: &mut Server, gamemode: GameMode) { pub fn set_gamemode(&mut self, server: &mut Server, gamemode: GameMode) {
// We could send the same gamemode without problems. But why waste bandwidth ?
assert!(
self.gamemode != gamemode,
"Setting the same gamemode as already is"
);
self.gamemode = gamemode; self.gamemode = gamemode;
// So a little story time. I actually made an abitlties_from_gamemode function. I looked at vanilla and they always send the abilties from the gamemode. But the funny thing actually is. That the client
// does actually use the same method and set the abilties when receiving the CGameEvent gamemode packet. Just Mojang nonsense
server.broadcast_packet( server.broadcast_packet(
self, self,
&CPlayerInfoUpdate::new( &CPlayerInfoUpdate::new(