#pragma once //////////////////////////////////////////////////////////////////////// // Event System - Make it easier to subscribe game events // // [Examples] // // Event::PlayerJoinEvent::subscribe([](const Event::PlayerJoinEvent& ev) { //Common situation - Const parameter "ev" // ev.mPlayer->sendText("hello world~"); // return true; // }); // // Event::PlayerChatEvent::subscribe_ref([](Event::PlayerChatEvent& ev) { //Need to modify event's parameters - Reference parameter "ev" // ev.mMessage = "[Plugin Modified] " + ev.mMessage; // return true; // }); // // auto listener = Event::PlayerPickupItemEvent::subscribe([](const Event::PlayerPickupItemEvent& ev) { // if(ev.mPlayer->getName() == "Jack") // return false; //Prevent events to be done - return false // else // return true; // }); // ...... // ...... // listener.remove(); //Remove this event listener // //////////////////////////////////////////////////////////////////////// #include "Global.h" #include "LoggerAPI.h" #include "MC/BlockInstance.hpp" #include "MC/MCRESULT.hpp" #include #include #include #include #include #include #include class Actor; class ServerPlayer; class Player; class Block; class Mob; struct ActorDefinitionIdentifier; class ItemStack; class ActorDamageSource; class Certificate; class CommandRegistry; class MobEffectInstance; class Container; class WitherBoss; class ArmorStand; class Objective; struct ScoreboardId; namespace Event { ///////////////////////////// Impl ///////////////////////////// constexpr bool Ok = true; constexpr bool Cancel = false; template class EventManager { public: LIAPI static int addEventListener(std::string name, std::function callback); LIAPI static int addEventListenerRef(std::string name, std::function callback); LIAPI static bool removeEventListener(int id); LIAPI static bool hasListener(); LIAPI static bool call(EVENT& ev); LIAPI static bool callToPlugin(std::string pluginName, EVENT& ev); }; template class EventListener { private: int listenerId; bool deleted = false; public: EventListener(int id) : listenerId(id) { } void remove() { if (!deleted) { deleted = true; EventManager::removeEventListener(listenerId); } } }; template class EventTemplate { public: static EventListener subscribe(std::function callback) { auto plugin = LL::getPlugin(GetCurrentModule()); return EventListener(EventManager::addEventListener(plugin ? plugin->name : "", callback)); } static EventListener subscribe_ref(std::function callback) { auto plugin = LL::getPlugin(GetCurrentModule()); return EventListener(EventManager::addEventListenerRef(plugin ? plugin->name : "", callback)); } static void unsubscribe(const EventListener& listener) { listener.remove(); } static bool hasListener() { return EventManager::hasListener(); } bool call() { return EventManager::call(*(EVENT*)this); } bool callToPlugin(std::string pluginName) { return EventManager::callToPlugin(pluginName, *(EVENT*)this); } ////////////////////// For compatibility DO NOT UPDATE ////////////////////// protected: friend class EventManager; LIAPI static std::list>> listeners; LIAPI static std::list>> listenersNoConst; ////////////////////// For compatibility DO NOT UPDATE ////////////////////// }; ///////////////////////////// Player Events ///////////////////////////// class PlayerPreJoinEvent : public EventTemplate { public: Player* mPlayer; string mIP; string mXUID; }; class PlayerJoinEvent : public EventTemplate { public: Player* mPlayer; }; class PlayerLeftEvent : public EventTemplate { public: Player* mPlayer; string mXUID; }; class PlayerRespawnEvent : public EventTemplate { public: Player* mPlayer; }; class PlayerUseItemEvent : public EventTemplate { public: Player* mPlayer; ItemStack* mItemStack; }; class PlayerUseItemOnEvent : public EventTemplate { public: Player* mPlayer; ItemStack* mItemStack; BlockInstance mBlockInstance; unsigned char mFace; Vec3 mClickPos; }; class PlayerChatEvent : public EventTemplate { public: Player* mPlayer; string mMessage; }; class PlayerChangeDimEvent : public EventTemplate { public: Player* mPlayer; int mToDimensionId; }; class PlayerJumpEvent : public EventTemplate { public: Player* mPlayer; }; class PlayerSneakEvent : public EventTemplate { public: Player* mPlayer; bool mIsSneaking; }; class PlayerAttackEvent : public EventTemplate { public: Player* mPlayer; Actor* mTarget; int mAttackDamage; }; class PlayerAttackBlockEvent : public EventTemplate { public: Player* mPlayer; ItemStack* mItemStack; BlockInstance mBlockInstance; }; class PlayerDieEvent : public EventTemplate { public: Player* mPlayer; ActorDamageSource* mDamageSource; }; class PlayerPickupItemEvent : public EventTemplate { public: Player* mPlayer; Actor* mItemEntity; ItemStack* mItemStack; }; class PlayerDropItemEvent : public EventTemplate { public: Player* mPlayer; ItemStack* mItemStack; }; class PlayerEatEvent : public EventTemplate { public: Player* mPlayer; ItemStack* mFoodItem; }; class PlayerConsumeTotemEvent : public EventTemplate { public: Player* mPlayer; }; class PlayerCmdEvent : public EventTemplate { public: Player* mPlayer; string mCommand; MCRESULT* mResult; }; class PlayerEffectChangedEvent : public EventTemplate { public: enum class EventType { Add, Remove, Update }; Player* mPlayer; EventType mEventType; MobEffectInstance* mEffect; }; class PlayerStartDestroyBlockEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; }; class PlayerDestroyBlockEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; }; class PlayerPlaceBlockEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; }; class BlockPlacedByPlayerEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; }; class PlayerOpenContainerEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; Container* mContainer; }; class PlayerCloseContainerEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; Container* mContainer; }; class PlayerInventoryChangeEvent : public EventTemplate { public: Player* mPlayer; int mSlot; ItemStack* mPreviousItemStack; ItemStack* mNewItemStack; }; class PlayerMoveEvent : public EventTemplate { public: Player* mPlayer; Vec3 mPos; }; class PlayerSprintEvent : public EventTemplate { public: Player* mPlayer; bool mIsSprinting; }; class PlayerSetArmorEvent : public EventTemplate { public: Player* mPlayer; int mSlot; ItemStack* mArmorItem; }; class PlayerUseRespawnAnchorEvent : public EventTemplate { public: Player* mPlayer; BlockInstance mBlockInstance; }; class PlayerOpenContainerScreenEvent : public EventTemplate { public: Player* mPlayer; }; class PlayerUseFrameBlockEvent : public EventTemplate { public: enum class Type { Use, Attack }; Type mType; Player* mPlayer; BlockInstance mBlockInstance; }; class PlayerScoreChangedEvent : public EventTemplate { public: Player* mPlayer; int mScore; Objective* mObjective; ScoreboardId* mScoreboardId; }; class PlayerExperienceAddEvent : public EventTemplate { public: Player* mPlayer; int mExp; }; class PlayerInteractEntityEvent : public EventTemplate { public: enum class InteractiveMode { RightClick, LeftClick }; ServerPlayer* mPlayer; ActorRuntimeID mTargetId; InteractiveMode mInteractiveMode; }; ///////////////////////////// Block Events ///////////////////////////// class BlockInteractedEvent : public EventTemplate { public: BlockInstance mBlockInstance; Player* mPlayer; }; class BlockChangedEvent : public EventTemplate { public: BlockInstance mPreviousBlockInstance; BlockInstance mNewBlockInstance; }; class BlockExplodedEvent : public EventTemplate { public: BlockInstance mBlockInstance; Actor* mExplodeSource; }; class FireSpreadEvent : public EventTemplate { public: BlockPos mTarget; int mDimensionId; }; class ContainerChangeEvent : public EventTemplate { public: Player* mPlayer; Actor* mActor; BlockInstance mBlockInstance; Container* mContainer; int mSlot; ItemStack* mPreviousItemStack; ItemStack* mNewItemStack; }; class ProjectileHitBlockEvent : public EventTemplate { public: BlockInstance mBlockInstance; Actor* mSource; }; class RedStoneUpdateEvent : public EventTemplate { public: BlockInstance mBlockInstance; int mRedStonePower; bool mIsActivated; }; class HopperSearchItemEvent : public EventTemplate { public: bool isMinecart; BlockInstance mHopperBlock; Vec3 mMinecartPos; int mDimensionId; }; class HopperPushOutEvent : public EventTemplate { public: Vec3 mPos; int mDimensionId; }; class PistonTryPushEvent : public EventTemplate { public: BlockInstance mPistonBlockInstance; BlockInstance mTargetBlockInstance; }; class PistonPushEvent : public EventTemplate { public: BlockInstance mPistonBlockInstance; BlockInstance mTargetBlockInstance; }; class FarmLandDecayEvent : public EventTemplate { public: BlockInstance mBlockInstance; Actor* mActor; }; class LiquidSpreadEvent : public EventTemplate { public: BlockInstance mBlockInstance; BlockPos mTarget; int mDimensionId; }; class CmdBlockExecuteEvent : public EventTemplate { public: string mCommand; bool mIsMinecart; BlockInstance mBlockInstance; Actor* mMinecart; }; class BlockExplodeEvent : public EventTemplate { public: BlockInstance mBlockInstance; float mRadius; float mMaxResistance; bool mBreaking; bool mFire; }; ///////////////////////////// Entity Events ///////////////////////////// class EntityExplodeEvent : public EventTemplate { public: Actor* mActor; Vec3 mPos; BlockSource* mDimension; float mRadius; float mMaxResistance; bool mBreaking; bool mFire; }; class MobHurtEvent : public EventTemplate { public: Mob* mMob; ActorDamageSource* mDamageSource; float mDamage; }; class MobDieEvent : public EventTemplate { public: Mob* mMob; ActorDamageSource* mDamageSource; }; class ProjectileHitEntityEvent : public EventTemplate { public: Actor* mTarget; Actor* mSource; }; class WitherBossDestroyEvent : public EventTemplate { public: WitherBoss* mWitherBoss; AABB mDestroyRange = {{}, {}}; }; class EntityRideEvent : public EventTemplate { public: Actor* mRider; Actor* mVehicle; }; class EntityStepOnPressurePlateEvent : public EventTemplate { public: Actor* mActor; BlockInstance mBlockInstance; }; class NpcCmdEvent : public EventTemplate { public: Actor* mNpc; std::string mCommand; Player* mPlayer; }; class ProjectileSpawnEvent : public EventTemplate { public: Actor* mShooter; ActorDefinitionIdentifier* mIdentifier; std::string mType; }; class ProjectileCreatedEvent : public EventTemplate { public: Actor* mShooter; Actor* mProjectile; }; class ArmorStandChangeEvent : public EventTemplate { public: ArmorStand* mArmorStand; Player* mPlayer; int mSlot; }; class EntityTransformEvent : public EventTemplate { public: ActorUniqueID* mBeforeEntityUniqueId; Actor* mAfterEntity; }; ///////////////////////////// Other Events ///////////////////////////// class PostInitEvent : public EventTemplate { }; class ServerStartedEvent : public EventTemplate { }; class ServerStoppedEvent : public EventTemplate { }; class ConsoleCmdEvent : public EventTemplate { public: std::string mCommand; }; class RegCmdEvent : public EventTemplate { public: CommandRegistry* mCommandRegistry; }; class ConsoleOutputEvent : public EventTemplate { public: std::string mOutput; }; class PlayerBedEnterEvent : public EventTemplate { public: Player* mPlayer; BlockInstance* mBlockInstance; }; class ScriptPluginManagerEvent : public EventTemplate { public: enum class Operation { Load, Unload, Reload }; enum class PluginType { SingleFile, // like .js / .lua PluginPackage, // like .llplugin UncompressedPackage // like plugins/nodejs/ABC }; Operation operation; std::string target; std::string otherInfo; std::string pluginExtention; bool success = false; PluginType pluginType; }; class MobSpawnEvent : public EventTemplate { public: string mTypeName; Vec3 mPos; int mDimensionId; }; class FormResponsePacketEvent : public EventTemplate { public: ServerPlayer* mServerPlayer; unsigned mFormId; string mJsonData; }; class ResourcePackInitEvent : public EventTemplate { public: ResourcePackRepository* mRepo; }; }; // namespace Event