feat: add some more events

This commit is contained in:
Alexander Medvedev
2026-08-04 14:57:33 +02:00
parent 9ececd9eca
commit 42d9391804
90 changed files with 3497 additions and 159 deletions

View File

@@ -1456,7 +1456,8 @@ fn get_be_data_from_nbt<R: Read + Seek>(
let data_end = reader.seek(SeekFrom::End(0)).unwrap();
let _ = reader.seek(SeekFrom::Start(data_start));
let nbt_reader = &mut NbtReadHelperBedrock::new(pumpkin_nbt::deserializer::NbtStreamReader(&mut *reader));
let nbt_reader =
&mut NbtReadHelperBedrock::new(pumpkin_nbt::deserializer::NbtStreamReader(&mut *reader));
loop {
if nbt_reader.reader().0.stream_position().unwrap() >= data_end {

View File

@@ -835,7 +835,9 @@ impl ToTokens for ItemComponents {
}
if let Some(scale) = self.potion_duration_scale {
let scale_lit = LitFloat::new(&format!("{scale:?}f32"), Span::call_site());
tokens.extend(quote! { (PotionDurationScale, &PotionDurationScaleImpl { scale: #scale_lit }), });
tokens.extend(
quote! { (PotionDurationScale, &PotionDurationScaleImpl { scale: #scale_lit }), },
);
}
if self.provides_banner_patterns.is_some() {
tokens.extend(quote! { (ProvidesBannerPatterns, &ProvidesBannerPatternsImpl), });

View File

@@ -18,8 +18,8 @@ mod block;
mod carver;
pub mod chest_loot;
mod chunk_gen_settings;
mod chunk_view_lut;
mod chunk_status;
mod chunk_view_lut;
mod composter_increase_chance;
mod configured_feature;
mod damage_type;

View File

@@ -679,23 +679,39 @@ impl DensityFunctionRepr {
fn optimize(&mut self) {
match self {
Self::BlendDensity { input } => input.optimize(),
Self::FindTopSurface { density, upper_bound, .. } => {
Self::FindTopSurface {
density,
upper_bound,
..
} => {
density.optimize();
upper_bound.optimize();
}
Self::ShiftedNoise { shift_x, shift_y, shift_z, .. } => {
Self::ShiftedNoise {
shift_x,
shift_y,
shift_z,
..
} => {
shift_x.optimize();
shift_y.optimize();
shift_z.optimize();
}
Self::IntervalSelect { input, functions, .. } => {
Self::IntervalSelect {
input, functions, ..
} => {
input.optimize();
for f in functions.iter_mut() {
f.optimize();
}
}
Self::Wrapper { input, .. } => input.optimize(),
Self::RangeChoice { input, when_in_range, when_out_range, .. } => {
Self::RangeChoice {
input,
when_in_range,
when_out_range,
..
} => {
input.optimize();
when_in_range.optimize();
when_out_range.optimize();
@@ -707,7 +723,9 @@ impl DensityFunctionRepr {
LinearOperation::Add => value.0 + data.argument.0,
LinearOperation::Mul => value.0 * data.argument.0,
};
*self = Self::Constant { value: HashableF64(val) };
*self = Self::Constant {
value: HashableF64(val),
};
return;
}
match data.operation {
@@ -720,22 +738,32 @@ impl DensityFunctionRepr {
if data.argument.0 == 1.0 {
*self = *input.clone();
} else if data.argument.0 == 0.0 {
*self = Self::Constant { value: HashableF64(0.0) };
*self = Self::Constant {
value: HashableF64(0.0),
};
}
}
}
}
Self::Binary { argument1, argument2, data } => {
Self::Binary {
argument1,
argument2,
data,
} => {
argument1.optimize();
argument2.optimize();
if let (Self::Constant { value: v1 }, Self::Constant { value: v2 }) = (&**argument1, &**argument2) {
if let (Self::Constant { value: v1 }, Self::Constant { value: v2 }) =
(&**argument1, &**argument2)
{
let res = match data.operation {
BinaryOperation::Add => v1.0 + v2.0,
BinaryOperation::Mul => v1.0 * v2.0,
BinaryOperation::Min => v1.0.min(v2.0),
BinaryOperation::Max => v1.0.max(v2.0),
};
*self = Self::Constant { value: HashableF64(res) };
*self = Self::Constant {
value: HashableF64(res),
};
return;
}
match data.operation {
@@ -759,7 +787,9 @@ impl DensityFunctionRepr {
*self = *argument2.clone();
return;
} else if value.0 == 0.0 {
*self = Self::Constant { value: HashableF64(0.0) };
*self = Self::Constant {
value: HashableF64(0.0),
};
return;
}
}
@@ -768,7 +798,9 @@ impl DensityFunctionRepr {
*self = *argument1.clone();
return;
} else if value.0 == 0.0 {
*self = Self::Constant { value: HashableF64(0.0) };
*self = Self::Constant {
value: HashableF64(0.0),
};
return;
}
}
@@ -783,21 +815,43 @@ impl DensityFunctionRepr {
UnaryOperation::Abs => value.0.abs(),
UnaryOperation::Square => value.0 * value.0,
UnaryOperation::Cube => value.0 * value.0 * value.0,
UnaryOperation::HalfNegative => if value.0 > 0.0 { value.0 } else { value.0 * 0.5 },
UnaryOperation::QuarterNegative => if value.0 > 0.0 { value.0 } else { value.0 * 0.25 },
UnaryOperation::HalfNegative => {
if value.0 > 0.0 {
value.0
} else {
value.0 * 0.5
}
}
UnaryOperation::QuarterNegative => {
if value.0 > 0.0 {
value.0
} else {
value.0 * 0.25
}
}
UnaryOperation::Squeeze => {
let c = value.0.clamp(-1.0, 1.0);
c / 2.0 - c * c * c / 24.0
}
UnaryOperation::Invert => if value.0 == 0.0 { f64::INFINITY } else { 1.0 / value.0 },
UnaryOperation::Invert => {
if value.0 == 0.0 {
f64::INFINITY
} else {
1.0 / value.0
}
}
};
*self = Self::Constant {
value: HashableF64(val),
};
*self = Self::Constant { value: HashableF64(val) };
}
}
Self::Clamp { input, data } => {
input.optimize();
if let Self::Constant { value } = &**input {
*self = Self::Constant { value: HashableF64(value.0.clamp(data.min_value.0, data.max_value.0)) };
*self = Self::Constant {
value: HashableF64(value.0.clamp(data.min_value.0, data.max_value.0)),
};
}
}
_ => {}
@@ -844,7 +898,8 @@ impl DensityFunctionRepr {
}
Self::Linear { input, data } => {
let child_idx = input.get_index_for_component_readonly(hash_to_index_map);
let child_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let child_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let arg = data.argument.0;
let body = match data.operation {
LinearOperation::Add => quote! { #child_fn(pos, ctx) + #arg },
@@ -859,15 +914,24 @@ impl DensityFunctionRepr {
}
Self::Unary { input, data } => {
let child_idx = input.get_index_for_component_readonly(hash_to_index_map);
let child_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let child_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let body = match data.operation {
UnaryOperation::Abs => quote! { #child_fn(pos, ctx).abs() },
UnaryOperation::Square => quote! { let v = #child_fn(pos, ctx); v * v },
UnaryOperation::Cube => quote! { let v = #child_fn(pos, ctx); v * v * v },
UnaryOperation::HalfNegative => quote! { let v = #child_fn(pos, ctx); if v > 0.0 { v } else { v * 0.5 } },
UnaryOperation::QuarterNegative => quote! { let v = #child_fn(pos, ctx); if v > 0.0 { v } else { v * 0.25 } },
UnaryOperation::Squeeze => quote! { let c = #child_fn(pos, ctx).clamp(-1.0, 1.0); c / 2.0 - c * c * c / 24.0 },
UnaryOperation::Invert => quote! { let v = #child_fn(pos, ctx); if v == 0.0 { f64::INFINITY } else { 1.0 / v } },
UnaryOperation::HalfNegative => {
quote! { let v = #child_fn(pos, ctx); if v > 0.0 { v } else { v * 0.5 } }
}
UnaryOperation::QuarterNegative => {
quote! { let v = #child_fn(pos, ctx); if v > 0.0 { v } else { v * 0.25 } }
}
UnaryOperation::Squeeze => {
quote! { let c = #child_fn(pos, ctx).clamp(-1.0, 1.0); c / 2.0 - c * c * c / 24.0 }
}
UnaryOperation::Invert => {
quote! { let v = #child_fn(pos, ctx); if v == 0.0 { f64::INFINITY } else { 1.0 / v } }
}
};
quote! {
#[inline(always)]
@@ -878,7 +942,8 @@ impl DensityFunctionRepr {
}
Self::Clamp { input, data } => {
let child_idx = input.get_index_for_component_readonly(hash_to_index_map);
let child_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let child_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let min_v = data.min_value.0;
let max_v = data.max_value.0;
quote! {
@@ -888,16 +953,26 @@ impl DensityFunctionRepr {
}
}
}
Self::Binary { argument1, argument2, data } => {
Self::Binary {
argument1,
argument2,
data,
} => {
let child1_idx = argument1.get_index_for_component_readonly(hash_to_index_map);
let child2_idx = argument2.get_index_for_component_readonly(hash_to_index_map);
let child1_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child1_idx), Span::call_site());
let child2_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child2_idx), Span::call_site());
let child1_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child1_idx), Span::call_site());
let child2_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child2_idx), Span::call_site());
let body = match data.operation {
BinaryOperation::Add => quote! { #child1_fn(pos, ctx) + #child2_fn(pos, ctx) },
BinaryOperation::Mul => quote! { #child1_fn(pos, ctx) * #child2_fn(pos, ctx) },
BinaryOperation::Min => quote! { #child1_fn(pos, ctx).min(#child2_fn(pos, ctx)) },
BinaryOperation::Max => quote! { #child1_fn(pos, ctx).max(#child2_fn(pos, ctx)) },
BinaryOperation::Min => {
quote! { #child1_fn(pos, ctx).min(#child2_fn(pos, ctx)) }
}
BinaryOperation::Max => {
quote! { #child1_fn(pos, ctx).max(#child2_fn(pos, ctx)) }
}
};
quote! {
#[inline(always)]
@@ -906,13 +981,24 @@ impl DensityFunctionRepr {
}
}
}
Self::RangeChoice { input, when_in_range, when_out_range, data } => {
Self::RangeChoice {
input,
when_in_range,
when_out_range,
data,
} => {
let input_idx = input.get_index_for_component_readonly(hash_to_index_map);
let when_in_idx = when_in_range.get_index_for_component_readonly(hash_to_index_map);
let when_out_idx = when_out_range.get_index_for_component_readonly(hash_to_index_map);
let input_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, input_idx), Span::call_site());
let when_in_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, when_in_idx), Span::call_site());
let when_out_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, when_out_idx), Span::call_site());
let when_out_idx =
when_out_range.get_index_for_component_readonly(hash_to_index_map);
let input_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, input_idx), Span::call_site());
let when_in_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, when_in_idx), Span::call_site());
let when_out_fn = syn::Ident::new(
&format!("{}_{}", fn_prefix, when_out_idx),
Span::call_site(),
);
let min_inc = data.min_inclusive.0;
let max_exc = data.max_exclusive.0;
quote! {
@@ -956,13 +1042,21 @@ impl DensityFunctionRepr {
}
}
}
Self::ShiftedNoise { shift_x, shift_y, shift_z, data } => {
Self::ShiftedNoise {
shift_x,
shift_y,
shift_z,
data,
} => {
let sx_idx = shift_x.get_index_for_component_readonly(hash_to_index_map);
let sy_idx = shift_y.get_index_for_component_readonly(hash_to_index_map);
let sz_idx = shift_z.get_index_for_component_readonly(hash_to_index_map);
let sx_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, sx_idx), Span::call_site());
let sy_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, sy_idx), Span::call_site());
let sz_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, sz_idx), Span::call_site());
let sx_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, sx_idx), Span::call_site());
let sy_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, sy_idx), Span::call_site());
let sz_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, sz_idx), Span::call_site());
let noise_id = quote::format_ident!("{}", data.noise_id.to_shouty_snake_case());
let xz_scale = data.xz_scale.0;
let y_scale = data.y_scale.0;
@@ -994,7 +1088,8 @@ impl DensityFunctionRepr {
}
Self::BlendDensity { input } => {
let child_idx = input.get_index_for_component_readonly(hash_to_index_map);
let child_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let child_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
quote! {
#[inline(always)]
pub fn #fn_name<C: NoiseEvaluationContext>(pos: &pumpkin_util::math::vector3::Vector3<i32>, ctx: &mut C) -> f64 {
@@ -1021,7 +1116,8 @@ impl DensityFunctionRepr {
}
Self::Wrapper { input, wrapper } => {
let child_idx = input.get_index_for_component_readonly(hash_to_index_map);
let child_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let child_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, child_idx), Span::call_site());
let wrapper_repr = wrapper.into_token_stream();
let comp_idx = index;
quote! {
@@ -1031,9 +1127,14 @@ impl DensityFunctionRepr {
}
}
}
Self::IntervalSelect { input, thresholds, functions } => {
Self::IntervalSelect {
input,
thresholds,
functions,
} => {
let input_idx = input.get_index_for_component_readonly(hash_to_index_map);
let input_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, input_idx), Span::call_site());
let input_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, input_idx), Span::call_site());
let func_fns = functions
.iter()
.map(|f| {
@@ -1044,7 +1145,11 @@ impl DensityFunctionRepr {
let threshold_values = thresholds.iter().map(|t| t.0).collect::<Vec<_>>();
let th_indices = (0..threshold_values.len()).collect::<Vec<_>>();
let last_func_fn = func_fns.last().unwrap();
let initial_func_fns = if func_fns.len() > 1 { &func_fns[..func_fns.len() - 1] } else { &[] };
let initial_func_fns = if func_fns.len() > 1 {
&func_fns[..func_fns.len() - 1]
} else {
&[]
};
quote! {
#[inline(always)]
pub fn #fn_name<C: NoiseEvaluationContext>(pos: &pumpkin_util::math::vector3::Vector3<i32>, ctx: &mut C) -> f64 {
@@ -1075,10 +1180,15 @@ impl DensityFunctionRepr {
Self::Spline { spline, .. } => {
let loc_idx = match spline {
SplineRepr::Fixed { .. } => None,
SplineRepr::Standard { location_function, .. } => Some(location_function.get_index_for_component_readonly(hash_to_index_map)),
SplineRepr::Standard {
location_function, ..
} => {
Some(location_function.get_index_for_component_readonly(hash_to_index_map))
}
};
if let Some(loc_idx) = loc_idx {
let loc_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, loc_idx), Span::call_site());
let loc_fn =
syn::Ident::new(&format!("{}_{}", fn_prefix, loc_idx), Span::call_site());
quote! {
#[inline(always)]
pub fn #fn_name<C: NoiseEvaluationContext>(pos: &pumpkin_util::math::vector3::Vector3<i32>, ctx: &mut C) -> f64 {
@@ -1087,7 +1197,10 @@ impl DensityFunctionRepr {
}
}
} else {
let val = match spline { SplineRepr::Fixed { value } => value.0 as f64, _ => 0.0 };
let val = match spline {
SplineRepr::Fixed { value } => value.0 as f64,
_ => 0.0,
};
quote! {
#[inline(always)]
pub fn #fn_name<C: NoiseEvaluationContext>(pos: &pumpkin_util::math::vector3::Vector3<i32>, ctx: &mut C) -> f64 {
@@ -1097,7 +1210,11 @@ impl DensityFunctionRepr {
}
}
}
Self::FindTopSurface { density, upper_bound, data } => {
Self::FindTopSurface {
density,
upper_bound,
data,
} => {
let d_idx = density.get_index_for_component_readonly(hash_to_index_map);
let u_idx = upper_bound.get_index_for_component_readonly(hash_to_index_map);
let d_fn = syn::Ident::new(&format!("{}_{}", fn_prefix, d_idx), Span::call_site());
@@ -1163,7 +1280,8 @@ impl DensityFunctionRepr {
upper_bound,
data,
} => {
let density_index = density.get_index_for_component(stack, nodes, hash_to_index_map);
let density_index =
density.get_index_for_component(stack, nodes, hash_to_index_map);
let upper_bound_index =
upper_bound.get_index_for_component(stack, nodes, hash_to_index_map);
let lower_bound = data.lower_bound;
@@ -1246,9 +1364,12 @@ impl DensityFunctionRepr {
shift_z,
data,
} => {
let shift_x_index = shift_x.get_index_for_component(stack, nodes, hash_to_index_map);
let shift_y_index = shift_y.get_index_for_component(stack, nodes, hash_to_index_map);
let shift_z_index = shift_z.get_index_for_component(stack, nodes, hash_to_index_map);
let shift_x_index =
shift_x.get_index_for_component(stack, nodes, hash_to_index_map);
let shift_y_index =
shift_y.get_index_for_component(stack, nodes, hash_to_index_map);
let shift_z_index =
shift_z.get_index_for_component(stack, nodes, hash_to_index_map);
let xz_scale = &data.xz_scale;
let y_scale = &data.y_scale;
@@ -1274,7 +1395,8 @@ impl DensityFunctionRepr {
data,
} => {
let input_index = input.get_index_for_component(stack, nodes, hash_to_index_map);
let when_in_index = when_in_range.get_index_for_component(stack, nodes, hash_to_index_map);
let when_in_index =
when_in_range.get_index_for_component(stack, nodes, hash_to_index_map);
let when_out_index =
when_out_range.get_index_for_component(stack, nodes, hash_to_index_map);
@@ -1298,8 +1420,10 @@ impl DensityFunctionRepr {
argument2,
data,
} => {
let argument1_index = argument1.get_index_for_component(stack, nodes, hash_to_index_map);
let argument2_index = argument2.get_index_for_component(stack, nodes, hash_to_index_map);
let argument1_index =
argument1.get_index_for_component(stack, nodes, hash_to_index_map);
let argument2_index =
argument2.get_index_for_component(stack, nodes, hash_to_index_map);
let action = data.operation.get_token_stream();
quote! {
@@ -1526,69 +1650,104 @@ impl NoiseRouterRepr {
let mut noise_lookup_map = BTreeMap::new();
// The aquifer sampler is called most often
let final_density = self
.final_density
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let barrier_noise = self
.barrier_noise
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let fluid_level_floodedness_noise = self
.fluid_level_floodedness_noise
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let fluid_level_spread_noise = self
.fluid_level_spread_noise
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let lava_noise = self
.lava_noise
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let final_density = self.final_density.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let barrier_noise = self.barrier_noise.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let fluid_level_floodedness_noise =
self.fluid_level_floodedness_noise.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let fluid_level_spread_noise = self.fluid_level_spread_noise.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let lava_noise = self.lava_noise.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
// Ore sampler is called fewer times than aquifer sampler
let vein_toggle = self
.vein_toggle
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let vein_ridged = self
.vein_ridged
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let vein_gap = self
.vein_gap
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let vein_toggle = self.vein_toggle.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let vein_ridged = self.vein_ridged.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let vein_gap = self.vein_gap.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
// These should all be cached so it doesn't matter where their components are
let noise_erosion = self
.erosion
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let noise_depth = self
.depth
.get_index_for_component(&mut noise_component_stack, &mut noise_nodes, &mut noise_lookup_map);
let noise_erosion = self.erosion.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let noise_depth = self.depth.get_index_for_component(
&mut noise_component_stack,
&mut noise_nodes,
&mut noise_lookup_map,
);
let mut surface_component_stack = Vec::new();
let mut surface_nodes = Vec::new();
let mut surface_lookup_map = BTreeMap::new();
let _ = self
.preliminary_surface_level
.get_index_for_component(&mut surface_component_stack, &mut surface_nodes, &mut surface_lookup_map);
let _ = self.preliminary_surface_level.get_index_for_component(
&mut surface_component_stack,
&mut surface_nodes,
&mut surface_lookup_map,
);
let mut multinoise_component_stack = Vec::new();
let mut multinoise_nodes = Vec::new();
let mut multinoise_lookup_map = BTreeMap::new();
let ridges = self
.ridges
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let temperature = self
.temperature
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let vegetation = self
.vegetation
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let continents = self
.continents
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let multi_erosion = self
.erosion
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let multi_depth = self
.depth
.get_index_for_component(&mut multinoise_component_stack, &mut multinoise_nodes, &mut multinoise_lookup_map);
let ridges = self.ridges.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let temperature = self.temperature.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let vegetation = self.vegetation.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let continents = self.continents.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let multi_erosion = self.erosion.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let multi_depth = self.depth.get_index_for_component(
&mut multinoise_component_stack,
&mut multinoise_nodes,
&mut multinoise_lookup_map,
);
let base_routers_ts = quote! {
BaseNoiseRouters {
@@ -1623,13 +1782,15 @@ impl NoiseRouterRepr {
let mod_ident = quote::format_ident!("{}_noise_evaluator", router_name);
let prefix = format!("{}_node", router_name);
let fn_tokens = noise_nodes.iter().enumerate().map(|(idx, node)| {
node.emit_compiled_eval_fn(idx, &prefix, &noise_lookup_map)
});
let fn_tokens = noise_nodes
.iter()
.enumerate()
.map(|(idx, node)| node.emit_compiled_eval_fn(idx, &prefix, &noise_lookup_map));
let final_density_fn = quote::format_ident!("{}_{}", prefix, final_density);
let barrier_noise_fn = quote::format_ident!("{}_{}", prefix, barrier_noise);
let fluid_floodedness_fn = quote::format_ident!("{}_{}", prefix, fluid_level_floodedness_noise);
let fluid_floodedness_fn =
quote::format_ident!("{}_{}", prefix, fluid_level_floodedness_noise);
let fluid_spread_fn = quote::format_ident!("{}_{}", prefix, fluid_level_spread_noise);
let lava_noise_fn = quote::format_ident!("{}_{}", prefix, lava_noise);
let vein_toggle_fn = quote::format_ident!("{}_{}", prefix, vein_toggle);
@@ -1724,7 +1885,8 @@ pub fn build() -> TokenStream {
let _ = reprs.end;
let _ = reprs.end_islands;
let (overworld_router, overworld_compiled) = reprs.overworld.into_token_stream_compiled("overworld");
let (overworld_router, overworld_compiled) =
reprs.overworld.into_token_stream_compiled("overworld");
let (nether_router, nether_compiled) = reprs.nether.into_token_stream_compiled("nether");
let (end_router, end_compiled) = reprs.end.into_token_stream_compiled("end");

View File

@@ -34,10 +34,8 @@ pub fn build_enum() -> TokenStream {
})
.collect();
let all_names_tokens: Vec<TokenStream> = all_names
.iter()
.map(|name| quote! { #name })
.collect();
let all_names_tokens: Vec<TokenStream> =
all_names.iter().map(|name| quote! { #name }).collect();
quote! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{BlockDamageEventData, Event, EventType};
pub struct BlockDamageEvent;
impl FromIntoEvent for BlockDamageEvent {
const EVENT_TYPE: EventType = EventType::BlockDamageEvent;
type Data = BlockDamageEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::BlockDamageEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::BlockDamageEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{BlockFadeEventData, Event, EventType};
pub struct BlockFadeEvent;
impl FromIntoEvent for BlockFadeEvent {
const EVENT_TYPE: EventType = EventType::BlockFadeEvent;
type Data = BlockFadeEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::BlockFadeEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::BlockFadeEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{BlockFormEventData, Event, EventType};
pub struct BlockFormEvent;
impl FromIntoEvent for BlockFormEvent {
const EVENT_TYPE: EventType = EventType::BlockFormEvent;
type Data = BlockFormEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::BlockFormEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::BlockFormEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{BlockFromToEventData, Event, EventType};
pub struct BlockFromToEvent;
impl FromIntoEvent for BlockFromToEvent {
const EVENT_TYPE: EventType = EventType::BlockFromToEvent;
type Data = BlockFromToEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::BlockFromToEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::BlockFromToEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{BlockIgniteEventData, Event, EventType};
pub struct BlockIgniteEvent;
impl FromIntoEvent for BlockIgniteEvent {
const EVENT_TYPE: EventType = EventType::BlockIgniteEvent;
type Data = BlockIgniteEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::BlockIgniteEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::BlockIgniteEvent(data)
}
}

View File

@@ -1,13 +1,23 @@
pub mod block_break;
pub mod block_burn;
pub mod block_can_build;
pub mod block_damage;
pub mod block_fade;
pub mod block_form;
pub mod block_from_to;
pub mod block_grow;
pub mod block_ignite;
pub mod block_place;
pub mod block_redstone;
pub use block_break::*;
pub use block_burn::*;
pub use block_can_build::*;
pub use block_damage::*;
pub use block_fade::*;
pub use block_form::*;
pub use block_from_to::*;
pub use block_grow::*;
pub use block_ignite::*;
pub use block_place::*;
pub use block_redstone::*;

View File

@@ -0,0 +1,20 @@
use crate::wit::pumpkin::plugin::event::{EntityCombustEventData, Event, EventType};
use super::super::FromIntoEvent;
pub struct EntityCombustEvent;
impl FromIntoEvent for EntityCombustEvent {
const EVENT_TYPE: EventType = EventType::EntityCombustEvent;
type Data = EntityCombustEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityCombustEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntityCombustEvent(data)
}
}

View File

@@ -0,0 +1,20 @@
use crate::wit::pumpkin::plugin::event::{EntityDamageEventData, Event, EventType};
use super::super::FromIntoEvent;
pub struct EntityDamageEvent;
impl FromIntoEvent for EntityDamageEvent {
const EVENT_TYPE: EventType = EventType::EntityDamageEvent;
type Data = EntityDamageEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityDamageEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntityDamageEvent(data)
}
}

View File

@@ -0,0 +1,39 @@
use crate::wit::pumpkin::plugin::event::{
EntityDeathEventData, Event, EventType, PlayerDeathEventData,
};
use super::super::FromIntoEvent;
pub struct EntityDeathEvent;
impl FromIntoEvent for EntityDeathEvent {
const EVENT_TYPE: EventType = EventType::EntityDeathEvent;
type Data = EntityDeathEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityDeathEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntityDeathEvent(data)
}
}
pub struct PlayerDeathEvent;
impl FromIntoEvent for PlayerDeathEvent {
const EVENT_TYPE: EventType = EventType::PlayerDeathEvent;
type Data = PlayerDeathEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerDeathEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerDeathEvent(data)
}
}

View File

@@ -0,0 +1,20 @@
use crate::wit::pumpkin::plugin::event::{EntityRegainHealthEventData, Event, EventType};
use super::super::FromIntoEvent;
pub struct EntityRegainHealthEvent;
impl FromIntoEvent for EntityRegainHealthEvent {
const EVENT_TYPE: EventType = EventType::EntityRegainHealthEvent;
type Data = EntityRegainHealthEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityRegainHealthEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntityRegainHealthEvent(data)
}
}

View File

@@ -0,0 +1,20 @@
use crate::wit::pumpkin::plugin::event::{EntitySpawnEventData, Event, EventType};
use super::super::FromIntoEvent;
pub struct EntitySpawnEvent;
impl FromIntoEvent for EntitySpawnEvent {
const EVENT_TYPE: EventType = EventType::EntitySpawnEvent;
type Data = EntitySpawnEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntitySpawnEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntitySpawnEvent(data)
}
}

View File

@@ -0,0 +1,11 @@
pub mod entity_combust;
pub mod entity_damage;
pub mod entity_death;
pub mod entity_regain_health;
pub mod entity_spawn;
pub use entity_combust::*;
pub use entity_damage::*;
pub use entity_death::*;
pub use entity_regain_health::*;
pub use entity_spawn::*;

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{CraftItemEventData, Event, EventType};
pub struct CraftItemEvent;
impl FromIntoEvent for CraftItemEvent {
const EVENT_TYPE: EventType = EventType::CraftItemEvent;
type Data = CraftItemEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::CraftItemEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::CraftItemEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, FurnaceSmeltEventData};
pub struct FurnaceSmeltEvent;
impl FromIntoEvent for FurnaceSmeltEvent {
const EVENT_TYPE: EventType = EventType::FurnaceSmeltEvent;
type Data = FurnaceSmeltEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::FurnaceSmeltEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::FurnaceSmeltEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, InventoryDragEventData};
pub struct InventoryDragEvent;
impl FromIntoEvent for InventoryDragEvent {
const EVENT_TYPE: EventType = EventType::InventoryDragEvent;
type Data = InventoryDragEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::InventoryDragEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::InventoryDragEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, InventoryOpenEventData};
pub struct InventoryOpenEvent;
impl FromIntoEvent for InventoryOpenEvent {
const EVENT_TYPE: EventType = EventType::InventoryOpenEvent;
type Data = InventoryOpenEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::InventoryOpenEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::InventoryOpenEvent(data)
}
}

View File

@@ -0,0 +1,9 @@
pub mod craft_item;
pub mod furnace_smelt;
pub mod inventory_drag;
pub mod inventory_open;
pub use craft_item::*;
pub use furnace_smelt::*;
pub use inventory_drag::*;
pub use inventory_open::*;

View File

@@ -15,14 +15,20 @@ pub use crate::wit::pumpkin::plugin::event::{
use crate::{Context, Result, Server, wit::pumpkin::plugin::event::EventType};
pub mod block;
pub mod entity;
pub mod inventory;
pub mod packet;
pub mod player;
pub mod server;
pub mod world;
pub use block::*;
pub use entity::*;
pub use inventory::*;
pub use packet::*;
pub use player::*;
pub use server::*;
pub use world::*;
pub(crate) static NEXT_HANDLER_ID: AtomicU32 = AtomicU32::new(0);
pub(crate) static EVENT_HANDLERS: Mutex<BTreeMap<u32, Box<dyn ErasedEventHandler>>> =

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{Event, EventType, InventoryClickEventData};
use super::super::FromIntoEvent;
/// An event that occurs when a player clicks a slot in an inventory.
pub struct InventoryClickEvent;
impl FromIntoEvent for InventoryClickEvent {
const EVENT_TYPE: EventType = EventType::InventoryClickEvent;
type Data = InventoryClickEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::InventoryClickEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::InventoryClickEvent(data)
}
}

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{Event, EventType, InventoryCloseEventData};
use super::super::FromIntoEvent;
/// An event that occurs when a player closes an inventory.
pub struct InventoryCloseEvent;
impl FromIntoEvent for InventoryCloseEvent {
const EVENT_TYPE: EventType = EventType::InventoryCloseEvent;
type Data = InventoryCloseEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::InventoryCloseEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::InventoryCloseEvent(data)
}
}

View File

@@ -4,14 +4,22 @@ pub mod custom_click_action;
pub mod egg_throw;
pub mod exp_change;
pub mod fish;
pub mod inventory_click;
pub mod inventory_close;
pub mod item_held;
pub mod player_bed;
pub mod player_bucket;
pub mod player_change_world;
pub mod player_chat;
pub mod player_command_send;
pub mod player_custom_payload;
pub mod player_drop_item;
pub mod player_gamemode_change;
pub mod player_interact;
pub mod player_interact_entity;
pub mod player_interact_unknown_entity;
pub mod player_item_consume;
pub mod player_item_damage;
pub mod player_join;
pub mod player_leave;
pub mod player_login;
@@ -23,18 +31,28 @@ pub mod player_toggle_flight;
pub mod player_toggle_sneak;
pub mod player_toggle_sprint;
pub use bedrock_form_response::*;
pub use changed_main_hand::*;
pub use custom_click_action::*;
pub use egg_throw::*;
pub use exp_change::*;
pub use fish::*;
pub use inventory_click::*;
pub use inventory_close::*;
pub use item_held::*;
pub use player_bed::*;
pub use player_bucket::*;
pub use player_change_world::*;
pub use player_chat::*;
pub use player_command_send::*;
pub use player_custom_payload::*;
pub use player_drop_item::*;
pub use player_gamemode_change::*;
pub use player_interact::*;
pub use player_interact_entity::*;
pub use player_interact_unknown_entity::*;
pub use player_item_consume::*;
pub use player_item_damage::*;
pub use player_join::*;
pub use player_leave::*;
pub use player_login::*;

View File

@@ -0,0 +1,38 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{
Event, EventType, PlayerBedEnterEventData, PlayerBedLeaveEventData,
};
pub struct PlayerBedEnterEvent;
impl FromIntoEvent for PlayerBedEnterEvent {
const EVENT_TYPE: EventType = EventType::PlayerBedEnterEvent;
type Data = PlayerBedEnterEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerBedEnterEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerBedEnterEvent(data)
}
}
pub struct PlayerBedLeaveEvent;
impl FromIntoEvent for PlayerBedLeaveEvent {
const EVENT_TYPE: EventType = EventType::PlayerBedLeaveEvent;
type Data = PlayerBedLeaveEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerBedLeaveEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerBedLeaveEvent(data)
}
}

View File

@@ -0,0 +1,38 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{
Event, EventType, PlayerBucketEmptyEventData, PlayerBucketFillEventData,
};
pub struct PlayerBucketEmptyEvent;
impl FromIntoEvent for PlayerBucketEmptyEvent {
const EVENT_TYPE: EventType = EventType::PlayerBucketEmptyEvent;
type Data = PlayerBucketEmptyEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerBucketEmptyEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerBucketEmptyEvent(data)
}
}
pub struct PlayerBucketFillEvent;
impl FromIntoEvent for PlayerBucketFillEvent {
const EVENT_TYPE: EventType = EventType::PlayerBucketFillEvent;
type Data = PlayerBucketFillEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerBucketFillEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerBucketFillEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, PlayerDropItemEventData};
pub struct PlayerDropItemEvent;
impl FromIntoEvent for PlayerDropItemEvent {
const EVENT_TYPE: EventType = EventType::PlayerDropItemEvent;
type Data = PlayerDropItemEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerDropItemEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerDropItemEvent(data)
}
}

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{Event, EventType, PlayerInteractEntityEventData};
use super::super::FromIntoEvent;
/// An event that occurs when a player interacts with an entity.
pub struct PlayerInteractEntityEvent;
impl FromIntoEvent for PlayerInteractEntityEvent {
const EVENT_TYPE: EventType = EventType::PlayerInteractEntityEvent;
type Data = PlayerInteractEntityEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerInteractEntityEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerInteractEntityEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, PlayerItemConsumeEventData};
pub struct PlayerItemConsumeEvent;
impl FromIntoEvent for PlayerItemConsumeEvent {
const EVENT_TYPE: EventType = EventType::PlayerItemConsumeEvent;
type Data = PlayerItemConsumeEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerItemConsumeEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerItemConsumeEvent(data)
}
}

View File

@@ -0,0 +1,19 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{Event, EventType, PlayerItemDamageEventData};
pub struct PlayerItemDamageEvent;
impl FromIntoEvent for PlayerItemDamageEvent {
const EVENT_TYPE: EventType = EventType::PlayerItemDamageEvent;
type Data = PlayerItemDamageEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::PlayerItemDamageEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::PlayerItemDamageEvent(data)
}
}

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{ChunkLoadEventData, Event, EventType};
use super::super::FromIntoEvent;
/// An event that occurs when a chunk is loaded in a world.
pub struct ChunkLoadEvent;
impl FromIntoEvent for ChunkLoadEvent {
const EVENT_TYPE: EventType = EventType::ChunkLoadEvent;
type Data = ChunkLoadEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::ChunkLoadEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::ChunkLoadEvent(data)
}
}

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{ChunkSaveEventData, Event, EventType};
use super::super::FromIntoEvent;
/// An event that occurs when a chunk is saved in a world.
pub struct ChunkSaveEvent;
impl FromIntoEvent for ChunkSaveEvent {
const EVENT_TYPE: EventType = EventType::ChunkSaveEvent;
type Data = ChunkSaveEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::ChunkSaveEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::ChunkSaveEvent(data)
}
}

View File

@@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{ChunkSendEventData, Event, EventType};
use super::super::FromIntoEvent;
/// An event that occurs when a chunk is sent to a client.
pub struct ChunkSendEvent;
impl FromIntoEvent for ChunkSendEvent {
const EVENT_TYPE: EventType = EventType::ChunkSendEvent;
type Data = ChunkSendEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::ChunkSendEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::ChunkSendEvent(data)
}
}

View File

@@ -0,0 +1,11 @@
pub mod chunk_load;
pub mod chunk_save;
pub mod chunk_send;
pub mod weather_change;
pub mod world_load;
pub use chunk_load::*;
pub use chunk_save::*;
pub use chunk_send::*;
pub use weather_change::*;
pub use world_load::*;

View File

@@ -0,0 +1,38 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{
Event, EventType, ThunderChangeEventData, WeatherChangeEventData,
};
pub struct WeatherChangeEvent;
impl FromIntoEvent for WeatherChangeEvent {
const EVENT_TYPE: EventType = EventType::WeatherChangeEvent;
type Data = WeatherChangeEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::WeatherChangeEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::WeatherChangeEvent(data)
}
}
pub struct ThunderChangeEvent;
impl FromIntoEvent for ThunderChangeEvent {
const EVENT_TYPE: EventType = EventType::ThunderChangeEvent;
type Data = ThunderChangeEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::ThunderChangeEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::ThunderChangeEvent(data)
}
}

View File

@@ -0,0 +1,38 @@
use super::super::FromIntoEvent;
use crate::wit::pumpkin::plugin::event::{
Event, EventType, WorldLoadEventData, WorldUnloadEventData,
};
pub struct WorldLoadEvent;
impl FromIntoEvent for WorldLoadEvent {
const EVENT_TYPE: EventType = EventType::WorldLoadEvent;
type Data = WorldLoadEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::WorldLoadEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::WorldLoadEvent(data)
}
}
pub struct WorldUnloadEvent;
impl FromIntoEvent for WorldUnloadEvent {
const EVENT_TYPE: EventType = EventType::WorldUnloadEvent;
type Data = WorldUnloadEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::WorldUnloadEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::WorldUnloadEvent(data)
}
}

View File

@@ -358,6 +358,18 @@ impl BlockBehaviour for BedBlock {
}
}
if let Some(server) = args.world.server.upgrade() {
let mut event =
crate::plugin::api::events::player::player_bed::PlayerBedEnterEvent::new(
args.player.clone(),
bed_head_pos,
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return BlockActionResult::SuccessServer;
}
}
args.player.sleep(bed_head_pos);
args.player
.trigger_advancement(

View File

@@ -165,6 +165,17 @@ impl FireBlock {
.set_block_state(pos, new_state_id, BlockFlags::NOTIFY_NEIGHBORS)
.await;
} else {
let mut burn_event = crate::plugin::block::block_burn::BlockBurnEvent {
igniting_block: &Block::FIRE,
block: old_block,
cancelled: false,
};
if let Some(server) = world.server.upgrade() {
server.plugin_manager.fire(&server, &mut burn_event).await;
}
if burn_event.cancelled {
return;
}
world
.set_block_state(
pos,

View File

@@ -124,6 +124,17 @@ impl FlowingLava {
return false;
}
if below_is_soul_soil && world.get_block(&neighbor_pos) == &Block::BLUE_ICE {
if let Some(server) = world.server.upgrade() {
let mut event =
crate::plugin::api::events::block::block_form::BlockFormEvent::new(
*block_pos,
&Block::BASALT,
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return false;
}
}
world
.set_block_state(
block_pos,

View File

@@ -597,14 +597,34 @@ impl BlockRegistry {
// Mirror vanilla obstruction checks: only entities that block building should prevent
// placement. (e.g. arrows/xp orbs/displays/markers should not)
let state = BlockState::from_id(new_state);
let mut buildable = true;
for shape in state.get_block_collision_shapes() {
let placed_box = shape.at_pos(final_block_pos);
if Self::has_blocking_entity_in_box(world.as_ref(), &placed_box) {
return Ok(None);
buildable = false;
break;
}
}
let mut can_build_event = crate::plugin::block::block_can_build::BlockCanBuildEvent {
block_to_build: placed_block,
buildable,
player: player.clone(),
block: clicked_block,
cancelled: false,
};
server
.plugin_manager
.fire::<crate::plugin::block::block_can_build::BlockCanBuildEvent>(
server,
&mut can_build_event,
)
.await;
if can_build_event.cancelled || !can_build_event.buildable {
return Ok(None);
}
let mut event = crate::plugin::block::block_place::BlockPlaceEvent::new(
player.clone(),
placed_block,

View File

@@ -1266,6 +1266,16 @@ impl Player {
};
if let Some((result, updated_stack)) = updated {
if let Some(server) = self.world().server.upgrade()
&& let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id)
{
let mut event = crate::plugin::api::events::player::player_item_damage::PlayerItemDamageEvent::new(
player_arc,
updated_stack.item.registry_key.to_string(),
amount,
);
server.plugin_manager.fire(&server, &mut event).await;
}
// Send the break status before clearing the slot so the client can
// use the item texture for break particles.
if result == pumpkin_data::item_stack::DamageResult::Broken {
@@ -1766,6 +1776,17 @@ impl Player {
return;
};
if let Some(server) = world.server.upgrade()
&& let Some(player_arc) = world.get_player_by_uuid(self.gameprofile.id)
{
let mut event =
crate::plugin::api::events::player::player_bed::PlayerBedLeaveEvent::new(
player_arc,
respawn_point.position,
);
server.plugin_manager.fire(&server, &mut event).await;
}
let (bed, bed_state) = world.get_block_and_state_id(&respawn_point.position);
BedBlock::set_occupied(false, &world, bed, &respawn_point.position, bed_state).await;
@@ -3199,6 +3220,22 @@ impl Player {
let drop_amount = if drop_stack { item_stack.item_count } else { 1 };
let dropped_stack = item_stack.copy_with_count(drop_amount);
if let Some(server) = self.world().server.upgrade()
&& let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id)
{
let mut event =
crate::plugin::api::events::player::player_drop_item::PlayerDropItemEvent::new(
player_arc,
dropped_stack.item.registry_key.to_string(),
dropped_stack.item_count as u8,
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return;
}
}
item_stack.decrement(drop_amount);
let updated_stack = item_stack.clone();
let selected_slot = self.inventory.get_selected_slot();
@@ -3706,6 +3743,17 @@ impl Player {
self.close_handled_screen().await;
}
if let Some(server) = self.world().server.upgrade() {
let mut event =
crate::plugin::api::events::inventory::inventory_open::InventoryOpenEvent::new(
self.clone(),
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return None;
}
}
self.increment_screen_handler_sync_id();
if let Some(screen_handler) = screen_handler_factory

View File

@@ -314,6 +314,21 @@ impl ItemBehaviour for EmptyBucketItem {
return;
};
if let Some(server) = world.server.upgrade()
&& let Some(player_arc) = world.get_player_by_uuid(player.gameprofile.id)
{
let mut event =
crate::plugin::api::events::player::player_bucket::PlayerBucketFillEvent::new(
player_arc,
block_pos,
item.registry_key.to_string(),
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return;
}
}
give_player_bucket_item(player, item).await;
})
}
@@ -352,6 +367,18 @@ impl ItemBehaviour for FilledBucketItem {
return;
}
if let Some(server) = world.server.upgrade()
&& let Some(player_arc) = world.get_player_by_uuid(player.gameprofile.id)
{
let mut event =
crate::plugin::api::events::player::player_bucket::PlayerBucketEmptyEvent::new(
player_arc,
pos,
item.registry_key.to_string(),
);
server.plugin_manager.fire(&server, &mut event).await;
}
//TODO: Spawn entity if applicable
if player.gamemode.load() != GameMode::Creative {
let item_stack = ItemStack::new(1, &Item::BUCKET);

View File

@@ -35,6 +35,23 @@ impl ItemBehaviour for FlintAndSteelItem {
_server: &'a Server,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(server_ref) = player.world().server.upgrade() {
let player_arc = player.world().get_player_by_uuid(player.gameprofile.id);
let mut event =
crate::plugin::api::events::block::block_ignite::BlockIgniteEvent::new(
location,
&pumpkin_data::Block::FIRE,
player_arc,
);
server_ref
.plugin_manager
.fire(&server_ref, &mut event)
.await;
if event.cancelled {
return;
}
}
let ignited = Ignition::ignite_block(
|world: Arc<World>, pos: BlockPos, new_state_id: BlockStateId| async move {
world

View File

@@ -1933,6 +1933,24 @@ impl JavaClient {
let world = entity.world.load_full();
let (block, state) = world.get_block_and_state(&position);
if let Some(server_arc) = world.server.upgrade() {
let mut event =
crate::plugin::api::events::block::block_damage::BlockDamageEvent::new(
player.clone(),
block,
position,
false,
);
server_arc
.plugin_manager
.fire(&server_arc, &mut event)
.await;
if event.cancelled {
self.update_sequence(player, player_action.sequence.0);
return;
}
}
if block == &pumpkin_data::Block::NOTE_BLOCK {
let props =
pumpkin_data::block_properties::NoteBlockLikeProperties::from_state_id(

View File

@@ -0,0 +1,40 @@
use crate::entity::player::Player;
use pumpkin_data::Block;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;
/// An event that occurs when a player damages / breaks a block.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockDamageEvent {
/// The player damaging the block.
pub player: Arc<Player>,
/// The block being damaged.
pub block: &'static Block,
/// The position of the block.
pub block_pos: BlockPos,
/// Whether the block is instantly broken.
pub insta_break: bool,
}
impl BlockDamageEvent {
#[must_use]
pub const fn new(
player: Arc<Player>,
block: &'static Block,
block_pos: BlockPos,
insta_break: bool,
) -> Self {
Self {
player,
block,
block_pos,
insta_break,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block dispenses an item.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockDispenseEvent {
pub block_pos: BlockPos,
pub item_name: String,
}
impl BlockDispenseEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, item_name: String) -> Self {
Self {
block_pos,
item_name,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block explodes.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockExplodeEvent {
pub block_pos: BlockPos,
pub yield_rate: f32,
}
impl BlockExplodeEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, yield_rate: f32) -> Self {
Self {
block_pos,
yield_rate,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,25 @@
use pumpkin_data::Block;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block fades or melts away (e.g. ice, snow).
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockFadeEvent {
/// The position of the fading block.
pub block_pos: BlockPos,
/// The block fading.
pub block: &'static Block,
}
impl BlockFadeEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, block: &'static Block) -> Self {
Self {
block_pos,
block,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,25 @@
use pumpkin_data::Block;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block forms naturally (e.g. ice, snow, cobblestone).
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockFormEvent {
/// The position where the block forms.
pub block_pos: BlockPos,
/// The formed block type.
pub block: &'static Block,
}
impl BlockFormEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, block: &'static Block) -> Self {
Self {
block_pos,
block,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,29 @@
use pumpkin_data::Block;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block (such as fluid) spreads/flows from one location to another.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockFromToEvent {
/// The source block position.
pub from_pos: BlockPos,
/// The destination block position.
pub to_pos: BlockPos,
/// The block flowing.
pub block: &'static Block,
}
impl BlockFromToEvent {
#[must_use]
pub const fn new(from_pos: BlockPos, to_pos: BlockPos, block: &'static Block) -> Self {
Self {
from_pos,
to_pos,
block,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,35 @@
use crate::entity::player::Player;
use pumpkin_data::Block;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;
/// An event that occurs when a block ignites.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockIgniteEvent {
/// The position of the ignited block.
pub block_pos: BlockPos,
/// The block that ignited this block.
pub igniting_block: &'static Block,
/// The player that ignited the block, if any.
pub player: Option<Arc<Player>>,
}
impl BlockIgniteEvent {
#[must_use]
pub const fn new(
block_pos: BlockPos,
igniting_block: &'static Block,
player: Option<Arc<Player>>,
) -> Self {
Self {
block_pos,
igniting_block,
player,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a block physics check is run.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockPhysicsEvent {
pub block_pos: BlockPos,
pub changed_pos: BlockPos,
}
impl BlockPhysicsEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, changed_pos: BlockPos) -> Self {
Self {
block_pos,
changed_pos,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,40 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a piston extends.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockPistonExtendEvent {
pub block_pos: BlockPos,
pub direction: String,
}
impl BlockPistonExtendEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, direction: String) -> Self {
Self {
block_pos,
direction,
cancelled: false,
}
}
}
/// An event that occurs when a piston retracts.
#[cancellable]
#[derive(Event, Clone)]
pub struct BlockPistonRetractEvent {
pub block_pos: BlockPos,
pub direction: String,
}
impl BlockPistonRetractEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, direction: String) -> Self {
Self {
block_pos,
direction,
cancelled: false,
}
}
}

View File

@@ -1,9 +1,42 @@
pub mod block_break;
pub mod block_burn;
pub mod block_can_build;
pub mod block_damage;
pub mod block_dispense;
pub mod block_explode;
pub mod block_fade;
pub mod block_form;
pub mod block_from_to;
pub mod block_grow;
pub mod block_ignite;
pub mod block_physics;
pub mod block_piston;
pub mod block_place;
pub mod block_redstone;
pub mod note_play;
pub mod sign_change;
pub mod sponge_absorb;
pub mod tnt_prime;
pub use block_break::*;
pub use block_burn::*;
pub use block_can_build::*;
pub use block_damage::*;
pub use block_dispense::*;
pub use block_explode::*;
pub use block_fade::*;
pub use block_form::*;
pub use block_from_to::*;
pub use block_grow::*;
pub use block_ignite::*;
pub use block_physics::*;
pub use block_piston::*;
pub use block_place::*;
pub use block_redstone::*;
pub use note_play::*;
pub use sign_change::*;
pub use sponge_absorb::*;
pub use tnt_prime::*;
use pumpkin_data::Block;

View File

@@ -0,0 +1,23 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a note block plays.
#[cancellable]
#[derive(Event, Clone)]
pub struct NotePlayEvent {
pub block_pos: BlockPos,
pub instrument: String,
pub note: u8,
}
impl NotePlayEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, instrument: String, note: u8) -> Self {
Self {
block_pos,
instrument,
note,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,25 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;
/// An event that occurs when a sign's text is changed.
#[cancellable]
#[derive(Event, Clone)]
pub struct SignChangeEvent {
pub player: Arc<Player>,
pub block_pos: BlockPos,
pub lines: Vec<String>,
}
impl SignChangeEvent {
#[must_use]
pub const fn new(player: Arc<Player>, block_pos: BlockPos, lines: Vec<String>) -> Self {
Self {
player,
block_pos,
lines,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,19 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a sponge absorbs water.
#[cancellable]
#[derive(Event, Clone)]
pub struct SpongeAbsorbEvent {
pub block_pos: BlockPos,
}
impl SpongeAbsorbEvent {
#[must_use]
pub const fn new(block_pos: BlockPos) -> Self {
Self {
block_pos,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when TNT is primed.
#[cancellable]
#[derive(Event, Clone)]
pub struct TNTPrimeEvent {
pub block_pos: BlockPos,
pub prime_reason: String,
}
impl TNTPrimeEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, prime_reason: String) -> Self {
Self {
block_pos,
prime_reason,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,23 @@
use pumpkin_macros::{Event, cancellable};
/// An event that occurs when an entity catches fire.
#[cancellable]
#[derive(Event, Clone)]
pub struct EntityCombustEvent {
/// The ID of the entity that caught fire.
pub entity_id: i32,
/// The duration in seconds the entity will burn.
pub duration_secs: f32,
}
impl EntityCombustEvent {
#[must_use]
pub const fn new(entity_id: i32, duration_secs: f32) -> Self {
Self {
entity_id,
duration_secs,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,27 @@
use pumpkin_macros::{Event, cancellable};
/// An event that occurs when an entity takes damage.
#[cancellable]
#[derive(Event, Clone)]
pub struct EntityDamageEvent {
/// The ID of the entity taking damage.
pub entity_id: i32,
/// The amount of damage taken.
pub damage: f32,
/// The cause or type of damage as a string.
pub cause: String,
}
impl EntityDamageEvent {
#[must_use]
pub const fn new(entity_id: i32, damage_type: String, damage_amount: f32) -> Self {
Self {
entity_id,
damage: damage_amount,
cause: damage_type,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,54 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::text::TextComponent;
use std::sync::Arc;
/// An event that occurs when an entity dies.
#[derive(Event, Clone)]
pub struct EntityDeathEvent {
/// The ID of the entity that died.
pub entity_id: i32,
/// The amount of experience dropped by the entity.
pub dropped_exp: i32,
}
impl EntityDeathEvent {
#[must_use]
pub const fn new(entity_id: i32, dropped_exp: i32) -> Self {
Self {
entity_id,
dropped_exp,
}
}
}
/// An event that occurs when a player dies.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerDeathEvent {
/// The player that died.
pub player: Arc<Player>,
/// The death message to be broadcasted.
pub death_message: TextComponent,
/// The amount of experience dropped by the player.
pub dropped_exp: i32,
/// Whether the player keeps their inventory upon death.
pub keep_inventory: bool,
}
impl PlayerDeathEvent {
#[must_use]
pub const fn new(player: Arc<Player>, death_message: TextComponent, dropped_exp: i32) -> Self {
Self {
player,
death_message,
dropped_exp,
keep_inventory: false,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,23 @@
use pumpkin_macros::{Event, cancellable};
/// An event that occurs when an entity regains health.
#[cancellable]
#[derive(Event, Clone)]
pub struct EntityRegainHealthEvent {
/// The ID of the entity regaining health.
pub entity_id: i32,
/// The amount of health regained.
pub amount: f32,
}
impl EntityRegainHealthEvent {
#[must_use]
pub const fn new(entity_id: i32, amount: f32) -> Self {
Self {
entity_id,
amount,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,39 @@
use crate::world::World;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::vector3::Vector3;
use std::sync::Arc;
/// An event that occurs when an entity is spawned into a world.
#[cancellable]
#[derive(Event, Clone)]
pub struct EntitySpawnEvent {
/// The ID of the spawned entity.
pub entity_id: i32,
/// The registry name of the entity type.
pub entity_type: String,
/// The position where the entity is spawned.
pub position: Vector3<f64>,
/// The world in which the entity is spawned.
pub world: Arc<World>,
}
impl EntitySpawnEvent {
#[must_use]
pub const fn new(
entity_id: i32,
entity_type: String,
position: Vector3<f64>,
world: Arc<World>,
) -> Self {
Self {
entity_id,
entity_type,
position,
world,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,11 @@
pub mod entity_combust;
pub mod entity_damage;
pub mod entity_death;
pub mod entity_regain_health;
pub mod entity_spawn;
pub use entity_combust::*;
pub use entity_damage::*;
pub use entity_death::*;
pub use entity_regain_health::*;
pub use entity_spawn::*;

View File

@@ -0,0 +1,25 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a player crafts an item.
#[cancellable]
#[derive(Event, Clone)]
pub struct CraftItemEvent {
/// The player crafting the item.
pub player: Arc<Player>,
/// The recipe identifier.
pub recipe_id: String,
}
impl CraftItemEvent {
#[must_use]
pub const fn new(player: Arc<Player>, recipe_id: String) -> Self {
Self {
player,
recipe_id,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,28 @@
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
/// An event that occurs when a furnace smelts an item.
#[cancellable]
#[derive(Event, Clone)]
pub struct FurnaceSmeltEvent {
/// The position of the furnace block.
pub block_pos: BlockPos,
/// The source item being smelted.
pub source_item: String,
/// The resulting smelted item.
pub result_item: String,
}
impl FurnaceSmeltEvent {
#[must_use]
pub const fn new(block_pos: BlockPos, source_item: String, result_item: String) -> Self {
Self {
block_pos,
source_item,
result_item,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a player drags items across inventory slots.
#[cancellable]
#[derive(Event, Clone)]
pub struct InventoryDragEvent {
/// The player dragging items.
pub player: Arc<Player>,
}
impl InventoryDragEvent {
#[must_use]
pub const fn new(player: Arc<Player>) -> Self {
Self {
player,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,21 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a player opens an inventory.
#[cancellable]
#[derive(Event, Clone)]
pub struct InventoryOpenEvent {
/// The player opening the inventory.
pub player: Arc<Player>,
}
impl InventoryOpenEvent {
#[must_use]
pub const fn new(player: Arc<Player>) -> Self {
Self {
player,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,9 @@
pub mod craft_item;
pub mod furnace_smelt;
pub mod inventory_drag;
pub mod inventory_open;
pub use craft_item::*;
pub use furnace_smelt::*;
pub use inventory_drag::*;
pub use inventory_open::*;

View File

@@ -2,6 +2,8 @@ use std::any::Any;
use std::sync::Arc;
pub mod block;
pub mod entity;
pub mod inventory;
pub mod player;
pub mod server;
pub mod world;

View File

@@ -7,14 +7,19 @@ pub mod fish;
pub mod inventory_close;
pub mod inventory_interact;
pub mod item_held;
pub mod player_bed;
pub mod player_bucket;
pub mod player_change_world;
pub mod player_chat;
pub mod player_command_send;
pub mod player_custom_payload;
pub mod player_drop_item;
pub mod player_gamemode_change;
pub mod player_interact_entity_event;
pub mod player_interact_event;
pub mod player_interact_unknown_entity_event;
pub mod player_item_consume;
pub mod player_item_damage;
pub mod player_join;
pub mod player_leave;
pub mod player_login;
@@ -26,6 +31,39 @@ pub mod player_toggle_flight_event;
pub mod player_toggle_sneak_event;
pub mod player_toggle_sprint_event;
pub use bedrock_form_response::*;
pub use changed_main_hand::*;
pub use custom_click_action::*;
pub use egg_throw::*;
pub use exp_change::*;
pub use fish::*;
pub use inventory_close::*;
pub use inventory_interact::*;
pub use item_held::*;
pub use player_bed::*;
pub use player_bucket::*;
pub use player_change_world::*;
pub use player_chat::*;
pub use player_command_send::*;
pub use player_custom_payload::*;
pub use player_drop_item::*;
pub use player_gamemode_change::*;
pub use player_interact_entity_event::*;
pub use player_interact_event::*;
pub use player_interact_unknown_entity_event::*;
pub use player_item_consume::*;
pub use player_item_damage::*;
pub use player_join::*;
pub use player_leave::*;
pub use player_login::*;
pub use player_move::*;
pub use player_permission_check::*;
pub use player_respawn::*;
pub use player_teleport::*;
pub use player_toggle_flight_event::*;
pub use player_toggle_sneak_event::*;
pub use player_toggle_sprint_event::*;
use std::sync::Arc;
use crate::entity::player::Player;

View File

@@ -0,0 +1,43 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;
/// An event that occurs when a player enters a bed.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerBedEnterEvent {
/// The player entering the bed.
pub player: Arc<Player>,
/// The position of the bed.
pub bed_pos: BlockPos,
}
impl PlayerBedEnterEvent {
#[must_use]
pub const fn new(player: Arc<Player>, bed_pos: BlockPos) -> Self {
Self {
player,
bed_pos,
cancelled: false,
}
}
}
/// An event that occurs when a player leaves a bed.
#[derive(Event, Clone)]
pub struct PlayerBedLeaveEvent {
/// The player leaving the bed.
pub player: Arc<Player>,
/// The position of the bed.
pub bed_pos: BlockPos,
}
impl PlayerBedLeaveEvent {
#[must_use]
pub const fn new(player: Arc<Player>, bed_pos: BlockPos) -> Self {
Self { player, bed_pos }
}
}

View File

@@ -0,0 +1,56 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use pumpkin_util::math::position::BlockPos;
use std::sync::Arc;
/// An event that occurs when a player empties a bucket.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerBucketEmptyEvent {
/// The player emptying the bucket.
pub player: Arc<Player>,
/// The target block position where the bucket is emptied.
pub block_pos: BlockPos,
/// The bucket item used.
pub bucket: String,
}
impl PlayerBucketEmptyEvent {
#[must_use]
pub const fn new(player: Arc<Player>, block_pos: BlockPos, bucket: String) -> Self {
Self {
player,
block_pos,
bucket,
cancelled: false,
}
}
}
/// An event that occurs when a player fills a bucket.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerBucketFillEvent {
/// The player filling the bucket.
pub player: Arc<Player>,
/// The target block position being targeted for filling.
pub block_pos: BlockPos,
/// The bucket item used.
pub bucket: String,
}
impl PlayerBucketFillEvent {
#[must_use]
pub const fn new(player: Arc<Player>, block_pos: BlockPos, bucket: String) -> Self {
Self {
player,
block_pos,
bucket,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,29 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a player drops an item.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerDropItemEvent {
/// The player dropping the item.
pub player: Arc<Player>,
/// The registry name of the dropped item.
pub item_name: String,
/// The stack count of dropped items.
pub count: u8,
}
impl PlayerDropItemEvent {
#[must_use]
pub const fn new(player: Arc<Player>, item_name: String, count: u8) -> Self {
Self {
player,
item_name,
count,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,25 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a player consumes an item (food, potion, etc.).
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerItemConsumeEvent {
/// The player consuming the item.
pub player: Arc<Player>,
/// The registry name of the item being consumed.
pub item_name: String,
}
impl PlayerItemConsumeEvent {
#[must_use]
pub const fn new(player: Arc<Player>, item_name: String) -> Self {
Self {
player,
item_name,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,29 @@
use crate::entity::player::Player;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when an item held or worn by a player takes durability damage.
#[cancellable]
#[derive(Event, Clone)]
pub struct PlayerItemDamageEvent {
/// The player whose item is taking damage.
pub player: Arc<Player>,
/// The registry name of the item taking damage.
pub item_name: String,
/// The amount of durability damage.
pub damage: i32,
}
impl PlayerItemDamageEvent {
#[must_use]
pub const fn new(player: Arc<Player>, item_name: String, damage: i32) -> Self {
Self {
player,
item_name,
damage,
cancelled: false,
}
}
}

View File

@@ -2,3 +2,12 @@ pub mod chunk_load;
pub mod chunk_save;
pub mod chunk_send;
pub mod spawn_change;
pub mod weather_change;
pub mod world_load;
pub use chunk_load::*;
pub use chunk_save::*;
pub use chunk_send::*;
pub use spawn_change::*;
pub use weather_change::*;
pub use world_load::*;

View File

@@ -0,0 +1,47 @@
use crate::world::World;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when weather (raining) changes in a world.
#[cancellable]
#[derive(Event, Clone)]
pub struct WeatherChangeEvent {
/// The world where weather is changing.
pub world: Arc<World>,
/// The new weather state (true = raining, false = clear).
pub to_weather_state: bool,
}
impl WeatherChangeEvent {
#[must_use]
pub const fn new(world: Arc<World>, to_weather_state: bool) -> Self {
Self {
world,
to_weather_state,
cancelled: false,
}
}
}
/// An event that occurs when thundering state changes in a world.
#[cancellable]
#[derive(Event, Clone)]
pub struct ThunderChangeEvent {
/// The world where thunder state is changing.
pub world: Arc<World>,
/// The new thunder state (true = thundering, false = clear).
pub to_thunder_state: bool,
}
impl ThunderChangeEvent {
#[must_use]
pub const fn new(world: Arc<World>, to_thunder_state: bool) -> Self {
Self {
world,
to_thunder_state,
cancelled: false,
}
}
}

View File

@@ -0,0 +1,35 @@
use crate::world::World;
use pumpkin_macros::{Event, cancellable};
use std::sync::Arc;
/// An event that occurs when a world is loaded.
#[derive(Event, Clone)]
pub struct WorldLoadEvent {
/// The world that was loaded.
pub world: Arc<World>,
}
impl WorldLoadEvent {
#[must_use]
pub const fn new(world: Arc<World>) -> Self {
Self { world }
}
}
/// An event that occurs when a world is unloaded.
#[cancellable]
#[derive(Event, Clone)]
pub struct WorldUnloadEvent {
/// The world being unloaded.
pub world: Arc<World>,
}
impl WorldUnloadEvent {
#[must_use]
pub const fn new(world: Arc<World>) -> Self {
Self {
world,
cancelled: false,
}
}
}

View File

@@ -46,12 +46,15 @@ async fn register_player_event(
event_type: EventType,
) {
use crate::plugin::player::{
changed_main_hand::PlayerChangedMainHandEvent, egg_throw::PlayerEggThrowEvent,
exp_change::PlayerExpChangeEvent, fish::PlayerFishEvent, item_held::PlayerItemHeldEvent,
player_change_world::PlayerChangeWorldEvent, player_chat::PlayerChatEvent,
player_command_send::PlayerCommandSendEvent,
bedrock_form_response::BedrockFormResponseEvent,
changed_main_hand::PlayerChangedMainHandEvent, custom_click_action::CustomClickActionEvent,
egg_throw::PlayerEggThrowEvent, exp_change::PlayerExpChangeEvent, fish::PlayerFishEvent,
inventory_close::InventoryCloseEvent, inventory_interact::InventoryClickEvent,
item_held::PlayerItemHeldEvent, player_change_world::PlayerChangeWorldEvent,
player_chat::PlayerChatEvent, player_command_send::PlayerCommandSendEvent,
player_custom_payload::PlayerCustomPayloadEvent,
player_gamemode_change::PlayerGamemodeChangeEvent,
player_interact_entity_event::PlayerInteractEntityEvent,
player_interact_event::PlayerInteractEvent,
player_interact_unknown_entity_event::PlayerInteractUnknownEntityEvent,
player_join::PlayerJoinEvent, player_leave::PlayerLeaveEvent,
@@ -136,6 +139,12 @@ async fn register_player_event(
)
.await;
}
EventType::PlayerInteractEntityEvent => {
register_typed_event::<PlayerInteractEntityEvent>(
resource, handler, priority, blocking,
)
.await;
}
EventType::PlayerInteractEvent => {
register_typed_event::<PlayerInteractEvent>(resource, handler, priority, blocking)
.await;
@@ -152,6 +161,64 @@ async fn register_player_event(
register_typed_event::<PlayerToggleSprintEvent>(resource, handler, priority, blocking)
.await;
}
EventType::InventoryClickEvent => {
register_typed_event::<InventoryClickEvent>(resource, handler, priority, blocking)
.await;
}
EventType::InventoryCloseEvent => {
register_typed_event::<InventoryCloseEvent>(resource, handler, priority, blocking)
.await;
}
EventType::BedrockFormResponseEvent => {
register_typed_event::<BedrockFormResponseEvent>(resource, handler, priority, blocking)
.await;
}
EventType::CustomClickActionEvent => {
register_typed_event::<CustomClickActionEvent>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerItemConsumeEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_item_consume::PlayerItemConsumeEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerItemDamageEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_item_damage::PlayerItemDamageEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerDropItemEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_drop_item::PlayerDropItemEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerBedEnterEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_bed::PlayerBedEnterEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerBedLeaveEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_bed::PlayerBedLeaveEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerBucketEmptyEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_bucket::PlayerBucketEmptyEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::PlayerBucketFillEvent => {
register_typed_event::<
crate::plugin::api::events::player::player_bucket::PlayerBucketFillEvent,
>(resource, handler, priority, blocking)
.await;
}
_ => {
tracing::error!("non-player event should not be routed to register_player_event");
}
@@ -173,6 +240,78 @@ impl PluginHostState {
}
}
async fn register_entity_event(
resource: &ContextResource,
handler: &Arc<WasmPluginEventHandler>,
priority: crate::plugin::EventPriority,
blocking: bool,
event_type: EventType,
) {
use crate::plugin::entity::{
entity_combust::EntityCombustEvent,
entity_damage::EntityDamageEvent,
entity_death::{EntityDeathEvent, PlayerDeathEvent},
entity_regain_health::EntityRegainHealthEvent,
entity_spawn::EntitySpawnEvent,
};
match event_type {
EventType::EntityDamageEvent => {
register_typed_event::<EntityDamageEvent>(resource, handler, priority, blocking).await;
}
EventType::EntityDeathEvent => {
register_typed_event::<EntityDeathEvent>(resource, handler, priority, blocking).await;
}
EventType::PlayerDeathEvent => {
register_typed_event::<PlayerDeathEvent>(resource, handler, priority, blocking).await;
}
EventType::EntitySpawnEvent => {
register_typed_event::<EntitySpawnEvent>(resource, handler, priority, blocking).await;
}
EventType::EntityCombustEvent => {
register_typed_event::<EntityCombustEvent>(resource, handler, priority, blocking).await;
}
EventType::EntityRegainHealthEvent => {
register_typed_event::<EntityRegainHealthEvent>(resource, handler, priority, blocking)
.await;
}
_ => {
tracing::error!("non-entity event should not be routed to register_entity_event");
}
}
}
async fn register_inventory_event(
resource: &ContextResource,
handler: &Arc<WasmPluginEventHandler>,
priority: crate::plugin::EventPriority,
blocking: bool,
event_type: EventType,
) {
use crate::plugin::inventory::{
craft_item::CraftItemEvent, furnace_smelt::FurnaceSmeltEvent,
inventory_drag::InventoryDragEvent, inventory_open::InventoryOpenEvent,
};
match event_type {
EventType::InventoryOpenEvent => {
register_typed_event::<InventoryOpenEvent>(resource, handler, priority, blocking).await;
}
EventType::InventoryDragEvent => {
register_typed_event::<InventoryDragEvent>(resource, handler, priority, blocking).await;
}
EventType::CraftItemEvent => {
register_typed_event::<CraftItemEvent>(resource, handler, priority, blocking).await;
}
EventType::FurnaceSmeltEvent => {
register_typed_event::<FurnaceSmeltEvent>(resource, handler, priority, blocking).await;
}
_ => {
tracing::error!("non-inventory event should not be routed to register_inventory_event");
}
}
}
async fn register_world_event(
resource: &ContextResource,
handler: &Arc<WasmPluginEventHandler>,
@@ -180,12 +319,48 @@ async fn register_world_event(
blocking: bool,
event_type: EventType,
) {
use crate::plugin::world::spawn_change::SpawnChangeEvent;
use crate::plugin::world::{
chunk_load::ChunkLoad, chunk_save::ChunkSave, chunk_send::ChunkSend,
spawn_change::SpawnChangeEvent,
};
match event_type {
EventType::SpawnChangeEvent => {
register_typed_event::<SpawnChangeEvent>(resource, handler, priority, blocking).await;
}
EventType::ChunkLoadEvent => {
register_typed_event::<ChunkLoad>(resource, handler, priority, blocking).await;
}
EventType::ChunkSaveEvent => {
register_typed_event::<ChunkSave>(resource, handler, priority, blocking).await;
}
EventType::ChunkSendEvent => {
register_typed_event::<ChunkSend>(resource, handler, priority, blocking).await;
}
EventType::WeatherChangeEvent => {
register_typed_event::<
crate::plugin::api::events::world::weather_change::WeatherChangeEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::ThunderChangeEvent => {
register_typed_event::<
crate::plugin::api::events::world::weather_change::ThunderChangeEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::WorldLoadEvent => {
register_typed_event::<crate::plugin::api::events::world::world_load::WorldLoadEvent>(
resource, handler, priority, blocking,
)
.await;
}
EventType::WorldUnloadEvent => {
register_typed_event::<
crate::plugin::api::events::world::world_load::WorldUnloadEvent,
>(resource, handler, priority, blocking)
.await;
}
_ => {
tracing::error!("non-world event should not be routed to register_world_event");
}
@@ -224,6 +399,37 @@ async fn register_block_event(
EventType::BlockPlaceEvent => {
register_typed_event::<BlockPlaceEvent>(resource, handler, priority, blocking).await;
}
EventType::BlockDamageEvent => {
register_typed_event::<
crate::plugin::api::events::block::block_damage::BlockDamageEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::BlockIgniteEvent => {
register_typed_event::<
crate::plugin::api::events::block::block_ignite::BlockIgniteEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::BlockFromToEvent => {
register_typed_event::<
crate::plugin::api::events::block::block_from_to::BlockFromToEvent,
>(resource, handler, priority, blocking)
.await;
}
EventType::BlockFormEvent => {
register_typed_event::<crate::plugin::api::events::block::block_form::BlockFormEvent>(
resource, handler, priority, blocking,
)
.await;
}
EventType::BlockFadeEvent => {
register_typed_event::<crate::plugin::api::events::block::block_fade::BlockFadeEvent>(
resource, handler, priority, blocking,
)
.await;
}
_ => {
tracing::error!("non-block event should not be routed to register_block_event");
}
@@ -344,17 +550,43 @@ impl pumpkin::plugin::context::HostContext for PluginHostState {
| EventType::ServerTickStartEvent) => {
register_server_event(resource, &handler, priority, blocking, event_type).await;
}
event_type @ EventType::SpawnChangeEvent => {
event_type @ (EventType::SpawnChangeEvent
| EventType::ChunkLoadEvent
| EventType::ChunkSaveEvent
| EventType::ChunkSendEvent
| EventType::WeatherChangeEvent
| EventType::ThunderChangeEvent
| EventType::WorldLoadEvent
| EventType::WorldUnloadEvent) => {
register_world_event(resource, &handler, priority, blocking, event_type).await;
}
event_type @ (EventType::EntityDamageEvent
| EventType::EntityDeathEvent
| EventType::PlayerDeathEvent
| EventType::EntitySpawnEvent
| EventType::EntityCombustEvent
| EventType::EntityRegainHealthEvent) => {
register_entity_event(resource, &handler, priority, blocking, event_type).await;
}
event_type @ (EventType::BlockRedstoneEvent
| EventType::BlockBreakEvent
| EventType::BlockBurnEvent
| EventType::BlockCanBuildEvent
| EventType::BlockGrowEvent
| EventType::BlockPlaceEvent) => {
| EventType::BlockPlaceEvent
| EventType::BlockDamageEvent
| EventType::BlockIgniteEvent
| EventType::BlockFromToEvent
| EventType::BlockFormEvent
| EventType::BlockFadeEvent) => {
register_block_event(resource, &handler, priority, blocking, event_type).await;
}
event_type @ (EventType::InventoryOpenEvent
| EventType::InventoryDragEvent
| EventType::CraftItemEvent
| EventType::FurnaceSmeltEvent) => {
register_inventory_event(resource, &handler, priority, blocking, event_type).await;
}
event_type => {
register_player_event(resource, &handler, priority, blocking, event_type).await;
}

View File

@@ -15,7 +15,9 @@ use crate::plugin::{
},
pumpkin::plugin::event::{
BlockBreakEventData, BlockBurnEventData, BlockCanBuildEventData,
BlockGrowEventData, BlockPlaceEventData, BlockRedstoneEventData, Event,
BlockDamageEventData, BlockFadeEventData, BlockFormEventData, BlockFromToEventData,
BlockGrowEventData, BlockIgniteEventData, BlockPlaceEventData,
BlockRedstoneEventData, Event,
},
},
},
@@ -198,3 +200,114 @@ impl ToFromWasmEvent for BlockPlaceEvent {
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::block::block_damage::BlockDamageEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::BlockDamageEvent(BlockDamageEventData {
player,
block_pos: to_wasm_block_position(self.block_pos),
insta_break: self.insta_break,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::BlockDamageEvent(data) => Self {
player: consume_player(state, &data.player),
block: &pumpkin_data::Block::AIR,
block_pos: from_wasm_block_position(data.block_pos),
insta_break: data.insta_break,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::block::block_ignite::BlockIgniteEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::BlockIgniteEvent(BlockIgniteEventData {
block_pos: to_wasm_block_position(self.block_pos),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::BlockIgniteEvent(data) => Self {
block_pos: from_wasm_block_position(data.block_pos),
igniting_block: &pumpkin_data::Block::FIRE,
player: None,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::block::block_from_to::BlockFromToEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::BlockFromToEvent(BlockFromToEventData {
from_pos: to_wasm_block_position(self.from_pos),
to_pos: to_wasm_block_position(self.to_pos),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::BlockFromToEvent(data) => Self {
from_pos: from_wasm_block_position(data.from_pos),
to_pos: from_wasm_block_position(data.to_pos),
block: &pumpkin_data::Block::WATER,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::block::block_form::BlockFormEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::BlockFormEvent(BlockFormEventData {
block_pos: to_wasm_block_position(self.block_pos),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::BlockFormEvent(data) => Self {
block_pos: from_wasm_block_position(data.block_pos),
block: &pumpkin_data::Block::SNOW,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::block::block_fade::BlockFadeEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::BlockFadeEvent(BlockFadeEventData {
block_pos: to_wasm_block_position(self.block_pos),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::BlockFadeEvent(data) => Self {
block_pos: from_wasm_block_position(data.block_pos),
block: &pumpkin_data::Block::ICE,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}

View File

@@ -0,0 +1,174 @@
use crate::plugin::{
entity::{
entity_combust::EntityCombustEvent,
entity_damage::EntityDamageEvent,
entity_death::{EntityDeathEvent, PlayerDeathEvent},
entity_regain_health::EntityRegainHealthEvent,
entity_spawn::EntitySpawnEvent,
},
loader::wasm::wasm_host::{
state::PluginHostState,
wit::v0_1::{
events::{
ToFromWasmEvent, consume_player, consume_text_component, consume_world,
to_wasm_position,
},
pumpkin::plugin::event::{
EntityCombustEventData, EntityDamageEventData, EntityDeathEventData,
EntityRegainHealthEventData, EntitySpawnEventData, Event, PlayerDeathEventData,
},
},
},
};
impl ToFromWasmEvent for EntityDamageEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::EntityDamageEvent(EntityDamageEventData {
entity_id: self.entity_id,
damage: self.damage,
cause: self.cause.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::EntityDamageEvent(data) => Self {
entity_id: data.entity_id,
damage: data.damage,
cause: data.cause,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for EntityDeathEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::EntityDeathEvent(EntityDeathEventData {
entity_id: self.entity_id,
dropped_exp: self.dropped_exp,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::EntityDeathEvent(data) => Self {
entity_id: data.entity_id,
dropped_exp: data.dropped_exp,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for PlayerDeathEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
let death_message = state
.add_text_component(self.death_message.clone())
.expect("failed to add text component resource");
Event::PlayerDeathEvent(PlayerDeathEventData {
player,
death_message,
dropped_exp: self.dropped_exp,
keep_inventory: self.keep_inventory,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerDeathEvent(data) => Self {
player: consume_player(state, &data.player),
death_message: consume_text_component(state, &data.death_message),
dropped_exp: data.dropped_exp,
keep_inventory: data.keep_inventory,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for EntitySpawnEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::EntitySpawnEvent(EntitySpawnEventData {
entity_id: self.entity_id,
entity_type: self.entity_type.clone(),
position: to_wasm_position(self.position),
target_world,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::EntitySpawnEvent(data) => {
let world = consume_world(state, &data.target_world);
Self {
entity_id: data.entity_id,
entity_type: data.entity_type,
position: pumpkin_util::math::vector3::Vector3::new(
data.position.0,
data.position.1,
data.position.2,
),
world,
cancelled: data.cancelled,
}
}
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for EntityCombustEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::EntityCombustEvent(EntityCombustEventData {
entity_id: self.entity_id,
duration_secs: self.duration_secs,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::EntityCombustEvent(data) => Self {
entity_id: data.entity_id,
duration_secs: data.duration_secs,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for EntityRegainHealthEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::EntityRegainHealthEvent(EntityRegainHealthEventData {
entity_id: self.entity_id,
amount: self.amount,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::EntityRegainHealthEvent(data) => Self {
entity_id: data.entity_id,
amount: data.amount,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}

View File

@@ -0,0 +1,112 @@
use crate::plugin::{
inventory::{
craft_item::CraftItemEvent, furnace_smelt::FurnaceSmeltEvent,
inventory_drag::InventoryDragEvent, inventory_open::InventoryOpenEvent,
},
loader::wasm::wasm_host::{
state::PluginHostState,
wit::v0_1::{
events::{
ToFromWasmEvent, consume_player, from_wasm_block_position, to_wasm_block_position,
},
pumpkin::plugin::event::{
CraftItemEventData, Event, FurnaceSmeltEventData, InventoryDragEventData,
InventoryOpenEventData,
},
},
},
};
impl ToFromWasmEvent for InventoryOpenEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::InventoryOpenEvent(InventoryOpenEventData {
player,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::InventoryOpenEvent(data) => Self {
player: consume_player(state, &data.player),
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for InventoryDragEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::InventoryDragEvent(InventoryDragEventData {
player,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::InventoryDragEvent(data) => Self {
player: consume_player(state, &data.player),
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for CraftItemEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::CraftItemEvent(CraftItemEventData {
player,
recipe_id: self.recipe_id.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::CraftItemEvent(data) => Self {
player: consume_player(state, &data.player),
recipe_id: data.recipe_id,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for FurnaceSmeltEvent {
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
Event::FurnaceSmeltEvent(FurnaceSmeltEventData {
block_pos: to_wasm_block_position(self.block_pos),
source_item: self.source_item.clone(),
result_item: self.result_item.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::FurnaceSmeltEvent(data) => Self {
block_pos: from_wasm_block_position(data.block_pos),
source_item: data.source_item,
result_item: data.result_item,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}

View File

@@ -24,6 +24,8 @@ use crate::{
};
pub mod block;
pub mod entity;
pub mod inventory;
pub mod player;
pub mod server;
pub mod world;

View File

@@ -14,12 +14,15 @@ use crate::plugin::{
pumpkin::plugin::event::{
BedrockFormResponseEventData, CustomClickActionEventData, Event,
InteractAction as WasmInteractAction, InventoryClickEventData,
InventoryCloseEventData, PlayerChangeWorldEventData,
InventoryCloseEventData, PlayerBedEnterEventData, PlayerBedLeaveEventData,
PlayerBucketEmptyEventData, PlayerBucketFillEventData, PlayerChangeWorldEventData,
PlayerChangedMainHandEventData, PlayerChatEventData, PlayerCommandSendEventData,
PlayerCustomPayloadEventData, PlayerEggThrowEventData, PlayerExpChangeEventData,
PlayerFishEventData, PlayerFishState as WasmPlayerFishState,
PlayerGamemodeChangeEventData, PlayerInteractEventData,
PlayerInteractUnknownEntityEventData, PlayerItemHeldEventData, PlayerJoinEventData,
PlayerCustomPayloadEventData, PlayerDropItemEventData, PlayerEggThrowEventData,
PlayerExpChangeEventData, PlayerFishEventData,
PlayerFishState as WasmPlayerFishState, PlayerGamemodeChangeEventData,
PlayerInteractEntityEventData, PlayerInteractEventData,
PlayerInteractUnknownEntityEventData, PlayerItemConsumeEventData,
PlayerItemDamageEventData, PlayerItemHeldEventData, PlayerJoinEventData,
PlayerLeaveEventData, PlayerLoginEventData, PlayerMoveEventData,
PlayerPermissionCheckEventData, PlayerRespawnEventData, PlayerTeleportEventData,
PlayerToggleFlightEventData, PlayerToggleSneakEventData,
@@ -43,6 +46,7 @@ use crate::plugin::{
player_command_send::PlayerCommandSendEvent,
player_custom_payload::PlayerCustomPayloadEvent,
player_gamemode_change::PlayerGamemodeChangeEvent,
player_interact_entity_event::PlayerInteractEntityEvent,
player_interact_event::{InteractAction, PlayerInteractEvent},
player_interact_unknown_entity_event::PlayerInteractUnknownEntityEvent,
player_join::PlayerJoinEvent,
@@ -848,3 +852,225 @@ impl ToFromWasmEvent for CustomClickActionEvent {
}
}
}
impl ToFromWasmEvent for PlayerInteractEntityEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerInteractEntityEvent(PlayerInteractEntityEventData {
player,
entity_id: self.target.get_entity().entity_id,
action: to_wasm_entity_interaction_action(&self.action),
sneaking: self.sneaking,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerInteractEntityEvent(data) => {
let player = consume_player(state, &data.player);
let target = player
.world()
.get_entity_by_id(data.entity_id)
.expect("entity not found");
Self {
player,
target,
action: from_wasm_entity_interaction_action(data.action),
target_position: None,
sneaking: data.sneaking,
cancelled: data.cancelled,
}
}
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent
for crate::plugin::api::events::player::player_item_consume::PlayerItemConsumeEvent
{
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerItemConsumeEvent(PlayerItemConsumeEventData {
player,
item_name: self.item_name.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerItemConsumeEvent(data) => Self {
player: consume_player(state, &data.player),
item_name: data.item_name,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent
for crate::plugin::api::events::player::player_item_damage::PlayerItemDamageEvent
{
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerItemDamageEvent(PlayerItemDamageEventData {
player,
item_name: self.item_name.clone(),
damage: self.damage,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerItemDamageEvent(data) => Self {
player: consume_player(state, &data.player),
item_name: data.item_name,
damage: data.damage,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::player::player_drop_item::PlayerDropItemEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerDropItemEvent(PlayerDropItemEventData {
player,
item_name: self.item_name.clone(),
count: self.count,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerDropItemEvent(data) => Self {
player: consume_player(state, &data.player),
item_name: data.item_name,
count: data.count,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::player::player_bed::PlayerBedEnterEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerBedEnterEvent(PlayerBedEnterEventData {
player,
bed_pos: to_wasm_block_position(self.bed_pos),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerBedEnterEvent(data) => Self {
player: consume_player(state, &data.player),
bed_pos: from_wasm_block_position(data.bed_pos),
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::player::player_bed::PlayerBedLeaveEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerBedLeaveEvent(PlayerBedLeaveEventData {
player,
bed_pos: to_wasm_block_position(self.bed_pos),
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerBedLeaveEvent(data) => Self {
player: consume_player(state, &data.player),
bed_pos: from_wasm_block_position(data.bed_pos),
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::player::player_bucket::PlayerBucketEmptyEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerBucketEmptyEvent(PlayerBucketEmptyEventData {
player,
block_pos: to_wasm_block_position(self.block_pos),
bucket: self.bucket.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerBucketEmptyEvent(data) => Self {
player: consume_player(state, &data.player),
block_pos: from_wasm_block_position(data.block_pos),
bucket: data.bucket,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::player::player_bucket::PlayerBucketFillEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player = state
.add_player(self.player.clone())
.expect("failed to add player resource");
Event::PlayerBucketFillEvent(PlayerBucketFillEventData {
player,
block_pos: to_wasm_block_position(self.block_pos),
bucket: self.bucket.clone(),
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::PlayerBucketFillEvent(data) => Self {
player: consume_player(state, &data.player),
block_pos: from_wasm_block_position(data.block_pos),
bucket: data.bucket,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}

View File

@@ -1,3 +1,5 @@
use std::sync::Arc;
use crate::plugin::{
loader::wasm::wasm_host::{
state::PluginHostState,
@@ -5,10 +7,17 @@ use crate::plugin::{
events::{
ToFromWasmEvent, consume_world, from_wasm_block_position, to_wasm_block_position,
},
pumpkin::plugin::event::{Event, SpawnChangeEventData},
pumpkin::plugin::event::{
ChunkLoadEventData, ChunkSaveEventData, ChunkSendEventData, Event,
SpawnChangeEventData, ThunderChangeEventData, WeatherChangeEventData,
WorldLoadEventData, WorldUnloadEventData,
},
},
},
world::spawn_change::SpawnChangeEvent,
world::{
chunk_load::ChunkLoad, chunk_save::ChunkSave, chunk_send::ChunkSend,
spawn_change::SpawnChangeEvent,
},
};
impl ToFromWasmEvent for SpawnChangeEvent {
@@ -43,3 +52,241 @@ impl ToFromWasmEvent for SpawnChangeEvent {
}
}
}
impl ToFromWasmEvent for ChunkLoad {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
let guard = self.chunk.blocking_read();
Event::ChunkLoadEvent(ChunkLoadEventData {
target_world,
chunk_x: guard.x,
chunk_z: guard.z,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::ChunkLoadEvent(data) => {
let world = consume_world(state, &data.target_world);
let chunk_data = pumpkin_world::chunk::ChunkData {
section: pumpkin_world::chunk::ChunkSections::new(24, -64),
heightmap: std::sync::Mutex::new(
pumpkin_world::chunk::ChunkHeightmaps::default(),
),
x: data.chunk_x,
z: data.chunk_z,
block_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
fluid_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
pending_block_entities: std::sync::Mutex::new(
std::collections::HashMap::default(),
),
light_engine: std::sync::Mutex::new(pumpkin_world::chunk::ChunkLight::default()),
light_populated: std::sync::atomic::AtomicBool::new(false),
status: pumpkin_data::chunk::ChunkStatus::Empty,
blending_data: None,
dirty: std::sync::atomic::AtomicBool::new(false),
inhabited_time: std::sync::atomic::AtomicU64::new(0),
};
Self {
world,
chunk: Arc::new(tokio::sync::RwLock::new(chunk_data)),
cancelled: data.cancelled,
}
}
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for ChunkSave {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
let guard = self.chunk.blocking_read();
Event::ChunkSaveEvent(ChunkSaveEventData {
target_world,
chunk_x: guard.x,
chunk_z: guard.z,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::ChunkSaveEvent(data) => {
let world = consume_world(state, &data.target_world);
let chunk_data = pumpkin_world::chunk::ChunkData {
section: pumpkin_world::chunk::ChunkSections::new(24, -64),
heightmap: std::sync::Mutex::new(
pumpkin_world::chunk::ChunkHeightmaps::default(),
),
x: data.chunk_x,
z: data.chunk_z,
block_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
fluid_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
pending_block_entities: std::sync::Mutex::new(
std::collections::HashMap::default(),
),
light_engine: std::sync::Mutex::new(pumpkin_world::chunk::ChunkLight::default()),
light_populated: std::sync::atomic::AtomicBool::new(false),
status: pumpkin_data::chunk::ChunkStatus::Empty,
blending_data: None,
dirty: std::sync::atomic::AtomicBool::new(false),
inhabited_time: std::sync::atomic::AtomicU64::new(0),
};
Self {
world,
chunk: Arc::new(tokio::sync::RwLock::new(chunk_data)),
cancelled: data.cancelled,
}
}
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for ChunkSend {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::ChunkSendEvent(ChunkSendEventData {
target_world,
chunk_x: self.chunk.x,
chunk_z: self.chunk.z,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::ChunkSendEvent(data) => {
let world = consume_world(state, &data.target_world);
let chunk_data = pumpkin_world::chunk::ChunkData {
section: pumpkin_world::chunk::ChunkSections::new(24, -64),
heightmap: std::sync::Mutex::new(
pumpkin_world::chunk::ChunkHeightmaps::default(),
),
x: data.chunk_x,
z: data.chunk_z,
block_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
fluid_ticks: pumpkin_world::tick::scheduler::ChunkTickScheduler::default(),
pending_block_entities: std::sync::Mutex::new(
std::collections::HashMap::default(),
),
light_engine: std::sync::Mutex::new(pumpkin_world::chunk::ChunkLight::default()),
light_populated: std::sync::atomic::AtomicBool::new(false),
status: pumpkin_data::chunk::ChunkStatus::Empty,
blending_data: None,
dirty: std::sync::atomic::AtomicBool::new(false),
inhabited_time: std::sync::atomic::AtomicU64::new(0),
};
Self {
world,
chunk: Arc::new(chunk_data),
cancelled: data.cancelled,
}
}
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::world::weather_change::WeatherChangeEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::WeatherChangeEvent(WeatherChangeEventData {
target_world,
to_weather_state: self.to_weather_state,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::WeatherChangeEvent(data) => Self {
world: consume_world(state, &data.target_world),
to_weather_state: data.to_weather_state,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::world::weather_change::ThunderChangeEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::ThunderChangeEvent(ThunderChangeEventData {
target_world,
to_thunder_state: self.to_thunder_state,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::ThunderChangeEvent(data) => Self {
world: consume_world(state, &data.target_world),
to_thunder_state: data.to_thunder_state,
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::world::world_load::WorldLoadEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::WorldLoadEvent(WorldLoadEventData { target_world })
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::WorldLoadEvent(data) => Self {
world: consume_world(state, &data.target_world),
},
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for crate::plugin::api::events::world::world_load::WorldUnloadEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::WorldUnloadEvent(WorldUnloadEventData {
target_world,
cancelled: self.cancelled,
})
}
fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {
match event {
Event::WorldUnloadEvent(data) => Self {
world: consume_world(state, &data.target_world),
cancelled: data.cancelled,
},
_ => panic!("unexpected event type"),
}
}
}

View File

@@ -205,6 +205,16 @@ pub fn serialize_java_packet(
crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap();
Some(buf.into())
}
ClientboundPacket::CDebugSample(data) => {
let sample_vec: Vec<i64> = data.sample.iter().map(|v| *v as i64).collect();
let p = pumpkin_protocol::java::client::play::CDebugSample {
sample: &sample_vec,
sample_type: VarInt(data.sample_type),
};
let mut buf = Vec::new();
crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap();
Some(buf.into())
}
ClientboundPacket::CPlayDisconnect(data) => {
let component_reason = pumpkin_util::text::TextComponent::text(data.reason.clone());
let p = pumpkin_protocol::java::client::play::CPlayDisconnect {
@@ -525,6 +535,15 @@ pub fn serialize_java_packet(
crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap();
Some(buf.into())
}
ClientboundPacket::CSetEntityLink(data) => {
let p = pumpkin_protocol::java::client::play::CSetEntityLink {
attached_entity_id: data.attached_entity_id.try_into().unwrap(),
holding_entity_id: data.holding_entity_id.try_into().unwrap(),
};
let mut buf = Vec::new();
crate::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf).unwrap();
Some(buf.into())
}
ClientboundPacket::CSetExperience(data) => {
let p = pumpkin_protocol::java::client::play::CSetExperience {
progress: data.progress.try_into().unwrap(),
@@ -767,11 +786,12 @@ pub fn deserialize_java_serverbound_packet(
keep_alive_id: p.keep_alive_id.try_into().unwrap(),
}))
}
id if id == pumpkin_protocol::java::server::config::SKnownPacks::to_id(version) => {
id if id == pumpkin_protocol::java::server::config::SPluginMessage::to_id(version) => {
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::config::SKnownPacks as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::ConfigSKnownPacks(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSKnownPacks {
known_pack_count: p.known_packs.len().try_into().unwrap(),
let p = <pumpkin_protocol::java::server::config::SPluginMessage as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::ConfigSPluginMessage(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ConfigSPluginMessage {
channel: p.channel.into(),
data: p.data.iter().map(|v| *v as _).collect(),
}))
}
id if id == pumpkin_protocol::java::server::config::SConfigResourcePack::to_id(version) => {
@@ -864,6 +884,32 @@ pub fn deserialize_java_serverbound_packet(
button_id: p.button_id.0.try_into().unwrap(),
}))
}
id if id == pumpkin_protocol::java::server::play::SCustomPayload::to_id(version) => {
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SCustomPayload as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SCustomPayload(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SCustomPayload {
channel: p.channel.into(),
data: p.data.iter().map(|v| *v as _).collect(),
}))
}
id if id
== pumpkin_protocol::java::server::play::SDebugSampleSubscription::to_id(version) =>
{
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SDebugSampleSubscription as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SDebugSampleSubscription(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SDebugSampleSubscription {
sample_type: p.sample_type.0.try_into().unwrap(),
}))
}
id if id
== pumpkin_protocol::java::server::play::SDebugSubscriptionRequest::to_id(version) =>
{
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SDebugSubscriptionRequest as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SDebugSubscriptionRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SDebugSubscriptionRequest {
sample_type: p.sample_type.0.try_into().unwrap(),
}))
}
id if id == pumpkin_protocol::java::server::play::SJigsawGenerate::to_id(version) => {
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SJigsawGenerate as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
@@ -911,7 +957,7 @@ pub fn deserialize_java_serverbound_packet(
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SPickItemFromEntity as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SPickItemFromEntity(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SPickItemFromEntity {
id: p.id.0,
id: p.id.0.try_into().unwrap(),
include_data: p.include_data.try_into().unwrap(),
}))
}
@@ -1076,6 +1122,18 @@ pub fn deserialize_java_serverbound_packet(
target: crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::uuid::Uuid { high: p.target.as_u64_pair().1, low: p.target.as_u64_pair().0 },
}))
}
id if id == pumpkin_protocol::java::server::play::SUpdateSign::to_id(version) => {
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SUpdateSign as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SUpdateSign(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::SUpdateSign {
location: (p.location.0.x, p.location.0.y, p.location.0.z),
is_front_text: p.is_front_text.try_into().unwrap(),
line_1: p.line_1.into(),
line_2: p.line_2.into(),
line_3: p.line_3.into(),
line_4: p.line_4.into(),
}))
}
id if id == pumpkin_protocol::java::server::play::SUseItem::to_id(version) => {
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SUseItem as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
@@ -1283,6 +1341,15 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CCustomPaylo
}
}
impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CDebugSample<'_> {
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CDebugSample(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CDebugSample {
sample: self.sample.iter().map(|v| *v as _).collect(),
sample_type: self.sample_type.0.try_into().unwrap(),
})
}
}
impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayDisconnect<'_> {
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CPlayDisconnect(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CPlayDisconnect {
@@ -1557,6 +1624,15 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetContaine
}
}
impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetEntityLink {
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CSetEntityLink(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetEntityLink {
attached_entity_id: self.attached_entity_id.try_into().unwrap(),
holding_entity_id: self.holding_entity_id.try_into().unwrap(),
})
}
}
impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetExperience {
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CSetExperience(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::CSetExperience {
@@ -1814,6 +1890,9 @@ pub fn clientbound_java_any_to_wit(any: &dyn Any) -> Option<ClientboundPacket> {
if let Some(p) = any.downcast_ref::<pumpkin_protocol::java::client::play::CCustomPayload>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::java::client::play::CDebugSample>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::java::client::play::CPlayDisconnect>() {
return Some(p.to_wit());
}
@@ -1911,6 +1990,9 @@ pub fn clientbound_java_any_to_wit(any: &dyn Any) -> Option<ClientboundPacket> {
{
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::java::client::play::CSetEntityLink>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::java::client::play::CSetExperience>() {
return Some(p.to_wit());
}
@@ -1983,6 +2065,21 @@ use crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_
#[must_use]
pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option<Bytes> {
match packet {
BClientboundPacket::CChangeDimension(data) => {
let p = pumpkin_protocol::bedrock::client::CChangeDimension {
dimension: VarInt(data.dimension),
position: pumpkin_util::math::vector3::Vector3::new(
data.position.0 as _,
data.position.1 as _,
data.position.2 as _,
),
respawn: data.respawn.try_into().unwrap(),
has_loading_screen_id: data.has_loading_screen_id.try_into().unwrap(),
};
let mut buf = Vec::new();
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CChunkRadiusUpdate(data) => {
let p = pumpkin_protocol::bedrock::client::CChunkRadiusUpdate {
chunk_radius: VarInt(data.chunk_radius),
@@ -2053,6 +2150,25 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option<Bytes> {
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CLevelSoundEvent(data) => {
let p = pumpkin_protocol::bedrock::client::CLevelSoundEvent {
sound_id: pumpkin_protocol::codec::var_uint::VarUInt(
data.sound_id.try_into().unwrap(),
),
position: pumpkin_util::math::vector3::Vector3::new(
data.position.0 as _,
data.position.1 as _,
data.position.2 as _,
),
extra_data: VarInt(data.extra_data),
entity_type: data.entity_type.clone(),
is_baby_mob: data.is_baby_mob.try_into().unwrap(),
is_global: data.is_global.try_into().unwrap(),
};
let mut buf = Vec::new();
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CModalFormRequest(data) => {
let p = pumpkin_protocol::bedrock::client::CModalFormRequest {
form_id: VarInt(data.form_id),
@@ -2211,6 +2327,16 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option<Bytes> {
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CSetDifficulty(data) => {
let p = pumpkin_protocol::bedrock::client::CSetDifficulty {
difficulty: pumpkin_protocol::codec::var_uint::VarUInt(
data.difficulty.try_into().unwrap(),
),
};
let mut buf = Vec::new();
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CSetHealth(data) => {
let p = pumpkin_protocol::bedrock::client::CSetHealth {
health: VarInt(data.health),
@@ -2219,6 +2345,25 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option<Bytes> {
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CSetSpawnPosition(data) => {
let p = pumpkin_protocol::bedrock::client::CSetSpawnPosition {
spawn_type: VarInt(data.spawn_type),
position: pumpkin_util::math::position::BlockPos::new(
data.position.0,
data.position.1,
data.position.2,
),
dimension: VarInt(data.dimension),
spawn_position: pumpkin_util::math::position::BlockPos::new(
data.spawn_position.0,
data.spawn_position.1,
data.spawn_position.2,
),
};
let mut buf = Vec::new();
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CSetTime(data) => {
let p = pumpkin_protocol::bedrock::client::CSetTime {
time: VarInt(data.time),
@@ -2242,6 +2387,17 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option<Bytes> {
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CShowCredits(data) => {
let p = pumpkin_protocol::bedrock::client::CShowCredits {
player_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong(
data.player_runtime_id.try_into().unwrap(),
),
status: VarInt(data.status),
};
let mut buf = Vec::new();
crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap();
Some(buf.into())
}
BClientboundPacket::CTakeItemActor(data) => {
let p = pumpkin_protocol::bedrock::client::CTakeItemActor {
item_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong(
@@ -2308,19 +2464,6 @@ pub fn deserialize_bedrock_serverbound_packet(
cache_supported: p.cache_supported.try_into().unwrap(),
}))
}
id if id == <pumpkin_protocol::bedrock::server::SCommandRequest as pumpkin_protocol::Packet>::PACKET_ID as i32 => {
use pumpkin_protocol::BServerPacket;
let p = <pumpkin_protocol::bedrock::server::SCommandRequest as pumpkin_protocol::BServerPacket>::read(&mut Cursor::new(payload)).ok()?;
Some(BServerboundPacket::SCommandRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SCommandRequest {
command: p.command.into(),
command_type: p.command_type.into(),
command_uuid: crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::uuid::Uuid { high: p.command_uuid.as_u64_pair().1, low: p.command_uuid.as_u64_pair().0 },
request_id: p.request_id.into(),
player_actor_unique_id: p.player_actor_unique_id.try_into().unwrap(),
is_internal_source: p.is_internal_source.try_into().unwrap(),
version: p.version.into(),
}))
}
id if id == <pumpkin_protocol::bedrock::server::SContainerClose as pumpkin_protocol::Packet>::PACKET_ID as i32 => {
use pumpkin_protocol::BServerPacket;
let p = <pumpkin_protocol::bedrock::server::SContainerClose as pumpkin_protocol::BServerPacket>::read(&mut Cursor::new(payload)).ok()?;
@@ -2330,16 +2473,13 @@ pub fn deserialize_bedrock_serverbound_packet(
server_initiated: p.server_initiated.try_into().unwrap(),
}))
}
id if id == <pumpkin_protocol::bedrock::server::SEmote as pumpkin_protocol::Packet>::PACKET_ID as i32 => {
id if id == <pumpkin_protocol::bedrock::server::SPlayerHotbar as pumpkin_protocol::Packet>::PACKET_ID as i32 => {
use pumpkin_protocol::BServerPacket;
let p = <pumpkin_protocol::bedrock::server::SEmote as pumpkin_protocol::BServerPacket>::read(&mut Cursor::new(payload)).ok()?;
Some(BServerboundPacket::SEmote(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SEmote {
runtime_entity_id: p.runtime_entity_id.0.try_into().unwrap(),
emote_id: p.emote_id.into(),
emote_length: p.emote_length.try_into().unwrap(),
xuid: p.xuid.into(),
platform_id: p.platform_id.into(),
flags: p.flags.try_into().unwrap(),
let p = <pumpkin_protocol::bedrock::server::SPlayerHotbar as pumpkin_protocol::BServerPacket>::read(&mut Cursor::new(payload)).ok()?;
Some(BServerboundPacket::SPlayerHotbar(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SPlayerHotbar {
selected_slot: p.selected_slot.try_into().unwrap(),
container_id: p.container_id.try_into().unwrap(),
select_slot: p.select_slot.try_into().unwrap(),
}))
}
id if id == <pumpkin_protocol::bedrock::server::SRequestChunkRadius as pumpkin_protocol::Packet>::PACKET_ID as i32 => {
@@ -2391,6 +2531,17 @@ pub trait ToWitClientboundBedrock {
fn to_wit(&self) -> BClientboundPacket;
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChangeDimension {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CChangeDimension(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChangeDimension {
dimension: self.dimension.0.try_into().unwrap(),
position: (self.position.x as _, self.position.y as _, self.position.z as _),
respawn: self.respawn.try_into().unwrap(),
has_loading_screen_id: self.has_loading_screen_id.try_into().unwrap(),
})
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChunkRadiusUpdate {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CChunkRadiusUpdate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChunkRadiusUpdate {
@@ -2443,6 +2594,19 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelEvent
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelSoundEvent {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CLevelSoundEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CLevelSoundEvent {
sound_id: self.sound_id.0.try_into().unwrap(),
position: (self.position.x as _, self.position.y as _, self.position.z as _),
extra_data: self.extra_data.0.try_into().unwrap(),
entity_type: self.entity_type.to_string(),
is_baby_mob: self.is_baby_mob.try_into().unwrap(),
is_global: self.is_global.try_into().unwrap(),
})
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CModalFormRequest {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CModalFormRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CModalFormRequest {
@@ -2575,6 +2739,14 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetActorMot
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDifficulty {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CSetDifficulty(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetDifficulty {
difficulty: self.difficulty.0.try_into().unwrap(),
})
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CSetHealth(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetHealth {
@@ -2583,6 +2755,17 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth {
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetSpawnPosition {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CSetSpawnPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetSpawnPosition {
spawn_type: self.spawn_type.0.try_into().unwrap(),
position: (self.position.0.x, self.position.0.y, self.position.0.z),
dimension: self.dimension.0.try_into().unwrap(),
spawn_position: (self.spawn_position.0.x, self.spawn_position.0.y, self.spawn_position.0.z),
})
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTime {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CSetTime(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetTime {
@@ -2606,6 +2789,15 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTitle {
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CShowCredits {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CShowCredits(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CShowCredits {
player_runtime_id: self.player_runtime_id.0.try_into().unwrap(),
status: self.status.0.try_into().unwrap(),
})
}
}
impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTakeItemActor {
fn to_wit(&self) -> BClientboundPacket {
BClientboundPacket::CTakeItemActor(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CTakeItemActor {
@@ -2638,6 +2830,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CUpdateBlock
#[must_use]
pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option<BClientboundPacket> {
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CChangeDimension>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CChunkRadiusUpdate>() {
return Some(p.to_wit());
}
@@ -2653,6 +2848,9 @@ pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option<BClientboundPacke
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CLevelEvent>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CLevelSoundEvent>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CModalFormRequest>() {
return Some(p.to_wit());
}
@@ -2686,15 +2884,24 @@ pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option<BClientboundPacke
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetActorMotion>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetDifficulty>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetHealth>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetSpawnPosition>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetTime>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CSetTitle>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CShowCredits>() {
return Some(p.to_wit());
}
if let Some(p) = any.downcast_ref::<pumpkin_protocol::bedrock::client::CTakeItemActor>() {
return Some(p.to_wit());
}

View File

@@ -1747,6 +1747,17 @@ impl World {
}
pub async fn set_raining(&self, raining: bool) {
if let Some(server) = self.server.upgrade() {
let world_arc = server.get_world_from_dimension(&self.dimension);
let mut event =
crate::plugin::api::events::world::weather_change::WeatherChangeEvent::new(
world_arc, raining,
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return;
}
}
let mut weather = self.weather.lock().await;
if weather.raining != raining {
let thunder = weather.thundering;
@@ -1759,6 +1770,17 @@ impl World {
}
pub async fn set_thundering(&self, thundering: bool) {
if let Some(server) = self.server.upgrade() {
let world_arc = server.get_world_from_dimension(&self.dimension);
let mut event =
crate::plugin::api::events::world::weather_change::ThunderChangeEvent::new(
world_arc, thundering,
);
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return;
}
}
let mut weather = self.weather.lock().await;
if weather.thundering != thundering {
let raining = weather.raining;
@@ -2688,6 +2710,14 @@ impl World {
.level
.get_or_fetch_chunk(center_chunk, std::clone::Clone::clone)
.await;
if let Some(server) = self.server.upgrade() {
let mut event =
crate::plugin::world::chunk_send::ChunkSend::new(player.world(), chunk.clone());
server.plugin_manager.fire(&server, &mut event).await;
if event.cancelled {
return;
}
}
client.send_packet_now(&CChunkBatchStart).await;
client.send_packet_now(&CChunkData(&chunk)).await;
client.send_packet_now(&CChunkBatchEnd::new(1u16)).await;