diff --git a/lib/FormAPI-JS.js b/lib/FormAPI-JS.js index 0b8b9d4..7dfe46d 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); } - } -module.exports = { ServerSettingForm }; \ No newline at end of file +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, + NpcDialogueForm, + ChestForm +}; \ No newline at end of file diff --git a/src/Entry.cpp b/src/Entry.cpp index 3fa4628..fc029ec 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -3,7 +3,7 @@ ll::Logger logger(PLUGIN_NAME); -namespace GMLIB { +namespace gmlib { std::unique_ptr& LegacyRemoteCallApi::getInstance() { static std::unique_ptr instance; @@ -33,6 +33,6 @@ bool LegacyRemoteCallApi::enable() { return true; } bool LegacyRemoteCallApi::disable() { return true; } -} // namespace GMLIB +} // namespace gmlib LL_REGISTER_MOD(GMLIB::LegacyRemoteCallApi, GMLIB::LegacyRemoteCallApi::getInstance()); diff --git a/src/Entry.h b/src/Entry.h index 49821d5..0606144 100644 --- a/src/Entry.h +++ b/src/Entry.h @@ -2,7 +2,7 @@ #include #include -namespace GMLIB { +namespace gmlib { class LegacyRemoteCallApi { @@ -30,4 +30,4 @@ private: ll::mod::NativeMod& mSelf; }; -} // namespace GMLIB +} // namespace gmlib diff --git a/src/FormAPI.cpp b/src/FormAPI.cpp index 08012b9..399f190 100644 --- a/src/FormAPI.cpp +++ b/src/FormAPI.cpp @@ -2,28 +2,84 @@ using namespace ll::hash_utils; -// class LegacyScriptFormManager { -// private: -// int64 mNextFormCallbackId = 0; +class LegacyScriptFormManager { +private: + int64 mNextFormCallbackId = 0; + int64 mNextFormId = 0; + std::unordered_map> mNpcDialogueForms; + // std::unordered_map> mChestForms; -// public: -// std::string getNextFormCallbackId() { -// return "GMLIB_FormApi_" + std::to_string(mNextFormCallbackId++); -// } +public: + // std::string getNextFormCallbackId() { + // return "GMLIB_FormApi_" + std::to_string(mNextFormCallbackId++); + // } -// public: -// static LegacyScriptFormManager& getInstance() { -// static std::unique_ptr instance; -// if (!instance) instance = std::make_unique(); -// return *instance; -// } -// }; + 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 {}; + } + + /* + int64 createChestForm(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); + mChestForms[formId] = std::move(formPtr); + return formId; + } + + bool destroyChestForm(int64 formId) { + if (mChestForms.contains(formId)) { + mChestForms.erase(formId); + return true; + } + return false; + } + + optional_ref getChestForm(int64 formId) { + if (mChestForms.contains(formId)) { + return mChestForms[formId].get(); + } + return {}; + } + + */ +public: + static LegacyScriptFormManager& getInstance() { + static std::unique_ptr instance; + if (!instance) { + instance = std::make_unique(); + } + return *instance; + } +}; #define PLAYER_DETECROR \ - [detectorId, result](Player& pl) -> bool { \ + [detectorId, result](::Player& pl) -> bool { \ try { \ if (RemoteCall::hasFunc("GMLIB_FORM_CALLBACK", detectorId)) { \ - auto const& detector = RemoteCall::importAs("GMLIB_FORM_CALLBACK", detectorId); \ + auto const& detector = RemoteCall::importAs("GMLIB_FORM_CALLBACK", detectorId); \ return detector(&pl); \ } else { \ gmlib::form::ServerSettingForm::removeElement(result); \ @@ -44,15 +100,28 @@ using namespace ll::hash_utils; } catch (...) {} \ } +#define CALLBACK_TYPE_NORMAL \ + [callbackId](::Player& pl) { \ + try { \ + if (RemoteCall::hasFunc("GMLIB_FORM_CALLBACK", callbackId)) { \ + auto const& callback = RemoteCall::importAs("GMLIB_FORM_CALLBACK", callbackId); \ + callback(&pl); \ + } \ + } catch (...) {} \ + } + + void Export_Form_API() { - RemoteCall::exportAs("GMLIB_gmlib::form::ServerSettingForm", "getDefaultPriority", []() -> int { - return gmlib::form::ServerSettingForm::getDefaultPriority(); - }); + //////////////////////////////// Form Manager ///////////////////////////////// // RemoteCall::exportAs("GMLIB_FormAPI", "getNextFormCallbackId", []() -> std::string { // return LegacyScriptFormManager::getInstance().getNextFormCallbackId(); // }); - RemoteCall::exportAs("GMLIB_gmlib::form::ServerSettingForm", "hasTitle", []() -> bool { return gmlib::form::ServerSettingForm::hasTitle(); }); - RemoteCall::exportAs("GMLIB_gmlib::form::ServerSettingForm", "getTitle", []() -> std::string { + ////////////////////////////// ServerSettingForm ////////////////////////////// + RemoteCall::exportAs("GMLIB_ServerSettingForm", "getDefaultPriority", []() -> int { + return gmlib::form::ServerSettingForm::getDefaultPriority(); + }); + RemoteCall::exportAs("GMLIB_ServerSettingForm", "hasTitle", []() -> bool { return gmlib::form::ServerSettingForm::hasTitle(); }); + RemoteCall::exportAs("GMLIB_ServerSettingForm", "getTitle", []() -> std::string { return gmlib::form::ServerSettingForm::getTitle(); }); RemoteCall::exportAs("GMLIB_gmlib::form::ServerSettingForm", "setTitle", [](std::string const& title, bool forceModify) -> bool { @@ -181,4 +250,39 @@ void Export_Form_API() { RemoteCall::exportAs("GMLIB_gmlib::form::ServerSettingForm", "removeElement", [](uint id) -> bool { return gmlib::form::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, std::string const& callbackId) -> void { + if (auto formPtr = LegacyScriptFormManager::getInstance().getNpcDialogueForm(formId)) { + formPtr->addButton(button, CALLBACK_TYPE_NORMAL); + } + } + ); + RemoteCall::exportAs( + "GMLIB_NpcDialogueForm", + "onPlayerClose", + [](int64 formId, std::string const& callbackId) -> void { + if (auto formPtr = LegacyScriptFormManager::getInstance().getNpcDialogueForm(formId)) { + formPtr->onPlayerClose(CALLBACK_TYPE_NORMAL); + } + } + ); + RemoteCall::exportAs("GMLIB_NpcDialogueForm", "sendTo", [](int64 formId, ::Player* pl) -> void { + if (auto formPtr = LegacyScriptFormManager::getInstance().getNpcDialogueForm(formId)) { + formPtr->sendTo(*pl); + } + }); + ////////////////////////////// ChestForm ////////////////////////////// } \ No newline at end of file