From 5cc610a830cae8321f6f99ed8c1d8e8604726c0e Mon Sep 17 00:00:00 2001 From: KobeBryant114514 <116721335+KobeBryant114514@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:59:48 +0800 Subject: [PATCH] feat: add NpcDialogueForm --- lib/FormAPI-JS.js | 55 +++++++++++++++++++++++++++++++- src/FormAPI.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/lib/FormAPI-JS.js b/lib/FormAPI-JS.js index d51bfbe..eeb8a69 100644 --- a/lib/FormAPI-JS.js +++ b/lib/FormAPI-JS.js @@ -1,6 +1,10 @@ const getNextCallbackId = ll.import("GMLIB_FormAPI", "getNextFormCallbackId"); class ServerSettingForm { + constructor() { + throw new Error("Static class cannot be instantiated"); + } + static getDefaultPriority() { return ll.import("GMLIB_ServerSettingForm", "getDefaultPriority")(); } @@ -123,7 +127,56 @@ class ServerSettingForm { static removeElement(id) { return ll.import("GMLIB_ServerSettingForm", "removeElement")(id); } +} + +class NpcDialogueForm { + constructor(npcName, sceneName, dialogue) { + this.mFormId = ll.import("GMLIB_NpcDialogueForm", "createForm")(npcName, sceneName, dialogue); + } + + addButton(button) { + return ll.import("GMLIB_NpcDialogueForm", "addButton")(this.mFormId, button); + } + + sendTo(pl, callback = (pl, index, type) => { }, free = true) { + let callbackId = getNextCallbackId(); + ll.export(callback, "GMLIB_FORM_CALLBACK", callbackId); + ll.import("GMLIB_NpcDialogueForm", "sendTo")(this.mFormId, pl, callbackId); + if (free) { + this.destroy(); + } + } + destroy() { + ll.import("GMLIB_NpcDialogueForm", "destroyForm")(this.mFormId); + } +} + +class ChestForm { + constructor(npcName, sceneName, dialogue) { + this.mFormId = ll.import("GMLIB_NpcDialogueForm", "createForm")(npcName, sceneName, dialogue); + } + + addButton(button) { + return ll.import("GMLIB_NpcDialogueForm", "addButton")(this.mFormId, button); + } + + sendTo(pl, free = true) { + //let callbackId = getNextCallbackId(); + //ll.export(callback, "GMLIB_FORM_CALLBACK", callbackId); + //ll.import("GMLIB_NpcDialogueForm", "sendTo")(this.mFormId, pl, callbackId); + //if (free) { + // this.destroy(); + //} + } + + destroy() { + //ll.import("GMLIB_NpcDialogueForm", "destroyForm")(this.mFormId); + } } -module.exports = { ServerSettingForm }; \ No newline at end of file +module.exports = { + ServerSettingForm, + NpcDialogueForm, + ChestForm +}; \ No newline at end of file diff --git a/src/FormAPI.cpp b/src/FormAPI.cpp index 90da1c3..474516d 100644 --- a/src/FormAPI.cpp +++ b/src/FormAPI.cpp @@ -1,12 +1,16 @@ #include "Global.h" +#include + using namespace GMLIB::Server::Form; using namespace ll::hash_utils; class LegacyScriptFormManager { private: - int64 mNextFormCallbackId = 0; - // std::unordered_map mEventListeners; + int64 mNextFormCallbackId = 0; + int64 mNextFormId = 0; + std::unordered_map> mNpcDialogueForms; + std::unordered_map> mChestForms; public: std::string getNextFormCallbackId() { @@ -14,6 +18,33 @@ class LegacyScriptFormManager { return "GMLIB_EVENT_" + std::to_string(mNextFormCallbackId); } + int64 getNextFormId() { + mNextFormId++; + return mNextFormId; + } + + int64 createNpcDialogueForm(std::string const& npcName, std::string const& sceneName, std::string const& dialogue) { + auto formId = LegacyScriptFormManager::getInstance().getNextFormId(); + auto formPtr = std::make_unique(npcName, sceneName, dialogue); + mNpcDialogueForms[formId] = std::move(formPtr); + return formId; + } + + bool destroyNpcDialogueForm(int64 formId) { + if (mNpcDialogueForms.contains(formId)) { + mNpcDialogueForms.erase(formId); + return true; + } + return false; + } + + optional_ref getNpcDialogueForm(int64 formId) { + if (mNpcDialogueForms.contains(formId)) { + return mNpcDialogueForms[formId].get(); + } + return {}; + } + public: static LegacyScriptFormManager& getInstance() { static std::unique_ptr instance; @@ -89,12 +120,14 @@ class LegacyScriptFormManager { void Export_Form_API() { - RemoteCall::exportAs("GMLIB_ServerSettingForm", "getDefaultPriority", []() -> int { - return ServerSettingForm::getDefaultPriority(); - }); + //////////////////////////////// Form Manager ///////////////////////////////// RemoteCall::exportAs("GMLIB_FormAPI", "getNextFormCallbackId", []() -> std::string { return LegacyScriptFormManager::getInstance().getNextFormCallbackId(); }); + ////////////////////////////// ServerSettingForm ////////////////////////////// + RemoteCall::exportAs("GMLIB_ServerSettingForm", "getDefaultPriority", []() -> int { + return ServerSettingForm::getDefaultPriority(); + }); RemoteCall::exportAs("GMLIB_ServerSettingForm", "hasTitle", []() -> bool { return ServerSettingForm::hasTitle(); }); RemoteCall::exportAs("GMLIB_ServerSettingForm", "getTitle", []() -> std::string { return ServerSettingForm::getTitle(); @@ -229,4 +262,41 @@ void Export_Form_API() { RemoteCall::exportAs("GMLIB_ServerSettingForm", "removeElement", [](uint id) -> bool { return ServerSettingForm::removeElement(id); }); + ////////////////////////////// NpcDialogueForm ////////////////////////////// + RemoteCall::exportAs( + "GMLIB_NpcDialogueForm", + "createForm", + [](std::string const& npcName, std::string const& sceneName, std::string const& dialogue) -> int64 { + return LegacyScriptFormManager::getInstance().createNpcDialogueForm(npcName, sceneName, dialogue); + } + ); + RemoteCall::exportAs("GMLIB_NpcDialogueForm", "destroyForm", [](int64 formId) -> bool { + return LegacyScriptFormManager::getInstance().destroyNpcDialogueForm(formId); + }); + RemoteCall::exportAs("GMLIB_NpcDialogueForm", "addButton", [](int64 formId, std::string const& button) -> int { + if (auto formPtr = LegacyScriptFormManager::getInstance().getNpcDialogueForm(formId)) { + return formPtr->addButton(button); + } + return -1; + }); + RemoteCall::exportAs( + "GMLIB_NpcDialogueForm", + "sendTo", + [](int64 formId, Player* pl, std::string const& callbackId) -> void { + if (auto formPtr = LegacyScriptFormManager::getInstance().getNpcDialogueForm(formId)) { + formPtr->sendTo(*pl, [callbackId](Player& pl, int index, NpcRequestPacket::RequestType type) -> void { + try { + if (RemoteCall::hasFunc("GMLIB_FORM_CALLBACK", callbackId)) { + auto const& callback = RemoteCall::importAs( + "GMLIB_FORM_CALLBACK", + callbackId + ); + callback(&pl, index, (int)type); + } + } catch (...) {} + }); + } + } + ); + ////////////////////////////// ChestForm ////////////////////////////// } \ No newline at end of file