Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Splash Potion Implementation #523

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
6 changes: 3 additions & 3 deletions pumpkin-protocol/src/client/play/c_spawn_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct CSpawnEntity {
entity_id: VarInt,
#[serde(with = "uuid::serde::compact")]
entity_uuid: uuid::Uuid,
typ: VarInt,
entity_type: VarInt,
x: f64,
y: f64,
z: f64,
Expand All @@ -28,7 +28,7 @@ impl CSpawnEntity {
pub fn new(
entity_id: VarInt,
entity_uuid: uuid::Uuid,
typ: VarInt,
entity_type: VarInt,
x: f64,
y: f64,
z: f64,
Expand All @@ -43,7 +43,7 @@ impl CSpawnEntity {
Self {
entity_id,
entity_uuid,
typ,
entity_type,
x,
y,
z,
Expand Down
1 change: 1 addition & 0 deletions pumpkin-protocol/src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use thiserror::Error;
pub mod bit_set;
pub mod identifier;
pub mod slot;
pub mod slot_components;
pub mod var_int;
pub mod var_long;

Expand Down
70 changes: 66 additions & 4 deletions pumpkin-protocol/src/codec/slot.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::codec::slot_components::PotionContents;
use crate::VarInt;
use pumpkin_world::item::ItemStack;
use serde::ser::SerializeSeq;
Expand All @@ -16,6 +17,36 @@ pub struct Slot {
components_to_remove: Option<Vec<VarInt>>,
}

macro_rules! back_to_enum {
($(#[$meta:meta])* $vis:vis enum $name:ident {
$($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)*
}) => {
$(#[$meta])*
$vis enum $name {
$($(#[$vmeta])* $vname $(= $val)?,)*
}

impl std::convert::TryFrom<i32> for $name {
type Error = ();

fn try_from(v: i32) -> Result<Self, Self::Error> {
match v {
$(x if x == $name::$vname as i32 => Ok($name::$vname),)*
_ => Err(()),
}
}
}
}
}
back_to_enum! {
pub enum StructuredComponentType {
CustomData,
// TODO: Implement all
PotionContents = 41,

}
}

impl<'de> Deserialize<'de> for Slot {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down Expand Up @@ -55,12 +86,43 @@ impl<'de> Deserialize<'de> for Slot {
let num_components_to_remove = seq
.next_element::<VarInt>()?
.ok_or(de::Error::custom("Failed to decode VarInt"))?;
if num_components_to_add.0 != 0 || num_components_to_remove.0 != 0 {
return Err(de::Error::custom(
"Slot components are currently unsupported",
));

for _ in 0..num_components_to_add.0 {
let component_type = seq
.next_element::<VarInt>()?
.ok_or(de::Error::custom("Failed to decode VarInt!!"))?;
log::info!("dat: {:?}", component_type);
// let s: StructuredComponentType = component_type.into();
match component_type.0.try_into() {
Ok(StructuredComponentType::PotionContents) => {
log::info!("yesir");
let has_potion_id = seq
.next_element::<PotionContents>()?
.ok_or(de::Error::custom("Failed to decode potion"))?;
// let potion_id = seq
// .next_element::<VarInt>()?
// .ok_or(de::Error::custom("Failed to decode VarInt"))?;
}
Ok(StructuredComponentType::CustomData) => {
log::info!("uhhuh")
}
Err(_) => log::error!("nooooo"),
// _ => {
// log::error!("nooooo")
// }
}
// let component_data = seq
// .next_element::<Slot>()?
// .ok_or(de::Error::custom("Unable to parse item"))?;
// array_of_changed_slots.push((slot_number, slot));
}

// if num_components_to_add.0 != 0 || num_components_to_remove.0 != 0 {
// return Err(de::Error::custom(
// "Slot components are currently unsupported",
// ));
// }

Ok(Slot {
item_count,
item_id: Some(item_id),
Expand Down
3 changes: 3 additions & 0 deletions pumpkin-protocol/src/codec/slot_components/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod potion_contents;

pub use potion_contents::*;
150 changes: 150 additions & 0 deletions pumpkin-protocol/src/codec/slot_components/potion_contents.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
use crate::codec::slot::StructuredComponentType;
use crate::VarInt;
use serde::{
de::{self, SeqAccess},
Deserialize,
};

#[derive(serde::Serialize, Debug, Clone)]
pub struct PotionContents {
has_potion_id: bool,
potion_id: Option<VarInt>,
has_custom_color: bool,
custom_color: Option<u32>,
number_of_custom_effects: VarInt,
custom_effects: Vec<PotionEffect>,
custom_name: String,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
pub struct PotionEffect {
type_id: VarInt, // todo: enum
detail: Detail,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
pub struct Detail {
amplifier: VarInt,
duration: VarInt,
ambient: bool,
show_particles: bool,
show_icon: bool,
has_hidden_effect: bool,
hidden_effect: Option<Box<Detail>>, // only if prev is true
}

impl<'de> Deserialize<'de> for PotionContents {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = PotionContents;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid PotionContents encoded in a byte sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let has_potion_id = seq
.next_element::<bool>()?
.ok_or(de::Error::custom("Failed to decode bool"))?;

let potion_id: Option<VarInt>;
if has_potion_id {
potion_id = Some(
seq.next_element::<VarInt>()?
.ok_or(de::Error::custom("Failed to decode VarInt"))?,
);
} else {
potion_id = None
}

let has_custom_color = seq
.next_element::<bool>()?
.ok_or(de::Error::custom("Failed to decode bool"))?;
let custom_color: Option<u32>;
if has_custom_color {
custom_color = Some(
seq.next_element::<u32>()?
.ok_or(de::Error::custom("Failed to decode bool"))?,
);
} else {
custom_color = None;
}

let number_of_custom_effects = seq
.next_element::<VarInt>()?
.ok_or(de::Error::custom("Failed to decode VarInt"))?;

for _ in 0..number_of_custom_effects.0 {
let component_type = seq
.next_element::<VarInt>()?
.ok_or(de::Error::custom("Failed to decode VarInt!!"))?;
log::info!("dat: {:?}", component_type);
// let s: StructuredComponentType = component_type.into();
match component_type.0.try_into() {
Ok(StructuredComponentType::PotionContents) => {
log::info!("yesir");
let has_potion_id = seq
.next_element::<PotionContents>()?
.ok_or(de::Error::custom("Failed to decode potion"))?;
// let potion_id = seq
// .next_element::<VarInt>()?
// .ok_or(de::Error::custom("Failed to decode VarInt"))?;
}
Ok(StructuredComponentType::CustomData) => {
log::info!("uhhuh")
}
Err(_) => log::error!("nooooo"),
// _ => {
// log::error!("nooooo")
// }
}
// let component_data = seq
// .next_element::<Slot>()?
// .ok_or(de::Error::custom("Unable to parse item"))?;
// array_of_changed_slots.push((slot_number, slot));
}

let custom_name = seq
.next_element::<String>()?
.ok_or(de::Error::custom("Failed to decode VarInt"))?;

// if num_components_to_add.0 != 0 || num_components_to_remove.0 != 0 {
// return Err(de::Error::custom(
// "Slot components are currently unsupported",
// ));
// }

log::info!("has_potion: {}", has_potion_id);
if let Some(s) = potion_id.clone() {
log::info!("potion: {}", s.0);
}
log::info!("has_color: {}", has_custom_color);
if let Some(s) = custom_color {
log::info!("custom_color: {}", s);
}
log::info!("num_effects: {}", number_of_custom_effects.0);

log::info!("num_effects: {}", custom_name);

Ok(PotionContents {
has_potion_id,
potion_id,
has_custom_color,
custom_color,
number_of_custom_effects,
custom_effects: vec![],
custom_name,
})
}
}

deserializer.deserialize_seq(Visitor)
}
}
23 changes: 23 additions & 0 deletions pumpkin-util/src/math/vector3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ pub struct Vector3<T> {
pub z: T,
}

impl Vector3<f32> {
pub fn new_from_euler(yaw: f32, pitch: f32) -> Self {
// TODO: is this because the player is not oriented in the right direction?
let rad_yaw = (yaw + 90.0).to_radians();
let rad_pitch = (pitch * -1.0).to_radians();

let cos_rad_pitch = f32::cos(rad_pitch);
Vector3 {
x: f32::cos(rad_yaw) * cos_rad_pitch,
y: f32::sin(rad_pitch),
z: f32::sin(rad_yaw) * cos_rad_pitch,
}
}
}

impl<T: Math + Copy> Vector3<T> {
pub const fn new(x: T, y: T, z: T) -> Self {
Vector3 { x, y, z }
Expand All @@ -27,6 +42,14 @@ impl<T: Math + Copy> Vector3<T> {
}
}

pub fn add_indv(&self, x: T, y: T, z: T) -> Self {
Vector3 {
x: self.x + x,
y: self.y + y,
z: self.z + z,
}
}

pub fn sub(&self, other: &Vector3<T>) -> Self {
Vector3 {
x: self.x - other.x,
Expand Down
Loading
Loading