From 3a54aab0dd60347b9e21214e4135e94c76645948 Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 22 Jan 2025 23:14:58 +0000 Subject: [PATCH] feat: add `PlayerEmoteEvent` --- endstone/_internal/endstone_python.pyi | 14 ++++- endstone/event.py | 2 + include/endstone/endstone.hpp | 1 + .../event/player/player_emote_event.h | 53 +++++++++++++++++++ .../handlers/player_gameplay_handler.cpp | 14 ++++- .../event/handlers/player_gameplay_handler.h | 1 + src/endstone/python/event.cpp | 2 + 7 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 include/endstone/event/player/player_emote_event.h diff --git a/endstone/_internal/endstone_python.pyi b/endstone/_internal/endstone_python.pyi index c734486d8..c77d57bf2 100644 --- a/endstone/_internal/endstone_python.pyi +++ b/endstone/_internal/endstone_python.pyi @@ -4,7 +4,7 @@ import numpy import os import typing import uuid -__all__ = ['ActionForm', 'Actor', 'ActorDeathEvent', 'ActorEvent', 'ActorExplodeEvent', 'ActorKnockbackEvent', 'ActorRemoveEvent', 'ActorSpawnEvent', 'ActorTeleportEvent', 'BanEntry', 'BarColor', 'BarFlag', 'BarStyle', 'Block', 'BlockBreakEvent', 'BlockData', 'BlockEvent', 'BlockFace', 'BlockPlaceEvent', 'BlockState', 'BossBar', 'BroadcastMessageEvent', 'Cancellable', 'ColorFormat', 'Command', 'CommandExecutor', 'CommandSender', 'CommandSenderWrapper', 'ConsoleCommandSender', 'Criteria', 'Dimension', 'DisplaySlot', 'Dropdown', 'Event', 'EventPriority', 'GameMode', 'Inventory', 'IpBanEntry', 'IpBanList', 'ItemStack', 'Label', 'Language', 'Level', 'Location', 'Logger', 'MessageForm', 'Mob', 'ModalForm', 'Objective', 'ObjectiveSortOrder', 'OfflinePlayer', 'Packet', 'PacketType', 'Permissible', 'Permission', 'PermissionAttachment', 'PermissionAttachmentInfo', 'PermissionDefault', 'Player', 'PlayerBanEntry', 'PlayerBanList', 'PlayerChatEvent', 'PlayerCommandEvent', 'PlayerDeathEvent', 'PlayerEvent', 'PlayerGameModeChangeEvent', 'PlayerInteractActorEvent', 'PlayerInteractEvent', 'PlayerInventory', 'PlayerJoinEvent', 'PlayerKickEvent', 'PlayerLoginEvent', 'PlayerQuitEvent', 'PlayerTeleportEvent', 'Plugin', 'PluginCommand', 'PluginDescription', 'PluginDisableEvent', 'PluginEnableEvent', 'PluginLoadOrder', 'PluginLoader', 'PluginManager', 'Position', 'RenderType', 'Scheduler', 'Score', 'Scoreboard', 'ScriptMessageEvent', 'Server', 'ServerCommandEvent', 'ServerEvent', 'ServerListPingEvent', 'ServerLoadEvent', 'Skin', 'Slider', 'SocketAddress', 'SpawnParticleEffectPacket', 'StepSlider', 'Task', 'TextInput', 'ThunderChangeEvent', 'Toggle', 'Translatable', 'Vector', 'WeatherChangeEvent', 'WeatherEvent'] +__all__ = ['ActionForm', 'Actor', 'ActorDeathEvent', 'ActorEvent', 'ActorExplodeEvent', 'ActorKnockbackEvent', 'ActorRemoveEvent', 'ActorSpawnEvent', 'ActorTeleportEvent', 'BanEntry', 'BarColor', 'BarFlag', 'BarStyle', 'Block', 'BlockBreakEvent', 'BlockData', 'BlockEvent', 'BlockFace', 'BlockPlaceEvent', 'BlockState', 'BossBar', 'BroadcastMessageEvent', 'Cancellable', 'ColorFormat', 'Command', 'CommandExecutor', 'CommandSender', 'CommandSenderWrapper', 'ConsoleCommandSender', 'Criteria', 'Dimension', 'DisplaySlot', 'Dropdown', 'Event', 'EventPriority', 'GameMode', 'Inventory', 'IpBanEntry', 'IpBanList', 'ItemStack', 'Label', 'Language', 'Level', 'Location', 'Logger', 'MessageForm', 'Mob', 'ModalForm', 'Objective', 'ObjectiveSortOrder', 'OfflinePlayer', 'Packet', 'PacketType', 'Permissible', 'Permission', 'PermissionAttachment', 'PermissionAttachmentInfo', 'PermissionDefault', 'Player', 'PlayerBanEntry', 'PlayerBanList', 'PlayerChatEvent', 'PlayerCommandEvent', 'PlayerDeathEvent', 'PlayerEmoteEvent', 'PlayerEvent', 'PlayerGameModeChangeEvent', 'PlayerInteractActorEvent', 'PlayerInteractEvent', 'PlayerInventory', 'PlayerJoinEvent', 'PlayerKickEvent', 'PlayerLoginEvent', 'PlayerQuitEvent', 'PlayerTeleportEvent', 'Plugin', 'PluginCommand', 'PluginDescription', 'PluginDisableEvent', 'PluginEnableEvent', 'PluginLoadOrder', 'PluginLoader', 'PluginManager', 'Position', 'RenderType', 'Scheduler', 'Score', 'Scoreboard', 'ScriptMessageEvent', 'Server', 'ServerCommandEvent', 'ServerEvent', 'ServerListPingEvent', 'ServerLoadEvent', 'Skin', 'Slider', 'SocketAddress', 'SpawnParticleEffectPacket', 'StepSlider', 'Task', 'TextInput', 'ThunderChangeEvent', 'Toggle', 'Translatable', 'Vector', 'WeatherChangeEvent', 'WeatherEvent'] class ActionForm: """ Represents a form with buttons that let the player take action. @@ -2463,6 +2463,18 @@ class PlayerDeathEvent(ActorDeathEvent, PlayerEvent): @death_message.setter def death_message(self, arg1: str) -> None: ... +class PlayerEmoteEvent(PlayerEvent): + """ + Called when a player uses and emote + """ + @staticmethod + def _pybind11_conduit_v1_(*args, **kwargs): + ... + @property + def emote_id(self) -> str: + """ + Gets the emote ID + """ class PlayerEvent(Event): """ Represents a player related event diff --git a/endstone/event.py b/endstone/event.py index 06916efbe..fb3512a3c 100644 --- a/endstone/event.py +++ b/endstone/event.py @@ -16,6 +16,7 @@ PlayerChatEvent, PlayerCommandEvent, PlayerDeathEvent, + PlayerEmoteEvent, PlayerEvent, PlayerGameModeChangeEvent, PlayerInteractActorEvent, @@ -44,6 +45,7 @@ "ActorEvent", "ActorExplodeEvent", "ActorDeathEvent", + "PlayerEmoteEvent", "ActorKnockbackEvent", "ActorRemoveEvent", "ActorSpawnEvent", diff --git a/include/endstone/endstone.hpp b/include/endstone/endstone.hpp index 767608a8c..e78302b3c 100644 --- a/include/endstone/endstone.hpp +++ b/include/endstone/endstone.hpp @@ -66,6 +66,7 @@ static_assert(_ITERATOR_DEBUG_LEVEL == 0, #include "event/player/player_chat_event.h" #include "event/player/player_command_event.h" #include "event/player/player_death_event.h" +#include "event/player/player_emote_event.h" #include "event/player/player_event.h" #include "event/player/player_game_mode_change_event.h" #include "event/player/player_interact_actor_event.h" diff --git a/include/endstone/event/player/player_emote_event.h b/include/endstone/event/player/player_emote_event.h new file mode 100644 index 000000000..be572258e --- /dev/null +++ b/include/endstone/event/player/player_emote_event.h @@ -0,0 +1,53 @@ +// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "endstone/event/cancellable.h" +#include "endstone/event/player/player_event.h" + +namespace endstone { + +/** + * @brief Called when a player uses an emote. + */ +class PlayerEmoteEvent : public PlayerEvent { +public: + explicit PlayerEmoteEvent(Player &player, std::string emote_id) + : PlayerEvent(player), emote_id_(std::move(emote_id)) + { + } + ~PlayerEmoteEvent() override = default; + + inline static const std::string NAME = "PlayerEmoteEvent"; + [[nodiscard]] std::string getEventName() const override + { + return NAME; + } + + /** + * @brief Gets the emote ID + * + * @return The emote ID + */ + [[nodiscard]] std::string getEmoteId() const + { + return emote_id_; + } + +private: + std::string emote_id_; +}; + +} // namespace endstone diff --git a/src/endstone/core/event/handlers/player_gameplay_handler.cpp b/src/endstone/core/event/handlers/player_gameplay_handler.cpp index d6fa48710..a7aa459a0 100644 --- a/src/endstone/core/event/handlers/player_gameplay_handler.cpp +++ b/src/endstone/core/event/handlers/player_gameplay_handler.cpp @@ -23,6 +23,7 @@ #include "endstone/core/json.h" #include "endstone/core/player.h" #include "endstone/core/server.h" +#include "endstone/event/player/player_emote_event.h" #include "endstone/event/player/player_game_mode_change_event.h" #include "endstone/event/player/player_interact_actor_event.h" #include "endstone/event/player/player_interact_event.h" @@ -55,7 +56,8 @@ GameplayHandlerResult EndstonePlayerGameplayHandler::handleEv auto visitor = [&](auto &&arg) -> GameplayHandlerResult { using T = std::decay_t; if constexpr (std::is_same_v> || - std::is_same_v>) { + std::is_same_v> || + std::is_same_v>) { if (!handleEvent(arg.value())) { return {HandlerResult::BypassListeners, CoordinatorResult::Cancel}; } @@ -140,6 +142,16 @@ bool EndstonePlayerGameplayHandler::handleEvent(const PlayerInteractWithEntityBe return true; } +bool EndstonePlayerGameplayHandler::handleEvent(const ::PlayerEmoteEvent &event) +{ + if (const auto *player = WeakEntityRef(event.player).tryUnwrap<::Player>(); player) { + const auto &server = entt::locator::value(); + PlayerEmoteEvent e{player->getEndstoneActor(), event.emote_piece_id}; + server.getPluginManager().callEvent(e); + } + return true; +} + bool EndstonePlayerGameplayHandler::handleEvent(::PlayerGameModeChangeEvent &event) { if (auto *player = event.player.tryUnwrap<::Player>(); player) { diff --git a/src/endstone/core/event/handlers/player_gameplay_handler.h b/src/endstone/core/event/handlers/player_gameplay_handler.h index fdba6d1d6..d78969661 100644 --- a/src/endstone/core/event/handlers/player_gameplay_handler.h +++ b/src/endstone/core/event/handlers/player_gameplay_handler.h @@ -30,6 +30,7 @@ class EndstonePlayerGameplayHandler final : public PlayerGameplayHandler { private: bool handleEvent(const PlayerFormResponseEvent &event); bool handleEvent(const PlayerFormCloseEvent &event); + bool handleEvent(const PlayerEmoteEvent &event); bool handleEvent(const PlayerInteractWithBlockBeforeEvent &event); bool handleEvent(const PlayerInteractWithEntityBeforeEvent &event); bool handleEvent(::PlayerGameModeChangeEvent &event); diff --git a/src/endstone/python/event.cpp b/src/endstone/python/event.cpp index d733a9982..dfc7f12cd 100644 --- a/src/endstone/python/event.cpp +++ b/src/endstone/python/event.cpp @@ -126,6 +126,8 @@ void init_event(py::module_ &m, py::class_ &event, py::enum_(m, "PlayerDeathEvent", "Called when a player dies") .def_property("death_message", &PlayerDeathEvent::getDeathMessage, &PlayerDeathEvent::setDeathMessage, "Gets or sets the death message that will appear to everyone on the server."); + py::class_(m, "PlayerEmoteEvent", "Called when a player uses and emote") + .def_property_readonly("emote_id", &PlayerEmoteEvent::getEmoteId, "Gets the emote ID"); py::class_( m, "PlayerGameModeChangeEvent", "Called when the GameMode of the player is changed.") .def_property_readonly("new_game_mode", &PlayerGameModeChangeEvent::getNewGameMode,