chore: add some more events
This commit is contained in:
parent
bd47c40708
commit
f27e64afbf
@ -93,7 +93,7 @@ impl EnchantingTableScreenHandler {
|
|||||||
handler
|
handler
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_enchantments(&mut self, _player: &dyn InventoryPlayer) {
|
pub async fn update_enchantments(&mut self, player: &dyn InventoryPlayer) {
|
||||||
let item = self.inventory.get_stack(0).await;
|
let item = self.inventory.get_stack(0).await;
|
||||||
|
|
||||||
if item.is_empty() || item.has_enchantments() {
|
if item.is_empty() || item.has_enchantments() {
|
||||||
@ -145,6 +145,23 @@ impl EnchantingTableScreenHandler {
|
|||||||
self.enchantment_level[i] = -1;
|
self.enchantment_level[i] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if player
|
||||||
|
.fire_prepare_item_enchant_event(
|
||||||
|
&item,
|
||||||
|
&mut self.level_requirements,
|
||||||
|
&mut self.enchantment_id,
|
||||||
|
&mut self.enchantment_level,
|
||||||
|
self.bookshelf_count,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
for i in 0..3 {
|
||||||
|
self.level_requirements[i] = 0;
|
||||||
|
self.enchantment_id[i] = -1;
|
||||||
|
self.enchantment_level[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.send_property_updates().await;
|
self.send_property_updates().await;
|
||||||
@ -367,13 +384,21 @@ impl ScreenHandler for EnchantingTableScreenHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut random = self.create_enchantment_random(id as usize);
|
let mut random = self.create_enchantment_random(id as usize);
|
||||||
let enchantments =
|
let mut enchantments =
|
||||||
Self::get_enchantment_list(&mut random, &item_stack, id as usize, level_req);
|
Self::get_enchantment_list(&mut random, &item_stack, id as usize, level_req);
|
||||||
|
|
||||||
if enchantments.is_empty() {
|
if enchantments.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if player
|
||||||
|
.fire_enchant_item_event(&item_stack, id, level_req, &mut enchantments)
|
||||||
|
.await
|
||||||
|
|| enchantments.is_empty()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if !player.is_creative() {
|
if !player.is_creative() {
|
||||||
player.add_experience_levels(-(id + 1)).await;
|
player.add_experience_levels(-(id + 1)).await;
|
||||||
lapis_stack.decrement(lapis_cost);
|
lapis_stack.decrement(lapis_cost);
|
||||||
|
|||||||
@ -33,6 +33,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
use pumpkin_data::{
|
use pumpkin_data::{
|
||||||
|
Enchantment,
|
||||||
data_component_impl::{EquipmentSlot, EquipmentType, EquippableImpl},
|
data_component_impl::{EquipmentSlot, EquipmentType, EquippableImpl},
|
||||||
screen::WindowType,
|
screen::WindowType,
|
||||||
statistic::StatisticCategory,
|
statistic::StatisticCategory,
|
||||||
@ -203,6 +204,29 @@ pub trait InventoryPlayer: Send + Sync {
|
|||||||
stat_id: i32,
|
stat_id: i32,
|
||||||
amount: i32,
|
amount: i32,
|
||||||
) -> PlayerFuture<'_, ()>;
|
) -> PlayerFuture<'_, ()>;
|
||||||
|
|
||||||
|
/// Fires a prepare item enchant event. Returns true if cancelled.
|
||||||
|
fn fire_prepare_item_enchant_event<'a>(
|
||||||
|
&'a self,
|
||||||
|
_item: &'a ItemStack,
|
||||||
|
_level_requirements: &'a mut [i32; 3],
|
||||||
|
_enchantment_id: &'a mut [i32; 3],
|
||||||
|
_enchantment_level: &'a mut [i32; 3],
|
||||||
|
_bookshelf_count: i32,
|
||||||
|
) -> PlayerFuture<'a, bool> {
|
||||||
|
Box::pin(async move { false })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fires an enchant item event. Returns true if cancelled.
|
||||||
|
fn fire_enchant_item_event<'a>(
|
||||||
|
&'a self,
|
||||||
|
_item: &'a ItemStack,
|
||||||
|
_option: i32,
|
||||||
|
_exp_level_cost: i32,
|
||||||
|
_enchantments_to_add: &'a mut Vec<(&'static Enchantment, i32)>,
|
||||||
|
) -> PlayerFuture<'a, bool> {
|
||||||
|
Box::pin(async move { false })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gives a stack to the player or drops it if inventory is full.
|
/// Gives a stack to the player or drops it if inventory is full.
|
||||||
|
|||||||
20
crates/pumpkin-plugin-api/src/events/block/block_dispense.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/block_dispense.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{BlockDispenseEventData, Event, EventType};
|
||||||
|
|
||||||
|
/// An event that occurs when a block dispenses an item.
|
||||||
|
pub struct BlockDispenseEvent;
|
||||||
|
impl FromIntoEvent for BlockDispenseEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::BlockDispenseEvent;
|
||||||
|
type Data = BlockDispenseEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::BlockDispenseEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::BlockDispenseEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin-plugin-api/src/events/block/block_explode.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/block_explode.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{BlockExplodeEventData, Event, EventType};
|
||||||
|
|
||||||
|
/// An event that occurs when a block explodes.
|
||||||
|
pub struct BlockExplodeEvent;
|
||||||
|
impl FromIntoEvent for BlockExplodeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::BlockExplodeEvent;
|
||||||
|
type Data = BlockExplodeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::BlockExplodeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::BlockExplodeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin-plugin-api/src/events/block/block_physics.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/block_physics.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{BlockPhysicsEventData, Event, EventType};
|
||||||
|
|
||||||
|
/// An event that occurs when a block physics check is run.
|
||||||
|
pub struct BlockPhysicsEvent;
|
||||||
|
impl FromIntoEvent for BlockPhysicsEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::BlockPhysicsEvent;
|
||||||
|
type Data = BlockPhysicsEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::BlockPhysicsEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::BlockPhysicsEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
40
crates/pumpkin-plugin-api/src/events/block/block_piston.rs
Normal file
40
crates/pumpkin-plugin-api/src/events/block/block_piston.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{
|
||||||
|
BlockPistonExtendEventData, BlockPistonRetractEventData, Event, EventType,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An event that occurs when a piston extends.
|
||||||
|
pub struct BlockPistonExtendEvent;
|
||||||
|
impl FromIntoEvent for BlockPistonExtendEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::BlockPistonExtendEvent;
|
||||||
|
type Data = BlockPistonExtendEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::BlockPistonExtendEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::BlockPistonExtendEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An event that occurs when a piston retracts.
|
||||||
|
pub struct BlockPistonRetractEvent;
|
||||||
|
impl FromIntoEvent for BlockPistonRetractEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::BlockPistonRetractEvent;
|
||||||
|
type Data = BlockPistonRetractEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::BlockPistonRetractEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::BlockPistonRetractEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,10 @@ pub mod block_burn;
|
|||||||
pub mod block_can_build;
|
pub mod block_can_build;
|
||||||
/// Block damage event.
|
/// Block damage event.
|
||||||
pub mod block_damage;
|
pub mod block_damage;
|
||||||
|
/// Block dispense event.
|
||||||
|
pub mod block_dispense;
|
||||||
|
/// Block explode event.
|
||||||
|
pub mod block_explode;
|
||||||
/// Block fade event.
|
/// Block fade event.
|
||||||
pub mod block_fade;
|
pub mod block_fade;
|
||||||
/// Block form event.
|
/// Block form event.
|
||||||
@ -16,19 +20,39 @@ pub mod block_from_to;
|
|||||||
pub mod block_grow;
|
pub mod block_grow;
|
||||||
/// Block ignite event.
|
/// Block ignite event.
|
||||||
pub mod block_ignite;
|
pub mod block_ignite;
|
||||||
|
/// Block physics event.
|
||||||
|
pub mod block_physics;
|
||||||
|
/// Block piston event.
|
||||||
|
pub mod block_piston;
|
||||||
/// Block place event.
|
/// Block place event.
|
||||||
pub mod block_place;
|
pub mod block_place;
|
||||||
/// Block redstone signal event.
|
/// Block redstone signal event.
|
||||||
pub mod block_redstone;
|
pub mod block_redstone;
|
||||||
|
/// Note block play event.
|
||||||
|
pub mod note_play;
|
||||||
|
/// Sign text change event.
|
||||||
|
pub mod sign_change;
|
||||||
|
/// Sponge absorb water event.
|
||||||
|
pub mod sponge_absorb;
|
||||||
|
/// TNT prime event.
|
||||||
|
pub mod tnt_prime;
|
||||||
|
|
||||||
pub use block_break::*;
|
pub use block_break::*;
|
||||||
pub use block_burn::*;
|
pub use block_burn::*;
|
||||||
pub use block_can_build::*;
|
pub use block_can_build::*;
|
||||||
pub use block_damage::*;
|
pub use block_damage::*;
|
||||||
|
pub use block_dispense::*;
|
||||||
|
pub use block_explode::*;
|
||||||
pub use block_fade::*;
|
pub use block_fade::*;
|
||||||
pub use block_form::*;
|
pub use block_form::*;
|
||||||
pub use block_from_to::*;
|
pub use block_from_to::*;
|
||||||
pub use block_grow::*;
|
pub use block_grow::*;
|
||||||
pub use block_ignite::*;
|
pub use block_ignite::*;
|
||||||
|
pub use block_physics::*;
|
||||||
|
pub use block_piston::*;
|
||||||
pub use block_place::*;
|
pub use block_place::*;
|
||||||
pub use block_redstone::*;
|
pub use block_redstone::*;
|
||||||
|
pub use note_play::*;
|
||||||
|
pub use sign_change::*;
|
||||||
|
pub use sponge_absorb::*;
|
||||||
|
pub use tnt_prime::*;
|
||||||
|
|||||||
20
crates/pumpkin-plugin-api/src/events/block/note_play.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/note_play.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{Event, EventType, NotePlayEventData};
|
||||||
|
|
||||||
|
/// An event that occurs when a note block plays.
|
||||||
|
pub struct NotePlayEvent;
|
||||||
|
impl FromIntoEvent for NotePlayEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::NotePlayEvent;
|
||||||
|
type Data = NotePlayEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::NotePlayEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::NotePlayEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin-plugin-api/src/events/block/sign_change.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/sign_change.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{Event, EventType, SignChangeEventData};
|
||||||
|
|
||||||
|
/// An event that occurs when a sign's text is changed.
|
||||||
|
pub struct SignChangeEvent;
|
||||||
|
impl FromIntoEvent for SignChangeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::SignChangeEvent;
|
||||||
|
type Data = SignChangeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::SignChangeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::SignChangeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin-plugin-api/src/events/block/sponge_absorb.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/sponge_absorb.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{Event, EventType, SpongeAbsorbEventData};
|
||||||
|
|
||||||
|
/// An event that occurs when a sponge absorbs water.
|
||||||
|
pub struct SpongeAbsorbEvent;
|
||||||
|
impl FromIntoEvent for SpongeAbsorbEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::SpongeAbsorbEvent;
|
||||||
|
type Data = SpongeAbsorbEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::SpongeAbsorbEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::SpongeAbsorbEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin-plugin-api/src/events/block/tnt_prime.rs
Normal file
20
crates/pumpkin-plugin-api/src/events/block/tnt_prime.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use super::super::FromIntoEvent;
|
||||||
|
use crate::wit::pumpkin::plugin::event::{Event, EventType, TntPrimeEventData};
|
||||||
|
|
||||||
|
/// An event that occurs when TNT is primed.
|
||||||
|
pub struct TNTPrimeEvent;
|
||||||
|
impl FromIntoEvent for TNTPrimeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::TntPrimeEvent;
|
||||||
|
type Data = TntPrimeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::TntPrimeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::TntPrimeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityAirChangeEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity's air level changes.
|
||||||
|
pub struct EntityAirChangeEvent;
|
||||||
|
impl FromIntoEvent for EntityAirChangeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityAirChangeEvent;
|
||||||
|
type Data = EntityAirChangeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityAirChangeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityAirChangeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_breed.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_breed.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityBreedEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when two entities breed.
|
||||||
|
pub struct EntityBreedEvent;
|
||||||
|
impl FromIntoEvent for EntityBreedEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityBreedEvent;
|
||||||
|
type Data = EntityBreedEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityBreedEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityBreedEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityDismountEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity dismounts another entity.
|
||||||
|
pub struct EntityDismountEvent;
|
||||||
|
impl FromIntoEvent for EntityDismountEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityDismountEvent;
|
||||||
|
type Data = EntityDismountEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityDismountEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityDismountEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_dye.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_dye.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityDyeEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity is dyed.
|
||||||
|
pub struct EntityDyeEvent;
|
||||||
|
impl FromIntoEvent for EntityDyeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityDyeEvent;
|
||||||
|
type Data = EntityDyeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityDyeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityDyeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityEnterLoveModeEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity enters love mode.
|
||||||
|
pub struct EntityEnterLoveModeEvent;
|
||||||
|
impl FromIntoEvent for EntityEnterLoveModeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityEnterLoveModeEvent;
|
||||||
|
type Data = EntityEnterLoveModeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityEnterLoveModeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityEnterLoveModeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityExplodeEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity explodes.
|
||||||
|
pub struct EntityExplodeEvent;
|
||||||
|
impl FromIntoEvent for EntityExplodeEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityExplodeEvent;
|
||||||
|
type Data = EntityExplodeEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityExplodeEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityExplodeEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_mount.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_mount.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityMountEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity mounts another entity.
|
||||||
|
pub struct EntityMountEvent;
|
||||||
|
impl FromIntoEvent for EntityMountEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityMountEvent;
|
||||||
|
type Data = EntityMountEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityMountEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityMountEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityPickupItemEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity picks up an item.
|
||||||
|
pub struct EntityPickupItemEvent;
|
||||||
|
impl FromIntoEvent for EntityPickupItemEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityPickupItemEvent;
|
||||||
|
type Data = EntityPickupItemEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityPickupItemEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityPickupItemEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_portal.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_portal.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityPortalEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity enters a portal.
|
||||||
|
pub struct EntityPortalEvent;
|
||||||
|
impl FromIntoEvent for EntityPortalEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityPortalEvent;
|
||||||
|
type Data = EntityPortalEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityPortalEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityPortalEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityResurrectEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity is resurrected.
|
||||||
|
pub struct EntityResurrectEvent;
|
||||||
|
impl FromIntoEvent for EntityResurrectEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityResurrectEvent;
|
||||||
|
type Data = EntityResurrectEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityResurrectEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityResurrectEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityShootBowEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity shoots a bow.
|
||||||
|
pub struct EntityShootBowEvent;
|
||||||
|
impl FromIntoEvent for EntityShootBowEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityShootBowEvent;
|
||||||
|
type Data = EntityShootBowEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityShootBowEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityShootBowEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_tame.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_tame.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityTameEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity is tamed.
|
||||||
|
pub struct EntityTameEvent;
|
||||||
|
impl FromIntoEvent for EntityTameEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityTameEvent;
|
||||||
|
type Data = EntityTameEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityTameEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityTameEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/pumpkin-plugin-api/src/events/entity/entity_target.rs
Normal file
21
crates/pumpkin-plugin-api/src/events/entity/entity_target.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityTargetEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity targets another entity.
|
||||||
|
pub struct EntityTargetEvent;
|
||||||
|
impl FromIntoEvent for EntityTargetEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityTargetEvent;
|
||||||
|
type Data = EntityTargetEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityTargetEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityTargetEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityTeleportEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity teleports.
|
||||||
|
pub struct EntityTeleportEvent;
|
||||||
|
impl FromIntoEvent for EntityTeleportEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityTeleportEvent;
|
||||||
|
type Data = EntityTeleportEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityTeleportEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityTeleportEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityToggleGlideEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity toggles gliding.
|
||||||
|
pub struct EntityToggleGlideEvent;
|
||||||
|
impl FromIntoEvent for EntityToggleGlideEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityToggleGlideEvent;
|
||||||
|
type Data = EntityToggleGlideEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityToggleGlideEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityToggleGlideEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
use crate::wit::pumpkin::plugin::event::{EntityTransformEventData, Event, EventType};
|
||||||
|
|
||||||
|
use super::super::FromIntoEvent;
|
||||||
|
|
||||||
|
/// Event triggered when an entity transforms into another entity.
|
||||||
|
pub struct EntityTransformEvent;
|
||||||
|
impl FromIntoEvent for EntityTransformEvent {
|
||||||
|
const EVENT_TYPE: EventType = EventType::EntityTransformEvent;
|
||||||
|
type Data = EntityTransformEventData;
|
||||||
|
|
||||||
|
fn data_from_event(event: Event) -> Self::Data {
|
||||||
|
match event {
|
||||||
|
Event::EntityTransformEvent(data) => data,
|
||||||
|
_ => panic!("unexpected event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_into_event(data: Self::Data) -> Event {
|
||||||
|
Event::EntityTransformEvent(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,64 @@
|
|||||||
|
/// Entity air change event.
|
||||||
|
pub mod entity_air_change;
|
||||||
|
/// Entity breeding event.
|
||||||
|
pub mod entity_breed;
|
||||||
/// Entity combust (catch fire) event.
|
/// Entity combust (catch fire) event.
|
||||||
pub mod entity_combust;
|
pub mod entity_combust;
|
||||||
/// Entity damage event.
|
/// Entity damage event.
|
||||||
pub mod entity_damage;
|
pub mod entity_damage;
|
||||||
/// Entity death and player death events.
|
/// Entity death and player death events.
|
||||||
pub mod entity_death;
|
pub mod entity_death;
|
||||||
|
/// Entity dismount event.
|
||||||
|
pub mod entity_dismount;
|
||||||
|
/// Entity dye event.
|
||||||
|
pub mod entity_dye;
|
||||||
|
/// Entity enter love mode event.
|
||||||
|
pub mod entity_enter_love_mode;
|
||||||
|
/// Entity explode event.
|
||||||
|
pub mod entity_explode;
|
||||||
|
/// Entity mount event.
|
||||||
|
pub mod entity_mount;
|
||||||
|
/// Entity pickup item event.
|
||||||
|
pub mod entity_pickup_item;
|
||||||
|
/// Entity portal travel event.
|
||||||
|
pub mod entity_portal;
|
||||||
/// Entity health regeneration event.
|
/// Entity health regeneration event.
|
||||||
pub mod entity_regain_health;
|
pub mod entity_regain_health;
|
||||||
|
/// Entity resurrect event.
|
||||||
|
pub mod entity_resurrect;
|
||||||
|
/// Entity shoot bow event.
|
||||||
|
pub mod entity_shoot_bow;
|
||||||
/// Entity spawn event.
|
/// Entity spawn event.
|
||||||
pub mod entity_spawn;
|
pub mod entity_spawn;
|
||||||
|
/// Entity tame event.
|
||||||
|
pub mod entity_tame;
|
||||||
|
/// Entity target event.
|
||||||
|
pub mod entity_target;
|
||||||
|
/// Entity teleport event.
|
||||||
|
pub mod entity_teleport;
|
||||||
|
/// Entity toggle glide event.
|
||||||
|
pub mod entity_toggle_glide;
|
||||||
|
/// Entity transform event.
|
||||||
|
pub mod entity_transform;
|
||||||
|
|
||||||
|
pub use entity_air_change::*;
|
||||||
|
pub use entity_breed::*;
|
||||||
pub use entity_combust::*;
|
pub use entity_combust::*;
|
||||||
pub use entity_damage::*;
|
pub use entity_damage::*;
|
||||||
pub use entity_death::*;
|
pub use entity_death::*;
|
||||||
|
pub use entity_dismount::*;
|
||||||
|
pub use entity_dye::*;
|
||||||
|
pub use entity_enter_love_mode::*;
|
||||||
|
pub use entity_explode::*;
|
||||||
|
pub use entity_mount::*;
|
||||||
|
pub use entity_pickup_item::*;
|
||||||
|
pub use entity_portal::*;
|
||||||
pub use entity_regain_health::*;
|
pub use entity_regain_health::*;
|
||||||
|
pub use entity_resurrect::*;
|
||||||
|
pub use entity_shoot_bow::*;
|
||||||
pub use entity_spawn::*;
|
pub use entity_spawn::*;
|
||||||
|
pub use entity_tame::*;
|
||||||
|
pub use entity_target::*;
|
||||||
|
pub use entity_teleport::*;
|
||||||
|
pub use entity_toggle_glide::*;
|
||||||
|
pub use entity_transform::*;
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 6d5dc27d6bd7372e072e54af08881db4197a99ef
|
Subproject commit 12e3fdd3ed121c58d57902450ad40bec538def71
|
||||||
@ -89,6 +89,18 @@ impl BlockBehaviour for FarmlandBlock {
|
|||||||
.get_block(&args.position.up())
|
.get_block(&args.position.up())
|
||||||
.has_tag(&tag::Block::MINECRAFT_MAINTAINS_FARMLAND)
|
.has_tag(&tag::Block::MINECRAFT_MAINTAINS_FARMLAND)
|
||||||
{
|
{
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::block::block_fade::BlockFadeEvent::new(
|
||||||
|
*args.position,
|
||||||
|
&Block::DIRT,
|
||||||
|
);
|
||||||
|
if let Some(server) = args.world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO push entities up
|
//TODO push entities up
|
||||||
args.world
|
args.world
|
||||||
.set_block_state(
|
.set_block_state(
|
||||||
|
|||||||
@ -27,6 +27,17 @@ pub struct NoteBlock;
|
|||||||
impl NoteBlock {
|
impl NoteBlock {
|
||||||
pub async fn play_note(props: &NoteBlockLikeProperties, world: &World, pos: &BlockPos) {
|
pub async fn play_note(props: &NoteBlockLikeProperties, world: &World, pos: &BlockPos) {
|
||||||
if !is_base_block(props.instrument) || world.get_block_state(&pos.up()).is_air() {
|
if !is_base_block(props.instrument) || world.get_block_state(&pos.up()).is_air() {
|
||||||
|
let mut event = crate::plugin::api::events::block::note_play::NotePlayEvent::new(
|
||||||
|
*pos,
|
||||||
|
format!("{:?}", props.instrument),
|
||||||
|
props.note,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
world.add_synced_block_event(*pos, 0, 0).await;
|
world.add_synced_block_event(*pos, 0, 0).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,6 +168,18 @@ impl BlockBehaviour for PistonBlock {
|
|||||||
|
|
||||||
// Extend Piston
|
// Extend Piston
|
||||||
if r#type == 0 {
|
if r#type == 0 {
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::block::block_piston::BlockPistonExtendEvent::new(
|
||||||
|
*pos,
|
||||||
|
format!("{dir:?}"),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if !move_piston(world, dir, pos, true, sticky).await {
|
if !move_piston(world, dir, pos, true, sticky).await {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,6 +204,18 @@ impl BlockBehaviour for PistonBlock {
|
|||||||
}
|
}
|
||||||
// Reduce Piston
|
// Reduce Piston
|
||||||
|
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::block::block_piston::BlockPistonRetractEvent::new(
|
||||||
|
*pos,
|
||||||
|
format!("{dir:?}"),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let extended_pos = pos.offset(dir.to_offset());
|
let extended_pos = pos.offset(dir.to_offset());
|
||||||
|
|
||||||
if let Some(block_entity) = world.get_block_entity(&extended_pos)
|
if let Some(block_entity) = world.get_block_entity(&extended_pos)
|
||||||
|
|||||||
@ -18,6 +18,15 @@ pub struct SaplingBlock;
|
|||||||
|
|
||||||
impl SaplingBlock {
|
impl SaplingBlock {
|
||||||
async fn generate(&self, world: &Arc<World>, pos: &BlockPos) {
|
async fn generate(&self, world: &Arc<World>, pos: &BlockPos) {
|
||||||
|
use crate::plugin::api::events::world::structure_grow::{StructureGrowEvent, TreeType};
|
||||||
|
let mut event = StructureGrowEvent::new(*pos, TreeType::Oak, false);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let (block, state) = world.get_block_and_state_id(pos);
|
let (block, state) = world.get_block_and_state_id(pos);
|
||||||
let mut props = SaplingProperties::from_state_id(state, block);
|
let mut props = SaplingProperties::from_state_id(state, block);
|
||||||
if props.stage == 0 {
|
if props.stage == 0 {
|
||||||
|
|||||||
@ -255,6 +255,19 @@ impl DispenserBlock {
|
|||||||
dispenser: &DispenserBlockEntity,
|
dispenser: &DispenserBlockEntity,
|
||||||
item: &mut ItemStack,
|
item: &mut ItemStack,
|
||||||
) {
|
) {
|
||||||
|
let mut event = crate::plugin::api::events::block::block_dispense::BlockDispenseEvent::new(
|
||||||
|
*ctx.position,
|
||||||
|
item.item.registry_key.to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = ctx.world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
ctx.world
|
||||||
|
.sync_world_event(WorldEvent::SoundDispenserFail, *ctx.position, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Still missing some specific dispenser behavior that you can find here:
|
// Still missing some specific dispenser behavior that you can find here:
|
||||||
// https://minecraft.wiki/w/Dispenser#Usage
|
// https://minecraft.wiki/w/Dispenser#Usage
|
||||||
let arrows = [
|
let arrows = [
|
||||||
|
|||||||
@ -67,6 +67,15 @@ impl SpongeBlock {
|
|||||||
if water_blocks.is_empty() {
|
if water_blocks.is_empty() {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::block::sponge_absorb::SpongeAbsorbEvent::new(*position);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for water_pos in &water_blocks {
|
for water_pos in &water_blocks {
|
||||||
world
|
world
|
||||||
.set_block_state(water_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
.set_block_state(water_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
||||||
|
|||||||
@ -24,7 +24,31 @@ pub struct TNTBlock;
|
|||||||
|
|
||||||
impl TNTBlock {
|
impl TNTBlock {
|
||||||
pub async fn prime(world: &Arc<World>, location: &BlockPos) {
|
pub async fn prime(world: &Arc<World>, location: &BlockPos) {
|
||||||
|
let mut event = crate::plugin::api::events::block::tnt_prime::TNTPrimeEvent::new(
|
||||||
|
*location,
|
||||||
|
"REDSTONE".to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let entity = Entity::new(world.clone(), location.to_f64(), &EntityType::TNT);
|
let entity = Entity::new(world.clone(), location.to_f64(), &EntityType::TNT);
|
||||||
|
let mut prime_event =
|
||||||
|
crate::plugin::api::events::entity::explosion_prime::ExplosionPrimeEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
DEFAULT_POWER,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut prime_event).await;
|
||||||
|
}
|
||||||
|
if prime_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let pos = entity.pos.load();
|
let pos = entity.pos.load();
|
||||||
let tnt = Arc::new(TNTEntity::new(entity, DEFAULT_POWER, DEFAULT_FUSE));
|
let tnt = Arc::new(TNTEntity::new(entity, DEFAULT_POWER, DEFAULT_FUSE));
|
||||||
world.spawn_entity(tnt).await;
|
world.spawn_entity(tnt).await;
|
||||||
|
|||||||
@ -177,6 +177,17 @@ impl BrewingStandBlockEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut event = crate::plugin::api::events::inventory::brew::BrewEvent::new(
|
||||||
|
self.position,
|
||||||
|
self.fuel.load(std::sync::atomic::Ordering::Relaxed) as u8,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Consume ingredient
|
// Consume ingredient
|
||||||
let mut items = self.items.write().await;
|
let mut items = self.items.write().await;
|
||||||
items[3].decrement(1);
|
items[3].decrement(1);
|
||||||
|
|||||||
@ -411,8 +411,20 @@ macro_rules! impl_block_entity_for_cooking {
|
|||||||
base_fuel_ticks
|
base_fuel_ticks
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut burn_event = $crate::plugin::api::events::inventory::furnace_burn::FurnaceBurnEvent::new(
|
||||||
|
self.position,
|
||||||
|
bottom_item.item.registry_key.to_string(),
|
||||||
|
adjusted_fuel_ticks as u32,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut burn_event).await;
|
||||||
|
}
|
||||||
|
if burn_event.cancelled {
|
||||||
|
self.set_lit_time_remaining(0);
|
||||||
|
} else {
|
||||||
self.set_lit_time_remaining(adjusted_fuel_ticks);
|
self.set_lit_time_remaining(adjusted_fuel_ticks);
|
||||||
self.set_lit_total_time(adjusted_fuel_ticks);
|
self.set_lit_total_time(adjusted_fuel_ticks);
|
||||||
|
}
|
||||||
|
|
||||||
if self.is_burning() {
|
if self.is_burning() {
|
||||||
is_dirty = true;
|
is_dirty = true;
|
||||||
@ -442,10 +454,20 @@ macro_rules! impl_block_entity_for_cooking {
|
|||||||
let cooking_total_time = cooking_recipe.cookingtime;
|
let cooking_total_time = cooking_recipe.cookingtime;
|
||||||
self.set_cooking_total_time(cooking_total_time as u16);
|
self.set_cooking_total_time(cooking_total_time as u16);
|
||||||
|
|
||||||
|
let mut smelt_event = $crate::plugin::api::events::inventory::furnace_smelt::FurnaceSmeltEvent::new(
|
||||||
|
self.position,
|
||||||
|
top_item.item.registry_key.to_string(),
|
||||||
|
cooking_recipe.result.id.to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut smelt_event).await;
|
||||||
|
}
|
||||||
|
if !smelt_event.cancelled {
|
||||||
self.craft_recipe(Some(cooking_recipe)).await;
|
self.craft_recipe(Some(cooking_recipe)).await;
|
||||||
is_dirty = true;
|
is_dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.set_cooking_time_spent(0);
|
self.set_cooking_time_spent(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -372,6 +372,18 @@ pub trait FlowingFluid: Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut event = crate::plugin::api::events::block::block_from_to::BlockFromToEvent::new(
|
||||||
|
*pos,
|
||||||
|
*pos,
|
||||||
|
&pumpkin_data::Block::WATER,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
world
|
world
|
||||||
.set_block_state(pos, state_id, BlockFlags::NOTIFY_ALL)
|
.set_block_state(pos, state_id, BlockFlags::NOTIFY_ALL)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@ -70,6 +70,19 @@ impl BowAttackGoal {
|
|||||||
let entity = mob.get_entity();
|
let entity = mob.get_entity();
|
||||||
let world = entity.world.load();
|
let world = entity.world.load();
|
||||||
|
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_shoot_bow::EntityShootBowEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
"minecraft:bow".to_string(),
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let arrow_entity = Entity::new(world.clone(), entity.pos.load(), &EntityType::ARROW);
|
let arrow_entity = Entity::new(world.clone(), entity.pos.load(), &EntityType::ARROW);
|
||||||
let projectile = ItemStack::new(1, &Item::ARROW);
|
let projectile = ItemStack::new(1, &Item::ARROW);
|
||||||
let arrow = ArrowEntity::new_shot(arrow_entity, entity, &projectile, ArrowPickup::Allowed);
|
let arrow = ArrowEntity::new_shot(arrow_entity, entity, &projectile, ArrowPickup::Allowed);
|
||||||
|
|||||||
@ -83,6 +83,18 @@ impl Goal for PickUpBlockGoal {
|
|||||||
|
|
||||||
let default_state_id = block.default_state.id;
|
let default_state_id = block.default_state.id;
|
||||||
|
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_change_block::EntityChangeBlockEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
target_pos,
|
||||||
|
"minecraft:air".to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Emit game event (BLOCK_DESTROY)
|
// TODO: Emit game event (BLOCK_DESTROY)
|
||||||
world
|
world
|
||||||
.set_block_state(&target_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
.set_block_state(&target_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
||||||
|
|||||||
@ -345,9 +345,21 @@ impl ItemEntity {
|
|||||||
let age = self.item_age.fetch_add(1, Ordering::Relaxed) + 1;
|
let age = self.item_age.fetch_add(1, Ordering::Relaxed) + 1;
|
||||||
|
|
||||||
if age >= 6000 {
|
if age >= 6000 {
|
||||||
|
let mut despawn_event =
|
||||||
|
crate::plugin::api::events::entity::item_despawn::ItemDespawnEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = entity.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut despawn_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if !despawn_event.cancelled {
|
||||||
entity.remove().await;
|
entity.remove().await;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let n = if entity
|
let n = if entity
|
||||||
.last_pos
|
.last_pos
|
||||||
|
|||||||
@ -241,8 +241,25 @@ impl LivingEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Picks up and Item entity or XP Orb
|
/// Picks up an Item entity or XP Orb
|
||||||
pub fn pickup(&self, item: &Entity, stack_amount: u32) {
|
pub fn pickup(&self, item: &Entity, stack_amount: u32) {
|
||||||
|
let mut pickup_event =
|
||||||
|
crate::plugin::api::events::entity::entity_pickup_item::EntityPickupItemEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
item.entity_type.id.to_string(),
|
||||||
|
stack_amount as u8,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut pickup_event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if pickup_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let chunk_pos = self.entity.chunk_pos.load();
|
let chunk_pos = self.entity.chunk_pos.load();
|
||||||
self.entity.world.load().broadcast_to_chunk_editioned_sync(
|
self.entity.world.load().broadcast_to_chunk_editioned_sync(
|
||||||
chunk_pos,
|
chunk_pos,
|
||||||
@ -335,6 +352,21 @@ impl LivingEntity {
|
|||||||
|
|
||||||
pub fn heal(&self, additional_health: f32) {
|
pub fn heal(&self, additional_health: f32) {
|
||||||
assert!(additional_health > 0.0);
|
assert!(additional_health > 0.0);
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_regain_health::EntityRegainHealthEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
additional_health,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.set_health(self.health.load() + additional_health);
|
self.set_health(self.health.load() + additional_health);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +561,20 @@ impl LivingEntity {
|
|||||||
|
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
pub async fn add_effect(&self, effect: Effect) {
|
pub async fn add_effect(&self, effect: Effect) {
|
||||||
|
let mut effect_event =
|
||||||
|
crate::plugin::api::events::entity::entity_potion_effect::EntityPotionEffectEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
effect.effect_type.translation_key.to_string(),
|
||||||
|
effect.duration,
|
||||||
|
effect.amplifier,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut effect_event).await;
|
||||||
|
}
|
||||||
|
if effect_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Apply instant effects immediately before storing
|
// Apply instant effects immediately before storing
|
||||||
if effect.effect_type == &StatusEffect::INSTANT_HEALTH {
|
if effect.effect_type == &StatusEffect::INSTANT_HEALTH {
|
||||||
let heal_amount = 4.0 * (1 << effect.amplifier) as f32;
|
let heal_amount = 4.0 * (1 << effect.amplifier) as f32;
|
||||||
@ -1800,6 +1846,20 @@ impl LivingEntity {
|
|||||||
|
|
||||||
// Clear the stack and use the totem of undying
|
// Clear the stack and use the totem of undying
|
||||||
if stack.get_data_component::<DeathProtectionImpl>().is_some() {
|
if stack.get_data_component::<DeathProtectionImpl>().is_some() {
|
||||||
|
let mut resurrect_event =
|
||||||
|
crate::plugin::api::events::entity::entity_resurrect::EntityResurrectEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut resurrect_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if resurrect_event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
stack.clear();
|
stack.clear();
|
||||||
let slot = match hand {
|
let slot = match hand {
|
||||||
Hand::Right => EquipmentSlot::MAIN_HAND,
|
Hand::Right => EquipmentSlot::MAIN_HAND,
|
||||||
@ -2197,6 +2257,20 @@ impl EntityBase for LivingEntity {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut damage_event =
|
||||||
|
crate::plugin::api::events::entity::entity_damage::EntityDamageEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
damage_type.id.to_string(),
|
||||||
|
amount,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut damage_event).await;
|
||||||
|
}
|
||||||
|
if damage_event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
amount = damage_event.damage;
|
||||||
|
|
||||||
let world = self.entity.world.load();
|
let world = self.entity.world.load();
|
||||||
let is_fire_damage = damage_type == DamageType::IN_FIRE
|
let is_fire_damage = damage_type == DamageType::IN_FIRE
|
||||||
|| damage_type == DamageType::ON_FIRE
|
|| damage_type == DamageType::ON_FIRE
|
||||||
@ -2616,6 +2690,31 @@ impl EntityBase for LivingEntity {
|
|||||||
if clamped_health <= 0.0
|
if clamped_health <= 0.0
|
||||||
&& (bypasses_cooldown_protection || !self.try_use_death_protector(caller).await)
|
&& (bypasses_cooldown_protection || !self.try_use_death_protector(caller).await)
|
||||||
{
|
{
|
||||||
|
let mut death_event =
|
||||||
|
crate::plugin::api::events::entity::entity_death::EntityDeathEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut death_event).await;
|
||||||
|
}
|
||||||
|
if let Some(player) = caller.get_player()
|
||||||
|
&& let Some(player_arc) = world.get_player_by_uuid(player.gameprofile.id)
|
||||||
|
{
|
||||||
|
let mut player_death_event =
|
||||||
|
crate::plugin::api::events::entity::entity_death::PlayerDeathEvent::new(
|
||||||
|
player_arc,
|
||||||
|
pumpkin_util::text::TextComponent::text("Died"),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut player_death_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.on_death(damage_type, source, cause).await;
|
self.on_death(damage_type, source, cause).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -572,7 +572,20 @@ pub trait Mob: EntityBase + Send + Sync {
|
|||||||
/// Set or clear the mob's target. Override to add side effects when targeting changes.
|
/// Set or clear the mob's target. Override to add side effects when targeting changes.
|
||||||
fn set_mob_target(&self, target: Option<Arc<dyn EntityBase>>) -> EntityBaseFuture<'_, ()> {
|
fn set_mob_target(&self, target: Option<Arc<dyn EntityBase>>) -> EntityBaseFuture<'_, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let mut mob_target = self.get_mob_entity().target.lock().await;
|
let target_id = target.as_ref().map(|t| t.get_entity().entity_id);
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_target::EntityTargetEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
target_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut mob_target = mob.target.lock().await;
|
||||||
*mob_target = target;
|
*mob_target = target;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -585,6 +598,138 @@ pub trait Mob: EntityBase + Send + Sync {
|
|||||||
Box::pin(async move { self.get_mob_entity().mob_interact(player, item_stack).await })
|
Box::pin(async move { self.get_mob_entity().mob_interact(player, item_stack).await })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tame<'a>(&'a self, player: &'a Arc<Player>) -> EntityBaseFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_tame::EntityTameEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
player.clone(),
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn breed(&self, father_id: i32, mother_id: i32, child_id: i32) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_breed::EntityBreedEvent::new(
|
||||||
|
father_id, mother_id, child_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dye<'a>(
|
||||||
|
&'a self,
|
||||||
|
color: crate::plugin::api::events::entity::entity_dye::DyeColor,
|
||||||
|
player: Option<&'a Arc<Player>>,
|
||||||
|
) -> EntityBaseFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_dye::EntityDyeEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
color,
|
||||||
|
player.cloned(),
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_love_mode(
|
||||||
|
&self,
|
||||||
|
human_entity_id: Option<i32>,
|
||||||
|
ticks_in_love: i32,
|
||||||
|
) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_enter_love_mode::EntityEnterLoveModeEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
human_entity_id,
|
||||||
|
ticks_in_love,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform(&self, new_entity_id: i32, transform_reason: String) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_transform::EntityTransformEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
new_entity_id,
|
||||||
|
transform_reason,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn break_door(&self, block_pos: BlockPos) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_break_door::EntityBreakDoorEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
block_pos,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_block(&self, block_pos: BlockPos) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_enter_block::EntityEnterBlockEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
block_pos,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn interact(&self, block_pos: BlockPos) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event =
|
||||||
|
crate::plugin::api::events::entity::entity_interact::EntityInteractEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
block_pos,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn place_block(&self, block_pos: BlockPos, block_name: String) -> EntityBaseFuture<'_, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mob = self.get_mob_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_place::EntityPlaceEvent::new(
|
||||||
|
mob.living_entity.entity.entity_id,
|
||||||
|
block_pos,
|
||||||
|
block_name,
|
||||||
|
);
|
||||||
|
if let Some(server) = mob.living_entity.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn mob_player_collision<'a>(&'a self, _player: &'a Arc<Player>) -> EntityBaseFuture<'a, ()> {
|
fn mob_player_collision<'a>(&'a self, _player: &'a Arc<Player>) -> EntityBaseFuture<'a, ()> {
|
||||||
Box::pin(async {})
|
Box::pin(async {})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -378,6 +378,20 @@ pub trait EntityBase: Send + Sync + NBTStorage + std::any::Any {
|
|||||||
|
|
||||||
fn set_on_fire_for_ticks(&self, ticks: u32) {
|
fn set_on_fire_for_ticks(&self, ticks: u32) {
|
||||||
let entity = self.get_entity();
|
let entity = self.get_entity();
|
||||||
|
let mut event = crate::plugin::api::events::entity::entity_combust::EntityCombustEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
ticks as f32 / 20.0,
|
||||||
|
);
|
||||||
|
if let Some(server) = entity.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if entity.fire_ticks.load(Ordering::Relaxed) < ticks as i32 {
|
if entity.fire_ticks.load(Ordering::Relaxed) < ticks as i32 {
|
||||||
entity.fire_ticks.store(ticks as i32, Ordering::Relaxed);
|
entity.fire_ticks.store(ticks as i32, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@ -2418,6 +2432,18 @@ impl Entity {
|
|||||||
portal_world: Arc<World>,
|
portal_world: Arc<World>,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
) {
|
) {
|
||||||
|
let mut portal_event =
|
||||||
|
crate::plugin::api::events::entity::entity_portal::EntityPortalEvent::new(
|
||||||
|
self.entity_id,
|
||||||
|
pos,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut portal_event).await;
|
||||||
|
}
|
||||||
|
if portal_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Passengers don't teleport independently - they wait for their vehicle
|
// Passengers don't teleport independently - they wait for their vehicle
|
||||||
if self.has_vehicle().await {
|
if self.has_vehicle().await {
|
||||||
return;
|
return;
|
||||||
@ -2656,10 +2682,21 @@ impl Entity {
|
|||||||
self.sneaking.load(Ordering::Relaxed)
|
self.sneaking.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_swimming(&self, invisible: bool) {
|
pub async fn set_swimming(&self, swimming: bool) {
|
||||||
if self.swimming.load(Ordering::Relaxed) != invisible {
|
if self.swimming.load(Ordering::Relaxed) != swimming {
|
||||||
self.swimming.store(invisible, Relaxed);
|
let mut event =
|
||||||
self.set_flag(Flag::Swimming, invisible).await;
|
crate::plugin::api::events::entity::entity_toggle_swim::EntityToggleSwimEvent::new(
|
||||||
|
self.entity_id,
|
||||||
|
swimming,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.swimming.store(event.is_swimming, Relaxed);
|
||||||
|
self.set_flag(Flag::Swimming, event.is_swimming).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2949,6 +2986,22 @@ impl Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pose(&self, pose: EntityPose) {
|
pub fn set_pose(&self, pose: EntityPose) {
|
||||||
|
let mut pose_event =
|
||||||
|
crate::plugin::api::events::entity::entity_pose_change::EntityPoseChangeEvent::new(
|
||||||
|
self.entity_id,
|
||||||
|
(pose as u8).to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut pose_event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if pose_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let dimension = Self::get_entity_dimensions(pose);
|
let dimension = Self::get_entity_dimensions(pose);
|
||||||
let position = self.pos.load();
|
let position = self.pos.load();
|
||||||
let aabb = BoundingBox::new_from_pos(position.x, position.y, position.z, &dimension);
|
let aabb = BoundingBox::new_from_pos(position.x, position.y, position.z, &dimension);
|
||||||
@ -3247,6 +3300,27 @@ impl Entity {
|
|||||||
vehicle: Arc<dyn EntityBase>,
|
vehicle: Arc<dyn EntityBase>,
|
||||||
passenger: Arc<dyn EntityBase>,
|
passenger: Arc<dyn EntityBase>,
|
||||||
) {
|
) {
|
||||||
|
let mut mount_event =
|
||||||
|
crate::plugin::api::events::entity::entity_mount::EntityMountEvent::new(
|
||||||
|
passenger.get_entity().entity_id,
|
||||||
|
self.entity_id,
|
||||||
|
);
|
||||||
|
let mut vehicle_enter =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_enter::VehicleEnterEvent::new(
|
||||||
|
self.entity_id,
|
||||||
|
passenger.get_entity().entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut mount_event).await;
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut vehicle_enter)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if mount_event.cancelled || vehicle_enter.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let passenger_entity = passenger.get_entity();
|
let passenger_entity = passenger.get_entity();
|
||||||
*passenger_entity.vehicle.lock().await = Some(vehicle);
|
*passenger_entity.vehicle.lock().await = Some(vehicle);
|
||||||
|
|
||||||
@ -3290,6 +3364,27 @@ impl Entity {
|
|||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub async fn remove_passenger(&self, passenger_id: i32) {
|
pub async fn remove_passenger(&self, passenger_id: i32) {
|
||||||
|
let mut dismount_event =
|
||||||
|
crate::plugin::api::events::entity::entity_dismount::EntityDismountEvent::new(
|
||||||
|
passenger_id,
|
||||||
|
self.entity_id,
|
||||||
|
);
|
||||||
|
let mut vehicle_exit =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_exit::VehicleExitEvent::new(
|
||||||
|
self.entity_id,
|
||||||
|
passenger_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut dismount_event)
|
||||||
|
.await;
|
||||||
|
server.plugin_manager.fire(&server, &mut vehicle_exit).await;
|
||||||
|
}
|
||||||
|
if dismount_event.cancelled || vehicle_exit.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut passengers = self.passengers.lock().await;
|
let mut passengers = self.passengers.lock().await;
|
||||||
let removed_passenger = if let Some(idx) = passengers
|
let removed_passenger = if let Some(idx) = passengers
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@ -194,7 +194,18 @@ impl Mob for ChickenEntity {
|
|||||||
let next_time = rand::rng().random_range(6000..12000);
|
let next_time = rand::rng().random_range(6000..12000);
|
||||||
let world = entity.world.load_full();
|
let world = entity.world.load_full();
|
||||||
let pos = entity.block_pos.load();
|
let pos = entity.block_pos.load();
|
||||||
|
let mut drop_event =
|
||||||
|
crate::plugin::api::events::entity::entity_drop_item::EntityDropItemEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
"minecraft:egg".to_string(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut drop_event).await;
|
||||||
|
}
|
||||||
|
if !drop_event.cancelled {
|
||||||
world.drop_stack(&pos, ItemStack::new(1, &Item::EGG)).await;
|
world.drop_stack(&pos, ItemStack::new(1, &Item::EGG)).await;
|
||||||
|
}
|
||||||
self.egg_lay_time.store(next_time, Ordering::Relaxed);
|
self.egg_lay_time.store(next_time, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use std::sync::atomic::{AtomicBool, AtomicI8, AtomicI32, AtomicU8, AtomicU32, Or
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use crate::plugin::api::events::enchantment::{EnchantItemEvent, PrepareItemEnchantEvent};
|
||||||
use crate::world::scoreboard::{BedrockScoreboard, Scoreboard};
|
use crate::world::scoreboard::{BedrockScoreboard, Scoreboard};
|
||||||
use advancement::PlayerAdvancement;
|
use advancement::PlayerAdvancement;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
@ -3416,7 +3417,22 @@ impl Player {
|
|||||||
if self.abilities.lock().await.invulnerable {
|
if self.abilities.lock().await.invulnerable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.hunger_manager.add_exhaustion(exhaustion);
|
let mut exhaustion_event =
|
||||||
|
crate::plugin::api::events::entity::entity_exhaustion::EntityExhaustionEvent::new(
|
||||||
|
self.entity_id(),
|
||||||
|
exhaustion,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut exhaustion_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if exhaustion_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.hunger_manager
|
||||||
|
.add_exhaustion(exhaustion_event.exhaustion);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn heal(&self, additional_health: f32) {
|
pub async fn heal(&self, additional_health: f32) {
|
||||||
@ -3563,7 +3579,18 @@ impl Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_food_level(&self, food_level: u8) {
|
pub async fn set_food_level(&self, food_level: u8) {
|
||||||
self.hunger_manager.set_level(food_level);
|
let mut food_event =
|
||||||
|
crate::plugin::api::events::entity::food_level_change::FoodLevelChangeEvent::new(
|
||||||
|
self.living_entity.entity.entity_id,
|
||||||
|
food_level,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut food_event).await;
|
||||||
|
}
|
||||||
|
if food_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.hunger_manager.set_level(food_event.food_level);
|
||||||
self.send_health().await;
|
self.send_health().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4535,6 +4562,20 @@ impl Player {
|
|||||||
|
|
||||||
pub async fn on_rename_item(self: &Arc<Self>, packet: SRenameItem<'_>) {
|
pub async fn on_rename_item(self: &Arc<Self>, packet: SRenameItem<'_>) {
|
||||||
self.update_last_action_time();
|
self.update_last_action_time();
|
||||||
|
|
||||||
|
let mut prepare_event =
|
||||||
|
crate::plugin::api::events::inventory::prepare_anvil::PrepareAnvilEvent::new(
|
||||||
|
self.clone(),
|
||||||
|
packet.item_name.to_string(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut prepare_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
let screen_handler_arc = self.current_screen_handler.lock().await.clone();
|
let screen_handler_arc = self.current_screen_handler.lock().await.clone();
|
||||||
let mut screen_handler = screen_handler_arc.lock().await;
|
let mut screen_handler = screen_handler_arc.lock().await;
|
||||||
|
|
||||||
@ -4809,7 +4850,7 @@ impl Player {
|
|||||||
click_type,
|
click_type,
|
||||||
slot,
|
slot,
|
||||||
raw_slot,
|
raw_slot,
|
||||||
clicked_item,
|
clicked_item.clone(),
|
||||||
cursor_item,
|
cursor_item,
|
||||||
i32::from(hotbar_button),
|
i32::from(hotbar_button),
|
||||||
);
|
);
|
||||||
@ -4820,6 +4861,38 @@ impl Player {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
if slot == 0
|
||||||
|
&& let Some(ref stack) = clicked_item
|
||||||
|
&& !stack.is_empty()
|
||||||
|
{
|
||||||
|
let mut craft_event =
|
||||||
|
crate::plugin::api::events::inventory::craft_item::CraftItemEvent::new(
|
||||||
|
self.clone(),
|
||||||
|
stack.item.registry_key.to_string(),
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut craft_event).await;
|
||||||
|
}
|
||||||
|
if craft_event.cancelled {
|
||||||
|
screen_handler.cancel().await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.mode == SlotActionType::QuickCraft {
|
||||||
|
let mut drag_event =
|
||||||
|
crate::plugin::api::events::inventory::inventory_drag::InventoryDragEvent::new(
|
||||||
|
self.clone(),
|
||||||
|
);
|
||||||
|
if let Some(server) = self.world().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut drag_event).await;
|
||||||
|
}
|
||||||
|
if drag_event.cancelled {
|
||||||
|
screen_handler.cancel().await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Enforce flags
|
// Enforce flags
|
||||||
let is_container_slot = slot >= 0 && i32::from(slot) < container_slots as i32;
|
let is_container_slot = slot >= 0 && i32::from(slot) < container_slots as i32;
|
||||||
|
|
||||||
@ -6271,6 +6344,70 @@ impl InventoryPlayer for Player {
|
|||||||
self.increment_stat(category, stat_id, amount).await;
|
self.increment_stat(category, stat_id, amount).await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fire_prepare_item_enchant_event<'a>(
|
||||||
|
&'a self,
|
||||||
|
item: &'a ItemStack,
|
||||||
|
level_requirements: &'a mut [i32; 3],
|
||||||
|
enchantment_id: &'a mut [i32; 3],
|
||||||
|
enchantment_level: &'a mut [i32; 3],
|
||||||
|
bookshelf_count: i32,
|
||||||
|
) -> PlayerFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(server) = self.world().server.upgrade() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let mut event = PrepareItemEnchantEvent::new(
|
||||||
|
player_arc,
|
||||||
|
item.clone(),
|
||||||
|
*level_requirements,
|
||||||
|
*enchantment_id,
|
||||||
|
*enchantment_level,
|
||||||
|
bookshelf_count,
|
||||||
|
);
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
if event.cancelled {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*level_requirements = event.level_requirements;
|
||||||
|
*enchantment_id = event.enchantment_id;
|
||||||
|
*enchantment_level = event.enchantment_level;
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fire_enchant_item_event<'a>(
|
||||||
|
&'a self,
|
||||||
|
item: &'a ItemStack,
|
||||||
|
option: i32,
|
||||||
|
exp_level_cost: i32,
|
||||||
|
enchantments_to_add: &'a mut Vec<(&'static pumpkin_data::Enchantment, i32)>,
|
||||||
|
) -> PlayerFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let Some(player_arc) = self.world().get_player_by_uuid(self.gameprofile.id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(server) = self.world().server.upgrade() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let mut event = EnchantItemEvent::new(
|
||||||
|
player_arc,
|
||||||
|
item.clone(),
|
||||||
|
option,
|
||||||
|
exp_level_cost,
|
||||||
|
enchantments_to_add.clone(),
|
||||||
|
);
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
if event.cancelled {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*enchantments_to_add = event.enchantments_to_add;
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -116,7 +116,18 @@ impl ArrowEntity {
|
|||||||
let mut owner_pos = shooter.pos.load();
|
let mut owner_pos = shooter.pos.load();
|
||||||
owner_pos.y = owner_pos.y + f64::from(shooter.entity_dimension.load().eye_height) - 0.1;
|
owner_pos.y = owner_pos.y + f64::from(shooter.entity_dimension.load().eye_height) - 0.1;
|
||||||
entity.pos.store(owner_pos);
|
entity.pos.store(owner_pos);
|
||||||
entity.set_velocity(Vector3::new(0.0, 0.1, 0.0));
|
let mut launch_event =
|
||||||
|
crate::plugin::api::events::entity::projectile_launch::ProjectileLaunchEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
Some(shooter.entity_id),
|
||||||
|
);
|
||||||
|
if let Some(server) = entity.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut launch_event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
entity,
|
entity,
|
||||||
@ -443,6 +454,27 @@ impl EntityBase for ArrowEntity {
|
|||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn on_hit(&self, hit: ProjectileHit) -> EntityBaseFuture<'_, ()> {
|
fn on_hit(&self, hit: ProjectileHit) -> EntityBaseFuture<'_, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
let (hit_pos, hit_entity) = match hit {
|
||||||
|
ProjectileHit::Block { hit_pos, .. } => (hit_pos, None),
|
||||||
|
ProjectileHit::Entity {
|
||||||
|
ref entity,
|
||||||
|
hit_pos,
|
||||||
|
..
|
||||||
|
} => (hit_pos, Some(entity.get_entity().entity_id)),
|
||||||
|
};
|
||||||
|
let mut hit_event =
|
||||||
|
crate::plugin::api::events::entity::projectile_hit::ProjectileHitEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
hit_pos,
|
||||||
|
hit_entity,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut hit_event).await;
|
||||||
|
}
|
||||||
|
if hit_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let entity = self.get_entity();
|
let entity = self.get_entity();
|
||||||
let world = entity.world.load();
|
let world = entity.world.load();
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,70 @@ impl VehicleEntity {
|
|||||||
if current_damage > 0.0 {
|
if current_damage > 0.0 {
|
||||||
self.damage.store(current_damage - 1.0);
|
self.damage.store(current_damage - 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut update_event =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_update::VehicleUpdateEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
server.plugin_manager.fire(&server, &mut update_event).await;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create(&self) {
|
||||||
|
let mut create_event =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_create::VehicleCreateEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut create_event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn move_vehicle(
|
||||||
|
&self,
|
||||||
|
from: pumpkin_util::math::vector3::Vector3<f64>,
|
||||||
|
to: pumpkin_util::math::vector3::Vector3<f64>,
|
||||||
|
) {
|
||||||
|
let mut move_event =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_move::VehicleMoveEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut move_event).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn collide_entity(&self, collided_entity_id: i32) {
|
||||||
|
let mut collide_event = crate::plugin::api::events::vehicle::vehicle_entity_collision::VehicleEntityCollisionEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
collided_entity_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut collide_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn collide_block(&self, block_pos: pumpkin_util::math::position::BlockPos) {
|
||||||
|
let mut collide_event = crate::plugin::api::events::vehicle::vehicle_block_collision::VehicleBlockCollisionEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
block_pos,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut collide_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_damage(&self, damage: f32) {
|
pub fn set_damage(&self, damage: f32) {
|
||||||
@ -134,6 +198,20 @@ impl VehicleEntity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let attacker_id = source.map(|s| s.get_entity().entity_id);
|
||||||
|
let mut damage_event =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_damage::VehicleDamageEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
amount,
|
||||||
|
attacker_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut damage_event).await;
|
||||||
|
}
|
||||||
|
if damage_event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let new_strength = self.apply_damage_wobble(amount);
|
let new_strength = self.apply_damage_wobble(amount);
|
||||||
|
|
||||||
let is_creative = source
|
let is_creative = source
|
||||||
@ -141,6 +219,21 @@ impl VehicleEntity {
|
|||||||
.is_some_and(|p| p.gamemode.load() == GameMode::Creative);
|
.is_some_and(|p| p.gamemode.load() == GameMode::Creative);
|
||||||
|
|
||||||
if is_creative || new_strength > 40.0 {
|
if is_creative || new_strength > 40.0 {
|
||||||
|
let mut destroy_event =
|
||||||
|
crate::plugin::api::events::vehicle::vehicle_destroy::VehicleDestroyEvent::new(
|
||||||
|
self.entity.entity_id,
|
||||||
|
attacker_id,
|
||||||
|
);
|
||||||
|
if let Some(server) = self.entity.world.load().server.upgrade() {
|
||||||
|
server
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server, &mut destroy_event)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if destroy_event.cancelled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if is_creative {
|
if is_creative {
|
||||||
self.entity.remove().await;
|
self.entity.remove().await;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -15,6 +15,8 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use crate::item::items::ignite::ignition::Ignition;
|
use crate::item::items::ignite::ignition::Ignition;
|
||||||
|
|
||||||
|
use crate::plugin::api::events::world::portal_create::{PortalCreateEvent, PortalType};
|
||||||
|
|
||||||
pub struct FlintAndSteelItem;
|
pub struct FlintAndSteelItem;
|
||||||
|
|
||||||
impl ItemMetadata for FlintAndSteelItem {
|
impl ItemMetadata for FlintAndSteelItem {
|
||||||
@ -49,7 +51,12 @@ impl ItemBehaviour for FlintAndSteelItem {
|
|||||||
.plugin_manager
|
.plugin_manager
|
||||||
.fire(&server_ref, &mut event)
|
.fire(&server_ref, &mut event)
|
||||||
.await;
|
.await;
|
||||||
if event.cancelled {
|
let mut portal_event = PortalCreateEvent::new(location, PortalType::Nether);
|
||||||
|
server_ref
|
||||||
|
.plugin_manager
|
||||||
|
.fire(&server_ref, &mut portal_event)
|
||||||
|
.await;
|
||||||
|
if event.cancelled || portal_event.cancelled {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,14 @@ impl JavaClient {
|
|||||||
Action::StartFlyingElytra => {
|
Action::StartFlyingElytra => {
|
||||||
let fall_flying = entity.check_fall_flying();
|
let fall_flying = entity.check_fall_flying();
|
||||||
if entity.is_fall_flying() != fall_flying {
|
if entity.is_fall_flying() != fall_flying {
|
||||||
entity.set_fall_flying(fall_flying).await;
|
let mut event = crate::plugin::api::events::entity::entity_toggle_glide::EntityToggleGlideEvent::new(
|
||||||
|
entity.entity_id,
|
||||||
|
fall_flying,
|
||||||
|
);
|
||||||
|
server.plugin_manager.fire(server, &mut event).await;
|
||||||
|
if !event.cancelled {
|
||||||
|
entity.set_fall_flying(event.is_gliding).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// <= 1.21.5
|
// <= 1.21.5
|
||||||
|
|||||||
@ -3,6 +3,17 @@ use super::*;
|
|||||||
|
|
||||||
impl JavaClient {
|
impl JavaClient {
|
||||||
pub async fn handle_select_trade(&self, player: &Arc<Player>, packet: SSelectTrade) {
|
pub async fn handle_select_trade(&self, player: &Arc<Player>, packet: SSelectTrade) {
|
||||||
|
let mut event = crate::plugin::api::events::inventory::trade_select::TradeSelectEvent::new(
|
||||||
|
player.clone(),
|
||||||
|
packet.selected_slot.0 as u8,
|
||||||
|
);
|
||||||
|
if let Some(server) = player.world().server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let screen_handler = player.current_screen_handler.lock().await;
|
let screen_handler = player.current_screen_handler.lock().await;
|
||||||
let mut screen_handler = screen_handler.lock().await;
|
let mut screen_handler = screen_handler.lock().await;
|
||||||
if let Some(merchant) = screen_handler
|
if let Some(merchant) = screen_handler
|
||||||
|
|||||||
@ -14,6 +14,27 @@ impl JavaClient {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lines = vec![
|
||||||
|
sign_data.line_1.to_string(),
|
||||||
|
sign_data.line_2.to_string(),
|
||||||
|
sign_data.line_3.to_string(),
|
||||||
|
sign_data.line_4.to_string(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if let Some(player_arc) = world.get_player_by_uuid(player.gameprofile.id) {
|
||||||
|
let mut event = crate::plugin::api::events::block::sign_change::SignChangeEvent::new(
|
||||||
|
player_arc,
|
||||||
|
sign_data.location,
|
||||||
|
lines.clone(),
|
||||||
|
);
|
||||||
|
if let Some(server) = world.server.upgrade() {
|
||||||
|
server.plugin_manager.fire(&server, &mut event).await;
|
||||||
|
}
|
||||||
|
if event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let text = if sign_data.is_front_text {
|
let text = if sign_data.is_front_text {
|
||||||
&sign_entity.front_text
|
&sign_entity.front_text
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -22,6 +22,16 @@ impl JavaClient {
|
|||||||
|
|
||||||
let mut item_in_hand = inventory.get_stack_in_hand(hand).await;
|
let mut item_in_hand = inventory.get_stack_in_hand(hand).await;
|
||||||
|
|
||||||
|
let mut consume_event =
|
||||||
|
crate::plugin::api::events::player::player_item_consume::PlayerItemConsumeEvent::new(
|
||||||
|
player.clone(),
|
||||||
|
item_in_hand.item.registry_key.to_string(),
|
||||||
|
);
|
||||||
|
server.plugin_manager.fire(server, &mut consume_event).await;
|
||||||
|
if consume_event.cancelled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let (item_id, _item) = (item_in_hand.item.id, item_in_hand.item);
|
let (item_id, _item) = (item_in_hand.item.id, item_in_hand.item);
|
||||||
player
|
player
|
||||||
.increment_stat(StatisticCategory::Used, item_id as i32, 1)
|
.increment_stat(StatisticCategory::Used, item_id as i32, 1)
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
use pumpkin_data::Enchantment;
|
||||||
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::entity::player::Player;
|
||||||
|
|
||||||
|
/// An event triggered when an item is enchanted at an enchanting table.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EnchantItemEvent {
|
||||||
|
/// The player enchanting the item.
|
||||||
|
pub player: Arc<Player>,
|
||||||
|
|
||||||
|
/// The item being enchanted.
|
||||||
|
pub item: ItemStack,
|
||||||
|
|
||||||
|
/// The button index selected (0, 1, or 2).
|
||||||
|
pub option: i32,
|
||||||
|
|
||||||
|
/// The cost in experience levels for the enchantment.
|
||||||
|
pub exp_level_cost: i32,
|
||||||
|
|
||||||
|
/// The list of enchantments and levels to apply.
|
||||||
|
pub enchantments_to_add: Vec<(&'static Enchantment, i32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnchantItemEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(
|
||||||
|
player: Arc<Player>,
|
||||||
|
item: ItemStack,
|
||||||
|
option: i32,
|
||||||
|
exp_level_cost: i32,
|
||||||
|
enchantments_to_add: Vec<(&'static Enchantment, i32)>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
player,
|
||||||
|
item,
|
||||||
|
option,
|
||||||
|
exp_level_cost,
|
||||||
|
enchantments_to_add,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
crates/pumpkin/src/plugin/api/events/enchantment/mod.rs
Normal file
5
crates/pumpkin/src/plugin/api/events/enchantment/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub mod enchant_item;
|
||||||
|
pub mod prepare_item_enchant;
|
||||||
|
|
||||||
|
pub use enchant_item::EnchantItemEvent;
|
||||||
|
pub use prepare_item_enchant::PrepareItemEnchantEvent;
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::entity::player::Player;
|
||||||
|
|
||||||
|
/// An event triggered when an item is prepared for enchanting in an enchanting table.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct PrepareItemEnchantEvent {
|
||||||
|
/// The player preparing the enchantment.
|
||||||
|
pub player: Arc<Player>,
|
||||||
|
|
||||||
|
/// The item being enchanted.
|
||||||
|
pub item: ItemStack,
|
||||||
|
|
||||||
|
/// The required level costs for each of the 3 slots.
|
||||||
|
pub level_requirements: [i32; 3],
|
||||||
|
|
||||||
|
/// The enchantment clue ID for each of the 3 slots (-1 if none).
|
||||||
|
pub enchantment_id: [i32; 3],
|
||||||
|
|
||||||
|
/// The enchantment clue level for each of the 3 slots (-1 if none).
|
||||||
|
pub enchantment_level: [i32; 3],
|
||||||
|
|
||||||
|
/// The bookshelf count surrounding the enchanting table.
|
||||||
|
pub bookshelf_count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrepareItemEnchantEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(
|
||||||
|
player: Arc<Player>,
|
||||||
|
item: ItemStack,
|
||||||
|
level_requirements: [i32; 3],
|
||||||
|
enchantment_id: [i32; 3],
|
||||||
|
enchantment_level: [i32; 3],
|
||||||
|
bookshelf_count: i32,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
player,
|
||||||
|
item,
|
||||||
|
level_requirements,
|
||||||
|
enchantment_id,
|
||||||
|
enchantment_level,
|
||||||
|
bookshelf_count,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity breaks a door.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityBreakDoorEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the door block.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityBreakDoorEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, block_pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
block_pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity changes a block in the world.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityChangeBlockEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the block.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
/// The new block state identifier.
|
||||||
|
pub new_block: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityChangeBlockEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, block_pos: BlockPos, new_block: String) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
block_pos,
|
||||||
|
new_block,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity dismounts another entity.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityDismountEvent {
|
||||||
|
/// The ID of the dismounting entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The ID of the vehicle entity being dismounted.
|
||||||
|
pub dismounted_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityDismountEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, dismounted_id: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
dismounted_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity drops an item.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityDropItemEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Registry name of the item.
|
||||||
|
pub item_name: String,
|
||||||
|
/// Amount dropped.
|
||||||
|
pub count: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityDropItemEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, item_name: String, count: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
item_name,
|
||||||
|
count,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity enters a block.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityEnterBlockEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the block entered.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityEnterBlockEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, block_pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
block_pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an animal enters love mode for breeding.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityEnterLoveModeEvent {
|
||||||
|
/// The ID of the animal entering love mode.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The ID of the human player that fed the animal, if any.
|
||||||
|
pub human_entity_id: Option<i32>,
|
||||||
|
|
||||||
|
/// The duration of love mode in ticks.
|
||||||
|
pub ticks_in_love: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityEnterLoveModeEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, human_entity_id: Option<i32>, ticks_in_love: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
human_entity_id,
|
||||||
|
ticks_in_love,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity experiences hunger exhaustion.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityExhaustionEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// The amount of exhaustion added.
|
||||||
|
pub exhaustion: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityExhaustionEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, exhaustion: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
exhaustion,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity interacts with a block.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityInteractEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the interacted block.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityInteractEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, block_pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
block_pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity picks up an item stack.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityPickupItemEvent {
|
||||||
|
/// The ID of the picking entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The registry name of the item.
|
||||||
|
pub item_name: String,
|
||||||
|
|
||||||
|
/// The count of items picked up.
|
||||||
|
pub count: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityPickupItemEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, item_name: String, count: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
item_name,
|
||||||
|
count,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
crates/pumpkin/src/plugin/api/events/entity/entity_place.rs
Normal file
26
crates/pumpkin/src/plugin/api/events/entity/entity_place.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity places a block.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityPlaceEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the placed block.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
/// The placed block state identifier.
|
||||||
|
pub block_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityPlaceEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, block_pos: BlockPos, block_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
block_pos,
|
||||||
|
block_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
crates/pumpkin/src/plugin/api/events/entity/entity_portal.rs
Normal file
24
crates/pumpkin/src/plugin/api/events/entity/entity_portal.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when an entity enters a portal to travel between dimensions.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityPortalEvent {
|
||||||
|
/// The ID of the entity entering the portal.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The position of the portal block.
|
||||||
|
pub portal_pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityPortalEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, portal_pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
portal_pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity's pose changes.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityPoseChangeEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// The new pose name.
|
||||||
|
pub pose: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityPoseChangeEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, pose: String) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
pose,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a potion status effect is applied to an entity.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityPotionEffectEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Effect name.
|
||||||
|
pub effect_name: String,
|
||||||
|
/// Duration in ticks.
|
||||||
|
pub duration: i32,
|
||||||
|
/// Amplifier.
|
||||||
|
pub amplifier: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityPotionEffectEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, effect_name: String, duration: i32, amplifier: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
effect_name,
|
||||||
|
duration,
|
||||||
|
amplifier,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity is saved from death by Totem of Undying.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityResurrectEvent {
|
||||||
|
/// The ID of the resurrected entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityResurrectEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity shoots a bow or crossbow.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityShootBowEvent {
|
||||||
|
/// The ID of the shooting entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The registry name of the weapon item.
|
||||||
|
pub weapon_name: String,
|
||||||
|
|
||||||
|
/// The shot force/velocity factor.
|
||||||
|
pub force: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityShootBowEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, weapon_name: String, force: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
weapon_name,
|
||||||
|
force,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity starts or stops gliding with an elytra.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityToggleGlideEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// Whether the entity is now gliding.
|
||||||
|
pub is_gliding: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityToggleGlideEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, is_gliding: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
is_gliding,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity starts or stops swimming.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityToggleSwimEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Whether the entity is swimming.
|
||||||
|
pub is_swimming: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityToggleSwimEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, is_swimming: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
is_swimming,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity transforms into another entity.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct EntityTransformEvent {
|
||||||
|
/// The ID of the original entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
|
||||||
|
/// The ID of the new transformed entity.
|
||||||
|
pub new_entity_id: i32,
|
||||||
|
|
||||||
|
/// The reason for transformation.
|
||||||
|
pub transform_reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityTransformEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, new_entity_id: i32, transform_reason: String) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
new_entity_id,
|
||||||
|
transform_reason,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity is primed to explode.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ExplosionPrimeEvent {
|
||||||
|
/// The ID of the entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// The explosion radius.
|
||||||
|
pub radius: f32,
|
||||||
|
/// Whether it creates fire.
|
||||||
|
pub fire: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExplosionPrimeEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, radius: f32, fire: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
radius,
|
||||||
|
fire,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an entity's food level changes.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct FoodLevelChangeEvent {
|
||||||
|
/// Entity ID.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// The new food level.
|
||||||
|
pub food_level: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FoodLevelChangeEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, food_level: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
food_level,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
crates/pumpkin/src/plugin/api/events/entity/item_despawn.rs
Normal file
19
crates/pumpkin/src/plugin/api/events/entity/item_despawn.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when an item entity despawns after aging.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ItemDespawnEvent {
|
||||||
|
/// The ID of the item entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemDespawnEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
crates/pumpkin/src/plugin/api/events/entity/item_spawn.rs
Normal file
26
crates/pumpkin/src/plugin/api/events/entity/item_spawn.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
|
|
||||||
|
/// An event that occurs when an item entity spawns in the world.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ItemSpawnEvent {
|
||||||
|
/// The ID of the item entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Position of the item entity.
|
||||||
|
pub position: Vector3<f64>,
|
||||||
|
/// Item registry name.
|
||||||
|
pub item_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemSpawnEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, position: Vector3<f64>, item_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
position,
|
||||||
|
item_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,27 +1,75 @@
|
|||||||
pub mod entity_air_change;
|
pub mod entity_air_change;
|
||||||
|
pub mod entity_break_door;
|
||||||
pub mod entity_breed;
|
pub mod entity_breed;
|
||||||
|
pub mod entity_change_block;
|
||||||
pub mod entity_combust;
|
pub mod entity_combust;
|
||||||
pub mod entity_damage;
|
pub mod entity_damage;
|
||||||
pub mod entity_death;
|
pub mod entity_death;
|
||||||
|
pub mod entity_dismount;
|
||||||
|
pub mod entity_drop_item;
|
||||||
pub mod entity_dye;
|
pub mod entity_dye;
|
||||||
|
pub mod entity_enter_block;
|
||||||
|
pub mod entity_enter_love_mode;
|
||||||
|
pub mod entity_exhaustion;
|
||||||
pub mod entity_explode;
|
pub mod entity_explode;
|
||||||
|
pub mod entity_interact;
|
||||||
pub mod entity_mount;
|
pub mod entity_mount;
|
||||||
|
pub mod entity_pickup_item;
|
||||||
|
pub mod entity_place;
|
||||||
|
pub mod entity_portal;
|
||||||
|
pub mod entity_pose_change;
|
||||||
|
pub mod entity_potion_effect;
|
||||||
pub mod entity_regain_health;
|
pub mod entity_regain_health;
|
||||||
|
pub mod entity_resurrect;
|
||||||
|
pub mod entity_shoot_bow;
|
||||||
pub mod entity_spawn;
|
pub mod entity_spawn;
|
||||||
pub mod entity_tame;
|
pub mod entity_tame;
|
||||||
pub mod entity_target;
|
pub mod entity_target;
|
||||||
pub mod entity_teleport;
|
pub mod entity_teleport;
|
||||||
|
pub mod entity_toggle_glide;
|
||||||
|
pub mod entity_toggle_swim;
|
||||||
|
pub mod entity_transform;
|
||||||
|
pub mod explosion_prime;
|
||||||
|
pub mod food_level_change;
|
||||||
|
pub mod item_despawn;
|
||||||
|
pub mod item_spawn;
|
||||||
|
pub mod projectile_hit;
|
||||||
|
pub mod projectile_launch;
|
||||||
|
|
||||||
pub use entity_air_change::*;
|
pub use entity_air_change::*;
|
||||||
|
pub use entity_break_door::*;
|
||||||
pub use entity_breed::*;
|
pub use entity_breed::*;
|
||||||
|
pub use entity_change_block::*;
|
||||||
pub use entity_combust::*;
|
pub use entity_combust::*;
|
||||||
pub use entity_damage::*;
|
pub use entity_damage::*;
|
||||||
pub use entity_death::*;
|
pub use entity_death::*;
|
||||||
|
pub use entity_dismount::*;
|
||||||
|
pub use entity_drop_item::*;
|
||||||
pub use entity_dye::*;
|
pub use entity_dye::*;
|
||||||
|
pub use entity_enter_block::*;
|
||||||
|
pub use entity_enter_love_mode::*;
|
||||||
|
pub use entity_exhaustion::*;
|
||||||
pub use entity_explode::*;
|
pub use entity_explode::*;
|
||||||
|
pub use entity_interact::*;
|
||||||
pub use entity_mount::*;
|
pub use entity_mount::*;
|
||||||
|
pub use entity_pickup_item::*;
|
||||||
|
pub use entity_place::*;
|
||||||
|
pub use entity_portal::*;
|
||||||
|
pub use entity_pose_change::*;
|
||||||
|
pub use entity_potion_effect::*;
|
||||||
pub use entity_regain_health::*;
|
pub use entity_regain_health::*;
|
||||||
|
pub use entity_resurrect::*;
|
||||||
|
pub use entity_shoot_bow::*;
|
||||||
pub use entity_spawn::*;
|
pub use entity_spawn::*;
|
||||||
pub use entity_tame::*;
|
pub use entity_tame::*;
|
||||||
pub use entity_target::*;
|
pub use entity_target::*;
|
||||||
pub use entity_teleport::*;
|
pub use entity_teleport::*;
|
||||||
|
pub use entity_toggle_glide::*;
|
||||||
|
pub use entity_toggle_swim::*;
|
||||||
|
pub use entity_transform::*;
|
||||||
|
pub use explosion_prime::*;
|
||||||
|
pub use food_level_change::*;
|
||||||
|
pub use item_despawn::*;
|
||||||
|
pub use item_spawn::*;
|
||||||
|
pub use projectile_hit::*;
|
||||||
|
pub use projectile_launch::*;
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
|
|
||||||
|
/// An event that occurs when a projectile hits an entity or block.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ProjectileHitEvent {
|
||||||
|
/// The ID of the projectile entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// Hit position.
|
||||||
|
pub hit_position: Vector3<f64>,
|
||||||
|
/// ID of hit entity if applicable.
|
||||||
|
pub hit_entity_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProjectileHitEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(
|
||||||
|
entity_id: i32,
|
||||||
|
hit_position: Vector3<f64>,
|
||||||
|
hit_entity_id: Option<i32>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
hit_position,
|
||||||
|
hit_entity_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a projectile is launched.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ProjectileLaunchEvent {
|
||||||
|
/// The ID of the projectile entity.
|
||||||
|
pub entity_id: i32,
|
||||||
|
/// The ID of the shooter entity if applicable.
|
||||||
|
pub shooter_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProjectileLaunchEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(entity_id: i32, shooter_id: Option<i32>) -> Self {
|
||||||
|
Self {
|
||||||
|
entity_id,
|
||||||
|
shooter_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,10 +2,13 @@ use std::any::Any;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
|
pub mod enchantment;
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
pub mod inventory;
|
pub mod inventory;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
|
pub mod raid;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
pub mod vehicle;
|
||||||
pub mod world;
|
pub mod world;
|
||||||
|
|
||||||
/// A trait representing an event in the system.
|
/// A trait representing an event in the system.
|
||||||
|
|||||||
9
crates/pumpkin/src/plugin/api/events/raid/mod.rs
Normal file
9
crates/pumpkin/src/plugin/api/events/raid/mod.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
pub mod raid_finish;
|
||||||
|
pub mod raid_spawn_wave;
|
||||||
|
pub mod raid_stop;
|
||||||
|
pub mod raid_trigger;
|
||||||
|
|
||||||
|
pub use raid_finish::*;
|
||||||
|
pub use raid_spawn_wave::*;
|
||||||
|
pub use raid_stop::*;
|
||||||
|
pub use raid_trigger::*;
|
||||||
19
crates/pumpkin/src/plugin/api/events/raid/raid_finish.rs
Normal file
19
crates/pumpkin/src/plugin/api/events/raid/raid_finish.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a raid finishes.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct RaidFinishEvent {
|
||||||
|
/// Whether victory was achieved by players.
|
||||||
|
pub victory: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaidFinishEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(victory: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
victory,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
crates/pumpkin/src/plugin/api/events/raid/raid_spawn_wave.rs
Normal file
23
crates/pumpkin/src/plugin/api/events/raid/raid_spawn_wave.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when a wave of a raid spawns.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct RaidSpawnWaveEvent {
|
||||||
|
/// Wave number.
|
||||||
|
pub wave: u32,
|
||||||
|
/// Spawn position.
|
||||||
|
pub pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaidSpawnWaveEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(wave: u32, pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
wave,
|
||||||
|
pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
crates/pumpkin/src/plugin/api/events/raid/raid_stop.rs
Normal file
19
crates/pumpkin/src/plugin/api/events/raid/raid_stop.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a raid stops.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct RaidStopEvent {
|
||||||
|
/// Reason for raid stopping.
|
||||||
|
pub reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaidStopEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(reason: String) -> Self {
|
||||||
|
Self {
|
||||||
|
reason,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
crates/pumpkin/src/plugin/api/events/raid/raid_trigger.rs
Normal file
20
crates/pumpkin/src/plugin/api/events/raid/raid_trigger.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when a raid is triggered.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct RaidTriggerEvent {
|
||||||
|
/// Raid center block position.
|
||||||
|
pub pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RaidTriggerEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,27 @@
|
|||||||
pub mod list_ping;
|
pub mod list_ping;
|
||||||
pub mod packet;
|
pub mod packet;
|
||||||
|
pub mod plugin_disable;
|
||||||
|
pub mod plugin_enable;
|
||||||
|
pub mod remote_server_command;
|
||||||
pub mod server_broadcast;
|
pub mod server_broadcast;
|
||||||
pub mod server_command;
|
pub mod server_command;
|
||||||
pub mod server_load;
|
pub mod server_load;
|
||||||
pub mod server_tick_end;
|
pub mod server_tick_end;
|
||||||
pub mod server_tick_start;
|
pub mod server_tick_start;
|
||||||
|
pub mod service_register;
|
||||||
|
pub mod service_unregister;
|
||||||
|
pub mod tab_complete;
|
||||||
|
|
||||||
|
pub use list_ping::*;
|
||||||
|
pub use packet::*;
|
||||||
|
pub use plugin_disable::*;
|
||||||
|
pub use plugin_enable::*;
|
||||||
|
pub use remote_server_command::*;
|
||||||
|
pub use server_broadcast::*;
|
||||||
|
pub use server_command::*;
|
||||||
|
pub use server_load::*;
|
||||||
|
pub use server_tick_end::*;
|
||||||
|
pub use server_tick_start::*;
|
||||||
|
pub use service_register::*;
|
||||||
|
pub use service_unregister::*;
|
||||||
|
pub use tab_complete::*;
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a plugin is disabled.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct PluginDisableEvent {
|
||||||
|
/// Name of the plugin being disabled.
|
||||||
|
pub plugin_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginDisableEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(plugin_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
plugin_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
crates/pumpkin/src/plugin/api/events/server/plugin_enable.rs
Normal file
19
crates/pumpkin/src/plugin/api/events/server/plugin_enable.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a plugin is enabled.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct PluginEnableEvent {
|
||||||
|
/// Name of the plugin being enabled.
|
||||||
|
pub plugin_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginEnableEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(plugin_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
plugin_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a command is executed via remote console (RCON).
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct RemoteServerCommandEvent {
|
||||||
|
/// Command line executed.
|
||||||
|
pub command: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoteServerCommandEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(command: String) -> Self {
|
||||||
|
Self {
|
||||||
|
command,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a service is registered.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ServiceRegisterEvent {
|
||||||
|
/// Name of the service.
|
||||||
|
pub service_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServiceRegisterEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(service_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
service_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a service is unregistered.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct ServiceUnregisterEvent {
|
||||||
|
/// Name of the service.
|
||||||
|
pub service_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServiceUnregisterEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(service_name: String) -> Self {
|
||||||
|
Self {
|
||||||
|
service_name,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
crates/pumpkin/src/plugin/api/events/server/tab_complete.rs
Normal file
22
crates/pumpkin/src/plugin/api/events/server/tab_complete.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when tab completions are requested.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct TabCompleteEvent {
|
||||||
|
/// Buffer / text being completed.
|
||||||
|
pub buffer: String,
|
||||||
|
/// Completion suggestions.
|
||||||
|
pub completions: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TabCompleteEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(buffer: String, completions: Vec<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
buffer,
|
||||||
|
completions,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
crates/pumpkin/src/plugin/api/events/vehicle/mod.rs
Normal file
19
crates/pumpkin/src/plugin/api/events/vehicle/mod.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
pub mod vehicle_block_collision;
|
||||||
|
pub mod vehicle_create;
|
||||||
|
pub mod vehicle_damage;
|
||||||
|
pub mod vehicle_destroy;
|
||||||
|
pub mod vehicle_enter;
|
||||||
|
pub mod vehicle_entity_collision;
|
||||||
|
pub mod vehicle_exit;
|
||||||
|
pub mod vehicle_move;
|
||||||
|
pub mod vehicle_update;
|
||||||
|
|
||||||
|
pub use vehicle_block_collision::*;
|
||||||
|
pub use vehicle_create::*;
|
||||||
|
pub use vehicle_damage::*;
|
||||||
|
pub use vehicle_destroy::*;
|
||||||
|
pub use vehicle_enter::*;
|
||||||
|
pub use vehicle_entity_collision::*;
|
||||||
|
pub use vehicle_exit::*;
|
||||||
|
pub use vehicle_move::*;
|
||||||
|
pub use vehicle_update::*;
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
use pumpkin_util::math::position::BlockPos;
|
||||||
|
|
||||||
|
/// An event that occurs when a vehicle collides with a block.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct VehicleBlockCollisionEvent {
|
||||||
|
/// The ID of the vehicle entity.
|
||||||
|
pub vehicle_id: i32,
|
||||||
|
/// Position of the collided block.
|
||||||
|
pub block_pos: BlockPos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VehicleBlockCollisionEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(vehicle_id: i32, block_pos: BlockPos) -> Self {
|
||||||
|
Self {
|
||||||
|
vehicle_id,
|
||||||
|
block_pos,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a vehicle is created.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct VehicleCreateEvent {
|
||||||
|
/// The ID of the vehicle entity.
|
||||||
|
pub vehicle_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VehicleCreateEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(vehicle_id: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
vehicle_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a vehicle takes damage.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct VehicleDamageEvent {
|
||||||
|
/// The ID of the vehicle entity.
|
||||||
|
pub vehicle_id: i32,
|
||||||
|
/// The damage amount.
|
||||||
|
pub damage: f32,
|
||||||
|
/// ID of attacker if applicable.
|
||||||
|
pub attacker_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VehicleDamageEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(vehicle_id: i32, damage: f32, attacker_id: Option<i32>) -> Self {
|
||||||
|
Self {
|
||||||
|
vehicle_id,
|
||||||
|
damage,
|
||||||
|
attacker_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
use pumpkin_macros::{Event, cancellable};
|
||||||
|
|
||||||
|
/// An event that occurs when a vehicle is destroyed.
|
||||||
|
#[cancellable]
|
||||||
|
#[derive(Event, Clone)]
|
||||||
|
pub struct VehicleDestroyEvent {
|
||||||
|
/// The ID of the vehicle entity.
|
||||||
|
pub vehicle_id: i32,
|
||||||
|
/// ID of attacker if applicable.
|
||||||
|
pub attacker_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VehicleDestroyEvent {
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new(vehicle_id: i32, attacker_id: Option<i32>) -> Self {
|
||||||
|
Self {
|
||||||
|
vehicle_id,
|
||||||
|
attacker_id,
|
||||||
|
cancelled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user