mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	ESM::Dialogue Lua bindings 3
This commit is contained in:
		
							parent
							
								
									807d78a0d0
								
							
						
					
					
						commit
						d14fc1d28c
					
				
					 1 changed files with 385 additions and 97 deletions
				
			
		|  | @ -1,7 +1,10 @@ | ||||||
| #include "dialoguebindings.hpp" | #include "dialoguebindings.hpp" | ||||||
|  | #include <algorithm> | ||||||
|  | #include "apps/openmw/mwbase/environment.hpp" | ||||||
|  | #include "apps/openmw/mwworld/esmstore.hpp" | ||||||
| #include "apps/openmw/mwworld/store.hpp" | #include "apps/openmw/mwworld/store.hpp" | ||||||
| #include "context.hpp" | #include "context.hpp" | ||||||
| #include "recordstore.hpp" | #include "object.hpp" | ||||||
| #include <components/esm3/loaddial.hpp> | #include <components/esm3/loaddial.hpp> | ||||||
| #include <components/lua/luastate.hpp> | #include <components/lua/luastate.hpp> | ||||||
| #include <components/misc/resourcehelpers.hpp> | #include <components/misc/resourcehelpers.hpp> | ||||||
|  | @ -9,81 +12,386 @@ | ||||||
| 
 | 
 | ||||||
