Skip to main content

pumpkinplus/modules/mechanics/player/
enderchest.rs

1//! Enderchest module - per-player enderchest sharing and management.
2//!
3//! ## Configuration
4//!
5//! | Field       | Default                | Description                               |
6//! |-------------|------------------------|-------------------------------------------|
7//! | `enabled`   | `false`                | Whether this module is active             |
8//! | `gamemodes` | `["Survival", "Adventure"]` | Gamemodes allowed to use enderchests      |
9//! | `actions`   | `["RightClickAir"]`        | Interaction actions that trigger the GUI  |
10
11use crate::config::ConfigManager;
12use crate::mechanics::mechanic::Mechanic;
13use crate::{GameMode, InteractAction};
14use pumpkin_plugin_api::events::{EventData, EventHandler, EventPriority, PlayerInteractEvent};
15use pumpkin_plugin_api::{Context, Server};
16use serde::{Deserialize, Serialize};
17
18/// Handles enderchest mechanics.
19#[derive(Default)]
20pub struct Enderchest;
21
22impl Mechanic for Enderchest {
23    fn enabled(&self) -> bool {
24        ConfigManager::get()
25            .map(|cm| cm.get_config::<EnderchestConfig>().enabled)
26            .unwrap_or(true)
27    }
28
29    fn events(&self, context: &Context) {
30        context
31            .register_event_handler::<PlayerInteractEvent, _>(
32                Enderchest,
33                EventPriority::Normal,
34                true,
35            )
36            .expect("failed to register enderchest event handler");
37    }
38}
39
40impl EventHandler<PlayerInteractEvent> for Enderchest {
41    fn handle(
42        &self,
43        _server: Server,
44        event: EventData<PlayerInteractEvent>,
45    ) -> EventData<PlayerInteractEvent> {
46        if !self.enabled() {
47            return event;
48        }
49
50        let config: EnderchestConfig = ConfigManager::get()
51            .map(|cm| cm.get_config())
52            .unwrap_or_default();
53
54        let action = InteractAction::from(event.action);
55        if !action.matches_config(&config.actions) {
56            return event;
57        }
58
59        if event.block != "minecraft:ender_chest" {
60            return event;
61        }
62
63        let gamemode = GameMode::from(event.player.get_gamemode());
64        if !gamemode.matches_config(&config.gamemodes) {
65            return event;
66        }
67
68        //TODO: notify api-maintainers to add enderchest support.
69
70        event
71    }
72}
73
74/// Configuration for the enderchest mechanics module.
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct EnderchestConfig {
77    /// Whether this module is active.
78    pub enabled: bool,
79    /// List of gamemodes allowed to use enderchests. Use variant names like "Survival", "Creative", etc. Leave empty to allow all.
80    pub gamemodes: Vec<GameMode>,
81    /// List of interaction actions that trigger opening the enderchest. Use variant names like "RightClickBlock", "RightClickAir", etc. Leave empty to allow all.
82    pub actions: Vec<InteractAction>,
83}
84
85impl Default for EnderchestConfig {
86    fn default() -> Self {
87        Self {
88            enabled: false,
89            gamemodes: vec![GameMode::Survival, GameMode::Adventure],
90            actions: vec![InteractAction::RightClickAir],
91        }
92    }
93}