mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
chore: add some more events
This commit is contained in:
@@ -93,7 +93,7 @@ impl EnchantingTableScreenHandler {
|
||||
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;
|
||||
|
||||
if item.is_empty() || item.has_enchantments() {
|
||||
@@ -145,6 +145,23 @@ impl EnchantingTableScreenHandler {
|
||||
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;
|
||||
@@ -367,13 +384,21 @@ impl ScreenHandler for EnchantingTableScreenHandler {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if enchantments.is_empty() {
|
||||
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() {
|
||||
player.add_experience_levels(-(id + 1)).await;
|
||||
lapis_stack.decrement(lapis_cost);
|
||||
|
||||
@@ -33,6 +33,7 @@ use crate::{
|
||||
};
|
||||
use pumpkin_data::item_stack::ItemStack;
|
||||
use pumpkin_data::{
|
||||
Enchantment,
|
||||
data_component_impl::{EquipmentSlot, EquipmentType, EquippableImpl},
|
||||
screen::WindowType,
|
||||
statistic::StatisticCategory,
|
||||
@@ -203,6 +204,29 @@ pub trait InventoryPlayer: Send + Sync {
|
||||
stat_id: i32,
|
||||
amount: i32,
|
||||
) -> 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.
|
||||
|
||||
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;
|
||||
/// Block damage event.
|
||||
pub mod block_damage;
|
||||
/// Block dispense event.
|
||||
pub mod block_dispense;
|
||||
/// Block explode event.
|
||||
pub mod block_explode;
|
||||
/// Block fade event.
|
||||
pub mod block_fade;
|
||||
/// Block form event.
|
||||
@@ -16,19 +20,39 @@ pub mod block_from_to;
|
||||
pub mod block_grow;
|
||||
/// Block ignite event.
|
||||
pub mod block_ignite;
|
||||
/// Block physics event.
|
||||
pub mod block_physics;
|
||||
/// Block piston event.
|
||||
pub mod block_piston;
|
||||
/// Block place event.
|
||||
pub mod block_place;
|
||||
/// Block redstone signal event.
|
||||
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_burn::*;
|
||||
pub use block_can_build::*;
|
||||
pub use block_damage::*;
|
||||
pub use block_dispense::*;
|
||||
pub use block_explode::*;
|
||||
pub use block_fade::*;
|
||||
pub use block_form::*;
|
||||
pub use block_from_to::*;
|
||||
pub use block_grow::*;
|
||||
pub use block_ignite::*;
|
||||
pub use block_physics::*;
|
||||
pub use block_piston::*;
|
||||
pub use block_place::*;
|
||||
pub use block_redstone::*;
|
||||
pub use note_play::*;
|
||||
pub use sign_change::*;
|
||||
pub use sponge_absorb::*;
|
||||
pub use tnt_prime::*;
|
||||
|
||||
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.
|
||||
pub mod entity_combust;
|
||||
/// Entity damage event.
|
||||
pub mod entity_damage;
|
||||
/// Entity death and player death events.
|
||||
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.
|
||||
pub mod entity_regain_health;
|
||||
/// Entity resurrect event.
|
||||
pub mod entity_resurrect;
|
||||
/// Entity shoot bow event.
|
||||
pub mod entity_shoot_bow;
|
||||
/// Entity spawn event.
|
||||
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_damage::*;
|
||||
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_resurrect::*;
|
||||
pub use entity_shoot_bow::*;
|
||||
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::*;
|
||||
|
||||
Submodule crates/pumpkin-plugin-wit updated: 6d5dc27d6b...12e3fdd3ed
@@ -89,6 +89,18 @@ impl BlockBehaviour for FarmlandBlock {
|
||||
.get_block(&args.position.up())
|
||||
.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
|
||||
args.world
|
||||
.set_block_state(
|
||||
|
||||
@@ -27,6 +27,17 @@ pub struct NoteBlock;
|
||||
impl NoteBlock {
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +168,18 @@ impl BlockBehaviour for PistonBlock {
|
||||
|
||||
// Extend Piston
|
||||
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 {
|
||||
return false;
|
||||
}
|
||||
@@ -192,6 +204,18 @@ impl BlockBehaviour for PistonBlock {
|
||||
}
|
||||
// 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());
|
||||
|
||||
if let Some(block_entity) = world.get_block_entity(&extended_pos)
|
||||
|
||||
@@ -18,6 +18,15 @@ pub struct SaplingBlock;
|
||||
|
||||
impl SaplingBlock {
|
||||
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 mut props = SaplingProperties::from_state_id(state, block);
|
||||
if props.stage == 0 {
|
||||
|
||||
@@ -255,6 +255,19 @@ impl DispenserBlock {
|
||||
dispenser: &DispenserBlockEntity,
|
||||
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:
|
||||
// https://minecraft.wiki/w/Dispenser#Usage
|
||||
let arrows = [
|
||||
|
||||
@@ -67,6 +67,15 @@ impl SpongeBlock {
|
||||
if water_blocks.is_empty() {
|
||||
false
|
||||
} 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 {
|
||||
world
|
||||
.set_block_state(water_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
||||
|
||||
@@ -24,7 +24,31 @@ pub struct TNTBlock;
|
||||
|
||||
impl TNTBlock {
|
||||
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 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 tnt = Arc::new(TNTEntity::new(entity, DEFAULT_POWER, DEFAULT_FUSE));
|
||||
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
|
||||
let mut items = self.items.write().await;
|
||||
items[3].decrement(1);
|
||||
|
||||
@@ -411,41 +411,63 @@ macro_rules! impl_block_entity_for_cooking {
|
||||
base_fuel_ticks
|
||||
};
|
||||
|
||||
self.set_lit_time_remaining(adjusted_fuel_ticks);
|
||||
self.set_lit_total_time(adjusted_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_total_time(adjusted_fuel_ticks);
|
||||
}
|
||||
|
||||
if self.is_burning() {
|
||||
is_dirty = true;
|
||||
let mut items_guard = self.items.write().await;
|
||||
if !items_guard[1].is_empty() {
|
||||
items_guard[1].decrement(1);
|
||||
if let Some(remainder_id) =
|
||||
pumpkin_data::recipe_remainder::get_recipe_remainder_id(
|
||||
items_guard[1].item.id,
|
||||
)
|
||||
&& items_guard[1].is_empty()
|
||||
&& let Some(remainder_item) =
|
||||
pumpkin_data::item::Item::from_id(remainder_id)
|
||||
{
|
||||
items_guard[1] = ItemStack::new(1, remainder_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.is_burning() {
|
||||
is_dirty = true;
|
||||
let mut items_guard = self.items.write().await;
|
||||
if !items_guard[1].is_empty() {
|
||||
items_guard[1].decrement(1);
|
||||
if let Some(remainder_id) =
|
||||
pumpkin_data::recipe_remainder::get_recipe_remainder_id(
|
||||
items_guard[1].item.id,
|
||||
)
|
||||
&& items_guard[1].is_empty()
|
||||
&& let Some(remainder_item) =
|
||||
pumpkin_data::item::Item::from_id(remainder_id)
|
||||
{
|
||||
items_guard[1] = ItemStack::new(1, remainder_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.is_burning() && can_accept_output {
|
||||
self.cooking_time_spent.fetch_add(1, Ordering::Relaxed);
|
||||
if self.is_burning() && can_accept_output {
|
||||
self.cooking_time_spent.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
if self.get_cooking_time_spent() == self.get_cooking_total_time() {
|
||||
self.set_cooking_time_spent(0);
|
||||
if let Some(cooking_recipe) = furnace_recipe {
|
||||
let cooking_total_time = cooking_recipe.cookingtime;
|
||||
self.set_cooking_total_time(cooking_total_time as u16);
|
||||
if self.get_cooking_time_spent() == self.get_cooking_total_time() {
|
||||
self.set_cooking_time_spent(0);
|
||||
if let Some(cooking_recipe) = furnace_recipe {
|
||||
let cooking_total_time = cooking_recipe.cookingtime;
|
||||
self.set_cooking_total_time(cooking_total_time as u16);
|
||||
|
||||
self.craft_recipe(Some(cooking_recipe)).await;
|
||||
is_dirty = true;
|
||||
}
|
||||
}
|
||||
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;
|
||||
is_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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
|
||||
.set_block_state(pos, state_id, BlockFlags::NOTIFY_ALL)
|
||||
.await;
|
||||
|
||||
@@ -70,6 +70,19 @@ impl BowAttackGoal {
|
||||
let entity = mob.get_entity();
|
||||
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 projectile = ItemStack::new(1, &Item::ARROW);
|
||||
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 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)
|
||||
world
|
||||
.set_block_state(&target_pos, BlockStateId::AIR, BlockFlags::NOTIFY_ALL)
|
||||
|
||||
@@ -345,8 +345,20 @@ impl ItemEntity {
|
||||
let age = self.item_age.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
|
||||
if age >= 6000 {
|
||||
entity.remove().await;
|
||||
return false;
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let n = if entity
|
||||
|
||||
@@ -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) {
|
||||
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();
|
||||
self.entity.world.load().broadcast_to_chunk_editioned_sync(
|
||||
chunk_pos,
|
||||
@@ -335,6 +352,21 @@ impl LivingEntity {
|
||||
|
||||
pub fn heal(&self, additional_health: f32) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -529,6 +561,20 @@ impl LivingEntity {
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
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
|
||||
if effect.effect_type == &StatusEffect::INSTANT_HEALTH {
|
||||
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
|
||||
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();
|
||||
let slot = match hand {
|
||||
Hand::Right => EquipmentSlot::MAIN_HAND,
|
||||
@@ -2197,6 +2257,20 @@ impl EntityBase for LivingEntity {
|
||||
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 is_fire_damage = damage_type == DamageType::IN_FIRE
|
||||
|| damage_type == DamageType::ON_FIRE
|
||||
@@ -2616,6 +2690,31 @@ impl EntityBase for LivingEntity {
|
||||
if clamped_health <= 0.0
|
||||
&& (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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
fn set_mob_target(&self, target: Option<Arc<dyn EntityBase>>) -> EntityBaseFuture<'_, ()> {
|
||||
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;
|
||||
})
|
||||
}
|
||||
@@ -585,6 +598,138 @@ pub trait Mob: EntityBase + Send + Sync {
|
||||
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, ()> {
|
||||
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) {
|
||||
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 {
|
||||
entity.fire_ticks.store(ticks as i32, Ordering::Relaxed);
|
||||
}
|
||||
@@ -2418,6 +2432,18 @@ impl Entity {
|
||||
portal_world: Arc<World>,
|
||||
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
|
||||
if self.has_vehicle().await {
|
||||
return;
|
||||
@@ -2656,10 +2682,21 @@ impl Entity {
|
||||
self.sneaking.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub async fn set_swimming(&self, invisible: bool) {
|
||||
if self.swimming.load(Ordering::Relaxed) != invisible {
|
||||
self.swimming.store(invisible, Relaxed);
|
||||
self.set_flag(Flag::Swimming, invisible).await;
|
||||
pub async fn set_swimming(&self, swimming: bool) {
|
||||
if self.swimming.load(Ordering::Relaxed) != swimming {
|
||||
let mut event =
|
||||
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) {
|
||||
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 position = self.pos.load();
|
||||
let aabb = BoundingBox::new_from_pos(position.x, position.y, position.z, &dimension);
|
||||
@@ -3247,6 +3300,27 @@ impl Entity {
|
||||
vehicle: 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();
|
||||
*passenger_entity.vehicle.lock().await = Some(vehicle);
|
||||
|
||||
@@ -3290,6 +3364,27 @@ impl Entity {
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
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 removed_passenger = if let Some(idx) = passengers
|
||||
.iter()
|
||||
|
||||
@@ -194,7 +194,18 @@ impl Mob for ChickenEntity {
|
||||
let next_time = rand::rng().random_range(6000..12000);
|
||||
let world = entity.world.load_full();
|
||||
let pos = entity.block_pos.load();
|
||||
world.drop_stack(&pos, ItemStack::new(1, &Item::EGG)).await;
|
||||
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;
|
||||
}
|
||||
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::time::{Duration, Instant};
|
||||
|
||||
use crate::plugin::api::events::enchantment::{EnchantItemEvent, PrepareItemEnchantEvent};
|
||||
use crate::world::scoreboard::{BedrockScoreboard, Scoreboard};
|
||||
use advancement::PlayerAdvancement;
|
||||
use arc_swap::ArcSwap;
|
||||
@@ -3416,7 +3417,22 @@ impl Player {
|
||||
if self.abilities.lock().await.invulnerable {
|
||||
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) {
|
||||
@@ -3563,7 +3579,18 @@ impl Player {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -4535,6 +4562,20 @@ impl Player {
|
||||
|
||||
pub async fn on_rename_item(self: &Arc<Self>, packet: SRenameItem<'_>) {
|
||||
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 mut screen_handler = screen_handler_arc.lock().await;
|
||||
|
||||
@@ -4809,7 +4850,7 @@ impl Player {
|
||||
click_type,
|
||||
slot,
|
||||
raw_slot,
|
||||
clicked_item,
|
||||
clicked_item.clone(),
|
||||
cursor_item,
|
||||
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
|
||||
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;
|
||||
})
|
||||
}
|
||||
|
||||
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)]
|
||||
|
||||
@@ -116,7 +116,18 @@ impl ArrowEntity {
|
||||
let mut owner_pos = shooter.pos.load();
|
||||
owner_pos.y = owner_pos.y + f64::from(shooter.entity_dimension.load().eye_height) - 0.1;
|
||||
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 {
|
||||
entity,
|
||||
@@ -443,6 +454,27 @@ impl EntityBase for ArrowEntity {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn on_hit(&self, hit: ProjectileHit) -> EntityBaseFuture<'_, ()> {
|
||||
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 world = entity.world.load();
|
||||
|
||||
|
||||
@@ -38,6 +38,70 @@ impl VehicleEntity {
|
||||
if current_damage > 0.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) {
|
||||
@@ -134,6 +198,20 @@ impl VehicleEntity {
|
||||
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 is_creative = source
|
||||
@@ -141,6 +219,21 @@ impl VehicleEntity {
|
||||
.is_some_and(|p| p.gamemode.load() == GameMode::Creative);
|
||||
|
||||
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 {
|
||||
self.entity.remove().await;
|
||||
} else {
|
||||
|
||||
@@ -15,6 +15,8 @@ use std::sync::Arc;
|
||||
|
||||
use crate::item::items::ignite::ignition::Ignition;
|
||||
|
||||
use crate::plugin::api::events::world::portal_create::{PortalCreateEvent, PortalType};
|
||||
|
||||
pub struct FlintAndSteelItem;
|
||||
|
||||
impl ItemMetadata for FlintAndSteelItem {
|
||||
@@ -49,7 +51,12 @@ impl ItemBehaviour for FlintAndSteelItem {
|
||||
.plugin_manager
|
||||
.fire(&server_ref, &mut event)
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,14 @@ impl JavaClient {
|
||||
Action::StartFlyingElytra => {
|
||||
let fall_flying = entity.check_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
|
||||
|
||||
@@ -3,6 +3,17 @@ use super::*;
|
||||
|
||||
impl JavaClient {
|
||||
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 mut screen_handler = screen_handler.lock().await;
|
||||
if let Some(merchant) = screen_handler
|
||||
|
||||
@@ -14,6 +14,27 @@ impl JavaClient {
|
||||
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 {
|
||||
&sign_entity.front_text
|
||||
} else {
|
||||
|
||||
@@ -22,6 +22,16 @@ impl JavaClient {
|
||||
|
||||
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);
|
||||
player
|
||||
.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_break_door;
|
||||
pub mod entity_breed;
|
||||
pub mod entity_change_block;
|
||||
pub mod entity_combust;
|
||||
pub mod entity_damage;
|
||||
pub mod entity_death;
|
||||
pub mod entity_dismount;
|
||||
pub mod entity_drop_item;
|
||||
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_interact;
|
||||
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_resurrect;
|
||||
pub mod entity_shoot_bow;
|
||||
pub mod entity_spawn;
|
||||
pub mod entity_tame;
|
||||
pub mod entity_target;
|
||||
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_break_door::*;
|
||||
pub use entity_breed::*;
|
||||
pub use entity_change_block::*;
|
||||
pub use entity_combust::*;
|
||||
pub use entity_damage::*;
|
||||
pub use entity_death::*;
|
||||
pub use entity_dismount::*;
|
||||
pub use entity_drop_item::*;
|
||||
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_interact::*;
|
||||
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_resurrect::*;
|
||||
pub use entity_shoot_bow::*;
|
||||
pub use entity_spawn::*;
|
||||
pub use entity_tame::*;
|
||||
pub use entity_target::*;
|
||||
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;
|
||||
|
||||
pub mod block;
|
||||
pub mod enchantment;
|
||||
pub mod entity;
|
||||
pub mod inventory;
|
||||
pub mod player;
|
||||
pub mod raid;
|
||||
pub mod server;
|
||||
pub mod vehicle;
|
||||
pub mod world;
|
||||
|
||||
/// 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 packet;
|
||||
pub mod plugin_disable;
|
||||
pub mod plugin_enable;
|
||||
pub mod remote_server_command;
|
||||
pub mod server_broadcast;
|
||||
pub mod server_command;
|
||||
pub mod server_load;
|
||||
pub mod server_tick_end;
|
||||
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
Reference in New Issue
Block a user