| namespace | namespace | ||||||
| { | { | ||||||
|     sol::table prepareJournalRecord(sol::state_view& lua, const ESM::Dialogue& mwDialogue) |     template <ESM::Dialogue::Type filter> | ||||||
|  |     class FilteredDialogueStore | ||||||
|     { |     { | ||||||
|         const auto dialogueRecordId = mwDialogue.mId.serializeText(); |         const MWWorld::Store<ESM::Dialogue>& mDialogueStore; | ||||||
|         sol::table result(lua, sol::create); |  | ||||||
|         result["text"] = mwDialogue.mStringId; |  | ||||||
| 
 | 
 | ||||||
|         sol::table preparedInfos(lua, sol::create); |         const ESM::Dialogue* foundDialogueFilteredOut(const ESM::Dialogue* possibleResult) const | ||||||
|         unsigned index = 1; |         { | ||||||
|         for (const auto& mwDialogueInfo : mwDialogue.mInfo) |             if (possibleResult and possibleResult->mType == filter) | ||||||
|  |             { | ||||||
|  |                 return possibleResult; | ||||||
|  |             } | ||||||
|  |             return nullptr; | ||||||
|  |         } | ||||||
|  |     public: | ||||||
|  |         FilteredDialogueStore() | ||||||
|  |             : mDialogueStore{MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>()} | ||||||
|  |         {} | ||||||
|  | 
 | ||||||
|  |         class FilteredDialogueIterator | ||||||
|  |         { | ||||||
|  |             using DecoratedIterator = MWWorld::Store<ESM::Dialogue>::iterator; | ||||||
|  |             DecoratedIterator mIter; | ||||||
|  |         public: | ||||||
|  |             FilteredDialogueIterator(const DecoratedIterator& decoratedIterator) | ||||||
|  |                 : mIter{decoratedIterator} | ||||||
|  |             {} | ||||||
|  | 
 | ||||||
|  |             FilteredDialogueIterator& operator++() | ||||||
|  |             { | ||||||
|  |                 do | ||||||
|  |                 { | ||||||
|  |                     std::advance(mIter, 1); | ||||||
|  |                 } while (mIter->mType != filter); | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             FilteredDialogueIterator operator++(int) | ||||||
|  |             { | ||||||
|  |                 FilteredDialogueIterator iter = *this; | ||||||
|  |                 do | ||||||
|  |                 { | ||||||
|  |                     std::advance(mIter, 1); | ||||||
|  |                 } while (mIter->mType != filter); | ||||||
|  |                 return iter; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator==(const FilteredDialogueIterator& x) const { return mIter == x.mIter; } | ||||||
|  | 
 | ||||||
|  |             bool operator!=(const FilteredDialogueIterator& x) const { return not (*this == x); } | ||||||
|  | 
 | ||||||
|  |             const ESM::Dialogue& operator*() const { return *mIter; } | ||||||
|  | 
 | ||||||
|  |             const ESM::Dialogue* operator->() const { return &(*mIter); } | ||||||
|  |         }; | ||||||
|  |         using iterator = FilteredDialogueIterator; | ||||||
|  | 
 | ||||||
|  |         const ESM::Dialogue* search(const ESM::RefId& id) const | ||||||
|  |         { | ||||||
|  |             return foundDialogueFilteredOut(mDialogueStore.search(id)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const ESM::Dialogue* at(size_t index) const | ||||||
|  |         { | ||||||
|  |             if (index >= getSize()) | ||||||
|  |             { | ||||||
|  |                 return nullptr; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             auto result = begin(); | ||||||
|  |             std::advance(result, index); | ||||||
|  | 
 | ||||||
|  |             return &(*result); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         size_t getSize() const | ||||||
|  |         { | ||||||
|  |             return std::count_if(mDialogueStore.begin(), mDialogueStore.end(), [this](const auto& d) { return d.mType == filter; }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         iterator begin() const | ||||||
|  |         { | ||||||
|  |             iterator result{mDialogueStore.begin()}; | ||||||
|  |             while (result != end() and result->mType != filter) | ||||||
|  |             { | ||||||
|  |                 std::advance(result, 1); | ||||||
|  |             } | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         iterator end() const | ||||||
|  |         { | ||||||
|  |             return iterator{mDialogueStore.end()}; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     template <ESM::Dialogue::Type filter> | ||||||
|  |     void prepareBindingsForDialogueRecordStores(sol::table& table, const MWLua::Context& context) | ||||||
|  |     { | ||||||
|  |         using StoreT = FilteredDialogueStore<filter>; | ||||||
|  | 
 | ||||||
|  |         table["record"] = sol::overload( | ||||||
|  |             [](const MWLua::Object& obj) -> const ESM::Dialogue* { return obj.ptr().get<ESM::Dialogue>()->mBase; }, | ||||||
|  |             [](std::string_view id) -> const ESM::Dialogue* | ||||||
|  |             { | ||||||
|  |                 return StoreT{}.search(ESM::RefId::deserializeText(Misc::StringUtils::lowerCase(id))); | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |         sol::state_view& lua = context.mLua->sol(); | ||||||
|  |         sol::usertype<StoreT> storeBindingsClass = lua.new_usertype<StoreT>("ESM3_Dialogue_Type" + std::to_string(filter) + " Store"); | ||||||
|  |         storeBindingsClass[sol::meta_function::to_string] = [](const StoreT& store) | ||||||
|  |         { | ||||||
|  |             return "{" + std::to_string(store.getSize()) + " ESM3_Dialogue_Type" + std::to_string(filter) + " records}"; | ||||||
|  |         }; | ||||||
|  |         storeBindingsClass[sol::meta_function::length] = [](const StoreT& store) { return store.getSize(); }; | ||||||
|  |         storeBindingsClass[sol::meta_function::index] = sol::overload( | ||||||
|  |             [](const StoreT& store, size_t index) -> const ESM::Dialogue* | ||||||
|  |             { | ||||||
|  |                 if (index == 0 or index > store.getSize()) | ||||||
|  |                 { | ||||||
|  |                     return nullptr; | ||||||
|  |                 } | ||||||
|  |                 return store.at(index - 1); | ||||||
|  |             }, | ||||||
|  |             [](const StoreT& store, std::string_view id) -> const ESM::Dialogue* | ||||||
|  |             { | ||||||
|  |                 return store.search(ESM::RefId::deserializeText(Misc::StringUtils::lowerCase(id))); | ||||||
|  |             }); | ||||||
|  |         storeBindingsClass[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
|  |         storeBindingsClass[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
|  | 
 | ||||||
|  |         table["records"] = StoreT{}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     struct DialogueInfos | ||||||
|  |     { | ||||||
|  |         ESM::RefId mDialogueRecordId; | ||||||
|  | 
 | ||||||
|  |         const ESM::Dialogue* getDialogueRecord() const | ||||||
|  |         { | ||||||
|  |             const auto& dialogueStore{MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>()}; | ||||||
|  |             return dialogueStore.search(mDialogueRecordId); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     void prepareBindingsForDialogueRecord(sol::state_view& lua) | ||||||
|  |     { | ||||||
|  |         auto recordBindingsClass = lua.new_usertype<ESM::Dialogue>("ESM3_Dialogue"); | ||||||
|  |         recordBindingsClass[sol::meta_function::to_string] = [lua](const ESM::Dialogue& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             return sol::make_object(lua, "ESM3_Dialogue[" + rec.mId.toDebugString() + "]"); | ||||||
|  |         }; | ||||||
|  |         recordBindingsClass["id"] = sol::readonly_property([lua](const ESM::Dialogue& rec) | ||||||
|  |         { | ||||||
|  |             return sol::make_object(lua, rec.mId.serializeText()); | ||||||
|  |         }); | ||||||
|  |         recordBindingsClass["name"] = sol::readonly_property([lua](const ESM::Dialogue& rec) | ||||||
|  |         { | ||||||
|  |             return sol::make_object(lua, rec.mStringId); | ||||||
|  |         }); | ||||||
|  |         recordBindingsClass["questName"] = sol::readonly_property([lua](const ESM::Dialogue& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mType != ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             for (const auto& mwDialogueInfo : rec.mInfo) | ||||||
|             { |             { | ||||||
|                 if (mwDialogueInfo.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Name) |                 if (mwDialogueInfo.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Name) | ||||||
|                 { |                 { | ||||||
|                 result["questName"] = mwDialogueInfo.mResponse; |                     return sol::make_object(lua, mwDialogueInfo.mResponse); | ||||||
|                 continue; |  | ||||||
|                 } |                 } | ||||||
|             sol::table infoElement(lua, sol::create); |             } | ||||||
|             infoElement["id"] = (dialogueRecordId + '#' + mwDialogueInfo.mId.serializeText()); |             return sol::nil; | ||||||
|             infoElement["text"] = mwDialogueInfo.mResponse; |         }); | ||||||
|             infoElement["questStage"] = mwDialogueInfo.mData.mJournalIndex; |         recordBindingsClass["infos"] = sol::readonly_property([lua](const ESM::Dialogue& rec) | ||||||
|             infoElement["questFinished"] = (mwDialogueInfo.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Finished); |         { | ||||||
|             infoElement["questRestart"] = (mwDialogueInfo.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Restart); |             return DialogueInfos{rec.mId}; | ||||||
|             preparedInfos[index++] = infoElement; |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         result["infos"] = LuaUtil::makeStrictReadOnly(preparedInfos); |     void prepareBindingsForDialogueRecordInfoList(sol::state_view& lua) | ||||||
|         return result; |     { | ||||||
|  |         auto recordInfosBindingsClass = lua.new_usertype<DialogueInfos>("ESM3_Dialogue_Infos"); | ||||||
|  |         recordInfosBindingsClass[sol::meta_function::to_string] = [lua](const DialogueInfos& store) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (const ESM::Dialogue* dialogueRecord = store.getDialogueRecord()) | ||||||
|  |             { | ||||||
|  |                 return sol::make_object(lua, "{" + std::to_string(dialogueRecord->mInfo.size()) + " ESM3_Dialogue[" + dialogueRecord->mId.toDebugString() + "] info elements}"); | ||||||
|  |             } | ||||||
|  |             return sol::nil; | ||||||
|  |         }; | ||||||
|  |         recordInfosBindingsClass[sol::meta_function::length] = [](const DialogueInfos& store) | ||||||
|  |         { | ||||||
|  |             const ESM::Dialogue* dialogueRecord = store.getDialogueRecord(); | ||||||
|  |             return dialogueRecord ? dialogueRecord->mInfo.size() : 0; | ||||||
|  |         }; | ||||||
|  |         recordInfosBindingsClass[sol::meta_function::index] = [](const DialogueInfos& store, size_t index) -> const ESM::DialInfo* | ||||||
|  |         { | ||||||
|  |             const ESM::Dialogue* dialogueRecord = store.getDialogueRecord(); | ||||||
|  |             if (not dialogueRecord or index == 0 or index > dialogueRecord->mInfo.size()) | ||||||
|  |             { | ||||||
|  |                 return nullptr; | ||||||
|  |             } | ||||||
|  |             ESM::Dialogue::InfoContainer::const_iterator iter{dialogueRecord->mInfo.cbegin()}; | ||||||
|  |             std::advance(iter, index - 1); | ||||||
|  |             return &(*iter); | ||||||
|  |         }; | ||||||
|  |         recordInfosBindingsClass[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
|  |         recordInfosBindingsClass[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     sol::table prepareNonJournalRecord(sol::state_view& lua, const ESM::Dialogue& mwDialogue) |     void prepareBindingsForDialogueRecordInfoListElement(sol::state_view& lua) | ||||||
|     { |     { | ||||||
|         const auto dialogueRecordId = mwDialogue.mId.serializeText(); |         auto recordInfoBindingsClass = lua.new_usertype<ESM::DialInfo>("ESM3_Dialogue_Info"); | ||||||
|         sol::table result(lua, sol::create); |  | ||||||
|         result["text"] = mwDialogue.mStringId; |  | ||||||
| 
 | 
 | ||||||
|         sol::table preparedInfos(lua, sol::create); |         recordInfoBindingsClass[sol::meta_function::to_string] = [lua](const ESM::DialInfo& rec) | ||||||
|         unsigned index = 1; |  | ||||||
|         for (const auto& mwDialogueInfo : mwDialogue.mInfo) |  | ||||||
|         { |         { | ||||||
|             sol::table infoElement(lua, sol::create); |             return sol::make_object(lua, "ESM3_Dialogue_Info[" + rec.mId.toDebugString() + "]"); | ||||||
|             infoElement["id"] = (dialogueRecordId + '#' + mwDialogueInfo.mId.serializeText()); |         }; | ||||||
|             infoElement["text"] = mwDialogueInfo.mResponse; |         recordInfoBindingsClass["id"] = sol::readonly_property([lua](const ESM::DialInfo& rec) | ||||||
|             infoElement["actorId"] = mwDialogueInfo.mActor.serializeText(); |  | ||||||
|             infoElement["actorRace"] = mwDialogueInfo.mRace.serializeText(); |  | ||||||
|             infoElement["actorClass"] = mwDialogueInfo.mClass.serializeText(); |  | ||||||
|             infoElement["actorFaction"] = mwDialogueInfo.mFaction.serializeText(); |  | ||||||
|             if (mwDialogueInfo.mData.mRank != -1) |  | ||||||
|         { |         { | ||||||
|                 infoElement["actorFactionRank"] = mwDialogueInfo.mData.mRank; |             return sol::make_object(lua, rec.mId.serializeText()); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["text"] = sol::readonly_property([lua](const ESM::DialInfo& rec) | ||||||
|  |         { | ||||||
|  |             return sol::make_object(lua, rec.mResponse); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["questStage"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType != ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|             } |             } | ||||||
|             infoElement["actorCell"] = mwDialogueInfo.mClass.serializeText(); |             return sol::make_object(lua, rec.mData.mJournalIndex); | ||||||
|             infoElement["actorDisposition"] = mwDialogueInfo.mData.mDisposition; |         }); | ||||||
|             if (mwDialogueInfo.mData.mGender != ESM::DialInfo::Gender::NA) |         recordInfoBindingsClass["questFinished"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|         { |         { | ||||||
|                 infoElement["actorGender"] = mwDialogueInfo.mData.mGender; |             if (rec.mData.mType != ESM::Dialogue::Type::Journal) | ||||||
|             } |  | ||||||
|             infoElement["playerFaction"] = mwDialogueInfo.mPcFaction.serializeText(); |  | ||||||
|             if (mwDialogueInfo.mData.mPCrank != -1) |  | ||||||
|             { |             { | ||||||
|                 infoElement["playerFactionRank"] = mwDialogueInfo.mData.mPCrank; |                 return sol::nil; | ||||||
|             } |             } | ||||||
|             if (not mwDialogueInfo.mSound.empty()) |             return sol::make_object(lua, rec.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Finished); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["questRestart"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|         { |         { | ||||||
|                 infoElement["sound"] |             if (rec.mData.mType != ESM::Dialogue::Type::Journal) | ||||||
|                     = Misc::ResourceHelpers::correctSoundPath(VFS::Path::Normalized(mwDialogueInfo.mSound)).value(); |             { | ||||||
|  |                 return sol::nil; | ||||||
|             } |             } | ||||||
|             // mResultScript TODO
 |             return sol::make_object(lua, rec.mQuestStatus == ESM::DialInfo::QuestStatus::QS_Restart); | ||||||
|             // mSelects TODO
 |         }); | ||||||
|             preparedInfos[index++] = infoElement; |         recordInfoBindingsClass["filterActorId"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mActor.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorRace"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mRace.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorClass"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mClass.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorFaction"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mFaction.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorFactionRank"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mData.mRank; | ||||||
|  |             return result == -1 ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorCell"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mCell.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorDisposition"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             return sol::make_object(lua, rec.mData.mDisposition); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterActorGender"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mData.mGender; | ||||||
|  |             return result == -1 ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterPlayerFaction"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mPcFaction.serializeText(); | ||||||
|  |             return result.empty() ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["filterPlayerFactionRank"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal) | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             const auto result = rec.mData.mPCrank; | ||||||
|  |             return result == -1 ? sol::nil : sol::make_object(lua, result); | ||||||
|  |         }); | ||||||
|  |         recordInfoBindingsClass["sound"] = sol::readonly_property([lua](const ESM::DialInfo& rec) -> sol::object | ||||||
|  |         { | ||||||
|  |             if (rec.mData.mType == ESM::Dialogue::Type::Journal or rec.mSound == "") | ||||||
|  |             { | ||||||
|  |                 return sol::nil; | ||||||
|  |             } | ||||||
|  |             return sol::make_object(lua, Misc::ResourceHelpers::correctSoundPath(VFS::Path::Normalized(rec.mSound)).value()); | ||||||
|  |         }); | ||||||
|  |         // // mResultScript TODO
 | ||||||
|  |         // // mSelects TODO
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         result["infos"] = LuaUtil::makeStrictReadOnly(preparedInfos); |     void prepareBindingsForDialogueRecords(sol::state_view& lua) | ||||||
|         return result; |     { | ||||||
|  |         prepareBindingsForDialogueRecord(lua); | ||||||
|  |         prepareBindingsForDialogueRecordInfoList(lua); | ||||||
|  |         prepareBindingsForDialogueRecordInfoListElement(lua); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace sol | ||||||
|  | { | ||||||
|  |     template <ESM::Dialogue::Type filter> | ||||||
|  |     struct is_automagical<FilteredDialogueStore<filter>> : std::false_type | ||||||
|  |     { | ||||||
|  |     }; | ||||||
|  |     template <> | ||||||
|  |     struct is_automagical<ESM::Dialogue> : std::false_type | ||||||
|  |     { | ||||||
|  |     }; | ||||||
|  |     template <> | ||||||
|  |     struct is_automagical<DialogueInfos> : std::false_type | ||||||
|  |     { | ||||||
|  |     }; | ||||||
|  |     template <> | ||||||
|  |     struct is_automagical<ESM::DialInfo> : std::false_type | ||||||
|  |     { | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace MWLua | namespace MWLua | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | @ -92,43 +400,23 @@ namespace MWLua | ||||||
|         sol::state_view& lua = context.mLua->sol(); |         sol::state_view& lua = context.mLua->sol(); | ||||||
|         sol::table api(lua, sol::create); |         sol::table api(lua, sol::create); | ||||||
| 
 | 
 | ||||||
|         const MWWorld::Store<ESM::Dialogue>& mwDialogueStore |         sol::table journalTable(lua, sol::create); | ||||||
|             = MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>(); |         sol::table topicTable(lua, sol::create); | ||||||
|  |         sol::table greetingTable(lua, sol::create); | ||||||
|  |         sol::table persuasionTable(lua, sol::create); | ||||||
|  |         sol::table voiceTable(lua, sol::create); | ||||||
|  |         prepareBindingsForDialogueRecordStores<ESM::Dialogue::Type::Journal>(journalTable, context); | ||||||
|  |         prepareBindingsForDialogueRecordStores<ESM::Dialogue::Type::Topic>(topicTable, context); | ||||||
|  |         prepareBindingsForDialogueRecordStores<ESM::Dialogue::Type::Greeting>(greetingTable, context); | ||||||
|  |         prepareBindingsForDialogueRecordStores<ESM::Dialogue::Type::Persuasion>(persuasionTable, context); | ||||||
|  |         prepareBindingsForDialogueRecordStores<ESM::Dialogue::Type::Voice>(voiceTable, context); | ||||||
|  |         api["journal"] = journalTable; | ||||||
|  |         api["topic"] = topicTable; | ||||||
|  |         api["greeting"] = greetingTable; | ||||||
|  |         api["persuasion"] = persuasionTable; | ||||||
|  |         api["voice"] = voiceTable; | ||||||
| 
 | 
 | ||||||
|         sol::table journalRecordsByQuestId(lua, sol::create); |         prepareBindingsForDialogueRecords(lua); | ||||||
|         sol::table topicRecordsByTopicId(lua, sol::create); |  | ||||||
|         sol::table voiceRecordsById(lua, sol::create); |  | ||||||
|         sol::table greetingRecordsById(lua, sol::create); |  | ||||||
|         sol::table persuasionRecordsById(lua, sol::create); |  | ||||||
|         for (const auto& mwDialogue : mwDialogueStore) |  | ||||||
|         { |  | ||||||
|             const auto dialogueRecordId = mwDialogue.mId.serializeText(); |  | ||||||
|             if (mwDialogue.mType == ESM::Dialogue::Type::Journal) |  | ||||||
|             { |  | ||||||
|                 journalRecordsByQuestId[dialogueRecordId] = prepareJournalRecord(lua, mwDialogue); |  | ||||||
|             } |  | ||||||
|             else if (mwDialogue.mType == ESM::Dialogue::Type::Topic) |  | ||||||
|             { |  | ||||||
|                 topicRecordsByTopicId[dialogueRecordId] = prepareNonJournalRecord(lua, mwDialogue); |  | ||||||
|             } |  | ||||||
|             else if (mwDialogue.mType == ESM::Dialogue::Type::Voice) |  | ||||||
|             { |  | ||||||
|                 voiceRecordsById[dialogueRecordId] = prepareNonJournalRecord(lua, mwDialogue); |  | ||||||
|             } |  | ||||||
|             else if (mwDialogue.mType == ESM::Dialogue::Type::Greeting) |  | ||||||
|             { |  | ||||||
|                 greetingRecordsById[dialogueRecordId] = prepareNonJournalRecord(lua, mwDialogue); |  | ||||||
|             } |  | ||||||
|             else if (mwDialogue.mType == ESM::Dialogue::Type::Persuasion) |  | ||||||
|             { |  | ||||||
|                 persuasionRecordsById[dialogueRecordId] = prepareNonJournalRecord(lua, mwDialogue); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         api["journalRecords"] = LuaUtil::makeStrictReadOnly(journalRecordsByQuestId); |  | ||||||
|         api["topicRecords"] = LuaUtil::makeStrictReadOnly(topicRecordsByTopicId); |  | ||||||
|         api["voiceRecords"] = LuaUtil::makeStrictReadOnly(voiceRecordsById); |  | ||||||
|         api["greetingRecords"] = LuaUtil::makeStrictReadOnly(greetingRecordsById); |  | ||||||
|         api["persuasionRecords"] = LuaUtil::makeStrictReadOnly(persuasionRecordsById); |  | ||||||
| 
 | 
 | ||||||
|         return LuaUtil::makeReadOnly(api); |         return LuaUtil::makeReadOnly(api); | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue