mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 09:15:33 +00:00
Wrap all memory allocating Lua functions in protected calls
This commit is contained in:
parent
566e5b5588
commit
c9783344a0
61 changed files with 1090 additions and 943 deletions
|
@ -99,45 +99,48 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initAnimationPackage(const Context& context)
|
sol::table initAnimationPackage(const Context& context)
|
||||||
{
|
{
|
||||||
auto* lua = context.mLua;
|
auto view = context.sol();
|
||||||
auto mechanics = MWBase::Environment::get().getMechanicsManager();
|
auto mechanics = MWBase::Environment::get().getMechanicsManager();
|
||||||
auto world = MWBase::Environment::get().getWorld();
|
auto world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
sol::table api(lua->sol(), sol::create);
|
sol::table api(view, sol::create);
|
||||||
|
|
||||||
api["PRIORITY"]
|
api["PRIORITY"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWMechanics::Priority>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWMechanics::Priority>(view,
|
||||||
{ "Default", MWMechanics::Priority::Priority_Default },
|
{
|
||||||
{ "WeaponLowerBody", MWMechanics::Priority::Priority_WeaponLowerBody },
|
{ "Default", MWMechanics::Priority::Priority_Default },
|
||||||
{ "SneakIdleLowerBody", MWMechanics::Priority::Priority_SneakIdleLowerBody },
|
{ "WeaponLowerBody", MWMechanics::Priority::Priority_WeaponLowerBody },
|
||||||
{ "SwimIdle", MWMechanics::Priority::Priority_SwimIdle },
|
{ "SneakIdleLowerBody", MWMechanics::Priority::Priority_SneakIdleLowerBody },
|
||||||
{ "Jump", MWMechanics::Priority::Priority_Jump },
|
{ "SwimIdle", MWMechanics::Priority::Priority_SwimIdle },
|
||||||
{ "Movement", MWMechanics::Priority::Priority_Movement },
|
{ "Jump", MWMechanics::Priority::Priority_Jump },
|
||||||
{ "Hit", MWMechanics::Priority::Priority_Hit },
|
{ "Movement", MWMechanics::Priority::Priority_Movement },
|
||||||
{ "Weapon", MWMechanics::Priority::Priority_Weapon },
|
{ "Hit", MWMechanics::Priority::Priority_Hit },
|
||||||
{ "Block", MWMechanics::Priority::Priority_Block },
|
{ "Weapon", MWMechanics::Priority::Priority_Weapon },
|
||||||
{ "Knockdown", MWMechanics::Priority::Priority_Knockdown },
|
{ "Block", MWMechanics::Priority::Priority_Block },
|
||||||
{ "Torch", MWMechanics::Priority::Priority_Torch },
|
{ "Knockdown", MWMechanics::Priority::Priority_Knockdown },
|
||||||
{ "Storm", MWMechanics::Priority::Priority_Storm },
|
{ "Torch", MWMechanics::Priority::Priority_Torch },
|
||||||
{ "Death", MWMechanics::Priority::Priority_Death },
|
{ "Storm", MWMechanics::Priority::Priority_Storm },
|
||||||
{ "Scripted", MWMechanics::Priority::Priority_Scripted },
|
{ "Death", MWMechanics::Priority::Priority_Death },
|
||||||
|
{ "Scripted", MWMechanics::Priority::Priority_Scripted },
|
||||||
|
}));
|
||||||
|
|
||||||
|
api["BLEND_MASK"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, BlendMask>(view,
|
||||||
|
{
|
||||||
|
{ "LowerBody", BlendMask::BlendMask_LowerBody },
|
||||||
|
{ "Torso", BlendMask::BlendMask_Torso },
|
||||||
|
{ "LeftArm", BlendMask::BlendMask_LeftArm },
|
||||||
|
{ "RightArm", BlendMask::BlendMask_RightArm },
|
||||||
|
{ "UpperBody", BlendMask::BlendMask_UpperBody },
|
||||||
|
{ "All", BlendMask::BlendMask_All },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
api["BLEND_MASK"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, BlendMask>({
|
api["BONE_GROUP"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, BoneGroup>(view,
|
||||||
{ "LowerBody", BlendMask::BlendMask_LowerBody },
|
{
|
||||||
{ "Torso", BlendMask::BlendMask_Torso },
|
{ "LowerBody", BoneGroup::BoneGroup_LowerBody },
|
||||||
{ "LeftArm", BlendMask::BlendMask_LeftArm },
|
{ "Torso", BoneGroup::BoneGroup_Torso },
|
||||||
{ "RightArm", BlendMask::BlendMask_RightArm },
|
{ "LeftArm", BoneGroup::BoneGroup_LeftArm },
|
||||||
{ "UpperBody", BlendMask::BlendMask_UpperBody },
|
{ "RightArm", BoneGroup::BoneGroup_RightArm },
|
||||||
{ "All", BlendMask::BlendMask_All },
|
}));
|
||||||
}));
|
|
||||||
|
|
||||||
api["BONE_GROUP"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, BoneGroup>({
|
|
||||||
{ "LowerBody", BoneGroup::BoneGroup_LowerBody },
|
|
||||||
{ "Torso", BoneGroup::BoneGroup_Torso },
|
|
||||||
{ "LeftArm", BoneGroup::BoneGroup_LeftArm },
|
|
||||||
{ "RightArm", BoneGroup::BoneGroup_RightArm },
|
|
||||||
}));
|
|
||||||
|
|
||||||
api["hasAnimation"] = [world](const sol::object& object) -> bool {
|
api["hasAnimation"] = [world](const sol::object& object) -> bool {
|
||||||
return world->getAnimation(getPtrOrThrow(ObjectVariant(object))) != nullptr;
|
return world->getAnimation(getPtrOrThrow(ObjectVariant(object))) != nullptr;
|
||||||
|
@ -305,8 +308,7 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initWorldVfxBindings(const Context& context)
|
sol::table initWorldVfxBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::table api(context.mLua->unsafeState(), sol::create);
|
||||||
sol::table api(lua, sol::create);
|
|
||||||
auto world = MWBase::Environment::get().getWorld();
|
auto world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
api["spawn"]
|
api["spawn"]
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initBirthSignRecordBindings(const Context& context)
|
sol::table initBirthSignRecordBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table birthSigns(context.mLua->sol(), sol::create);
|
sol::table birthSigns(lua, sol::create);
|
||||||
addRecordFunctionBinding<ESM::BirthSign>(birthSigns, context);
|
addRecordFunctionBinding<ESM::BirthSign>(birthSigns, context);
|
||||||
|
|
||||||
auto signT = lua.new_usertype<ESM::BirthSign>("ESM3_BirthSign");
|
auto signT = lua.new_usertype<ESM::BirthSign>("ESM3_BirthSign");
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MWLua
|
||||||
|
|
||||||
using CameraMode = MWRender::Camera::Mode;
|
using CameraMode = MWRender::Camera::Mode;
|
||||||
|
|
||||||
sol::table initCameraPackage(sol::state_view& lua)
|
sol::table initCameraPackage(sol::state_view lua)
|
||||||
{
|
{
|
||||||
MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera();
|
MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera();
|
||||||
MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager();
|
MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initCameraPackage(sol::state_view& lua);
|
sol::table initCameraPackage(sol::state_view lua);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_CAMERABINDINGS_H
|
#endif // MWLUA_CAMERABINDINGS_H
|
||||||
|
|
|
@ -69,7 +69,8 @@ namespace MWLua
|
||||||
template <class CellT, class ObjectT>
|
template <class CellT, class ObjectT>
|
||||||
static void initCellBindings(const std::string& prefix, const Context& context)
|
static void initCellBindings(const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
sol::usertype<CellT> cellT = context.mLua->sol().new_usertype<CellT>(prefix + "Cell");
|
auto view = context.sol();
|
||||||
|
sol::usertype<CellT> cellT = view.new_usertype<CellT>(prefix + "Cell");
|
||||||
|
|
||||||
cellT[sol::meta_function::equal_to] = [](const CellT& a, const CellT& b) { return a.mStore == b.mStore; };
|
cellT[sol::meta_function::equal_to] = [](const CellT& a, const CellT& b) { return a.mStore == b.mStore; };
|
||||||
cellT[sol::meta_function::to_string] = [](const CellT& c) {
|
cellT[sol::meta_function::to_string] = [](const CellT& c) {
|
||||||
|
@ -127,8 +128,7 @@ namespace MWLua
|
||||||
|
|
||||||
if constexpr (std::is_same_v<CellT, GCell>)
|
if constexpr (std::is_same_v<CellT, GCell>)
|
||||||
{ // only for global scripts
|
{ // only for global scripts
|
||||||
cellT["getAll"] = [ids = getPackageToTypeTable(context.mLua->sol())](
|
cellT["getAll"] = [ids = getPackageToTypeTable(view)](const CellT& cell, sol::optional<sol::table> type) {
|
||||||
const CellT& cell, sol::optional<sol::table> type) {
|
|
||||||
if (cell.mStore->getState() != MWWorld::CellStore::State_Loaded)
|
if (cell.mStore->getState() != MWWorld::CellStore::State_Loaded)
|
||||||
cell.mStore->load();
|
cell.mStore->load();
|
||||||
ObjectIdList res = std::make_shared<std::vector<ObjectId>>();
|
ObjectIdList res = std::make_shared<std::vector<ObjectId>>();
|
||||||
|
|
|
@ -19,8 +19,8 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initClassRecordBindings(const Context& context)
|
sol::table initClassRecordBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table classes(context.mLua->sol(), sol::create);
|
sol::table classes(lua, sol::create);
|
||||||
addRecordFunctionBinding<ESM::Class>(classes, context);
|
addRecordFunctionBinding<ESM::Class>(classes, context);
|
||||||
|
|
||||||
auto classT = lua.new_usertype<ESM::Class>("ESM3_Class");
|
auto classT = lua.new_usertype<ESM::Class>("ESM3_Class");
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace MWLua
|
||||||
template <class... Str>
|
template <class... Str>
|
||||||
sol::object getCachedPackage(std::string_view first, const Str&... str) const
|
sol::object getCachedPackage(std::string_view first, const Str&... str) const
|
||||||
{
|
{
|
||||||
sol::object package = mLua->sol()[first];
|
sol::object package = sol()[first];
|
||||||
if constexpr (sizeof...(str) == 0)
|
if constexpr (sizeof...(str) == 0)
|
||||||
return package;
|
return package;
|
||||||
else
|
else
|
||||||
|
@ -58,7 +58,7 @@ namespace MWLua
|
||||||
template <class... Str>
|
template <class... Str>
|
||||||
const sol::object& setCachedPackage(const sol::object& value, std::string_view first, const Str&... str) const
|
const sol::object& setCachedPackage(const sol::object& value, std::string_view first, const Str&... str) const
|
||||||
{
|
{
|
||||||
sol::state_view& lua = mLua->sol();
|
sol::state_view lua = sol();
|
||||||
if constexpr (sizeof...(str) == 0)
|
if constexpr (sizeof...(str) == 0)
|
||||||
lua[first] = value;
|
lua[first] = value;
|
||||||
else
|
else
|
||||||
|
@ -90,10 +90,17 @@ namespace MWLua
|
||||||
|
|
||||||
bool initializeOnce(std::string_view key) const
|
bool initializeOnce(std::string_view key) const
|
||||||
{
|
{
|
||||||
sol::object flag = mLua->sol()[key];
|
auto view = sol();
|
||||||
mLua->sol()[key] = sol::make_object(mLua->sol(), true);
|
sol::object flag = view[key];
|
||||||
|
view[key] = sol::make_object(view, true);
|
||||||
return flag == sol::nil;
|
return flag == sol::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sol::state_view sol() const
|
||||||
|
{
|
||||||
|
// Bindings are initialized in a safe context
|
||||||
|
return mLua->unsafeState();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,19 +70,18 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initCorePackage(const Context& context)
|
sol::table initCorePackage(const Context& context)
|
||||||
{
|
{
|
||||||
auto* lua = context.mLua;
|
auto lua = context.sol();
|
||||||
|
|
||||||
sol::object cached = context.getTypePackage("openmw_core");
|
sol::object cached = context.getTypePackage("openmw_core");
|
||||||
if (cached != sol::nil)
|
if (cached != sol::nil)
|
||||||
return cached;
|
return cached;
|
||||||
|
|
||||||
sol::table api(lua->sol(), sol::create);
|
sol::table api(lua, sol::create);
|
||||||
api["API_REVISION"] = Version::getLuaApiRevision(); // specified in CMakeLists.txt
|
api["API_REVISION"] = Version::getLuaApiRevision(); // specified in CMakeLists.txt
|
||||||
api["quit"] = [lua]() {
|
api["quit"] = [lua = context.mLua]() {
|
||||||
Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback();
|
Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback();
|
||||||
MWBase::Environment::get().getStateManager()->requestQuit();
|
MWBase::Environment::get().getStateManager()->requestQuit();
|
||||||
};
|
};
|
||||||
api["contentFiles"] = initContentFilesBindings(lua->sol());
|
api["contentFiles"] = initContentFilesBindings(lua);
|
||||||
api["getFormId"] = [](std::string_view contentFile, unsigned int index) -> std::string {
|
api["getFormId"] = [](std::string_view contentFile, unsigned int index) -> std::string {
|
||||||
const std::vector<std::string>& contentList = MWBase::Environment::get().getWorld()->getContentFiles();
|
const std::vector<std::string>& contentList = MWBase::Environment::get().getWorld()->getContentFiles();
|
||||||
for (size_t i = 0; i < contentList.size(); ++i)
|
for (size_t i = 0; i < contentList.size(); ++i)
|
||||||
|
@ -103,10 +102,10 @@ namespace MWLua
|
||||||
api["dialogue"]
|
api["dialogue"]
|
||||||
= context.cachePackage("openmw_core_dialogue", [context]() { return initCoreDialogueBindings(context); });
|
= context.cachePackage("openmw_core_dialogue", [context]() { return initCoreDialogueBindings(context); });
|
||||||
api["l10n"] = context.cachePackage("openmw_core_l10n",
|
api["l10n"] = context.cachePackage("openmw_core_l10n",
|
||||||
[lua]() { return LuaUtil::initL10nLoader(lua->sol(), MWBase::Environment::get().getL10nManager()); });
|
[lua]() { return LuaUtil::initL10nLoader(lua, MWBase::Environment::get().getL10nManager()); });
|
||||||
const MWWorld::Store<ESM::GameSetting>* gmstStore
|
const MWWorld::Store<ESM::GameSetting>* gmstStore
|
||||||
= &MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
= &MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
||||||
api["getGMST"] = [lua = context.mLua, gmstStore](const std::string& setting) -> sol::object {
|
api["getGMST"] = [lua, gmstStore](const std::string& setting) -> sol::object {
|
||||||
const ESM::GameSetting* gmst = gmstStore->search(setting);
|
const ESM::GameSetting* gmst = gmstStore->search(setting);
|
||||||
if (gmst == nullptr)
|
if (gmst == nullptr)
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
|
@ -114,13 +113,13 @@ namespace MWLua
|
||||||
switch (value.getType())
|
switch (value.getType())
|
||||||
{
|
{
|
||||||
case ESM::VT_Float:
|
case ESM::VT_Float:
|
||||||
return sol::make_object<float>(lua->sol(), value.getFloat());
|
return sol::make_object<float>(lua, value.getFloat());
|
||||||
case ESM::VT_Short:
|
case ESM::VT_Short:
|
||||||
case ESM::VT_Long:
|
case ESM::VT_Long:
|
||||||
case ESM::VT_Int:
|
case ESM::VT_Int:
|
||||||
return sol::make_object<int>(lua->sol(), value.getInteger());
|
return sol::make_object<int>(lua, value.getInteger());
|
||||||
case ESM::VT_String:
|
case ESM::VT_String:
|
||||||
return sol::make_object<std::string>(lua->sol(), value.getString());
|
return sol::make_object<std::string>(lua, value.getString());
|
||||||
case ESM::VT_Unknown:
|
case ESM::VT_Unknown:
|
||||||
case ESM::VT_None:
|
case ESM::VT_None:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,19 +20,21 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initDebugPackage(const Context& context)
|
sol::table initDebugPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api = context.mLua->newTable();
|
auto view = context.sol();
|
||||||
|
sol::table api(view, sol::create);
|
||||||
|
|
||||||
api["RENDER_MODE"]
|
api["RENDER_MODE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWRender::RenderMode>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWRender::RenderMode>(view,
|
||||||
{ "CollisionDebug", MWRender::Render_CollisionDebug },
|
{
|
||||||
{ "Wireframe", MWRender::Render_Wireframe },
|
{ "CollisionDebug", MWRender::Render_CollisionDebug },
|
||||||
{ "Pathgrid", MWRender::Render_Pathgrid },
|
{ "Wireframe", MWRender::Render_Wireframe },
|
||||||
{ "Water", MWRender::Render_Water },
|
{ "Pathgrid", MWRender::Render_Pathgrid },
|
||||||
{ "Scene", MWRender::Render_Scene },
|
{ "Water", MWRender::Render_Water },
|
||||||
{ "NavMesh", MWRender::Render_NavMesh },
|
{ "Scene", MWRender::Render_Scene },
|
||||||
{ "ActorsPaths", MWRender::Render_ActorsPaths },
|
{ "NavMesh", MWRender::Render_NavMesh },
|
||||||
{ "RecastMesh", MWRender::Render_RecastMesh },
|
{ "ActorsPaths", MWRender::Render_ActorsPaths },
|
||||||
}));
|
{ "RecastMesh", MWRender::Render_RecastMesh },
|
||||||
|
}));
|
||||||
|
|
||||||
api["toggleRenderMode"] = [context](MWRender::RenderMode value) {
|
api["toggleRenderMode"] = [context](MWRender::RenderMode value) {
|
||||||
context.mLuaManager->addAction([value] { MWBase::Environment::get().getWorld()->toggleRenderMode(value); });
|
context.mLuaManager->addAction([value] { MWBase::Environment::get().getWorld()->toggleRenderMode(value); });
|
||||||
|
@ -56,10 +58,11 @@ namespace MWLua
|
||||||
api["reloadLua"] = []() { MWBase::Environment::get().getLuaManager()->reloadAllScripts(); };
|
api["reloadLua"] = []() { MWBase::Environment::get().getLuaManager()->reloadAllScripts(); };
|
||||||
|
|
||||||
api["NAV_MESH_RENDER_MODE"]
|
api["NAV_MESH_RENDER_MODE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, Settings::NavMeshRenderMode>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, Settings::NavMeshRenderMode>(view,
|
||||||
{ "AreaType", Settings::NavMeshRenderMode::AreaType },
|
{
|
||||||
{ "UpdateFrequency", Settings::NavMeshRenderMode::UpdateFrequency },
|
{ "AreaType", Settings::NavMeshRenderMode::AreaType },
|
||||||
}));
|
{ "UpdateFrequency", Settings::NavMeshRenderMode::UpdateFrequency },
|
||||||
|
}));
|
||||||
|
|
||||||
api["setNavMeshRenderMode"] = [context](Settings::NavMeshRenderMode value) {
|
api["setNavMeshRenderMode"] = [context](Settings::NavMeshRenderMode value) {
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace
|
||||||
{
|
{
|
||||||
using StoreT = FilteredDialogueStore<filter>;
|
using StoreT = FilteredDialogueStore<filter>;
|
||||||
|
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::usertype<StoreT> storeBindingsClass
|
sol::usertype<StoreT> storeBindingsClass
|
||||||
= lua.new_usertype<StoreT>("ESM3_Dialogue_Type" + std::to_string(filter) + " Store");
|
= lua.new_usertype<StoreT>("ESM3_Dialogue_Type" + std::to_string(filter) + " Store");
|
||||||
storeBindingsClass[sol::meta_function::to_string] = [](const StoreT& store) {
|
storeBindingsClass[sol::meta_function::to_string] = [](const StoreT& store) {
|
||||||
|
@ -317,7 +317,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initCoreDialogueBindings(const Context& context)
|
sol::table initCoreDialogueBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table api(lua, sol::create);
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
sol::table journalTable(lua, sol::create);
|
sol::table journalTable(lua, sol::create);
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initCoreFactionBindings(const Context& context)
|
sol::table initCoreFactionBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table factions(lua, sol::create);
|
sol::table factions(lua, sol::create);
|
||||||
addRecordFunctionBinding<ESM::Faction>(factions, context);
|
addRecordFunctionBinding<ESM::Faction>(factions, context);
|
||||||
// Faction record
|
// Faction record
|
||||||
|
|
|
@ -38,13 +38,13 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initInputPackage(const Context& context)
|
sol::table initInputPackage(const Context& context)
|
||||||
{
|
{
|
||||||
|
sol::state_view lua = context.sol();
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
|
||||||
if (lua["openmw_input"] != sol::nil)
|
if (lua["openmw_input"] != sol::nil)
|
||||||
return lua["openmw_input"];
|
return lua["openmw_input"];
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::usertype<SDL_Keysym> keyEvent = context.mLua->sol().new_usertype<SDL_Keysym>("KeyEvent");
|
sol::usertype<SDL_Keysym> keyEvent = lua.new_usertype<SDL_Keysym>("KeyEvent");
|
||||||
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) {
|
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) {
|
||||||
if (e.sym > 0 && e.sym <= 255)
|
if (e.sym > 0 && e.sym <= 255)
|
||||||
return std::string(1, static_cast<char>(e.sym));
|
return std::string(1, static_cast<char>(e.sym));
|
||||||
|
@ -57,7 +57,7 @@ namespace MWLua
|
||||||
keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; });
|
keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; });
|
||||||
keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; });
|
keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; });
|
||||||
|
|
||||||
auto touchpadEvent = context.mLua->sol().new_usertype<SDLUtil::TouchEvent>("TouchpadEvent");
|
auto touchpadEvent = lua.new_usertype<SDLUtil::TouchEvent>("TouchpadEvent");
|
||||||
touchpadEvent["device"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; });
|
touchpadEvent["device"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; });
|
||||||
touchpadEvent["finger"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; });
|
touchpadEvent["finger"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; });
|
||||||
touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f {
|
touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f {
|
||||||
|
@ -66,7 +66,7 @@ namespace MWLua
|
||||||
touchpadEvent["pressure"]
|
touchpadEvent["pressure"]
|
||||||
= sol::readonly_property([](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; });
|
= sol::readonly_property([](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; });
|
||||||
|
|
||||||
auto inputActions = context.mLua->sol().new_usertype<LuaUtil::InputAction::Registry>("InputActions");
|
auto inputActions = lua.new_usertype<LuaUtil::InputAction::Registry>("InputActions");
|
||||||
inputActions[sol::meta_function::index]
|
inputActions[sol::meta_function::index]
|
||||||
= [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; };
|
= [](LuaUtil::InputAction::Registry& registry, std::string_view key) { return registry[key]; };
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ namespace MWLua
|
||||||
inputActions[sol::meta_function::pairs] = pairs;
|
inputActions[sol::meta_function::pairs] = pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto actionInfo = context.mLua->sol().new_usertype<LuaUtil::InputAction::Info>("ActionInfo");
|
auto actionInfo = lua.new_usertype<LuaUtil::InputAction::Info>("ActionInfo");
|
||||||
actionInfo["key"] = sol::readonly_property(
|
actionInfo["key"] = sol::readonly_property(
|
||||||
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; });
|
[](const LuaUtil::InputAction::Info& info) -> std::string_view { return info.mKey; });
|
||||||
actionInfo["name"] = sol::readonly_property(
|
actionInfo["name"] = sol::readonly_property(
|
||||||
|
@ -98,7 +98,7 @@ namespace MWLua
|
||||||
actionInfo["defaultValue"]
|
actionInfo["defaultValue"]
|
||||||
= sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mDefaultValue; });
|
= sol::readonly_property([](const LuaUtil::InputAction::Info& info) { return info.mDefaultValue; });
|
||||||
|
|
||||||
auto inputTriggers = context.mLua->sol().new_usertype<LuaUtil::InputTrigger::Registry>("InputTriggers");
|
auto inputTriggers = lua.new_usertype<LuaUtil::InputTrigger::Registry>("InputTriggers");
|
||||||
inputTriggers[sol::meta_function::index]
|
inputTriggers[sol::meta_function::index]
|
||||||
= [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; };
|
= [](LuaUtil::InputTrigger::Registry& registry, std::string_view key) { return registry[key]; };
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ namespace MWLua
|
||||||
inputTriggers[sol::meta_function::pairs] = pairs;
|
inputTriggers[sol::meta_function::pairs] = pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto triggerInfo = context.mLua->sol().new_usertype<LuaUtil::InputTrigger::Info>("TriggerInfo");
|
auto triggerInfo = lua.new_usertype<LuaUtil::InputTrigger::Info>("TriggerInfo");
|
||||||
triggerInfo["key"] = sol::readonly_property(
|
triggerInfo["key"] = sol::readonly_property(
|
||||||
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; });
|
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mKey; });
|
||||||
triggerInfo["name"] = sol::readonly_property(
|
triggerInfo["name"] = sol::readonly_property(
|
||||||
|
@ -128,14 +128,15 @@ namespace MWLua
|
||||||
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mL10n; });
|
[](const LuaUtil::InputTrigger::Info& info) -> std::string_view { return info.mL10n; });
|
||||||
|
|
||||||
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
api["ACTION_TYPE"]
|
api["ACTION_TYPE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, LuaUtil::InputAction::Type>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, LuaUtil::InputAction::Type>(lua,
|
||||||
{ "Boolean", LuaUtil::InputAction::Type::Boolean },
|
{
|
||||||
{ "Number", LuaUtil::InputAction::Type::Number },
|
{ "Boolean", LuaUtil::InputAction::Type::Boolean },
|
||||||
{ "Range", LuaUtil::InputAction::Type::Range },
|
{ "Number", LuaUtil::InputAction::Type::Number },
|
||||||
}));
|
{ "Range", LuaUtil::InputAction::Type::Range },
|
||||||
|
}));
|
||||||
|
|
||||||
api["actions"] = std::ref(context.mLuaManager->inputActions());
|
api["actions"] = std::ref(context.mLuaManager->inputActions());
|
||||||
api["registerAction"] = [manager = context.mLuaManager](sol::table options) {
|
api["registerAction"] = [manager = context.mLuaManager](sol::table options) {
|
||||||
|
@ -231,215 +232,219 @@ namespace MWLua
|
||||||
|
|
||||||
api["getKeyName"] = [](SDL_Scancode code) { return SDL_GetScancodeName(code); };
|
api["getKeyName"] = [](SDL_Scancode code) { return SDL_GetScancodeName(code); };
|
||||||
|
|
||||||
api["ACTION"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWInput::Actions>({
|
api["ACTION"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWInput::Actions>(lua,
|
||||||
{ "GameMenu", MWInput::A_GameMenu },
|
{
|
||||||
{ "Screenshot", MWInput::A_Screenshot },
|
{ "GameMenu", MWInput::A_GameMenu },
|
||||||
{ "Inventory", MWInput::A_Inventory },
|
{ "Screenshot", MWInput::A_Screenshot },
|
||||||
{ "Console", MWInput::A_Console },
|
{ "Inventory", MWInput::A_Inventory },
|
||||||
|
{ "Console", MWInput::A_Console },
|
||||||
|
|
||||||
{ "MoveLeft", MWInput::A_MoveLeft },
|
{ "MoveLeft", MWInput::A_MoveLeft },
|
||||||
{ "MoveRight", MWInput::A_MoveRight },
|
{ "MoveRight", MWInput::A_MoveRight },
|
||||||
{ "MoveForward", MWInput::A_MoveForward },
|
{ "MoveForward", MWInput::A_MoveForward },
|
||||||
{ "MoveBackward", MWInput::A_MoveBackward },
|
{ "MoveBackward", MWInput::A_MoveBackward },
|
||||||
|
|
||||||
{ "Activate", MWInput::A_Activate },
|
{ "Activate", MWInput::A_Activate },
|
||||||
{ "Use", MWInput::A_Use },
|
{ "Use", MWInput::A_Use },
|
||||||
{ "Jump", MWInput::A_Jump },
|
{ "Jump", MWInput::A_Jump },
|
||||||
{ "AutoMove", MWInput::A_AutoMove },
|
{ "AutoMove", MWInput::A_AutoMove },
|
||||||
{ "Rest", MWInput::A_Rest },
|
{ "Rest", MWInput::A_Rest },
|
||||||
{ "Journal", MWInput::A_Journal },
|
{ "Journal", MWInput::A_Journal },
|
||||||
{ "Run", MWInput::A_Run },
|
{ "Run", MWInput::A_Run },
|
||||||
{ "CycleSpellLeft", MWInput::A_CycleSpellLeft },
|
{ "CycleSpellLeft", MWInput::A_CycleSpellLeft },
|
||||||
{ "CycleSpellRight", MWInput::A_CycleSpellRight },
|
{ "CycleSpellRight", MWInput::A_CycleSpellRight },
|
||||||
{ "CycleWeaponLeft", MWInput::A_CycleWeaponLeft },
|
{ "CycleWeaponLeft", MWInput::A_CycleWeaponLeft },
|
||||||
{ "CycleWeaponRight", MWInput::A_CycleWeaponRight },
|
{ "CycleWeaponRight", MWInput::A_CycleWeaponRight },
|
||||||
{ "AlwaysRun", MWInput::A_AlwaysRun },
|
{ "AlwaysRun", MWInput::A_AlwaysRun },
|
||||||
{ "Sneak", MWInput::A_Sneak },
|
{ "Sneak", MWInput::A_Sneak },
|
||||||
|
|
||||||
{ "QuickSave", MWInput::A_QuickSave },
|
{ "QuickSave", MWInput::A_QuickSave },
|
||||||
{ "QuickLoad", MWInput::A_QuickLoad },
|
{ "QuickLoad", MWInput::A_QuickLoad },
|
||||||
{ "QuickMenu", MWInput::A_QuickMenu },
|
{ "QuickMenu", MWInput::A_QuickMenu },
|
||||||
{ "ToggleWeapon", MWInput::A_ToggleWeapon },
|
{ "ToggleWeapon", MWInput::A_ToggleWeapon },
|
||||||
{ "ToggleSpell", MWInput::A_ToggleSpell },
|
{ "ToggleSpell", MWInput::A_ToggleSpell },
|
||||||
{ "TogglePOV", MWInput::A_TogglePOV },
|
{ "TogglePOV", MWInput::A_TogglePOV },
|
||||||
|
|
||||||
{ "QuickKey1", MWInput::A_QuickKey1 },
|
{ "QuickKey1", MWInput::A_QuickKey1 },
|
||||||
{ "QuickKey2", MWInput::A_QuickKey2 },
|
{ "QuickKey2", MWInput::A_QuickKey2 },
|
||||||
{ "QuickKey3", MWInput::A_QuickKey3 },
|
{ "QuickKey3", MWInput::A_QuickKey3 },
|
||||||
{ "QuickKey4", MWInput::A_QuickKey4 },
|
{ "QuickKey4", MWInput::A_QuickKey4 },
|
||||||
{ "QuickKey5", MWInput::A_QuickKey5 },
|
{ "QuickKey5", MWInput::A_QuickKey5 },
|
||||||
{ "QuickKey6", MWInput::A_QuickKey6 },
|
{ "QuickKey6", MWInput::A_QuickKey6 },
|
||||||
{ "QuickKey7", MWInput::A_QuickKey7 },
|
{ "QuickKey7", MWInput::A_QuickKey7 },
|
||||||
{ "QuickKey8", MWInput::A_QuickKey8 },
|
{ "QuickKey8", MWInput::A_QuickKey8 },
|
||||||
{ "QuickKey9", MWInput::A_QuickKey9 },
|
{ "QuickKey9", MWInput::A_QuickKey9 },
|
||||||
{ "QuickKey10", MWInput::A_QuickKey10 },
|
{ "QuickKey10", MWInput::A_QuickKey10 },
|
||||||
{ "QuickKeysMenu", MWInput::A_QuickKeysMenu },
|
{ "QuickKeysMenu", MWInput::A_QuickKeysMenu },
|
||||||
|
|
||||||
{ "ToggleHUD", MWInput::A_ToggleHUD },
|
{ "ToggleHUD", MWInput::A_ToggleHUD },
|
||||||
{ "ToggleDebug", MWInput::A_ToggleDebug },
|
{ "ToggleDebug", MWInput::A_ToggleDebug },
|
||||||
{ "TogglePostProcessorHUD", MWInput::A_TogglePostProcessorHUD },
|
{ "TogglePostProcessorHUD", MWInput::A_TogglePostProcessorHUD },
|
||||||
|
|
||||||
{ "ZoomIn", MWInput::A_ZoomIn },
|
{ "ZoomIn", MWInput::A_ZoomIn },
|
||||||
{ "ZoomOut", MWInput::A_ZoomOut },
|
{ "ZoomOut", MWInput::A_ZoomOut },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// input.CONTROL_SWITCH is deprecated, remove after releasing 0.49
|
// input.CONTROL_SWITCH is deprecated, remove after releasing 0.49
|
||||||
api["CONTROL_SWITCH"]
|
api["CONTROL_SWITCH"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, std::string_view>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, std::string_view>(lua,
|
||||||
{ "Controls", "playercontrols" },
|
{
|
||||||
{ "Fighting", "playerfighting" },
|
{ "Controls", "playercontrols" },
|
||||||
{ "Jumping", "playerjumping" },
|
{ "Fighting", "playerfighting" },
|
||||||
{ "Looking", "playerlooking" },
|
{ "Jumping", "playerjumping" },
|
||||||
{ "Magic", "playermagic" },
|
{ "Looking", "playerlooking" },
|
||||||
{ "ViewMode", "playerviewswitch" },
|
{ "Magic", "playermagic" },
|
||||||
{ "VanityMode", "vanitymode" },
|
{ "ViewMode", "playerviewswitch" },
|
||||||
}));
|
{ "VanityMode", "vanitymode" },
|
||||||
|
}));
|
||||||
|
|
||||||
api["CONTROLLER_BUTTON"]
|
api["CONTROLLER_BUTTON"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, SDL_GameControllerButton>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, SDL_GameControllerButton>(lua,
|
||||||
{ "A", SDL_CONTROLLER_BUTTON_A },
|
{
|
||||||
{ "B", SDL_CONTROLLER_BUTTON_B },
|
{ "A", SDL_CONTROLLER_BUTTON_A },
|
||||||
{ "X", SDL_CONTROLLER_BUTTON_X },
|
{ "B", SDL_CONTROLLER_BUTTON_B },
|
||||||
{ "Y", SDL_CONTROLLER_BUTTON_Y },
|
{ "X", SDL_CONTROLLER_BUTTON_X },
|
||||||
{ "Back", SDL_CONTROLLER_BUTTON_BACK },
|
{ "Y", SDL_CONTROLLER_BUTTON_Y },
|
||||||
{ "Guide", SDL_CONTROLLER_BUTTON_GUIDE },
|
{ "Back", SDL_CONTROLLER_BUTTON_BACK },
|
||||||
{ "Start", SDL_CONTROLLER_BUTTON_START },
|
{ "Guide", SDL_CONTROLLER_BUTTON_GUIDE },
|
||||||
{ "LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK },
|
{ "Start", SDL_CONTROLLER_BUTTON_START },
|
||||||
{ "RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK },
|
{ "LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK },
|
||||||
{ "LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER },
|
{ "RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK },
|
||||||
{ "RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER },
|
{ "LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER },
|
||||||
{ "DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP },
|
{ "RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER },
|
||||||
{ "DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN },
|
{ "DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP },
|
||||||
{ "DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT },
|
{ "DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN },
|
||||||
{ "DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT },
|
{ "DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT },
|
||||||
|
{ "DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT },
|
||||||
|
}));
|
||||||
|
|
||||||
|
api["CONTROLLER_AXIS"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
|
{
|
||||||
|
{ "LeftX", SDL_CONTROLLER_AXIS_LEFTX },
|
||||||
|
{ "LeftY", SDL_CONTROLLER_AXIS_LEFTY },
|
||||||
|
{ "RightX", SDL_CONTROLLER_AXIS_RIGHTX },
|
||||||
|
{ "RightY", SDL_CONTROLLER_AXIS_RIGHTY },
|
||||||
|
{ "TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT },
|
||||||
|
{ "TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT },
|
||||||
|
|
||||||
|
{ "LookUpDown", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_LookUpDown) },
|
||||||
|
{ "LookLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_LookLeftRight) },
|
||||||
|
{ "MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_MoveForwardBackward) },
|
||||||
|
{ "MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_MoveLeftRight) },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
api["CONTROLLER_AXIS"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
api["KEY"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, SDL_Scancode>(lua,
|
||||||
{ "LeftX", SDL_CONTROLLER_AXIS_LEFTX },
|
{
|
||||||
{ "LeftY", SDL_CONTROLLER_AXIS_LEFTY },
|
{ "_0", SDL_SCANCODE_0 },
|
||||||
{ "RightX", SDL_CONTROLLER_AXIS_RIGHTX },
|
{ "_1", SDL_SCANCODE_1 },
|
||||||
{ "RightY", SDL_CONTROLLER_AXIS_RIGHTY },
|
{ "_2", SDL_SCANCODE_2 },
|
||||||
{ "TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT },
|
{ "_3", SDL_SCANCODE_3 },
|
||||||
{ "TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT },
|
{ "_4", SDL_SCANCODE_4 },
|
||||||
|
{ "_5", SDL_SCANCODE_5 },
|
||||||
|
{ "_6", SDL_SCANCODE_6 },
|
||||||
|
{ "_7", SDL_SCANCODE_7 },
|
||||||
|
{ "_8", SDL_SCANCODE_8 },
|
||||||
|
{ "_9", SDL_SCANCODE_9 },
|
||||||
|
|
||||||
{ "LookUpDown", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_LookUpDown) },
|
{ "NP_0", SDL_SCANCODE_KP_0 },
|
||||||
{ "LookLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_LookLeftRight) },
|
{ "NP_1", SDL_SCANCODE_KP_1 },
|
||||||
{ "MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_MoveForwardBackward) },
|
{ "NP_2", SDL_SCANCODE_KP_2 },
|
||||||
{ "MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast<int>(MWInput::A_MoveLeftRight) },
|
{ "NP_3", SDL_SCANCODE_KP_3 },
|
||||||
}));
|
{ "NP_4", SDL_SCANCODE_KP_4 },
|
||||||
|
{ "NP_5", SDL_SCANCODE_KP_5 },
|
||||||
|
{ "NP_6", SDL_SCANCODE_KP_6 },
|
||||||
|
{ "NP_7", SDL_SCANCODE_KP_7 },
|
||||||
|
{ "NP_8", SDL_SCANCODE_KP_8 },
|
||||||
|
{ "NP_9", SDL_SCANCODE_KP_9 },
|
||||||
|
{ "NP_Divide", SDL_SCANCODE_KP_DIVIDE },
|
||||||
|
{ "NP_Enter", SDL_SCANCODE_KP_ENTER },
|
||||||
|
{ "NP_Minus", SDL_SCANCODE_KP_MINUS },
|
||||||
|
{ "NP_Multiply", SDL_SCANCODE_KP_MULTIPLY },
|
||||||
|
{ "NP_Delete", SDL_SCANCODE_KP_PERIOD },
|
||||||
|
{ "NP_Plus", SDL_SCANCODE_KP_PLUS },
|
||||||
|
|
||||||
api["KEY"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, SDL_Scancode>({
|
{ "F1", SDL_SCANCODE_F1 },
|
||||||
{ "_0", SDL_SCANCODE_0 },
|
{ "F2", SDL_SCANCODE_F2 },
|
||||||
{ "_1", SDL_SCANCODE_1 },
|
{ "F3", SDL_SCANCODE_F3 },
|
||||||
{ "_2", SDL_SCANCODE_2 },
|
{ "F4", SDL_SCANCODE_F4 },
|
||||||
{ "_3", SDL_SCANCODE_3 },
|
{ "F5", SDL_SCANCODE_F5 },
|
||||||
{ "_4", SDL_SCANCODE_4 },
|
{ "F6", SDL_SCANCODE_F6 },
|
||||||
{ "_5", SDL_SCANCODE_5 },
|
{ "F7", SDL_SCANCODE_F7 },
|
||||||
{ "_6", SDL_SCANCODE_6 },
|
{ "F8", SDL_SCANCODE_F8 },
|
||||||
{ "_7", SDL_SCANCODE_7 },
|
{ "F9", SDL_SCANCODE_F9 },
|
||||||
{ "_8", SDL_SCANCODE_8 },
|
{ "F10", SDL_SCANCODE_F10 },
|
||||||
{ "_9", SDL_SCANCODE_9 },
|
{ "F11", SDL_SCANCODE_F11 },
|
||||||
|
{ "F12", SDL_SCANCODE_F12 },
|
||||||
|
|
||||||
{ "NP_0", SDL_SCANCODE_KP_0 },
|
{ "A", SDL_SCANCODE_A },
|
||||||
{ "NP_1", SDL_SCANCODE_KP_1 },
|
{ "B", SDL_SCANCODE_B },
|
||||||
{ "NP_2", SDL_SCANCODE_KP_2 },
|
{ "C", SDL_SCANCODE_C },
|
||||||
{ "NP_3", SDL_SCANCODE_KP_3 },
|
{ "D", SDL_SCANCODE_D },
|
||||||
{ "NP_4", SDL_SCANCODE_KP_4 },
|
{ "E", SDL_SCANCODE_E },
|
||||||
{ "NP_5", SDL_SCANCODE_KP_5 },
|
{ "F", SDL_SCANCODE_F },
|
||||||
{ "NP_6", SDL_SCANCODE_KP_6 },
|
{ "G", SDL_SCANCODE_G },
|
||||||
{ "NP_7", SDL_SCANCODE_KP_7 },
|
{ "H", SDL_SCANCODE_H },
|
||||||
{ "NP_8", SDL_SCANCODE_KP_8 },
|
{ "I", SDL_SCANCODE_I },
|
||||||
{ "NP_9", SDL_SCANCODE_KP_9 },
|
{ "J", SDL_SCANCODE_J },
|
||||||
{ "NP_Divide", SDL_SCANCODE_KP_DIVIDE },
|
{ "K", SDL_SCANCODE_K },
|
||||||
{ "NP_Enter", SDL_SCANCODE_KP_ENTER },
|
{ "L", SDL_SCANCODE_L },
|
||||||
{ "NP_Minus", SDL_SCANCODE_KP_MINUS },
|
{ "M", SDL_SCANCODE_M },
|
||||||
{ "NP_Multiply", SDL_SCANCODE_KP_MULTIPLY },
|
{ "N", SDL_SCANCODE_N },
|
||||||
{ "NP_Delete", SDL_SCANCODE_KP_PERIOD },
|
{ "O", SDL_SCANCODE_O },
|
||||||
{ "NP_Plus", SDL_SCANCODE_KP_PLUS },
|
{ "P", SDL_SCANCODE_P },
|
||||||
|
{ "Q", SDL_SCANCODE_Q },
|
||||||
|
{ "R", SDL_SCANCODE_R },
|
||||||
|
{ "S", SDL_SCANCODE_S },
|
||||||
|
{ "T", SDL_SCANCODE_T },
|
||||||
|
{ "U", SDL_SCANCODE_U },
|
||||||
|
{ "V", SDL_SCANCODE_V },
|
||||||
|
{ "W", SDL_SCANCODE_W },
|
||||||
|
{ "X", SDL_SCANCODE_X },
|
||||||
|
{ "Y", SDL_SCANCODE_Y },
|
||||||
|
{ "Z", SDL_SCANCODE_Z },
|
||||||
|
|
||||||
{ "F1", SDL_SCANCODE_F1 },
|
{ "LeftArrow", SDL_SCANCODE_LEFT },
|
||||||
{ "F2", SDL_SCANCODE_F2 },
|
{ "RightArrow", SDL_SCANCODE_RIGHT },
|
||||||
{ "F3", SDL_SCANCODE_F3 },
|
{ "UpArrow", SDL_SCANCODE_UP },
|
||||||
{ "F4", SDL_SCANCODE_F4 },
|
{ "DownArrow", SDL_SCANCODE_DOWN },
|
||||||
{ "F5", SDL_SCANCODE_F5 },
|
|
||||||
{ "F6", SDL_SCANCODE_F6 },
|
|
||||||
{ "F7", SDL_SCANCODE_F7 },
|
|
||||||
{ "F8", SDL_SCANCODE_F8 },
|
|
||||||
{ "F9", SDL_SCANCODE_F9 },
|
|
||||||
{ "F10", SDL_SCANCODE_F10 },
|
|
||||||
{ "F11", SDL_SCANCODE_F11 },
|
|
||||||
{ "F12", SDL_SCANCODE_F12 },
|
|
||||||
|
|
||||||
{ "A", SDL_SCANCODE_A },
|
{ "LeftAlt", SDL_SCANCODE_LALT },
|
||||||
{ "B", SDL_SCANCODE_B },
|
{ "LeftCtrl", SDL_SCANCODE_LCTRL },
|
||||||
{ "C", SDL_SCANCODE_C },
|
{ "LeftBracket", SDL_SCANCODE_LEFTBRACKET },
|
||||||
{ "D", SDL_SCANCODE_D },
|
{ "LeftSuper", SDL_SCANCODE_LGUI },
|
||||||
{ "E", SDL_SCANCODE_E },
|
{ "LeftShift", SDL_SCANCODE_LSHIFT },
|
||||||
{ "F", SDL_SCANCODE_F },
|
{ "RightAlt", SDL_SCANCODE_RALT },
|
||||||
{ "G", SDL_SCANCODE_G },
|
{ "RightCtrl", SDL_SCANCODE_RCTRL },
|
||||||
{ "H", SDL_SCANCODE_H },
|
{ "RightSuper", SDL_SCANCODE_RGUI },
|
||||||
{ "I", SDL_SCANCODE_I },
|
{ "RightBracket", SDL_SCANCODE_RIGHTBRACKET },
|
||||||
{ "J", SDL_SCANCODE_J },
|
{ "RightShift", SDL_SCANCODE_RSHIFT },
|
||||||
{ "K", SDL_SCANCODE_K },
|
|
||||||
{ "L", SDL_SCANCODE_L },
|
|
||||||
{ "M", SDL_SCANCODE_M },
|
|
||||||
{ "N", SDL_SCANCODE_N },
|
|
||||||
{ "O", SDL_SCANCODE_O },
|
|
||||||
{ "P", SDL_SCANCODE_P },
|
|
||||||
{ "Q", SDL_SCANCODE_Q },
|
|
||||||
{ "R", SDL_SCANCODE_R },
|
|
||||||
{ "S", SDL_SCANCODE_S },
|
|
||||||
{ "T", SDL_SCANCODE_T },
|
|
||||||
{ "U", SDL_SCANCODE_U },
|
|
||||||
{ "V", SDL_SCANCODE_V },
|
|
||||||
{ "W", SDL_SCANCODE_W },
|
|
||||||
{ "X", SDL_SCANCODE_X },
|
|
||||||
{ "Y", SDL_SCANCODE_Y },
|
|
||||||
{ "Z", SDL_SCANCODE_Z },
|
|
||||||
|
|
||||||
{ "LeftArrow", SDL_SCANCODE_LEFT },
|
{ "Apostrophe", SDL_SCANCODE_APOSTROPHE },
|
||||||
{ "RightArrow", SDL_SCANCODE_RIGHT },
|
{ "BackSlash", SDL_SCANCODE_BACKSLASH },
|
||||||
{ "UpArrow", SDL_SCANCODE_UP },
|
{ "Backspace", SDL_SCANCODE_BACKSPACE },
|
||||||
{ "DownArrow", SDL_SCANCODE_DOWN },
|
{ "CapsLock", SDL_SCANCODE_CAPSLOCK },
|
||||||
|
{ "Comma", SDL_SCANCODE_COMMA },
|
||||||
|
{ "Delete", SDL_SCANCODE_DELETE },
|
||||||
|
{ "End", SDL_SCANCODE_END },
|
||||||
|
{ "Enter", SDL_SCANCODE_RETURN },
|
||||||
|
{ "Equals", SDL_SCANCODE_EQUALS },
|
||||||
|
{ "Escape", SDL_SCANCODE_ESCAPE },
|
||||||
|
{ "Home", SDL_SCANCODE_HOME },
|
||||||
|
{ "Insert", SDL_SCANCODE_INSERT },
|
||||||
|
{ "Minus", SDL_SCANCODE_MINUS },
|
||||||
|
{ "NumLock", SDL_SCANCODE_NUMLOCKCLEAR },
|
||||||
|
{ "PageDown", SDL_SCANCODE_PAGEDOWN },
|
||||||
|
{ "PageUp", SDL_SCANCODE_PAGEUP },
|
||||||
|
{ "Period", SDL_SCANCODE_PERIOD },
|
||||||
|
{ "Pause", SDL_SCANCODE_PAUSE },
|
||||||
|
{ "PrintScreen", SDL_SCANCODE_PRINTSCREEN },
|
||||||
|
{ "ScrollLock", SDL_SCANCODE_SCROLLLOCK },
|
||||||
|
{ "Semicolon", SDL_SCANCODE_SEMICOLON },
|
||||||
|
{ "Slash", SDL_SCANCODE_SLASH },
|
||||||
|
{ "Space", SDL_SCANCODE_SPACE },
|
||||||
|
{ "Tab", SDL_SCANCODE_TAB },
|
||||||
|
}));
|
||||||
|
|
||||||
{ "LeftAlt", SDL_SCANCODE_LALT },
|
|
||||||
{ "LeftCtrl", SDL_SCANCODE_LCTRL },
|
|
||||||
{ "LeftBracket", SDL_SCANCODE_LEFTBRACKET },
|
|
||||||
{ "LeftSuper", SDL_SCANCODE_LGUI },
|
|
||||||
{ "LeftShift", SDL_SCANCODE_LSHIFT },
|
|
||||||
{ "RightAlt", SDL_SCANCODE_RALT },
|
|
||||||
{ "RightCtrl", SDL_SCANCODE_RCTRL },
|
|
||||||
{ "RightSuper", SDL_SCANCODE_RGUI },
|
|
||||||
{ "RightBracket", SDL_SCANCODE_RIGHTBRACKET },
|
|
||||||
{ "RightShift", SDL_SCANCODE_RSHIFT },
|
|
||||||
|
|
||||||
{ "Apostrophe", SDL_SCANCODE_APOSTROPHE },
|
|
||||||
{ "BackSlash", SDL_SCANCODE_BACKSLASH },
|
|
||||||
{ "Backspace", SDL_SCANCODE_BACKSPACE },
|
|
||||||
{ "CapsLock", SDL_SCANCODE_CAPSLOCK },
|
|
||||||
{ "Comma", SDL_SCANCODE_COMMA },
|
|
||||||
{ "Delete", SDL_SCANCODE_DELETE },
|
|
||||||
{ "End", SDL_SCANCODE_END },
|
|
||||||
{ "Enter", SDL_SCANCODE_RETURN },
|
|
||||||
{ "Equals", SDL_SCANCODE_EQUALS },
|
|
||||||
{ "Escape", SDL_SCANCODE_ESCAPE },
|
|
||||||
{ "Home", SDL_SCANCODE_HOME },
|
|
||||||
{ "Insert", SDL_SCANCODE_INSERT },
|
|
||||||
{ "Minus", SDL_SCANCODE_MINUS },
|
|
||||||
{ "NumLock", SDL_SCANCODE_NUMLOCKCLEAR },
|
|
||||||
{ "PageDown", SDL_SCANCODE_PAGEDOWN },
|
|
||||||
{ "PageUp", SDL_SCANCODE_PAGEUP },
|
|
||||||
{ "Period", SDL_SCANCODE_PERIOD },
|
|
||||||
{ "Pause", SDL_SCANCODE_PAUSE },
|
|
||||||
{ "PrintScreen", SDL_SCANCODE_PRINTSCREEN },
|
|
||||||
{ "ScrollLock", SDL_SCANCODE_SCROLLLOCK },
|
|
||||||
{ "Semicolon", SDL_SCANCODE_SEMICOLON },
|
|
||||||
{ "Slash", SDL_SCANCODE_SLASH },
|
|
||||||
{ "Space", SDL_SCANCODE_SPACE },
|
|
||||||
{ "Tab", SDL_SCANCODE_TAB },
|
|
||||||
}));
|
|
||||||
|
|
||||||
sol::state_view& lua = context.mLua->sol();
|
|
||||||
lua["openmw_input"] = LuaUtil::makeReadOnly(api);
|
lua["openmw_input"] = LuaUtil::makeReadOnly(api);
|
||||||
return lua["openmw_input"];
|
return lua["openmw_input"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace MWLua
|
||||||
if (it != self->mStatsCache.end())
|
if (it != self->mStatsCache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
return sol::make_object(context.mLua->sol(), getValue(context, prop, mObject.ptr()));
|
return sol::make_object(context.mLua->unsafeState(), getValue(context, prop, mObject.ptr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const Context& context, std::string_view prop, const sol::object& value) const
|
void set(const Context& context, std::string_view prop, const sol::object& value) const
|
||||||
|
@ -82,9 +82,9 @@ namespace MWLua
|
||||||
if (prop == "condition")
|
if (prop == "condition")
|
||||||
{
|
{
|
||||||
if (ptr.mRef->getType() == ESM::REC_LIGH)
|
if (ptr.mRef->getType() == ESM::REC_LIGH)
|
||||||
return sol::make_object(context.mLua->sol(), ptr.getClass().getRemainingUsageTime(ptr));
|
return sol::make_object(context.mLua->unsafeState(), ptr.getClass().getRemainingUsageTime(ptr));
|
||||||
else if (ptr.getClass().hasItemHealth(ptr))
|
else if (ptr.getClass().hasItemHealth(ptr))
|
||||||
return sol::make_object(context.mLua->sol(),
|
return sol::make_object(context.mLua->unsafeState(),
|
||||||
ptr.getClass().getItemHealth(ptr) + ptr.getCellRef().getChargeIntRemainder());
|
ptr.getClass().getItemHealth(ptr) + ptr.getCellRef().getChargeIntRemainder());
|
||||||
}
|
}
|
||||||
else if (prop == "enchantmentCharge")
|
else if (prop == "enchantmentCharge")
|
||||||
|
@ -99,9 +99,10 @@ namespace MWLua
|
||||||
const auto* enchantment = store->get<ESM::Enchantment>().find(enchantmentName);
|
const auto* enchantment = store->get<ESM::Enchantment>().find(enchantmentName);
|
||||||
|
|
||||||
if (charge == -1) // return the full charge
|
if (charge == -1) // return the full charge
|
||||||
return sol::make_object(context.mLua->sol(), MWMechanics::getEnchantmentCharge(*enchantment));
|
return sol::make_object(
|
||||||
|
context.mLua->unsafeState(), MWMechanics::getEnchantmentCharge(*enchantment));
|
||||||
|
|
||||||
return sol::make_object(context.mLua->sol(), charge);
|
return sol::make_object(context.mLua->unsafeState(), charge);
|
||||||
}
|
}
|
||||||
else if (prop == "soul")
|
else if (prop == "soul")
|
||||||
{
|
{
|
||||||
|
@ -109,7 +110,7 @@ namespace MWLua
|
||||||
if (soul.empty())
|
if (soul.empty())
|
||||||
return sol::lua_nil;
|
return sol::lua_nil;
|
||||||
|
|
||||||
return sol::make_object(context.mLua->sol(), soul.serializeText());
|
return sol::make_object(context.mLua->unsafeState(), soul.serializeText());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sol::lua_nil;
|
return sol::lua_nil;
|
||||||
|
@ -185,7 +186,7 @@ namespace MWLua
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
sol::usertype<ItemData> itemData = context.mLua->sol().new_usertype<ItemData>("ItemData");
|
sol::usertype<ItemData> itemData = context.sol().new_usertype<ItemData>("ItemData");
|
||||||
itemData[sol::meta_function::new_index] = [](const ItemData& stat, const sol::variadic_args args) {
|
itemData[sol::meta_function::new_index] = [](const ItemData& stat, const sol::variadic_args args) {
|
||||||
throw std::runtime_error("Unknown ItemData property '" + args.get<std::string>() + "'");
|
throw std::runtime_error("Unknown ItemData property '" + args.get<std::string>() + "'");
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,8 +38,9 @@ namespace MWLua
|
||||||
|
|
||||||
void LocalScripts::initializeSelfPackage(const Context& context)
|
void LocalScripts::initializeSelfPackage(const Context& context)
|
||||||
{
|
{
|
||||||
|
auto lua = context.sol();
|
||||||
using ActorControls = MWBase::LuaManager::ActorControls;
|
using ActorControls = MWBase::LuaManager::ActorControls;
|
||||||
sol::usertype<ActorControls> controls = context.mLua->sol().new_usertype<ActorControls>("ActorControls");
|
sol::usertype<ActorControls> controls = lua.new_usertype<ActorControls>("ActorControls");
|
||||||
|
|
||||||
#define CONTROL(TYPE, FIELD) \
|
#define CONTROL(TYPE, FIELD) \
|
||||||
sol::property([](const ActorControls& c) { return c.FIELD; }, \
|
sol::property([](const ActorControls& c) { return c.FIELD; }, \
|
||||||
|
@ -57,8 +58,8 @@ namespace MWLua
|
||||||
controls["use"] = CONTROL(int, mUse);
|
controls["use"] = CONTROL(int, mUse);
|
||||||
#undef CONTROL
|
#undef CONTROL
|
||||||
|
|
||||||
sol::usertype<SelfObject> selfAPI = context.mLua->sol().new_usertype<SelfObject>(
|
sol::usertype<SelfObject> selfAPI
|
||||||
"SelfObject", sol::base_classes, sol::bases<LObject, Object>());
|
= lua.new_usertype<SelfObject>("SelfObject", sol::base_classes, sol::bases<LObject, Object>());
|
||||||
selfAPI[sol::meta_function::to_string]
|
selfAPI[sol::meta_function::to_string]
|
||||||
= [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; };
|
= [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; };
|
||||||
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
|
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
|
||||||
|
@ -66,13 +67,13 @@ namespace MWLua
|
||||||
selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; };
|
selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; };
|
||||||
selfAPI["enableAI"] = [](SelfObject& self, bool v) { self.mControls.mDisableAI = !v; };
|
selfAPI["enableAI"] = [](SelfObject& self, bool v) { self.mControls.mDisableAI = !v; };
|
||||||
selfAPI["ATTACK_TYPE"]
|
selfAPI["ATTACK_TYPE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWMechanics::AttackType>(
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWMechanics::AttackType>(lua,
|
||||||
{ { "NoAttack", MWMechanics::AttackType::NoAttack }, { "Any", MWMechanics::AttackType::Any },
|
{ { "NoAttack", MWMechanics::AttackType::NoAttack }, { "Any", MWMechanics::AttackType::Any },
|
||||||
{ "Chop", MWMechanics::AttackType::Chop }, { "Slash", MWMechanics::AttackType::Slash },
|
{ "Chop", MWMechanics::AttackType::Chop }, { "Slash", MWMechanics::AttackType::Slash },
|
||||||
{ "Thrust", MWMechanics::AttackType::Thrust } }));
|
{ "Thrust", MWMechanics::AttackType::Thrust } }));
|
||||||
|
|
||||||
using AiPackage = MWMechanics::AiPackage;
|
using AiPackage = MWMechanics::AiPackage;
|
||||||
sol::usertype<AiPackage> aiPackage = context.mLua->sol().new_usertype<AiPackage>("AiPackage");
|
sol::usertype<AiPackage> aiPackage = lua.new_usertype<AiPackage>("AiPackage");
|
||||||
aiPackage["type"] = sol::readonly_property([](const AiPackage& p) -> std::string_view {
|
aiPackage["type"] = sol::readonly_property([](const AiPackage& p) -> std::string_view {
|
||||||
switch (p.getTypeId())
|
switch (p.getTypeId())
|
||||||
{
|
{
|
||||||
|
@ -113,23 +114,24 @@ namespace MWLua
|
||||||
aiPackage["destPosition"] = sol::readonly_property([](const AiPackage& p) { return p.getDestination(); });
|
aiPackage["destPosition"] = sol::readonly_property([](const AiPackage& p) { return p.getDestination(); });
|
||||||
aiPackage["distance"] = sol::readonly_property([](const AiPackage& p) { return p.getDistance(); });
|
aiPackage["distance"] = sol::readonly_property([](const AiPackage& p) { return p.getDistance(); });
|
||||||
aiPackage["duration"] = sol::readonly_property([](const AiPackage& p) { return p.getDuration(); });
|
aiPackage["duration"] = sol::readonly_property([](const AiPackage& p) { return p.getDuration(); });
|
||||||
aiPackage["idle"] = sol::readonly_property([context](const AiPackage& p) -> sol::optional<sol::table> {
|
aiPackage["idle"]
|
||||||
if (p.getTypeId() == MWMechanics::AiPackageTypeId::Wander)
|
= sol::readonly_property([](sol::this_state lua, const AiPackage& p) -> sol::optional<sol::table> {
|
||||||
{
|
if (p.getTypeId() == MWMechanics::AiPackageTypeId::Wander)
|
||||||
sol::table idles(context.mLua->sol(), sol::create);
|
{
|
||||||
const std::vector<unsigned char>& idle = static_cast<const MWMechanics::AiWander&>(p).getIdle();
|
sol::table idles(lua, sol::create);
|
||||||
if (!idle.empty())
|
const std::vector<unsigned char>& idle = static_cast<const MWMechanics::AiWander&>(p).getIdle();
|
||||||
{
|
if (!idle.empty())
|
||||||
for (size_t i = 0; i < idle.size(); ++i)
|
{
|
||||||
{
|
for (size_t i = 0; i < idle.size(); ++i)
|
||||||
std::string_view groupName = MWMechanics::AiWander::getIdleGroupName(i);
|
{
|
||||||
idles[groupName] = idle[i];
|
std::string_view groupName = MWMechanics::AiWander::getIdleGroupName(i);
|
||||||
}
|
idles[groupName] = idle[i];
|
||||||
return idles;
|
}
|
||||||
}
|
return idles;
|
||||||
}
|
}
|
||||||
return sol::nullopt;
|
}
|
||||||
});
|
return sol::nullopt;
|
||||||
|
});
|
||||||
|
|
||||||
aiPackage["isRepeat"] = sol::readonly_property([](const AiPackage& p) { return p.getRepeat(); });
|
aiPackage["isRepeat"] = sol::readonly_property([](const AiPackage& p) { return p.getRepeat(); });
|
||||||
|
|
||||||
|
@ -226,7 +228,8 @@ namespace MWLua
|
||||||
: LuaUtil::ScriptsContainer(lua, "L" + obj.id().toString())
|
: LuaUtil::ScriptsContainer(lua, "L" + obj.id().toString())
|
||||||
, mData(obj)
|
, mData(obj)
|
||||||
{
|
{
|
||||||
this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData));
|
lua->protectedCall(
|
||||||
|
[&](LuaUtil::LuaView& view) { addPackage("openmw.self", sol::make_object(view.sol(), &mData)); });
|
||||||
registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers,
|
registerEngineHandlers({ &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers,
|
||||||
&mOnTeleportedHandlers, &mOnAnimationTextKeyHandlers, &mOnPlayAnimationHandlers, &mOnSkillUse,
|
&mOnTeleportedHandlers, &mOnAnimationTextKeyHandlers, &mOnPlayAnimationHandlers, &mOnSkillUse,
|
||||||
&mOnSkillLevelUp });
|
&mOnSkillLevelUp });
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
std::map<std::string, sol::object> initCommonPackages(const Context& context)
|
std::map<std::string, sol::object> initCommonPackages(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view lua = context.mLua->sol();
|
sol::state_view lua = context.mLua->unsafeState();
|
||||||
MWWorld::DateTimeManager* tm = MWBase::Environment::get().getWorld()->getTimeManager();
|
MWWorld::DateTimeManager* tm = MWBase::Environment::get().getWorld()->getTimeManager();
|
||||||
return {
|
return {
|
||||||
{ "openmw.animation", initAnimationPackage(context) },
|
{ "openmw.animation", initAnimationPackage(context) },
|
||||||
|
@ -69,7 +69,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ "openmw.ambient", initAmbientPackage(context) },
|
{ "openmw.ambient", initAmbientPackage(context) },
|
||||||
{ "openmw.camera", initCameraPackage(context.mLua->sol()) },
|
{ "openmw.camera", initCameraPackage(context.sol()) },
|
||||||
{ "openmw.debug", initDebugPackage(context) },
|
{ "openmw.debug", initDebugPackage(context) },
|
||||||
{ "openmw.input", initInputPackage(context) },
|
{ "openmw.input", initInputPackage(context) },
|
||||||
{ "openmw.postprocessing", initPostprocessingPackage(context) },
|
{ "openmw.postprocessing", initPostprocessingPackage(context) },
|
||||||
|
|
|
@ -83,47 +83,49 @@ namespace MWLua
|
||||||
|
|
||||||
void LuaManager::init()
|
void LuaManager::init()
|
||||||
{
|
{
|
||||||
Context globalContext;
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
globalContext.mType = Context::Global;
|
Context globalContext;
|
||||||
globalContext.mLuaManager = this;
|
globalContext.mType = Context::Global;
|
||||||
globalContext.mLua = &mLua;
|
globalContext.mLuaManager = this;
|
||||||
globalContext.mObjectLists = &mObjectLists;
|
globalContext.mLua = &mLua;
|
||||||
globalContext.mLuaEvents = &mLuaEvents;
|
globalContext.mObjectLists = &mObjectLists;
|
||||||
globalContext.mSerializer = mGlobalSerializer.get();
|
globalContext.mLuaEvents = &mLuaEvents;
|
||||||
|
globalContext.mSerializer = mGlobalSerializer.get();
|
||||||
|
|
||||||
Context localContext = globalContext;
|
Context localContext = globalContext;
|
||||||
localContext.mType = Context::Local;
|
localContext.mType = Context::Local;
|
||||||
localContext.mSerializer = mLocalSerializer.get();
|
localContext.mSerializer = mLocalSerializer.get();
|
||||||
|
|
||||||
Context menuContext = globalContext;
|
Context menuContext = globalContext;
|
||||||
menuContext.mType = Context::Menu;
|
menuContext.mType = Context::Menu;
|
||||||
|
|
||||||
for (const auto& [name, package] : initCommonPackages(globalContext))
|
for (const auto& [name, package] : initCommonPackages(globalContext))
|
||||||
mLua.addCommonPackage(name, package);
|
mLua.addCommonPackage(name, package);
|
||||||
for (const auto& [name, package] : initGlobalPackages(globalContext))
|
for (const auto& [name, package] : initGlobalPackages(globalContext))
|
||||||
mGlobalScripts.addPackage(name, package);
|
mGlobalScripts.addPackage(name, package);
|
||||||
for (const auto& [name, package] : initMenuPackages(menuContext))
|
for (const auto& [name, package] : initMenuPackages(menuContext))
|
||||||
mMenuScripts.addPackage(name, package);
|
mMenuScripts.addPackage(name, package);
|
||||||
|
|
||||||
mLocalPackages = initLocalPackages(localContext);
|
mLocalPackages = initLocalPackages(localContext);
|
||||||
|
|
||||||
mPlayerPackages = initPlayerPackages(localContext);
|
mPlayerPackages = initPlayerPackages(localContext);
|
||||||
mPlayerPackages.insert(mLocalPackages.begin(), mLocalPackages.end());
|
mPlayerPackages.insert(mLocalPackages.begin(), mLocalPackages.end());
|
||||||
|
|
||||||
LuaUtil::LuaStorage::initLuaBindings(mLua.sol());
|
LuaUtil::LuaStorage::initLuaBindings(view);
|
||||||
mGlobalScripts.addPackage("openmw.storage", LuaUtil::LuaStorage::initGlobalPackage(mLua, &mGlobalStorage));
|
mGlobalScripts.addPackage("openmw.storage", LuaUtil::LuaStorage::initGlobalPackage(view, &mGlobalStorage));
|
||||||
mMenuScripts.addPackage(
|
mMenuScripts.addPackage(
|
||||||
"openmw.storage", LuaUtil::LuaStorage::initMenuPackage(mLua, &mGlobalStorage, &mPlayerStorage));
|
"openmw.storage", LuaUtil::LuaStorage::initMenuPackage(view, &mGlobalStorage, &mPlayerStorage));
|
||||||
mLocalPackages["openmw.storage"] = LuaUtil::LuaStorage::initLocalPackage(mLua, &mGlobalStorage);
|
mLocalPackages["openmw.storage"] = LuaUtil::LuaStorage::initLocalPackage(view, &mGlobalStorage);
|
||||||
mPlayerPackages["openmw.storage"]
|
mPlayerPackages["openmw.storage"]
|
||||||
= LuaUtil::LuaStorage::initPlayerPackage(mLua, &mGlobalStorage, &mPlayerStorage);
|
= LuaUtil::LuaStorage::initPlayerPackage(view, &mGlobalStorage, &mPlayerStorage);
|
||||||
|
|
||||||
mPlayerStorage.setActive(true);
|
mPlayerStorage.setActive(true);
|
||||||
mGlobalStorage.setActive(false);
|
mGlobalStorage.setActive(false);
|
||||||
|
|
||||||
initConfiguration();
|
initConfiguration();
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
mMenuScripts.addAutoStartedScripts();
|
mMenuScripts.addAutoStartedScripts();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::loadPermanentStorage(const std::filesystem::path& userConfigPath)
|
void LuaManager::loadPermanentStorage(const std::filesystem::path& userConfigPath)
|
||||||
|
@ -132,23 +134,28 @@ namespace MWLua
|
||||||
mGlobalStorage.setActive(true);
|
mGlobalStorage.setActive(true);
|
||||||
const auto globalPath = userConfigPath / "global_storage.bin";
|
const auto globalPath = userConfigPath / "global_storage.bin";
|
||||||
const auto playerPath = userConfigPath / "player_storage.bin";
|
const auto playerPath = userConfigPath / "player_storage.bin";
|
||||||
if (std::filesystem::exists(globalPath))
|
|
||||||
mGlobalStorage.load(globalPath);
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
if (std::filesystem::exists(playerPath))
|
if (std::filesystem::exists(globalPath))
|
||||||
mPlayerStorage.load(playerPath);
|
mGlobalStorage.load(view.sol(), globalPath);
|
||||||
|
if (std::filesystem::exists(playerPath))
|
||||||
|
mPlayerStorage.load(view.sol(), playerPath);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::savePermanentStorage(const std::filesystem::path& userConfigPath)
|
void LuaManager::savePermanentStorage(const std::filesystem::path& userConfigPath)
|
||||||
{
|
{
|
||||||
if (mGlobalScriptsStarted)
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
mGlobalStorage.save(userConfigPath / "global_storage.bin");
|
if (mGlobalScriptsStarted)
|
||||||
mPlayerStorage.save(userConfigPath / "player_storage.bin");
|
mGlobalStorage.save(view.sol(), userConfigPath / "global_storage.bin");
|
||||||
|
mPlayerStorage.save(view.sol(), userConfigPath / "player_storage.bin");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::update()
|
void LuaManager::update()
|
||||||
{
|
{
|
||||||
if (const int steps = Settings::lua().mGcStepsPerFrame; steps > 0)
|
if (const int steps = Settings::lua().mGcStepsPerFrame; steps > 0)
|
||||||
lua_gc(mLua.sol(), LUA_GCSTEP, steps);
|
lua_gc(mLua.unsafeState(), LUA_GCSTEP, steps);
|
||||||
|
|
||||||
if (mPlayer.isEmpty())
|
if (mPlayer.isEmpty())
|
||||||
return; // The game is not started yet.
|
return; // The game is not started yet.
|
||||||
|
@ -330,7 +337,7 @@ namespace MWLua
|
||||||
mInputActions.clear();
|
mInputActions.clear();
|
||||||
mInputTriggers.clear();
|
mInputTriggers.clear();
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
lua_gc(mLua.sol(), LUA_GCCOLLECT, 0);
|
lua_gc(mLua.unsafeState(), LUA_GCCOLLECT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::setupPlayer(const MWWorld::Ptr& ptr)
|
void LuaManager::setupPlayer(const MWWorld::Ptr& ptr)
|
||||||
|
@ -424,35 +431,37 @@ namespace MWLua
|
||||||
const MWRender::AnimPriority& priority, int blendMask, bool autodisable, float speedmult,
|
const MWRender::AnimPriority& priority, int blendMask, bool autodisable, float speedmult,
|
||||||
std::string_view start, std::string_view stop, float startpoint, uint32_t loops, bool loopfallback)
|
std::string_view start, std::string_view stop, float startpoint, uint32_t loops, bool loopfallback)
|
||||||
{
|
{
|
||||||
sol::table options = mLua.newTable();
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
options["blendMask"] = blendMask;
|
sol::table options = view.newTable();
|
||||||
options["autoDisable"] = autodisable;
|
options["blendMask"] = blendMask;
|
||||||
options["speed"] = speedmult;
|
options["autoDisable"] = autodisable;
|
||||||
options["startKey"] = start;
|
options["speed"] = speedmult;
|
||||||
options["stopKey"] = stop;
|
options["startKey"] = start;
|
||||||
options["startPoint"] = startpoint;
|
options["stopKey"] = stop;
|
||||||
options["loops"] = loops;
|
options["startPoint"] = startpoint;
|
||||||
options["forceLoop"] = loopfallback;
|
options["loops"] = loops;
|
||||||
|
options["forceLoop"] = loopfallback;
|
||||||
|
|
||||||
bool priorityAsTable = false;
|
bool priorityAsTable = false;
|
||||||
for (uint32_t i = 1; i < MWRender::sNumBlendMasks; i++)
|
for (uint32_t i = 1; i < MWRender::sNumBlendMasks; i++)
|
||||||
if (priority[static_cast<MWRender::BoneGroup>(i)] != priority[static_cast<MWRender::BoneGroup>(0)])
|
if (priority[static_cast<MWRender::BoneGroup>(i)] != priority[static_cast<MWRender::BoneGroup>(0)])
|
||||||
priorityAsTable = true;
|
priorityAsTable = true;
|
||||||
if (priorityAsTable)
|
if (priorityAsTable)
|
||||||
{
|
{
|
||||||
sol::table priorityTable = mLua.newTable();
|
sol::table priorityTable = view.newTable();
|
||||||
for (uint32_t i = 0; i < MWRender::sNumBlendMasks; i++)
|
for (uint32_t i = 0; i < MWRender::sNumBlendMasks; i++)
|
||||||
priorityTable[static_cast<MWRender::BoneGroup>(i)] = priority[static_cast<MWRender::BoneGroup>(i)];
|
priorityTable[static_cast<MWRender::BoneGroup>(i)] = priority[static_cast<MWRender::BoneGroup>(i)];
|
||||||
options["priority"] = priorityTable;
|
options["priority"] = priorityTable;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
options["priority"] = priority[MWRender::BoneGroup_LowerBody];
|
options["priority"] = priority[MWRender::BoneGroup_LowerBody];
|
||||||
|
|
||||||
// mEngineEvents.addToQueue(event);
|
// mEngineEvents.addToQueue(event);
|
||||||
// Has to be called immediately, otherwise engine details that depend on animations playing immediately
|
// Has to be called immediately, otherwise engine details that depend on animations playing immediately
|
||||||
// break.
|
// break.
|
||||||
if (auto* scripts = actor.getRefData().getLuaScripts())
|
if (auto* scripts = actor.getRefData().getLuaScripts())
|
||||||
scripts->onPlayAnimation(groupname, options);
|
scripts->onPlayAnimation(groupname, options);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::skillUse(const MWWorld::Ptr& actor, ESM::RefId skillId, int useType, float scale)
|
void LuaManager::skillUse(const MWWorld::Ptr& actor, ESM::RefId skillId, int useType, float scale)
|
||||||
|
@ -593,7 +602,9 @@ namespace MWLua
|
||||||
|
|
||||||
ESM::LuaScripts globalScripts;
|
ESM::LuaScripts globalScripts;
|
||||||
globalScripts.load(reader);
|
globalScripts.load(reader);
|
||||||
mLuaEvents.load(mLua.sol(), reader, mContentFileMapping, mGlobalLoader.get());
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
|
mLuaEvents.load(view.sol(), reader, mContentFileMapping, mGlobalLoader.get());
|
||||||
|
});
|
||||||
|
|
||||||
mGlobalScripts.setSavedDataDeserializer(mGlobalLoader.get());
|
mGlobalScripts.setSavedDataDeserializer(mGlobalLoader.get());
|
||||||
mGlobalScripts.load(globalScripts);
|
mGlobalScripts.load(globalScripts);
|
||||||
|
@ -696,7 +707,9 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::object selected = sol::nil;
|
sol::object selected = sol::nil;
|
||||||
if (!selectedPtr.isEmpty())
|
if (!selectedPtr.isEmpty())
|
||||||
selected = sol::make_object(mLua.sol(), LObject(getId(selectedPtr)));
|
mLua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
|
selected = sol::make_object(view.sol(), LObject(getId(selectedPtr)));
|
||||||
|
});
|
||||||
if (playerScripts->consoleCommand(consoleMode, command, selected))
|
if (playerScripts->consoleCommand(consoleMode, command, selected))
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,8 +150,9 @@ namespace MWLua
|
||||||
template <class Arg>
|
template <class Arg>
|
||||||
std::function<void(Arg)> wrapLuaCallback(const LuaUtil::Callback& c)
|
std::function<void(Arg)> wrapLuaCallback(const LuaUtil::Callback& c)
|
||||||
{
|
{
|
||||||
return
|
return [this, c](Arg arg) {
|
||||||
[this, c](Arg arg) { this->queueCallback(c, sol::main_object(this->mLua.sol(), sol::in_place, arg)); };
|
this->queueCallback(c, sol::main_object(this->mLua.unsafeState(), sol::in_place, arg));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaUi::ResourceManager* uiResourceManager() { return &mUiResourceManager; }
|
LuaUi::ResourceManager* uiResourceManager() { return &mUiResourceManager; }
|
||||||
|
@ -227,8 +228,8 @@ namespace MWLua
|
||||||
std::vector<std::pair<std::string, Misc::Color>> mInGameConsoleMessages;
|
std::vector<std::pair<std::string, Misc::Color>> mInGameConsoleMessages;
|
||||||
std::optional<ObjectId> mDelayedUiModeChangedArg;
|
std::optional<ObjectId> mDelayedUiModeChangedArg;
|
||||||
|
|
||||||
LuaUtil::LuaStorage mGlobalStorage{ mLua.sol() };
|
LuaUtil::LuaStorage mGlobalStorage;
|
||||||
LuaUtil::LuaStorage mPlayerStorage{ mLua.sol() };
|
LuaUtil::LuaStorage mPlayerStorage;
|
||||||
|
|
||||||
LuaUtil::InputAction::Registry mInputActions;
|
LuaUtil::InputAction::Registry mInputActions;
|
||||||
LuaUtil::InputTrigger::Registry mInputTriggers;
|
LuaUtil::InputTrigger::Registry mInputTriggers;
|
||||||
|
|
|
@ -214,33 +214,36 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initCoreMagicBindings(const Context& context)
|
sol::table initCoreMagicBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table magicApi(lua, sol::create);
|
sol::table magicApi(lua, sol::create);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
magicApi["RANGE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, ESM::RangeType>({
|
magicApi["RANGE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, ESM::RangeType>(lua,
|
||||||
{ "Self", ESM::RT_Self },
|
{
|
||||||
{ "Touch", ESM::RT_Touch },
|
{ "Self", ESM::RT_Self },
|
||||||
{ "Target", ESM::RT_Target },
|
{ "Touch", ESM::RT_Touch },
|
||||||
}));
|
{ "Target", ESM::RT_Target },
|
||||||
|
}));
|
||||||
magicApi["SPELL_TYPE"]
|
magicApi["SPELL_TYPE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, ESM::Spell::SpellType>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, ESM::Spell::SpellType>(lua,
|
||||||
{ "Spell", ESM::Spell::ST_Spell },
|
{
|
||||||
{ "Ability", ESM::Spell::ST_Ability },
|
{ "Spell", ESM::Spell::ST_Spell },
|
||||||
{ "Blight", ESM::Spell::ST_Blight },
|
{ "Ability", ESM::Spell::ST_Ability },
|
||||||
{ "Disease", ESM::Spell::ST_Disease },
|
{ "Blight", ESM::Spell::ST_Blight },
|
||||||
{ "Curse", ESM::Spell::ST_Curse },
|
{ "Disease", ESM::Spell::ST_Disease },
|
||||||
{ "Power", ESM::Spell::ST_Power },
|
{ "Curse", ESM::Spell::ST_Curse },
|
||||||
}));
|
{ "Power", ESM::Spell::ST_Power },
|
||||||
|
}));
|
||||||
magicApi["ENCHANTMENT_TYPE"]
|
magicApi["ENCHANTMENT_TYPE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, ESM::Enchantment::Type>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, ESM::Enchantment::Type>(lua,
|
||||||
{ "CastOnce", ESM::Enchantment::Type::CastOnce },
|
{
|
||||||
{ "CastOnStrike", ESM::Enchantment::Type::WhenStrikes },
|
{ "CastOnce", ESM::Enchantment::Type::CastOnce },
|
||||||
{ "CastOnUse", ESM::Enchantment::Type::WhenUsed },
|
{ "CastOnStrike", ESM::Enchantment::Type::WhenStrikes },
|
||||||
{ "ConstantEffect", ESM::Enchantment::Type::ConstantEffect },
|
{ "CastOnUse", ESM::Enchantment::Type::WhenUsed },
|
||||||
}));
|
{ "ConstantEffect", ESM::Enchantment::Type::ConstantEffect },
|
||||||
|
}));
|
||||||
|
|
||||||
sol::table effect(context.mLua->sol(), sol::create);
|
sol::table effect(lua, sol::create);
|
||||||
magicApi["EFFECT_TYPE"] = LuaUtil::makeStrictReadOnly(effect);
|
magicApi["EFFECT_TYPE"] = LuaUtil::makeStrictReadOnly(effect);
|
||||||
for (const auto& name : ESM::MagicEffect::sIndexNames)
|
for (const auto& name : ESM::MagicEffect::sIndexNames)
|
||||||
{
|
{
|
||||||
|
@ -369,7 +372,7 @@ namespace MWLua
|
||||||
= sol::readonly_property([](const ESM::IndexedENAMstruct& params) -> int { return params.mIndex; });
|
= sol::readonly_property([](const ESM::IndexedENAMstruct& params) -> int { return params.mIndex; });
|
||||||
|
|
||||||
// MagicEffect record
|
// MagicEffect record
|
||||||
auto magicEffectT = context.mLua->sol().new_usertype<ESM::MagicEffect>("ESM3_MagicEffect");
|
auto magicEffectT = lua.new_usertype<ESM::MagicEffect>("ESM3_MagicEffect");
|
||||||
|
|
||||||
magicEffectT[sol::meta_function::to_string] = [](const ESM::MagicEffect& rec) {
|
magicEffectT[sol::meta_function::to_string] = [](const ESM::MagicEffect& rec) {
|
||||||
return "ESM3_MagicEffect[" + ESM::MagicEffect::indexToGmstString(rec.mIndex) + "]";
|
return "ESM3_MagicEffect[" + ESM::MagicEffect::indexToGmstString(rec.mIndex) + "]";
|
||||||
|
@ -437,7 +440,7 @@ namespace MWLua
|
||||||
// magicEffectT["projectileSpeed"]
|
// magicEffectT["projectileSpeed"]
|
||||||
// = sol::readonly_property([](const ESM::MagicEffect& rec) -> float { return rec.mData.mSpeed; });
|
// = sol::readonly_property([](const ESM::MagicEffect& rec) -> float { return rec.mData.mSpeed; });
|
||||||
|
|
||||||
auto activeSpellEffectT = context.mLua->sol().new_usertype<ESM::ActiveEffect>("ActiveSpellEffect");
|
auto activeSpellEffectT = lua.new_usertype<ESM::ActiveEffect>("ActiveSpellEffect");
|
||||||
activeSpellEffectT[sol::meta_function::to_string] = [](const ESM::ActiveEffect& effect) {
|
activeSpellEffectT[sol::meta_function::to_string] = [](const ESM::ActiveEffect& effect) {
|
||||||
return "ActiveSpellEffect[" + ESM::MagicEffect::indexToGmstString(effect.mEffectId) + "]";
|
return "ActiveSpellEffect[" + ESM::MagicEffect::indexToGmstString(effect.mEffectId) + "]";
|
||||||
};
|
};
|
||||||
|
@ -508,7 +511,7 @@ namespace MWLua
|
||||||
return effect.mDuration;
|
return effect.mDuration;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto activeSpellT = context.mLua->sol().new_usertype<ActiveSpell>("ActiveSpellParams");
|
auto activeSpellT = lua.new_usertype<ActiveSpell>("ActiveSpellParams");
|
||||||
activeSpellT[sol::meta_function::to_string] = [](const ActiveSpell& activeSpell) {
|
activeSpellT[sol::meta_function::to_string] = [](const ActiveSpell& activeSpell) {
|
||||||
return "ActiveSpellParams[" + activeSpell.mParams.getSourceSpellId().serializeText() + "]";
|
return "ActiveSpellParams[" + activeSpell.mParams.getSourceSpellId().serializeText() + "]";
|
||||||
};
|
};
|
||||||
|
@ -569,7 +572,7 @@ namespace MWLua
|
||||||
return activeSpell.mParams.getActiveSpellId().serializeText();
|
return activeSpell.mParams.getActiveSpellId().serializeText();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto activeEffectT = context.mLua->sol().new_usertype<ActiveEffect>("ActiveEffect");
|
auto activeEffectT = lua.new_usertype<ActiveEffect>("ActiveEffect");
|
||||||
|
|
||||||
activeEffectT[sol::meta_function::to_string] = [](const ActiveEffect& effect) {
|
activeEffectT[sol::meta_function::to_string] = [](const ActiveEffect& effect) {
|
||||||
return "ActiveEffect[" + ESM::MagicEffect::indexToGmstString(effect.key.mId) + "]";
|
return "ActiveEffect[" + ESM::MagicEffect::indexToGmstString(effect.key.mId) + "]";
|
||||||
|
@ -680,23 +683,24 @@ namespace MWLua
|
||||||
|
|
||||||
void addActorMagicBindings(sol::table& actor, const Context& context)
|
void addActorMagicBindings(sol::table& actor, const Context& context)
|
||||||
{
|
{
|
||||||
|
auto lua = context.sol();
|
||||||
const MWWorld::Store<ESM::Spell>* spellStore
|
const MWWorld::Store<ESM::Spell>* spellStore
|
||||||
= &MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>();
|
= &MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>();
|
||||||
|
|
||||||
// types.Actor.spells(o)
|
// types.Actor.spells(o)
|
||||||
actor["spells"] = [](const sol::object& actor) { return ActorSpells{ actor }; };
|
actor["spells"] = [](const sol::object& actor) { return ActorSpells{ actor }; };
|
||||||
auto spellsT = context.mLua->sol().new_usertype<ActorSpells>("ActorSpells");
|
auto spellsT = lua.new_usertype<ActorSpells>("ActorSpells");
|
||||||
spellsT[sol::meta_function::to_string]
|
spellsT[sol::meta_function::to_string]
|
||||||
= [](const ActorSpells& spells) { return "ActorSpells[" + spells.mActor.object().toString() + "]"; };
|
= [](const ActorSpells& spells) { return "ActorSpells[" + spells.mActor.object().toString() + "]"; };
|
||||||
|
|
||||||
actor["activeSpells"] = [](const sol::object& actor) { return ActorActiveSpells{ actor }; };
|
actor["activeSpells"] = [](const sol::object& actor) { return ActorActiveSpells{ actor }; };
|
||||||
auto activeSpellsT = context.mLua->sol().new_usertype<ActorActiveSpells>("ActorActiveSpells");
|
auto activeSpellsT = lua.new_usertype<ActorActiveSpells>("ActorActiveSpells");
|
||||||
activeSpellsT[sol::meta_function::to_string] = [](const ActorActiveSpells& spells) {
|
activeSpellsT[sol::meta_function::to_string] = [](const ActorActiveSpells& spells) {
|
||||||
return "ActorActiveSpells[" + spells.mActor.object().toString() + "]";
|
return "ActorActiveSpells[" + spells.mActor.object().toString() + "]";
|
||||||
};
|
};
|
||||||
|
|
||||||
actor["activeEffects"] = [](const sol::object& actor) { return ActorActiveEffects{ actor }; };
|
actor["activeEffects"] = [](const sol::object& actor) { return ActorActiveEffects{ actor }; };
|
||||||
auto activeEffectsT = context.mLua->sol().new_usertype<ActorActiveEffects>("ActorActiveEffects");
|
auto activeEffectsT = lua.new_usertype<ActorActiveEffects>("ActorActiveEffects");
|
||||||
activeEffectsT[sol::meta_function::to_string] = [](const ActorActiveEffects& effects) {
|
activeEffectsT[sol::meta_function::to_string] = [](const ActorActiveEffects& effects) {
|
||||||
return "ActorActiveEffects[" + effects.mActor.object().toString() + "]";
|
return "ActorActiveEffects[" + effects.mActor.object().toString() + "]";
|
||||||
};
|
};
|
||||||
|
@ -798,10 +802,10 @@ namespace MWLua
|
||||||
});
|
});
|
||||||
|
|
||||||
// pairs(types.Actor.spells(o))
|
// pairs(types.Actor.spells(o))
|
||||||
spellsT[sol::meta_function::pairs] = context.mLua->sol()["ipairsForArray"].template get<sol::function>();
|
spellsT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
|
|
||||||
// ipairs(types.Actor.spells(o))
|
// ipairs(types.Actor.spells(o))
|
||||||
spellsT[sol::meta_function::ipairs] = context.mLua->sol()["ipairsForArray"].template get<sol::function>();
|
spellsT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
|
|
||||||
// types.Actor.spells(o):add(id)
|
// types.Actor.spells(o):add(id)
|
||||||
spellsT["add"] = [context](const ActorSpells& spells, const sol::object& spellOrId) {
|
spellsT["add"] = [context](const ActorSpells& spells, const sol::object& spellOrId) {
|
||||||
|
|
|
@ -14,17 +14,17 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initMarkupPackage(const Context& context)
|
sol::table initMarkupPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::state_view lua = context.sol();
|
||||||
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
api["loadYaml"] = [lua = context.mLua, vfs](std::string_view fileName) {
|
api["loadYaml"] = [lua, vfs](std::string_view fileName) {
|
||||||
Files::IStreamPtr file = vfs->get(VFS::Path::Normalized(fileName));
|
Files::IStreamPtr file = vfs->get(VFS::Path::Normalized(fileName));
|
||||||
return LuaUtil::loadYaml(*file, lua->sol());
|
return LuaUtil::loadYaml(*file, lua);
|
||||||
};
|
|
||||||
api["decodeYaml"] = [lua = context.mLua](std::string_view inputData) {
|
|
||||||
return LuaUtil::loadYaml(std::string(inputData), lua->sol());
|
|
||||||
};
|
};
|
||||||
|
api["decodeYaml"]
|
||||||
|
= [lua](std::string_view inputData) { return LuaUtil::loadYaml(std::string(inputData), lua); };
|
||||||
|
|
||||||
return LuaUtil::makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,16 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initMenuPackage(const Context& context)
|
sol::table initMenuPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table api(lua, sol::create);
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
api["STATE"]
|
api["STATE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWBase::StateManager::State>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWBase::StateManager::State>(lua,
|
||||||
{ "NoGame", MWBase::StateManager::State_NoGame },
|
{
|
||||||
{ "Running", MWBase::StateManager::State_Running },
|
{ "NoGame", MWBase::StateManager::State_NoGame },
|
||||||
{ "Ended", MWBase::StateManager::State_Ended },
|
{ "Running", MWBase::StateManager::State_Running },
|
||||||
}));
|
{ "Ended", MWBase::StateManager::State_Ended },
|
||||||
|
}));
|
||||||
|
|
||||||
api["getState"] = []() -> int { return MWBase::Environment::get().getStateManager()->getState(); };
|
api["getState"] = []() -> int { return MWBase::Environment::get().getStateManager()->getState(); };
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,8 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initMWScriptBindings(const Context& context)
|
sol::table initMWScriptBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::state_view lua = lua;
|
||||||
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
api["getGlobalScript"]
|
api["getGlobalScript"]
|
||||||
= [](std::string_view recordId, sol::optional<GObject> player) -> sol::optional<MWScriptRef> {
|
= [](std::string_view recordId, sol::optional<GObject> player) -> sol::optional<MWScriptRef> {
|
||||||
|
@ -121,10 +122,8 @@ namespace MWLua
|
||||||
// api["getGlobalScripts"] = [](std::string_view recordId) -> list of scripts
|
// api["getGlobalScripts"] = [](std::string_view recordId) -> list of scripts
|
||||||
// api["getLocalScripts"] = [](const GObject& obj) -> list of scripts
|
// api["getLocalScripts"] = [](const GObject& obj) -> list of scripts
|
||||||
|
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::usertype<MWScriptRef> mwscript = lua.new_usertype<MWScriptRef>("MWScript");
|
||||||
sol::usertype<MWScriptRef> mwscript = context.mLua->sol().new_usertype<MWScriptRef>("MWScript");
|
sol::usertype<MWScriptVariables> mwscriptVars = lua.new_usertype<MWScriptVariables>("MWScriptVariables");
|
||||||
sol::usertype<MWScriptVariables> mwscriptVars
|
|
||||||
= context.mLua->sol().new_usertype<MWScriptVariables>("MWScriptVariables");
|
|
||||||
mwscript[sol::meta_function::to_string]
|
mwscript[sol::meta_function::to_string]
|
||||||
= [](const MWScriptRef& s) { return std::string("MWScript{") + s.mId.toDebugString() + "}"; };
|
= [](const MWScriptRef& s) { return std::string("MWScript{") + s.mId.toDebugString() + "}"; };
|
||||||
mwscript["isRunning"] = sol::readonly_property([](const MWScriptRef& s) { return s.isRunning(); });
|
mwscript["isRunning"] = sol::readonly_property([](const MWScriptRef& s) { return s.isRunning(); });
|
||||||
|
|
|
@ -53,11 +53,12 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initNearbyPackage(const Context& context)
|
sol::table initNearbyPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::state_view lua = context.sol();
|
||||||
|
sol::table api(lua, sol::create);
|
||||||
ObjectLists* objectLists = context.mObjectLists;
|
ObjectLists* objectLists = context.mObjectLists;
|
||||||
|
|
||||||
sol::usertype<MWPhysics::RayCastingResult> rayResult
|
sol::usertype<MWPhysics::RayCastingResult> rayResult
|
||||||
= context.mLua->sol().new_usertype<MWPhysics::RayCastingResult>("RayCastingResult");
|
= lua.new_usertype<MWPhysics::RayCastingResult>("RayCastingResult");
|
||||||
rayResult["hit"] = sol::readonly_property([](const MWPhysics::RayCastingResult& r) { return r.mHit; });
|
rayResult["hit"] = sol::readonly_property([](const MWPhysics::RayCastingResult& r) { return r.mHit; });
|
||||||
rayResult["hitPos"]
|
rayResult["hitPos"]
|
||||||
= sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional<osg::Vec3f> {
|
= sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional<osg::Vec3f> {
|
||||||
|
@ -82,18 +83,19 @@ namespace MWLua
|
||||||
});
|
});
|
||||||
|
|
||||||
api["COLLISION_TYPE"]
|
api["COLLISION_TYPE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWPhysics::CollisionType>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWPhysics::CollisionType>(lua,
|
||||||
{ "World", MWPhysics::CollisionType_World },
|
{
|
||||||
{ "Door", MWPhysics::CollisionType_Door },
|
{ "World", MWPhysics::CollisionType_World },
|
||||||
{ "Actor", MWPhysics::CollisionType_Actor },
|
{ "Door", MWPhysics::CollisionType_Door },
|
||||||
{ "HeightMap", MWPhysics::CollisionType_HeightMap },
|
{ "Actor", MWPhysics::CollisionType_Actor },
|
||||||
{ "Projectile", MWPhysics::CollisionType_Projectile },
|
{ "HeightMap", MWPhysics::CollisionType_HeightMap },
|
||||||
{ "Water", MWPhysics::CollisionType_Water },
|
{ "Projectile", MWPhysics::CollisionType_Projectile },
|
||||||
{ "Default", MWPhysics::CollisionType_Default },
|
{ "Water", MWPhysics::CollisionType_Water },
|
||||||
{ "AnyPhysical", MWPhysics::CollisionType_AnyPhysical },
|
{ "Default", MWPhysics::CollisionType_Default },
|
||||||
{ "Camera", MWPhysics::CollisionType_CameraOnly },
|
{ "AnyPhysical", MWPhysics::CollisionType_AnyPhysical },
|
||||||
{ "VisualOnly", MWPhysics::CollisionType_VisualOnly },
|
{ "Camera", MWPhysics::CollisionType_CameraOnly },
|
||||||
}));
|
{ "VisualOnly", MWPhysics::CollisionType_VisualOnly },
|
||||||
|
}));
|
||||||
|
|
||||||
api["castRay"] = [](const osg::Vec3f& from, const osg::Vec3f& to, sol::optional<sol::table> options) {
|
api["castRay"] = [](const osg::Vec3f& from, const osg::Vec3f& to, sol::optional<sol::table> options) {
|
||||||
std::vector<MWWorld::ConstPtr> ignore;
|
std::vector<MWWorld::ConstPtr> ignore;
|
||||||
|
@ -163,12 +165,13 @@ namespace MWLua
|
||||||
ignore = parseIgnoreList(*options);
|
ignore = parseIgnoreList(*options);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.mLuaManager->addAction([context, ignore = std::move(ignore),
|
context.mLuaManager->addAction(
|
||||||
callback = LuaUtil::Callback::fromLua(callback), from, to] {
|
[context, ignore = std::move(ignore), callback = LuaUtil::Callback::fromLua(callback), from, to] {
|
||||||
MWPhysics::RayCastingResult res;
|
MWPhysics::RayCastingResult res;
|
||||||
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false, ignore);
|
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false, ignore);
|
||||||
context.mLuaManager->queueCallback(callback, sol::main_object(context.mLua->sol(), sol::in_place, res));
|
context.mLuaManager->queueCallback(
|
||||||
});
|
callback, sol::main_object(context.mLua->unsafeState(), sol::in_place, res));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
api["getObjectByFormId"] = [](std::string_view formIdStr) -> LObject {
|
api["getObjectByFormId"] = [](std::string_view formIdStr) -> LObject {
|
||||||
|
@ -186,32 +189,35 @@ namespace MWLua
|
||||||
api["players"] = LObjectList{ objectLists->getPlayers() };
|
api["players"] = LObjectList{ objectLists->getPlayers() };
|
||||||
|
|
||||||
api["NAVIGATOR_FLAGS"]
|
api["NAVIGATOR_FLAGS"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, DetourNavigator::Flag>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, DetourNavigator::Flag>(lua,
|
||||||
{ "Walk", DetourNavigator::Flag_walk },
|
{
|
||||||
{ "Swim", DetourNavigator::Flag_swim },
|
{ "Walk", DetourNavigator::Flag_walk },
|
||||||
{ "OpenDoor", DetourNavigator::Flag_openDoor },
|
{ "Swim", DetourNavigator::Flag_swim },
|
||||||
{ "UsePathgrid", DetourNavigator::Flag_usePathgrid },
|
{ "OpenDoor", DetourNavigator::Flag_openDoor },
|
||||||
}));
|
{ "UsePathgrid", DetourNavigator::Flag_usePathgrid },
|
||||||
|
}));
|
||||||
|
|
||||||
api["COLLISION_SHAPE_TYPE"] = LuaUtil::makeStrictReadOnly(
|
api["COLLISION_SHAPE_TYPE"] = LuaUtil::makeStrictReadOnly(
|
||||||
context.mLua->tableFromPairs<std::string_view, DetourNavigator::CollisionShapeType>({
|
LuaUtil::tableFromPairs<std::string_view, DetourNavigator::CollisionShapeType>(lua,
|
||||||
{ "Aabb", DetourNavigator::CollisionShapeType::Aabb },
|
{
|
||||||
{ "RotatingBox", DetourNavigator::CollisionShapeType::RotatingBox },
|
{ "Aabb", DetourNavigator::CollisionShapeType::Aabb },
|
||||||
{ "Cylinder", DetourNavigator::CollisionShapeType::Cylinder },
|
{ "RotatingBox", DetourNavigator::CollisionShapeType::RotatingBox },
|
||||||
}));
|
{ "Cylinder", DetourNavigator::CollisionShapeType::Cylinder },
|
||||||
|
}));
|
||||||
|
|
||||||
api["FIND_PATH_STATUS"]
|
api["FIND_PATH_STATUS"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, DetourNavigator::Status>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, DetourNavigator::Status>(lua,
|
||||||
{ "Success", DetourNavigator::Status::Success },
|
{
|
||||||
{ "PartialPath", DetourNavigator::Status::PartialPath },
|
{ "Success", DetourNavigator::Status::Success },
|
||||||
{ "NavMeshNotFound", DetourNavigator::Status::NavMeshNotFound },
|
{ "PartialPath", DetourNavigator::Status::PartialPath },
|
||||||
{ "StartPolygonNotFound", DetourNavigator::Status::StartPolygonNotFound },
|
{ "NavMeshNotFound", DetourNavigator::Status::NavMeshNotFound },
|
||||||
{ "EndPolygonNotFound", DetourNavigator::Status::EndPolygonNotFound },
|
{ "StartPolygonNotFound", DetourNavigator::Status::StartPolygonNotFound },
|
||||||
{ "MoveAlongSurfaceFailed", DetourNavigator::Status::MoveAlongSurfaceFailed },
|
{ "EndPolygonNotFound", DetourNavigator::Status::EndPolygonNotFound },
|
||||||
{ "FindPathOverPolygonsFailed", DetourNavigator::Status::FindPathOverPolygonsFailed },
|
{ "MoveAlongSurfaceFailed", DetourNavigator::Status::MoveAlongSurfaceFailed },
|
||||||
{ "InitNavMeshQueryFailed", DetourNavigator::Status::InitNavMeshQueryFailed },
|
{ "FindPathOverPolygonsFailed", DetourNavigator::Status::FindPathOverPolygonsFailed },
|
||||||
{ "FindStraightPathFailed", DetourNavigator::Status::FindStraightPathFailed },
|
{ "InitNavMeshQueryFailed", DetourNavigator::Status::InitNavMeshQueryFailed },
|
||||||
}));
|
{ "FindStraightPathFailed", DetourNavigator::Status::FindStraightPathFailed },
|
||||||
|
}));
|
||||||
|
|
||||||
static const DetourNavigator::AgentBounds defaultAgentBounds{
|
static const DetourNavigator::AgentBounds defaultAgentBounds{
|
||||||
Settings::game().mActorCollisionShapeType,
|
Settings::game().mActorCollisionShapeType,
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace MWLua
|
||||||
void registerObjectList(const std::string& prefix, const Context& context)
|
void registerObjectList(const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
using ListT = ObjectList<ObjectT>;
|
using ListT = ObjectList<ObjectT>;
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::usertype<ListT> listT = lua.new_usertype<ListT>(prefix + "ObjectList");
|
sol::usertype<ListT> listT = lua.new_usertype<ListT>(prefix + "ObjectList");
|
||||||
listT[sol::meta_function::to_string]
|
listT[sol::meta_function::to_string]
|
||||||
= [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; };
|
= [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; };
|
||||||
|
@ -205,7 +205,7 @@ namespace MWLua
|
||||||
void addOwnerbindings(sol::usertype<ObjectT>& objectT, const std::string& prefix, const Context& context)
|
void addOwnerbindings(sol::usertype<ObjectT>& objectT, const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
using OwnerT = Owner<ObjectT>;
|
using OwnerT = Owner<ObjectT>;
|
||||||
sol::usertype<OwnerT> ownerT = context.mLua->sol().new_usertype<OwnerT>(prefix + "Owner");
|
sol::usertype<OwnerT> ownerT = context.sol().new_usertype<OwnerT>(prefix + "Owner");
|
||||||
|
|
||||||
ownerT[sol::meta_function::to_string] = [](const OwnerT& o) { return "Owner[" + o.mObj.toString() + "]"; };
|
ownerT[sol::meta_function::to_string] = [](const OwnerT& o) { return "Owner[" + o.mObj.toString() + "]"; };
|
||||||
|
|
||||||
|
@ -329,9 +329,10 @@ namespace MWLua
|
||||||
return LuaUtil::Box{ bb.center(), bb._max - bb.center() };
|
return LuaUtil::Box{ bb.center(), bb._max - bb.center() };
|
||||||
};
|
};
|
||||||
|
|
||||||
objectT["type"] = sol::readonly_property(
|
objectT["type"]
|
||||||
[types = getTypeToPackageTable(context.mLua->sol())](
|
= sol::readonly_property([types = getTypeToPackageTable(context.sol())](const ObjectT& o) mutable {
|
||||||
const ObjectT& o) mutable { return types[getLiveCellRefType(o.ptr().mRef)]; });
|
return types[getLiveCellRefType(o.ptr().mRef)];
|
||||||
|
});
|
||||||
|
|
||||||
objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getCellRef().getCount(); });
|
objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getCellRef().getCount(); });
|
||||||
objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); };
|
objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); };
|
||||||
|
@ -553,12 +554,12 @@ namespace MWLua
|
||||||
void addInventoryBindings(sol::usertype<ObjectT>& objectT, const std::string& prefix, const Context& context)
|
void addInventoryBindings(sol::usertype<ObjectT>& objectT, const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
using InventoryT = Inventory<ObjectT>;
|
using InventoryT = Inventory<ObjectT>;
|
||||||
sol::usertype<InventoryT> inventoryT = context.mLua->sol().new_usertype<InventoryT>(prefix + "Inventory");
|
sol::usertype<InventoryT> inventoryT = context.sol().new_usertype<InventoryT>(prefix + "Inventory");
|
||||||
|
|
||||||
inventoryT[sol::meta_function::to_string]
|
inventoryT[sol::meta_function::to_string]
|
||||||
= [](const InventoryT& inv) { return "Inventory[" + inv.mObj.toString() + "]"; };
|
= [](const InventoryT& inv) { return "Inventory[" + inv.mObj.toString() + "]"; };
|
||||||
|
|
||||||
inventoryT["getAll"] = [ids = getPackageToTypeTable(context.mLua->sol())](
|
inventoryT["getAll"] = [ids = getPackageToTypeTable(context.mLua->unsafeState())](
|
||||||
const InventoryT& inventory, sol::optional<sol::table> type) {
|
const InventoryT& inventory, sol::optional<sol::table> type) {
|
||||||
int mask = -1;
|
int mask = -1;
|
||||||
sol::optional<uint32_t> typeId = sol::nullopt;
|
sol::optional<uint32_t> typeId = sol::nullopt;
|
||||||
|
@ -681,7 +682,7 @@ namespace MWLua
|
||||||
void initObjectBindings(const std::string& prefix, const Context& context)
|
void initObjectBindings(const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
sol::usertype<ObjectT> objectT
|
sol::usertype<ObjectT> objectT
|
||||||
= context.mLua->sol().new_usertype<ObjectT>(prefix + "Object", sol::base_classes, sol::bases<Object>());
|
= context.sol().new_usertype<ObjectT>(prefix + "Object", sol::base_classes, sol::bases<Object>());
|
||||||
addBasicBindings<ObjectT>(objectT, context);
|
addBasicBindings<ObjectT>(objectT, context);
|
||||||
addInventoryBindings<ObjectT>(objectT, prefix, context);
|
addInventoryBindings<ObjectT>(objectT, prefix, context);
|
||||||
addOwnerbindings<ObjectT>(objectT, prefix, context);
|
addOwnerbindings<ObjectT>(objectT, prefix, context);
|
||||||
|
|
|
@ -96,9 +96,10 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initPostprocessingPackage(const Context& context)
|
sol::table initPostprocessingPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::state_view lua = context.sol();
|
||||||
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
sol::usertype<Shader> shader = context.mLua->sol().new_usertype<Shader>("Shader");
|
sol::usertype<Shader> shader = lua.new_usertype<Shader>("Shader");
|
||||||
shader[sol::meta_function::to_string] = [](const Shader& shader) { return shader.toString(); };
|
shader[sol::meta_function::to_string] = [](const Shader& shader) { return shader.toString(); };
|
||||||
|
|
||||||
shader["enable"] = [context](Shader& shader, sol::optional<int> optPos) {
|
shader["enable"] = [context](Shader& shader, sol::optional<int> optPos) {
|
||||||
|
|
|
@ -43,8 +43,8 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initRaceRecordBindings(const Context& context)
|
sol::table initRaceRecordBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table races(context.mLua->sol(), sol::create);
|
sol::table races(lua, sol::create);
|
||||||
addRecordFunctionBinding<ESM::Race>(races, context);
|
addRecordFunctionBinding<ESM::Race>(races, context);
|
||||||
|
|
||||||
auto raceT = lua.new_usertype<ESM::Race>("ESM3_Race");
|
auto raceT = lua.new_usertype<ESM::Race>("ESM3_Race");
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace MWLua
|
||||||
// Define a custom user type for the store.
|
// Define a custom user type for the store.
|
||||||
// Provide the interface of a read-only array.
|
// Provide the interface of a read-only array.
|
||||||
using StoreT = MWWorld::Store<T>;
|
using StoreT = MWWorld::Store<T>;
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::usertype<StoreT> storeT = lua.new_usertype<StoreT>(recordName + "WorldStore");
|
sol::usertype<StoreT> storeT = lua.new_usertype<StoreT>(recordName + "WorldStore");
|
||||||
storeT[sol::meta_function::to_string] = [recordName](const StoreT& store) {
|
storeT[sol::meta_function::to_string] = [recordName](const StoreT& store) {
|
||||||
return "{" + std::to_string(store.getSize()) + " " + recordName + " records}";
|
return "{" + std::to_string(store.getSize()) + " " + recordName + " records}";
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table initAmbientPackage(const Context& context)
|
sol::table initAmbientPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
if (lua["openmw_ambient"] != sol::nil)
|
if (lua["openmw_ambient"] != sol::nil)
|
||||||
return lua["openmw_ambient"];
|
return lua["openmw_ambient"];
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initCoreSoundBindings(const Context& context)
|
sol::table initCoreSoundBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table api(lua, sol::create);
|
sol::table api(lua, sol::create);
|
||||||
|
|
||||||
api["isEnabled"] = []() { return MWBase::Environment::get().getSoundManager()->isEnabled(); };
|
api["isEnabled"] = []() { return MWBase::Environment::get().getSoundManager()->isEnabled(); };
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace
|
||||||
if (it != self->mStatsCache.end())
|
if (it != self->mStatsCache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
return sol::make_object(context.mLua->sol(), getter(obj.ptr()));
|
return sol::make_object(context.mLua->unsafeState(), getter(obj.ptr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,11 +531,12 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addActorStatsBindings(sol::table& actor, const Context& context)
|
void addActorStatsBindings(sol::table& actor, const Context& context)
|
||||||
{
|
{
|
||||||
sol::table stats(context.mLua->sol(), sol::create);
|
sol::state_view lua = context.sol();
|
||||||
|
sol::table stats(lua, sol::create);
|
||||||
actor["stats"] = LuaUtil::makeReadOnly(stats);
|
actor["stats"] = LuaUtil::makeReadOnly(stats);
|
||||||
|
|
||||||
auto skillIncreasesForAttributeStatsT
|
auto skillIncreasesForAttributeStatsT
|
||||||
= context.mLua->sol().new_usertype<SkillIncreasesForAttributeStats>("SkillIncreasesForAttributeStats");
|
= lua.new_usertype<SkillIncreasesForAttributeStats>("SkillIncreasesForAttributeStats");
|
||||||
for (const auto& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
|
for (const auto& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
|
||||||
{
|
{
|
||||||
skillIncreasesForAttributeStatsT[ESM::RefId(attribute.mId).serializeText()] = sol::property(
|
skillIncreasesForAttributeStatsT[ESM::RefId(attribute.mId).serializeText()] = sol::property(
|
||||||
|
@ -546,8 +547,7 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
// ESM::Class::specializationIndexToLuaId.at(rec.mData.mSpecialization)
|
// ESM::Class::specializationIndexToLuaId.at(rec.mData.mSpecialization)
|
||||||
auto skillIncreasesForSpecializationStatsT
|
auto skillIncreasesForSpecializationStatsT
|
||||||
= context.mLua->sol().new_usertype<SkillIncreasesForSpecializationStats>(
|
= lua.new_usertype<SkillIncreasesForSpecializationStats>("skillIncreasesForSpecializationStats");
|
||||||
"skillIncreasesForSpecializationStats");
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
std::string_view index = ESM::Class::specializationIndexToLuaId.at(i);
|
std::string_view index = ESM::Class::specializationIndexToLuaId.at(i);
|
||||||
|
@ -558,7 +558,7 @@ namespace MWLua
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto levelStatT = context.mLua->sol().new_usertype<LevelStat>("LevelStat");
|
auto levelStatT = lua.new_usertype<LevelStat>("LevelStat");
|
||||||
levelStatT["current"] = sol::property([context](const LevelStat& stat) { return stat.getCurrent(context); },
|
levelStatT["current"] = sol::property([context](const LevelStat& stat) { return stat.getCurrent(context); },
|
||||||
[context](const LevelStat& stat, const sol::object& value) { stat.setCurrent(context, value); });
|
[context](const LevelStat& stat, const sol::object& value) { stat.setCurrent(context, value); });
|
||||||
levelStatT["progress"] = sol::property([context](const LevelStat& stat) { return stat.getProgress(context); },
|
levelStatT["progress"] = sol::property([context](const LevelStat& stat) { return stat.getProgress(context); },
|
||||||
|
@ -569,32 +569,32 @@ namespace MWLua
|
||||||
[](const LevelStat& stat) { return stat.getSkillIncreasesForSpecializationStats(); });
|
[](const LevelStat& stat) { return stat.getSkillIncreasesForSpecializationStats(); });
|
||||||
stats["level"] = addIndexedAccessor<LevelStat>(0);
|
stats["level"] = addIndexedAccessor<LevelStat>(0);
|
||||||
|
|
||||||
auto dynamicStatT = context.mLua->sol().new_usertype<DynamicStat>("DynamicStat");
|
auto dynamicStatT = lua.new_usertype<DynamicStat>("DynamicStat");
|
||||||
addProp(context, dynamicStatT, "base", &MWMechanics::DynamicStat<float>::getBase);
|
addProp(context, dynamicStatT, "base", &MWMechanics::DynamicStat<float>::getBase);
|
||||||
addProp(context, dynamicStatT, "current", &MWMechanics::DynamicStat<float>::getCurrent);
|
addProp(context, dynamicStatT, "current", &MWMechanics::DynamicStat<float>::getCurrent);
|
||||||
addProp(context, dynamicStatT, "modifier", &MWMechanics::DynamicStat<float>::getModifier);
|
addProp(context, dynamicStatT, "modifier", &MWMechanics::DynamicStat<float>::getModifier);
|
||||||
sol::table dynamic(context.mLua->sol(), sol::create);
|
sol::table dynamic(lua, sol::create);
|
||||||
stats["dynamic"] = LuaUtil::makeReadOnly(dynamic);
|
stats["dynamic"] = LuaUtil::makeReadOnly(dynamic);
|
||||||
dynamic["health"] = addIndexedAccessor<DynamicStat>(0);
|
dynamic["health"] = addIndexedAccessor<DynamicStat>(0);
|
||||||
dynamic["magicka"] = addIndexedAccessor<DynamicStat>(1);
|
dynamic["magicka"] = addIndexedAccessor<DynamicStat>(1);
|
||||||
dynamic["fatigue"] = addIndexedAccessor<DynamicStat>(2);
|
dynamic["fatigue"] = addIndexedAccessor<DynamicStat>(2);
|
||||||
|
|
||||||
auto attributeStatT = context.mLua->sol().new_usertype<AttributeStat>("AttributeStat");
|
auto attributeStatT = lua.new_usertype<AttributeStat>("AttributeStat");
|
||||||
addProp(context, attributeStatT, "base", &MWMechanics::AttributeValue::getBase);
|
addProp(context, attributeStatT, "base", &MWMechanics::AttributeValue::getBase);
|
||||||
addProp(context, attributeStatT, "damage", &MWMechanics::AttributeValue::getDamage);
|
addProp(context, attributeStatT, "damage", &MWMechanics::AttributeValue::getDamage);
|
||||||
attributeStatT["modified"]
|
attributeStatT["modified"]
|
||||||
= sol::readonly_property([=](const AttributeStat& stat) { return stat.getModified(context); });
|
= sol::readonly_property([=](const AttributeStat& stat) { return stat.getModified(context); });
|
||||||
addProp(context, attributeStatT, "modifier", &MWMechanics::AttributeValue::getModifier);
|
addProp(context, attributeStatT, "modifier", &MWMechanics::AttributeValue::getModifier);
|
||||||
sol::table attributes(context.mLua->sol(), sol::create);
|
sol::table attributes(lua, sol::create);
|
||||||
stats["attributes"] = LuaUtil::makeReadOnly(attributes);
|
stats["attributes"] = LuaUtil::makeReadOnly(attributes);
|
||||||
for (const ESM::Attribute& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
|
for (const ESM::Attribute& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
|
||||||
attributes[ESM::RefId(attribute.mId).serializeText()] = addIndexedAccessor<AttributeStat>(attribute.mId);
|
attributes[ESM::RefId(attribute.mId).serializeText()] = addIndexedAccessor<AttributeStat>(attribute.mId);
|
||||||
|
|
||||||
auto aiStatT = context.mLua->sol().new_usertype<AIStat>("AIStat");
|
auto aiStatT = lua.new_usertype<AIStat>("AIStat");
|
||||||
addProp(context, aiStatT, "base", &MWMechanics::Stat<int>::getBase);
|
addProp(context, aiStatT, "base", &MWMechanics::Stat<int>::getBase);
|
||||||
addProp(context, aiStatT, "modifier", &MWMechanics::Stat<int>::getModifier);
|
addProp(context, aiStatT, "modifier", &MWMechanics::Stat<int>::getModifier);
|
||||||
aiStatT["modified"] = sol::readonly_property([=](const AIStat& stat) { return stat.getModified(context); });
|
aiStatT["modified"] = sol::readonly_property([=](const AIStat& stat) { return stat.getModified(context); });
|
||||||
sol::table ai(context.mLua->sol(), sol::create);
|
sol::table ai(lua, sol::create);
|
||||||
stats["ai"] = LuaUtil::makeReadOnly(ai);
|
stats["ai"] = LuaUtil::makeReadOnly(ai);
|
||||||
ai["alarm"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Alarm);
|
ai["alarm"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Alarm);
|
||||||
ai["fight"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Fight);
|
ai["fight"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Fight);
|
||||||
|
@ -604,13 +604,14 @@ namespace MWLua
|
||||||
|
|
||||||
void addNpcStatsBindings(sol::table& npc, const Context& context)
|
void addNpcStatsBindings(sol::table& npc, const Context& context)
|
||||||
{
|
{
|
||||||
sol::table npcStats(context.mLua->sol(), sol::create);
|
sol::state_view lua = context.sol();
|
||||||
sol::table baseMeta(context.mLua->sol(), sol::create);
|
sol::table npcStats(lua, sol::create);
|
||||||
|
sol::table baseMeta(lua, sol::create);
|
||||||
baseMeta[sol::meta_function::index] = LuaUtil::getMutableFromReadOnly(npc["baseType"]["stats"]);
|
baseMeta[sol::meta_function::index] = LuaUtil::getMutableFromReadOnly(npc["baseType"]["stats"]);
|
||||||
npcStats[sol::metatable_key] = baseMeta;
|
npcStats[sol::metatable_key] = baseMeta;
|
||||||
npc["stats"] = LuaUtil::makeReadOnly(npcStats);
|
npc["stats"] = LuaUtil::makeReadOnly(npcStats);
|
||||||
|
|
||||||
auto skillStatT = context.mLua->sol().new_usertype<SkillStat>("SkillStat");
|
auto skillStatT = lua.new_usertype<SkillStat>("SkillStat");
|
||||||
addProp(context, skillStatT, "base", &MWMechanics::SkillValue::getBase);
|
addProp(context, skillStatT, "base", &MWMechanics::SkillValue::getBase);
|
||||||
addProp(context, skillStatT, "damage", &MWMechanics::SkillValue::getDamage);
|
addProp(context, skillStatT, "damage", &MWMechanics::SkillValue::getDamage);
|
||||||
skillStatT["modified"]
|
skillStatT["modified"]
|
||||||
|
@ -618,7 +619,7 @@ namespace MWLua
|
||||||
addProp(context, skillStatT, "modifier", &MWMechanics::SkillValue::getModifier);
|
addProp(context, skillStatT, "modifier", &MWMechanics::SkillValue::getModifier);
|
||||||
skillStatT["progress"] = sol::property([context](const SkillStat& stat) { return stat.getProgress(context); },
|
skillStatT["progress"] = sol::property([context](const SkillStat& stat) { return stat.getProgress(context); },
|
||||||
[context](const SkillStat& stat, const sol::object& value) { stat.cache(context, "progress", value); });
|
[context](const SkillStat& stat, const sol::object& value) { stat.cache(context, "progress", value); });
|
||||||
sol::table skills(context.mLua->sol(), sol::create);
|
sol::table skills(lua, sol::create);
|
||||||
npcStats["skills"] = LuaUtil::makeReadOnly(skills);
|
npcStats["skills"] = LuaUtil::makeReadOnly(skills);
|
||||||
for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get<ESM::Skill>())
|
for (const ESM::Skill& skill : MWBase::Environment::get().getESMStore()->get<ESM::Skill>())
|
||||||
skills[ESM::RefId(skill.mId).serializeText()] = addIndexedAccessor<SkillStat>(skill.mId);
|
skills[ESM::RefId(skill.mId).serializeText()] = addIndexedAccessor<SkillStat>(skill.mId);
|
||||||
|
@ -626,7 +627,7 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initCoreStatsBindings(const Context& context)
|
sol::table initCoreStatsBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table statsApi(lua, sol::create);
|
sol::table statsApi(lua, sol::create);
|
||||||
auto* vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto* vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
|
@ -635,7 +636,7 @@ namespace MWLua
|
||||||
statsApi["Attribute"] = LuaUtil::makeReadOnly(attributes);
|
statsApi["Attribute"] = LuaUtil::makeReadOnly(attributes);
|
||||||
statsApi["Attribute"][sol::metatable_key][sol::meta_function::to_string] = ESM::Attribute::getRecordType;
|
statsApi["Attribute"][sol::metatable_key][sol::meta_function::to_string] = ESM::Attribute::getRecordType;
|
||||||
|
|
||||||
auto attributeT = context.mLua->sol().new_usertype<ESM::Attribute>("Attribute");
|
auto attributeT = lua.new_usertype<ESM::Attribute>("Attribute");
|
||||||
attributeT[sol::meta_function::to_string]
|
attributeT[sol::meta_function::to_string]
|
||||||
= [](const ESM::Attribute& rec) { return "ESM3_Attribute[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Attribute& rec) { return "ESM3_Attribute[" + rec.mId.toDebugString() + "]"; };
|
||||||
attributeT["id"] = sol::readonly_property(
|
attributeT["id"] = sol::readonly_property(
|
||||||
|
@ -653,7 +654,7 @@ namespace MWLua
|
||||||
statsApi["Skill"] = LuaUtil::makeReadOnly(skills);
|
statsApi["Skill"] = LuaUtil::makeReadOnly(skills);
|
||||||
statsApi["Skill"][sol::metatable_key][sol::meta_function::to_string] = ESM::Skill::getRecordType;
|
statsApi["Skill"][sol::metatable_key][sol::meta_function::to_string] = ESM::Skill::getRecordType;
|
||||||
|
|
||||||
auto skillT = context.mLua->sol().new_usertype<ESM::Skill>("Skill");
|
auto skillT = lua.new_usertype<ESM::Skill>("Skill");
|
||||||
skillT[sol::meta_function::to_string]
|
skillT[sol::meta_function::to_string]
|
||||||
= [](const ESM::Skill& rec) { return "ESM3_Skill[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Skill& rec) { return "ESM3_Skill[" + rec.mId.toDebugString() + "]"; };
|
||||||
skillT["id"] = sol::readonly_property(
|
skillT["id"] = sol::readonly_property(
|
||||||
|
@ -683,7 +684,7 @@ namespace MWLua
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto schoolT = context.mLua->sol().new_usertype<ESM::MagicSchool>("MagicSchool");
|
auto schoolT = lua.new_usertype<ESM::MagicSchool>("MagicSchool");
|
||||||
schoolT[sol::meta_function::to_string]
|
schoolT[sol::meta_function::to_string]
|
||||||
= [](const ESM::MagicSchool& rec) { return "ESM3_MagicSchool[" + rec.mName + "]"; };
|
= [](const ESM::MagicSchool& rec) { return "ESM3_MagicSchool[" + rec.mName + "]"; };
|
||||||
schoolT["name"]
|
schoolT["name"]
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace MWLua
|
||||||
activator["createRecordDraft"] = tableToActivator;
|
activator["createRecordDraft"] = tableToActivator;
|
||||||
addRecordFunctionBinding<ESM::Activator>(activator, context);
|
addRecordFunctionBinding<ESM::Activator>(activator, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Activator> record = context.mLua->sol().new_usertype<ESM::Activator>("ESM3_Activator");
|
sol::usertype<ESM::Activator> record = context.sol().new_usertype<ESM::Activator>("ESM3_Activator");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Activator& rec) { return "ESM3_Activator[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Activator& rec) { return "ESM3_Activator[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -172,13 +172,15 @@ namespace MWLua
|
||||||
|
|
||||||
void addActorBindings(sol::table actor, const Context& context)
|
void addActorBindings(sol::table actor, const Context& context)
|
||||||
{
|
{
|
||||||
|
sol::state_view lua = context.sol();
|
||||||
actor["STANCE"]
|
actor["STANCE"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWMechanics::DrawState>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWMechanics::DrawState>(lua,
|
||||||
{ "Nothing", MWMechanics::DrawState::Nothing },
|
{
|
||||||
{ "Weapon", MWMechanics::DrawState::Weapon },
|
{ "Nothing", MWMechanics::DrawState::Nothing },
|
||||||
{ "Spell", MWMechanics::DrawState::Spell },
|
{ "Weapon", MWMechanics::DrawState::Weapon },
|
||||||
}));
|
{ "Spell", MWMechanics::DrawState::Spell },
|
||||||
actor["EQUIPMENT_SLOT"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>(
|
}));
|
||||||
|
actor["EQUIPMENT_SLOT"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ { "Helmet", MWWorld::InventoryStore::Slot_Helmet }, { "Cuirass", MWWorld::InventoryStore::Slot_Cuirass },
|
{ { "Helmet", MWWorld::InventoryStore::Slot_Helmet }, { "Cuirass", MWWorld::InventoryStore::Slot_Cuirass },
|
||||||
{ "Greaves", MWWorld::InventoryStore::Slot_Greaves },
|
{ "Greaves", MWWorld::InventoryStore::Slot_Greaves },
|
||||||
{ "LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron },
|
{ "LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron },
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MWLua
|
||||||
void addActorServicesBindings(sol::usertype<T>& record, const Context& context)
|
void addActorServicesBindings(sol::usertype<T>& record, const Context& context)
|
||||||
{
|
{
|
||||||
record["servicesOffered"] = sol::readonly_property([context](const T& rec) -> sol::table {
|
record["servicesOffered"] = sol::readonly_property([context](const T& rec) -> sol::table {
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table providedServices(lua, sol::create);
|
sol::table providedServices(lua, sol::create);
|
||||||
constexpr std::array<std::pair<int, std::string_view>, 19> serviceNames = { { { ESM::NPC::Spells,
|
constexpr std::array<std::pair<int, std::string_view>, 19> serviceNames = { { { ESM::NPC::Spells,
|
||||||
"Spells" },
|
"Spells" },
|
||||||
|
@ -51,7 +51,7 @@ namespace MWLua
|
||||||
});
|
});
|
||||||
|
|
||||||
record["travelDestinations"] = sol::readonly_property([context](const T& rec) -> sol::table {
|
record["travelDestinations"] = sol::readonly_property([context](const T& rec) -> sol::table {
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
sol::table travelDests(lua, sol::create);
|
sol::table travelDests(lua, sol::create);
|
||||||
if (!rec.getTransport().empty())
|
if (!rec.getTransport().empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,18 +20,20 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addApparatusBindings(sol::table apparatus, const Context& context)
|
void addApparatusBindings(sol::table apparatus, const Context& context)
|
||||||
{
|
{
|
||||||
apparatus["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
sol::state_view lua = context.sol();
|
||||||
{ "MortarPestle", ESM::Apparatus::MortarPestle },
|
apparatus["TYPE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ "Alembic", ESM::Apparatus::Alembic },
|
{
|
||||||
{ "Calcinator", ESM::Apparatus::Calcinator },
|
{ "MortarPestle", ESM::Apparatus::MortarPestle },
|
||||||
{ "Retort", ESM::Apparatus::Retort },
|
{ "Alembic", ESM::Apparatus::Alembic },
|
||||||
}));
|
{ "Calcinator", ESM::Apparatus::Calcinator },
|
||||||
|
{ "Retort", ESM::Apparatus::Retort },
|
||||||
|
}));
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Apparatus>(apparatus, context);
|
addRecordFunctionBinding<ESM::Apparatus>(apparatus, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Apparatus> record = context.mLua->sol().new_usertype<ESM::Apparatus>("ESM3_Apparatus");
|
sol::usertype<ESM::Apparatus> record = lua.new_usertype<ESM::Apparatus>("ESM3_Apparatus");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Apparatus& rec) { return "ESM3_Apparatus[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Apparatus& rec) { return "ESM3_Apparatus[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -69,26 +69,28 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addArmorBindings(sol::table armor, const Context& context)
|
void addArmorBindings(sol::table armor, const Context& context)
|
||||||
{
|
{
|
||||||
armor["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
sol::state_view lua = context.sol();
|
||||||
{ "Helmet", ESM::Armor::Helmet },
|
armor["TYPE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ "Cuirass", ESM::Armor::Cuirass },
|
{
|
||||||
{ "LPauldron", ESM::Armor::LPauldron },
|
{ "Helmet", ESM::Armor::Helmet },
|
||||||
{ "RPauldron", ESM::Armor::RPauldron },
|
{ "Cuirass", ESM::Armor::Cuirass },
|
||||||
{ "Greaves", ESM::Armor::Greaves },
|
{ "LPauldron", ESM::Armor::LPauldron },
|
||||||
{ "Boots", ESM::Armor::Boots },
|
{ "RPauldron", ESM::Armor::RPauldron },
|
||||||
{ "LGauntlet", ESM::Armor::LGauntlet },
|
{ "Greaves", ESM::Armor::Greaves },
|
||||||
{ "RGauntlet", ESM::Armor::RGauntlet },
|
{ "Boots", ESM::Armor::Boots },
|
||||||
{ "Shield", ESM::Armor::Shield },
|
{ "LGauntlet", ESM::Armor::LGauntlet },
|
||||||
{ "LBracer", ESM::Armor::LBracer },
|
{ "RGauntlet", ESM::Armor::RGauntlet },
|
||||||
{ "RBracer", ESM::Armor::RBracer },
|
{ "Shield", ESM::Armor::Shield },
|
||||||
}));
|
{ "LBracer", ESM::Armor::LBracer },
|
||||||
|
{ "RBracer", ESM::Armor::RBracer },
|
||||||
|
}));
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Armor>(armor, context);
|
addRecordFunctionBinding<ESM::Armor>(armor, context);
|
||||||
|
|
||||||
armor["createRecordDraft"] = tableToArmor;
|
armor["createRecordDraft"] = tableToArmor;
|
||||||
sol::usertype<ESM::Armor> record = context.mLua->sol().new_usertype<ESM::Armor>("ESM3_Armor");
|
sol::usertype<ESM::Armor> record = lua.new_usertype<ESM::Armor>("ESM3_Armor");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Armor& rec) -> std::string { return "ESM3_Armor[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Armor& rec) -> std::string { return "ESM3_Armor[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -82,9 +82,10 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addBookBindings(sol::table book, const Context& context)
|
void addBookBindings(sol::table book, const Context& context)
|
||||||
{
|
{
|
||||||
|
sol::state_view lua = context.sol();
|
||||||
// types.book.SKILL is deprecated (core.SKILL should be used instead)
|
// types.book.SKILL is deprecated (core.SKILL should be used instead)
|
||||||
// TODO: Remove book.SKILL after branching 0.49
|
// TODO: Remove book.SKILL after branching 0.49
|
||||||
sol::table skill(context.mLua->sol(), sol::create);
|
sol::table skill(lua, sol::create);
|
||||||
book["SKILL"] = LuaUtil::makeStrictReadOnly(skill);
|
book["SKILL"] = LuaUtil::makeStrictReadOnly(skill);
|
||||||
book["createRecordDraft"] = tableToBook;
|
book["createRecordDraft"] = tableToBook;
|
||||||
for (int id = 0; id < ESM::Skill::Length; ++id)
|
for (int id = 0; id < ESM::Skill::Length; ++id)
|
||||||
|
@ -97,7 +98,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Book>(book, context);
|
addRecordFunctionBinding<ESM::Book>(book, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Book> record = context.mLua->sol().new_usertype<ESM::Book>("ESM3_Book");
|
sol::usertype<ESM::Book> record = lua.new_usertype<ESM::Book>("ESM3_Book");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Book& rec) { return "ESM3_Book[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Book& rec) { return "ESM3_Book[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -66,24 +66,26 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
clothing["createRecordDraft"] = tableToClothing;
|
clothing["createRecordDraft"] = tableToClothing;
|
||||||
|
|
||||||
clothing["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
sol::state_view lua = context.sol();
|
||||||
{ "Amulet", ESM::Clothing::Amulet },
|
clothing["TYPE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ "Belt", ESM::Clothing::Belt },
|
{
|
||||||
{ "LGlove", ESM::Clothing::LGlove },
|
{ "Amulet", ESM::Clothing::Amulet },
|
||||||
{ "Pants", ESM::Clothing::Pants },
|
{ "Belt", ESM::Clothing::Belt },
|
||||||
{ "RGlove", ESM::Clothing::RGlove },
|
{ "LGlove", ESM::Clothing::LGlove },
|
||||||
{ "Ring", ESM::Clothing::Ring },
|
{ "Pants", ESM::Clothing::Pants },
|
||||||
{ "Robe", ESM::Clothing::Robe },
|
{ "RGlove", ESM::Clothing::RGlove },
|
||||||
{ "Shirt", ESM::Clothing::Shirt },
|
{ "Ring", ESM::Clothing::Ring },
|
||||||
{ "Shoes", ESM::Clothing::Shoes },
|
{ "Robe", ESM::Clothing::Robe },
|
||||||
{ "Skirt", ESM::Clothing::Skirt },
|
{ "Shirt", ESM::Clothing::Shirt },
|
||||||
}));
|
{ "Shoes", ESM::Clothing::Shoes },
|
||||||
|
{ "Skirt", ESM::Clothing::Skirt },
|
||||||
|
}));
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Clothing>(clothing, context);
|
addRecordFunctionBinding<ESM::Clothing>(clothing, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Clothing> record = context.mLua->sol().new_usertype<ESM::Clothing>("ESM3_Clothing");
|
sol::usertype<ESM::Clothing> record = lua.new_usertype<ESM::Clothing>("ESM3_Clothing");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Clothing& rec) -> std::string { return "ESM3_Clothing[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Clothing& rec) -> std::string { return "ESM3_Clothing[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Container>(container, context);
|
addRecordFunctionBinding<ESM::Container>(container, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Container> record = context.mLua->sol().new_usertype<ESM::Container>("ESM3_Container");
|
sol::usertype<ESM::Container> record = context.sol().new_usertype<ESM::Container>("ESM3_Container");
|
||||||
record[sol::meta_function::to_string] = [](const ESM::Container& rec) -> std::string {
|
record[sol::meta_function::to_string] = [](const ESM::Container& rec) -> std::string {
|
||||||
return "ESM3_Container[" + rec.mId.toDebugString() + "]";
|
return "ESM3_Container[" + rec.mId.toDebugString() + "]";
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,16 +20,18 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addCreatureBindings(sol::table creature, const Context& context)
|
void addCreatureBindings(sol::table creature, const Context& context)
|
||||||
{
|
{
|
||||||
creature["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
sol::state_view lua = context.sol();
|
||||||
{ "Creatures", ESM::Creature::Creatures },
|
creature["TYPE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ "Daedra", ESM::Creature::Daedra },
|
{
|
||||||
{ "Undead", ESM::Creature::Undead },
|
{ "Creatures", ESM::Creature::Creatures },
|
||||||
{ "Humanoid", ESM::Creature::Humanoid },
|
{ "Daedra", ESM::Creature::Daedra },
|
||||||
}));
|
{ "Undead", ESM::Creature::Undead },
|
||||||
|
{ "Humanoid", ESM::Creature::Humanoid },
|
||||||
|
}));
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Creature>(creature, context);
|
addRecordFunctionBinding<ESM::Creature>(creature, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Creature> record = context.mLua->sol().new_usertype<ESM::Creature>("ESM3_Creature");
|
sol::usertype<ESM::Creature> record = lua.new_usertype<ESM::Creature>("ESM3_Creature");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Creature& rec) { return "ESM3_Creature[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Creature& rec) { return "ESM3_Creature[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
@ -50,8 +52,7 @@ namespace MWLua
|
||||||
record["magicSkill"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mMagic; });
|
record["magicSkill"] = sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mMagic; });
|
||||||
record["stealthSkill"]
|
record["stealthSkill"]
|
||||||
= sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mStealth; });
|
= sol::readonly_property([](const ESM::Creature& rec) -> int { return rec.mData.mStealth; });
|
||||||
record["attack"] = sol::readonly_property([context](const ESM::Creature& rec) -> sol::table {
|
record["attack"] = sol::readonly_property([](sol::this_state lua, const ESM::Creature& rec) -> sol::table {
|
||||||
sol::state_view& lua = context.mLua->sol();
|
|
||||||
sol::table res(lua, sol::create);
|
sol::table res(lua, sol::create);
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (auto attack : rec.mData.mAttack)
|
for (auto attack : rec.mData.mAttack)
|
||||||
|
|
|
@ -41,11 +41,13 @@ namespace MWLua
|
||||||
|
|
||||||
void addDoorBindings(sol::table door, const Context& context)
|
void addDoorBindings(sol::table door, const Context& context)
|
||||||
{
|
{
|
||||||
door["STATE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, MWWorld::DoorState>({
|
sol::state_view lua = context.sol();
|
||||||
{ "Idle", MWWorld::DoorState::Idle },
|
door["STATE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWWorld::DoorState>(lua,
|
||||||
{ "Opening", MWWorld::DoorState::Opening },
|
{
|
||||||
{ "Closing", MWWorld::DoorState::Closing },
|
{ "Idle", MWWorld::DoorState::Idle },
|
||||||
}));
|
{ "Opening", MWWorld::DoorState::Opening },
|
||||||
|
{ "Closing", MWWorld::DoorState::Closing },
|
||||||
|
}));
|
||||||
door["getDoorState"] = [](const Object& o) -> MWWorld::DoorState {
|
door["getDoorState"] = [](const Object& o) -> MWWorld::DoorState {
|
||||||
auto door = doorPtr(o);
|
auto door = doorPtr(o);
|
||||||
return door.getClass().getDoorState(door);
|
return door.getClass().getDoorState(door);
|
||||||
|
@ -99,7 +101,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Door>(door, context);
|
addRecordFunctionBinding<ESM::Door>(door, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Door> record = context.mLua->sol().new_usertype<ESM::Door>("ESM3_Door");
|
sol::usertype<ESM::Door> record = lua.new_usertype<ESM::Door>("ESM3_Door");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Door& rec) -> std::string { return "ESM3_Door[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Door& rec) -> std::string { return "ESM3_Door[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
@ -136,7 +138,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM4::Door>(door, context, "ESM4Door");
|
addRecordFunctionBinding<ESM4::Door>(door, context, "ESM4Door");
|
||||||
|
|
||||||
sol::usertype<ESM4::Door> record = context.mLua->sol().new_usertype<ESM4::Door>("ESM4_Door");
|
sol::usertype<ESM4::Door> record = context.sol().new_usertype<ESM4::Door>("ESM4_Door");
|
||||||
record[sol::meta_function::to_string] = [](const ESM4::Door& rec) -> std::string {
|
record[sol::meta_function::to_string] = [](const ESM4::Door& rec) -> std::string {
|
||||||
return "ESM4_Door[" + ESM::RefId(rec.mId).toDebugString() + "]";
|
return "ESM4_Door[" + ESM::RefId(rec.mId).toDebugString() + "]";
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Ingredient>(ingredient, context);
|
addRecordFunctionBinding<ESM::Ingredient>(ingredient, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Ingredient> record = context.mLua->sol().new_usertype<ESM::Ingredient>(("ESM3_Ingredient"));
|
sol::usertype<ESM::Ingredient> record = context.sol().new_usertype<ESM::Ingredient>(("ESM3_Ingredient"));
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Ingredient& rec) { return "ESM3_Ingredient[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Ingredient& rec) { return "ESM3_Ingredient[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
@ -43,8 +43,8 @@ namespace MWLua
|
||||||
record["weight"]
|
record["weight"]
|
||||||
= sol::readonly_property([](const ESM::Ingredient& rec) -> float { return rec.mData.mWeight; });
|
= sol::readonly_property([](const ESM::Ingredient& rec) -> float { return rec.mData.mWeight; });
|
||||||
record["value"] = sol::readonly_property([](const ESM::Ingredient& rec) -> int { return rec.mData.mValue; });
|
record["value"] = sol::readonly_property([](const ESM::Ingredient& rec) -> int { return rec.mData.mValue; });
|
||||||
record["effects"] = sol::readonly_property([context](const ESM::Ingredient& rec) -> sol::table {
|
record["effects"] = sol::readonly_property([](sol::this_state lua, const ESM::Ingredient& rec) -> sol::table {
|
||||||
sol::table res(context.mLua->sol(), sol::create);
|
sol::table res(lua, sol::create);
|
||||||
for (size_t i = 0; i < 4; ++i)
|
for (size_t i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if (rec.mData.mEffectID[i] < 0)
|
if (rec.mData.mEffectID[i] < 0)
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addLevelledCreatureBindings(sol::table list, const Context& context)
|
void addLevelledCreatureBindings(sol::table list, const Context& context)
|
||||||
{
|
{
|
||||||
auto& state = context.mLua->sol();
|
auto state = context.sol();
|
||||||
auto item = state.new_usertype<ESM::LevelledListBase::LevelItem>("ESM3_LevelledListItem");
|
auto item = state.new_usertype<ESM::LevelledListBase::LevelItem>("ESM3_LevelledListItem");
|
||||||
item["id"] = sol::readonly_property(
|
item["id"] = sol::readonly_property(
|
||||||
[](const ESM::LevelledListBase::LevelItem& rec) -> std::string { return rec.mId.serializeText(); });
|
[](const ESM::LevelledListBase::LevelItem& rec) -> std::string { return rec.mId.serializeText(); });
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace MWLua
|
||||||
addRecordFunctionBinding<ESM::Light>(light, context);
|
addRecordFunctionBinding<ESM::Light>(light, context);
|
||||||
light["createRecordDraft"] = tableToLight;
|
light["createRecordDraft"] = tableToLight;
|
||||||
|
|
||||||
sol::usertype<ESM::Light> record = context.mLua->sol().new_usertype<ESM::Light>("ESM3_Light");
|
sol::usertype<ESM::Light> record = context.sol().new_usertype<ESM::Light>("ESM3_Light");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Light& rec) -> std::string { return "ESM3_Light[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Light& rec) -> std::string { return "ESM3_Light[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Lockpick>(lockpick, context);
|
addRecordFunctionBinding<ESM::Lockpick>(lockpick, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Lockpick> record = context.mLua->sol().new_usertype<ESM::Lockpick>("ESM3_Lockpick");
|
sol::usertype<ESM::Lockpick> record = context.sol().new_usertype<ESM::Lockpick>("ESM3_Lockpick");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Lockpick& rec) { return "ESM3_Lockpick[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Lockpick& rec) { return "ESM3_Lockpick[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -75,8 +75,7 @@ namespace MWLua
|
||||||
};
|
};
|
||||||
miscellaneous["soul"] = miscellaneous["getSoul"]; // for compatibility; should be removed later
|
miscellaneous["soul"] = miscellaneous["getSoul"]; // for compatibility; should be removed later
|
||||||
|
|
||||||
sol::usertype<ESM::Miscellaneous> record
|
sol::usertype<ESM::Miscellaneous> record = context.sol().new_usertype<ESM::Miscellaneous>("ESM3_Miscellaneous");
|
||||||
= context.mLua->sol().new_usertype<ESM::Miscellaneous>("ESM3_Miscellaneous");
|
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Miscellaneous& rec) { return "ESM3_Miscellaneous[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Miscellaneous& rec) { return "ESM3_Miscellaneous[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"] = sol::readonly_property(
|
record["id"] = sol::readonly_property(
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::NPC>(npc, context);
|
addRecordFunctionBinding<ESM::NPC>(npc, context);
|
||||||
|
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view lua = context.sol();
|
||||||
|
|
||||||
sol::usertype<ESM::NPC> record = lua.new_usertype<ESM::NPC>("ESM3_NPC");
|
sol::usertype<ESM::NPC> record = lua.new_usertype<ESM::NPC>("ESM3_NPC");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
|
|
|
@ -71,7 +71,8 @@ namespace MWLua
|
||||||
|| dynamic_cast<const SelfObject*>(&player) != nullptr;
|
|| dynamic_cast<const SelfObject*>(&player) != nullptr;
|
||||||
return Quests{ .mMutable = allowChanges };
|
return Quests{ .mMutable = allowChanges };
|
||||||
};
|
};
|
||||||
sol::usertype<Quests> quests = context.mLua->sol().new_usertype<Quests>("Quests");
|
sol::state_view lua = context.sol();
|
||||||
|
sol::usertype<Quests> quests = lua.new_usertype<Quests>("Quests");
|
||||||
quests[sol::meta_function::to_string] = [](const Quests& quests) { return "Quests"; };
|
quests[sol::meta_function::to_string] = [](const Quests& quests) { return "Quests"; };
|
||||||
quests[sol::meta_function::index] = [](const Quests& quests, std::string_view questId) -> sol::optional<Quest> {
|
quests[sol::meta_function::index] = [](const Quests& quests, std::string_view questId) -> sol::optional<Quest> {
|
||||||
ESM::RefId quest = ESM::RefId::deserializeText(questId);
|
ESM::RefId quest = ESM::RefId::deserializeText(questId);
|
||||||
|
@ -94,7 +95,7 @@ namespace MWLua
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sol::usertype<Quest> quest = context.mLua->sol().new_usertype<Quest>("Quest");
|
sol::usertype<Quest> quest = lua.new_usertype<Quest>("Quest");
|
||||||
quest[sol::meta_function::to_string]
|
quest[sol::meta_function::to_string]
|
||||||
= [](const Quest& quest) { return "Quest[" + quest.mQuestId.serializeText() + "]"; };
|
= [](const Quest& quest) { return "Quest[" + quest.mQuestId.serializeText() + "]"; };
|
||||||
|
|
||||||
|
@ -146,15 +147,16 @@ namespace MWLua
|
||||||
};
|
};
|
||||||
|
|
||||||
player["CONTROL_SWITCH"]
|
player["CONTROL_SWITCH"]
|
||||||
= LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, std::string_view>({
|
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, std::string_view>(lua,
|
||||||
{ "Controls", "playercontrols" },
|
{
|
||||||
{ "Fighting", "playerfighting" },
|
{ "Controls", "playercontrols" },
|
||||||
{ "Jumping", "playerjumping" },
|
{ "Fighting", "playerfighting" },
|
||||||
{ "Looking", "playerlooking" },
|
{ "Jumping", "playerjumping" },
|
||||||
{ "Magic", "playermagic" },
|
{ "Looking", "playerlooking" },
|
||||||
{ "ViewMode", "playerviewswitch" },
|
{ "Magic", "playermagic" },
|
||||||
{ "VanityMode", "vanitymode" },
|
{ "ViewMode", "playerviewswitch" },
|
||||||
}));
|
{ "VanityMode", "vanitymode" },
|
||||||
|
}));
|
||||||
|
|
||||||
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
|
||||||
player["getControlSwitch"] = [input](const Object& player, std::string_view key) {
|
player["getControlSwitch"] = [input](const Object& player, std::string_view key) {
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace MWLua
|
||||||
potion["createRecordDraft"] = tableToPotion;
|
potion["createRecordDraft"] = tableToPotion;
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
sol::usertype<ESM::Potion> record = context.mLua->sol().new_usertype<ESM::Potion>("ESM3_Potion");
|
sol::usertype<ESM::Potion> record = context.sol().new_usertype<ESM::Potion>("ESM3_Potion");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Potion& rec) { return "ESM3_Potion[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Potion& rec) { return "ESM3_Potion[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
@ -84,8 +84,8 @@ namespace MWLua
|
||||||
[](const ESM::Potion& rec) -> sol::optional<std::string> { return LuaUtil::serializeRefId(rec.mScript); });
|
[](const ESM::Potion& rec) -> sol::optional<std::string> { return LuaUtil::serializeRefId(rec.mScript); });
|
||||||
record["weight"] = sol::readonly_property([](const ESM::Potion& rec) -> float { return rec.mData.mWeight; });
|
record["weight"] = sol::readonly_property([](const ESM::Potion& rec) -> float { return rec.mData.mWeight; });
|
||||||
record["value"] = sol::readonly_property([](const ESM::Potion& rec) -> int { return rec.mData.mValue; });
|
record["value"] = sol::readonly_property([](const ESM::Potion& rec) -> int { return rec.mData.mValue; });
|
||||||
record["effects"] = sol::readonly_property([context](const ESM::Potion& rec) -> sol::table {
|
record["effects"] = sol::readonly_property([](sol::this_state lua, const ESM::Potion& rec) -> sol::table {
|
||||||
sol::table res(context.mLua->sol(), sol::create);
|
sol::table res(lua, sol::create);
|
||||||
for (size_t i = 0; i < rec.mEffects.mList.size(); ++i)
|
for (size_t i = 0; i < rec.mEffects.mList.size(); ++i)
|
||||||
res[LuaUtil::toLuaIndex(i)] = rec.mEffects.mList[i]; // ESM::IndexedENAMstruct (effect params)
|
res[LuaUtil::toLuaIndex(i)] = rec.mEffects.mList[i]; // ESM::IndexedENAMstruct (effect params)
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Probe>(probe, context);
|
addRecordFunctionBinding<ESM::Probe>(probe, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Probe> record = context.mLua->sol().new_usertype<ESM::Probe>("ESM3_Probe");
|
sol::usertype<ESM::Probe> record = context.sol().new_usertype<ESM::Probe>("ESM3_Probe");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Probe& rec) { return "ESM3_Probe[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Probe& rec) { return "ESM3_Probe[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace MWLua
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Repair>(repair, context);
|
addRecordFunctionBinding<ESM::Repair>(repair, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Repair> record = context.mLua->sol().new_usertype<ESM::Repair>("ESM3_Repair");
|
sol::usertype<ESM::Repair> record = context.sol().new_usertype<ESM::Repair>("ESM3_Repair");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Repair& rec) { return "ESM3_Repair[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Repair& rec) { return "ESM3_Repair[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
addRecordFunctionBinding<ESM::Static>(stat, context);
|
addRecordFunctionBinding<ESM::Static>(stat, context);
|
||||||
|
|
||||||
sol::usertype<ESM::Static> record = context.mLua->sol().new_usertype<ESM::Static>("ESM3_Static");
|
sol::usertype<ESM::Static> record = context.sol().new_usertype<ESM::Static>("ESM3_Static");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Static& rec) -> std::string { return "ESM3_Static[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Static& rec) -> std::string { return "ESM3_Static[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
addRecordFunctionBinding<ESM4::Terminal>(term, context, "ESM4Terminal");
|
addRecordFunctionBinding<ESM4::Terminal>(term, context, "ESM4Terminal");
|
||||||
|
|
||||||
sol::usertype<ESM4::Terminal> record = context.mLua->sol().new_usertype<ESM4::Terminal>("ESM4_Terminal");
|
sol::usertype<ESM4::Terminal> record = context.sol().new_usertype<ESM4::Terminal>("ESM4_Terminal");
|
||||||
record[sol::meta_function::to_string] = [](const ESM4::Terminal& rec) -> std::string {
|
record[sol::meta_function::to_string] = [](const ESM4::Terminal& rec) -> std::string {
|
||||||
return "ESM4_Terminal[" + ESM::RefId(rec.mId).toDebugString() + "]";
|
return "ESM4_Terminal[" + ESM::RefId(rec.mId).toDebugString() + "]";
|
||||||
};
|
};
|
||||||
|
|
|
@ -165,22 +165,22 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initTypesPackage(const Context& context)
|
sol::table initTypesPackage(const Context& context)
|
||||||
{
|
{
|
||||||
auto* lua = context.mLua;
|
auto lua = context.sol();
|
||||||
|
|
||||||
if (lua->sol()["openmw_types"] != sol::nil)
|
if (lua["openmw_types"] != sol::nil)
|
||||||
return lua->sol()["openmw_types"];
|
return lua["openmw_types"];
|
||||||
|
|
||||||
sol::table types(lua->sol(), sol::create);
|
sol::table types(lua, sol::create);
|
||||||
auto addType = [&](std::string_view name, std::vector<ESM::RecNameInts> recTypes,
|
auto addType = [&](std::string_view name, std::vector<ESM::RecNameInts> recTypes,
|
||||||
std::optional<std::string_view> base = std::nullopt) -> sol::table {
|
std::optional<std::string_view> base = std::nullopt) -> sol::table {
|
||||||
sol::table t(lua->sol(), sol::create);
|
sol::table t(lua, sol::create);
|
||||||
sol::table ro = LuaUtil::makeReadOnly(t);
|
sol::table ro = LuaUtil::makeReadOnly(t);
|
||||||
sol::table meta = ro[sol::metatable_key];
|
sol::table meta = ro[sol::metatable_key];
|
||||||
meta[sol::meta_function::to_string] = [name]() { return name; };
|
meta[sol::meta_function::to_string] = [name]() { return name; };
|
||||||
if (base)
|
if (base)
|
||||||
{
|
{
|
||||||
t["baseType"] = types[*base];
|
t["baseType"] = types[*base];
|
||||||
sol::table baseMeta(lua->sol(), sol::create);
|
sol::table baseMeta(lua, sol::create);
|
||||||
baseMeta[sol::meta_function::index] = LuaUtil::getMutableFromReadOnly(types[*base]);
|
baseMeta[sol::meta_function::index] = LuaUtil::getMutableFromReadOnly(types[*base]);
|
||||||
t[sol::metatable_key] = baseMeta;
|
t[sol::metatable_key] = baseMeta;
|
||||||
}
|
}
|
||||||
|
@ -251,8 +251,8 @@ namespace MWLua
|
||||||
addType(ObjectTypeName::ESM4Tree, { ESM::REC_TREE4 });
|
addType(ObjectTypeName::ESM4Tree, { ESM::REC_TREE4 });
|
||||||
addType(ObjectTypeName::ESM4Weapon, { ESM::REC_WEAP4 });
|
addType(ObjectTypeName::ESM4Weapon, { ESM::REC_WEAP4 });
|
||||||
|
|
||||||
sol::table typeToPackage = getTypeToPackageTable(context.mLua->sol());
|
sol::table typeToPackage = getTypeToPackageTable(lua);
|
||||||
sol::table packageToType = getPackageToTypeTable(context.mLua->sol());
|
sol::table packageToType = getPackageToTypeTable(lua);
|
||||||
for (const auto& [type, name] : luaObjectTypeInfo)
|
for (const auto& [type, name] : luaObjectTypeInfo)
|
||||||
{
|
{
|
||||||
sol::object t = types[name];
|
sol::object t = types[name];
|
||||||
|
@ -262,7 +262,7 @@ namespace MWLua
|
||||||
packageToType[t] = type;
|
packageToType[t] = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua->sol()["openmw_types"] = LuaUtil::makeReadOnly(types);
|
lua["openmw_types"] = LuaUtil::makeReadOnly(types);
|
||||||
return lua->sol()["openmw_types"];
|
return lua["openmw_types"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,29 +99,31 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
void addWeaponBindings(sol::table weapon, const Context& context)
|
void addWeaponBindings(sol::table weapon, const Context& context)
|
||||||
{
|
{
|
||||||
weapon["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string_view, int>({
|
sol::state_view lua = context.sol();
|
||||||
{ "ShortBladeOneHand", ESM::Weapon::ShortBladeOneHand },
|
weapon["TYPE"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, int>(lua,
|
||||||
{ "LongBladeOneHand", ESM::Weapon::LongBladeOneHand },
|
{
|
||||||
{ "LongBladeTwoHand", ESM::Weapon::LongBladeTwoHand },
|
{ "ShortBladeOneHand", ESM::Weapon::ShortBladeOneHand },
|
||||||
{ "BluntOneHand", ESM::Weapon::BluntOneHand },
|
{ "LongBladeOneHand", ESM::Weapon::LongBladeOneHand },
|
||||||
{ "BluntTwoClose", ESM::Weapon::BluntTwoClose },
|
{ "LongBladeTwoHand", ESM::Weapon::LongBladeTwoHand },
|
||||||
{ "BluntTwoWide", ESM::Weapon::BluntTwoWide },
|
{ "BluntOneHand", ESM::Weapon::BluntOneHand },
|
||||||
{ "SpearTwoWide", ESM::Weapon::SpearTwoWide },
|
{ "BluntTwoClose", ESM::Weapon::BluntTwoClose },
|
||||||
{ "AxeOneHand", ESM::Weapon::AxeOneHand },
|
{ "BluntTwoWide", ESM::Weapon::BluntTwoWide },
|
||||||
{ "AxeTwoHand", ESM::Weapon::AxeTwoHand },
|
{ "SpearTwoWide", ESM::Weapon::SpearTwoWide },
|
||||||
{ "MarksmanBow", ESM::Weapon::MarksmanBow },
|
{ "AxeOneHand", ESM::Weapon::AxeOneHand },
|
||||||
{ "MarksmanCrossbow", ESM::Weapon::MarksmanCrossbow },
|
{ "AxeTwoHand", ESM::Weapon::AxeTwoHand },
|
||||||
{ "MarksmanThrown", ESM::Weapon::MarksmanThrown },
|
{ "MarksmanBow", ESM::Weapon::MarksmanBow },
|
||||||
{ "Arrow", ESM::Weapon::Arrow },
|
{ "MarksmanCrossbow", ESM::Weapon::MarksmanCrossbow },
|
||||||
{ "Bolt", ESM::Weapon::Bolt },
|
{ "MarksmanThrown", ESM::Weapon::MarksmanThrown },
|
||||||
}));
|
{ "Arrow", ESM::Weapon::Arrow },
|
||||||
|
{ "Bolt", ESM::Weapon::Bolt },
|
||||||
|
}));
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
addRecordFunctionBinding<ESM::Weapon>(weapon, context);
|
addRecordFunctionBinding<ESM::Weapon>(weapon, context);
|
||||||
weapon["createRecordDraft"] = tableToWeapon;
|
weapon["createRecordDraft"] = tableToWeapon;
|
||||||
|
|
||||||
sol::usertype<ESM::Weapon> record = context.mLua->sol().new_usertype<ESM::Weapon>("ESM3_Weapon");
|
sol::usertype<ESM::Weapon> record = lua.new_usertype<ESM::Weapon>("ESM3_Weapon");
|
||||||
record[sol::meta_function::to_string]
|
record[sol::meta_function::to_string]
|
||||||
= [](const ESM::Weapon& rec) -> std::string { return "ESM3_Weapon[" + rec.mId.toDebugString() + "]"; };
|
= [](const ESM::Weapon& rec) -> std::string { return "ESM3_Weapon[" + rec.mId.toDebugString() + "]"; };
|
||||||
record["id"]
|
record["id"]
|
||||||
|
|
|
@ -82,11 +82,12 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table registerUiApi(const Context& context)
|
sol::table registerUiApi(const Context& context)
|
||||||
{
|
{
|
||||||
|
sol::state_view lua = context.sol();
|
||||||
bool menu = context.mType == Context::Menu;
|
bool menu = context.mType == Context::Menu;
|
||||||
|
|
||||||
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
||||||
|
|
||||||
sol::table api = context.mLua->newTable();
|
sol::table api(lua, sol::create);
|
||||||
api["_setHudVisibility"] = [luaManager = context.mLuaManager](bool state) {
|
api["_setHudVisibility"] = [luaManager = context.mLuaManager](bool state) {
|
||||||
luaManager->addAction([state] { MWBase::Environment::get().getWindowManager()->setHudVisibility(state); });
|
luaManager->addAction([state] { MWBase::Environment::get().getWindowManager()->setHudVisibility(state); });
|
||||||
};
|
};
|
||||||
|
@ -107,12 +108,13 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
luaManager->addUIMessage(message, mode);
|
luaManager->addUIMessage(message, mode);
|
||||||
};
|
};
|
||||||
api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs<std::string, Misc::Color>({
|
api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string, Misc::Color>(lua,
|
||||||
{ "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) },
|
{
|
||||||
{ "Error", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Error.substr(1)) },
|
{ "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) },
|
||||||
{ "Success", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Success.substr(1)) },
|
{ "Error", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Error.substr(1)) },
|
||||||
{ "Info", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Info.substr(1)) },
|
{ "Success", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Success.substr(1)) },
|
||||||
}));
|
{ "Info", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Info.substr(1)) },
|
||||||
|
}));
|
||||||
api["printToConsole"]
|
api["printToConsole"]
|
||||||
= [luaManager = context.mLuaManager](const std::string& message, const Misc::Color& color) {
|
= [luaManager = context.mLuaManager](const std::string& message, const Misc::Color& color) {
|
||||||
luaManager->addInGameConsoleMessage(message + "\n", color);
|
luaManager->addInGameConsoleMessage(message + "\n", color);
|
||||||
|
@ -150,7 +152,7 @@ namespace MWLua
|
||||||
};
|
};
|
||||||
api["_getMenuTransparency"] = []() -> float { return Settings::gui().mMenuTransparency; };
|
api["_getMenuTransparency"] = []() -> float { return Settings::gui().mMenuTransparency; };
|
||||||
|
|
||||||
sol::table layersTable = context.mLua->newTable();
|
sol::table layersTable(lua, sol::create);
|
||||||
layersTable["indexOf"] = [](std::string_view name) -> sol::optional<size_t> {
|
layersTable["indexOf"] = [](std::string_view name) -> sol::optional<size_t> {
|
||||||
size_t index = LuaUi::Layer::indexOf(name);
|
size_t index = LuaUi::Layer::indexOf(name);
|
||||||
if (index == LuaUi::Layer::count())
|
if (index == LuaUi::Layer::count())
|
||||||
|
@ -202,14 +204,14 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
api["layers"] = layers;
|
api["layers"] = layers;
|
||||||
|
|
||||||
sol::table typeTable = context.mLua->newTable();
|
sol::table typeTable(lua, sol::create);
|
||||||
for (const auto& it : LuaUi::widgetTypeToName())
|
for (const auto& it : LuaUi::widgetTypeToName())
|
||||||
typeTable.set(it.second, it.first);
|
typeTable.set(it.second, it.first);
|
||||||
api["TYPE"] = LuaUtil::makeStrictReadOnly(typeTable);
|
api["TYPE"] = LuaUtil::makeStrictReadOnly(typeTable);
|
||||||
|
|
||||||
api["ALIGNMENT"] = LuaUtil::makeStrictReadOnly(
|
api["ALIGNMENT"] = LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, LuaUi::Alignment>(lua,
|
||||||
context.mLua->tableFromPairs<std::string_view, LuaUi::Alignment>({ { "Start", LuaUi::Alignment::Start },
|
{ { "Start", LuaUi::Alignment::Start }, { "Center", LuaUi::Alignment::Center },
|
||||||
{ "Center", LuaUi::Alignment::Center }, { "End", LuaUi::Alignment::End } }));
|
{ "End", LuaUi::Alignment::End } }));
|
||||||
|
|
||||||
api["registerSettingsPage"] = &LuaUi::registerSettingsPage;
|
api["registerSettingsPage"] = &LuaUi::registerSettingsPage;
|
||||||
api["removeSettingsPage"] = &LuaUi::removeSettingsPage;
|
api["removeSettingsPage"] = &LuaUi::removeSettingsPage;
|
||||||
|
@ -297,7 +299,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
if (context.initializeOnce("openmw_ui_usertypes"))
|
if (context.initializeOnce("openmw_ui_usertypes"))
|
||||||
{
|
{
|
||||||
auto element = context.mLua->sol().new_usertype<LuaUi::Element>("UiElement");
|
auto element = context.sol().new_usertype<LuaUi::Element>("UiElement");
|
||||||
element[sol::meta_function::to_string] = [](const LuaUi::Element& element) {
|
element[sol::meta_function::to_string] = [](const LuaUi::Element& element) {
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
res << "UiElement";
|
res << "UiElement";
|
||||||
|
@ -321,7 +323,7 @@ namespace MWLua
|
||||||
[element] { wrapAction(element, [&] { LuaUi::Element::erase(element.get()); }); }, "Destroy UI");
|
[element] { wrapAction(element, [&] { LuaUi::Element::erase(element.get()); }); }, "Destroy UI");
|
||||||
};
|
};
|
||||||
|
|
||||||
auto uiLayer = context.mLua->sol().new_usertype<LuaUi::Layer>("UiLayer");
|
auto uiLayer = context.sol().new_usertype<LuaUi::Layer>("UiLayer");
|
||||||
uiLayer["name"]
|
uiLayer["name"]
|
||||||
= sol::readonly_property([](LuaUi::Layer& self) -> std::string_view { return self.name(); });
|
= sol::readonly_property([](LuaUi::Layer& self) -> std::string_view { return self.name(); });
|
||||||
uiLayer["size"] = sol::readonly_property([](LuaUi::Layer& self) { return self.size(); });
|
uiLayer["size"] = sol::readonly_property([](LuaUi::Layer& self) { return self.size(); });
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace MWLua
|
||||||
Log(Debug::Verbose) << "Read a large data chunk (" << size << " bytes) from '" << file.mFileName << "'.";
|
Log(Debug::Verbose) << "Read a large data chunk (" << size << " bytes) from '" << file.mFileName << "'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object readFile(LuaUtil::LuaState* lua, FileHandle& file)
|
sol::object readFile(sol::this_state lua, FileHandle& file)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
if (file.mFilePtr && file.mFilePtr->peek() != EOF)
|
if (file.mFilePtr && file.mFilePtr->peek() != EOF)
|
||||||
|
@ -76,34 +76,34 @@ namespace MWLua
|
||||||
|
|
||||||
auto result = os.str();
|
auto result = os.str();
|
||||||
printLargeDataMessage(file, result.size());
|
printLargeDataMessage(file, result.size());
|
||||||
return sol::make_object<std::string>(lua->sol(), std::move(result));
|
return sol::make_object<std::string>(lua, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object readLineFromFile(LuaUtil::LuaState* lua, FileHandle& file)
|
sol::object readLineFromFile(sol::this_state lua, FileHandle& file)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
if (file.mFilePtr && std::getline(*file.mFilePtr, result))
|
if (file.mFilePtr && std::getline(*file.mFilePtr, result))
|
||||||
{
|
{
|
||||||
printLargeDataMessage(file, result.size());
|
printLargeDataMessage(file, result.size());
|
||||||
return sol::make_object<std::string>(lua->sol(), result);
|
return sol::make_object<std::string>(lua, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object readNumberFromFile(LuaUtil::LuaState* lua, Files::IStreamPtr& file)
|
sol::object readNumberFromFile(sol::this_state lua, Files::IStreamPtr& file)
|
||||||
{
|
{
|
||||||
double number = 0;
|
double number = 0;
|
||||||
if (file && *file >> number)
|
if (file && *file >> number)
|
||||||
return sol::make_object<double>(lua->sol(), number);
|
return sol::make_object<double>(lua, number);
|
||||||
|
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object readCharactersFromFile(LuaUtil::LuaState* lua, FileHandle& file, size_t count)
|
sol::object readCharactersFromFile(sol::this_state lua, FileHandle& file, size_t count)
|
||||||
{
|
{
|
||||||
if (count <= 0 && file.mFilePtr->peek() != EOF)
|
if (count <= 0 && file.mFilePtr->peek() != EOF)
|
||||||
return sol::make_object<std::string>(lua->sol(), std::string());
|
return sol::make_object<std::string>(lua, std::string());
|
||||||
|
|
||||||
auto bytesLeft = getBytesLeftInStream(file.mFilePtr);
|
auto bytesLeft = getBytesLeftInStream(file.mFilePtr);
|
||||||
if (bytesLeft <= 0)
|
if (bytesLeft <= 0)
|
||||||
|
@ -116,7 +116,7 @@ namespace MWLua
|
||||||
if (file.mFilePtr->read(&result[0], count))
|
if (file.mFilePtr->read(&result[0], count))
|
||||||
{
|
{
|
||||||
printLargeDataMessage(file, result.size());
|
printLargeDataMessage(file, result.size());
|
||||||
return sol::make_object<std::string>(lua->sol(), result);
|
return sol::make_object<std::string>(lua, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
|
@ -131,7 +131,7 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::variadic_results seek(
|
sol::variadic_results seek(
|
||||||
LuaUtil::LuaState* lua, FileHandle& self, std::ios_base::seekdir dir, std::streamoff off)
|
sol::this_state lua, FileHandle& self, std::ios_base::seekdir dir, std::streamoff off)
|
||||||
{
|
{
|
||||||
sol::variadic_results values;
|
sol::variadic_results values;
|
||||||
try
|
try
|
||||||
|
@ -141,16 +141,16 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
auto msg = "Failed to seek in file '" + self.mFileName + "'";
|
auto msg = "Failed to seek in file '" + self.mFileName + "'";
|
||||||
values.push_back(sol::nil);
|
values.push_back(sol::nil);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(lua, msg));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
values.push_back(sol::make_object<std::streampos>(lua->sol(), self.mFilePtr->tellg()));
|
values.push_back(sol::make_object<std::streampos>(lua, self.mFilePtr->tellg()));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
auto msg = "Failed to seek in file '" + self.mFileName + "': " + std::string(e.what());
|
auto msg = "Failed to seek in file '" + self.mFileName + "': " + std::string(e.what());
|
||||||
values.push_back(sol::nil);
|
values.push_back(sol::nil);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(lua, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
|
@ -159,18 +159,18 @@ namespace MWLua
|
||||||
|
|
||||||
sol::table initVFSPackage(const Context& context)
|
sol::table initVFSPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::table api(context.mLua->unsafeState(), sol::create);
|
||||||
|
|
||||||
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
sol::usertype<FileHandle> handle = context.mLua->sol().new_usertype<FileHandle>("FileHandle");
|
sol::usertype<FileHandle> handle = context.sol().new_usertype<FileHandle>("FileHandle");
|
||||||
handle["fileName"]
|
handle["fileName"]
|
||||||
= sol::readonly_property([](const FileHandle& self) -> std::string_view { return self.mFileName; });
|
= sol::readonly_property([](const FileHandle& self) -> std::string_view { return self.mFileName; });
|
||||||
handle[sol::meta_function::to_string] = [](const FileHandle& self) {
|
handle[sol::meta_function::to_string] = [](const FileHandle& self) {
|
||||||
return "FileHandle{'" + self.mFileName + "'" + (!self.mFilePtr ? ", closed" : "") + "}";
|
return "FileHandle{'" + self.mFileName + "'" + (!self.mFilePtr ? ", closed" : "") + "}";
|
||||||
};
|
};
|
||||||
handle["seek"] = sol::overload(
|
handle["seek"] = sol::overload(
|
||||||
[lua = context.mLua](FileHandle& self, std::string_view whence, sol::optional<long> offset) {
|
[](sol::this_state lua, FileHandle& self, std::string_view whence, sol::optional<long> offset) {
|
||||||
validateFile(self);
|
validateFile(self);
|
||||||
|
|
||||||
auto off = static_cast<std::streamoff>(offset.value_or(0));
|
auto off = static_cast<std::streamoff>(offset.value_or(0));
|
||||||
|
@ -178,21 +178,21 @@ namespace MWLua
|
||||||
|
|
||||||
return seek(lua, self, dir, off);
|
return seek(lua, self, dir, off);
|
||||||
},
|
},
|
||||||
[lua = context.mLua](FileHandle& self, sol::optional<long> offset) {
|
[](sol::this_state lua, FileHandle& self, sol::optional<long> offset) {
|
||||||
validateFile(self);
|
validateFile(self);
|
||||||
|
|
||||||
auto off = static_cast<std::streamoff>(offset.value_or(0));
|
auto off = static_cast<std::streamoff>(offset.value_or(0));
|
||||||
|
|
||||||
return seek(lua, self, std::ios_base::cur, off);
|
return seek(lua, self, std::ios_base::cur, off);
|
||||||
});
|
});
|
||||||
handle["lines"] = [lua = context.mLua](FileHandle& self) {
|
handle["lines"] = [](sol::this_state lua, FileHandle& self) {
|
||||||
return sol::as_function([&lua, &self]() mutable {
|
return sol::as_function([&lua, &self]() mutable {
|
||||||
validateFile(self);
|
validateFile(self);
|
||||||
return readLineFromFile(lua, self);
|
return readLineFromFile(lua, self);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
api["lines"] = [lua = context.mLua, vfs](std::string_view fileName) {
|
api["lines"] = [vfs](sol::this_state lua, std::string_view fileName) {
|
||||||
auto normalizedName = VFS::Path::normalizeFilename(fileName);
|
auto normalizedName = VFS::Path::normalizeFilename(fileName);
|
||||||
return sol::as_function(
|
return sol::as_function(
|
||||||
[lua, file = FileHandle(vfs->getNormalized(normalizedName), normalizedName)]() mutable {
|
[lua, file = FileHandle(vfs->getNormalized(normalizedName), normalizedName)]() mutable {
|
||||||
|
@ -205,7 +205,7 @@ namespace MWLua
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handle["close"] = [lua = context.mLua](FileHandle& self) {
|
handle["close"] = [](lua_State* L, FileHandle& self) {
|
||||||
sol::variadic_results values;
|
sol::variadic_results values;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -214,22 +214,22 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
auto msg = "Can not close file '" + self.mFileName + "': file handle is still opened.";
|
auto msg = "Can not close file '" + self.mFileName + "': file handle is still opened.";
|
||||||
values.push_back(sol::nil);
|
values.push_back(sol::nil);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(L, msg));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
values.push_back(sol::make_object<bool>(lua->sol(), true));
|
values.push_back(sol::make_object<bool>(L, true));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
auto msg = "Can not close file '" + self.mFileName + "': " + std::string(e.what());
|
auto msg = "Can not close file '" + self.mFileName + "': " + std::string(e.what());
|
||||||
values.push_back(sol::nil);
|
values.push_back(sol::nil);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(L, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
};
|
};
|
||||||
|
|
||||||
handle["read"] = [lua = context.mLua](FileHandle& self, const sol::variadic_args args) {
|
handle["read"] = [](sol::this_state lua, FileHandle& self, const sol::variadic_args args) {
|
||||||
validateFile(self);
|
validateFile(self);
|
||||||
|
|
||||||
if (args.size() > sMaximumReadArguments)
|
if (args.size() > sMaximumReadArguments)
|
||||||
|
@ -297,25 +297,25 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
auto msg = "Error when handling '" + self.mFileName + "': can not read data for argument #"
|
auto msg = "Error when handling '" + self.mFileName + "': can not read data for argument #"
|
||||||
+ std::to_string(i);
|
+ std::to_string(i);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(lua, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
};
|
};
|
||||||
|
|
||||||
api["open"] = [lua = context.mLua, vfs](std::string_view fileName) {
|
api["open"] = [vfs](sol::this_state lua, std::string_view fileName) {
|
||||||
sol::variadic_results values;
|
sol::variadic_results values;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto normalizedName = VFS::Path::normalizeFilename(fileName);
|
auto normalizedName = VFS::Path::normalizeFilename(fileName);
|
||||||
auto handle = FileHandle(vfs->getNormalized(normalizedName), normalizedName);
|
auto handle = FileHandle(vfs->getNormalized(normalizedName), normalizedName);
|
||||||
values.push_back(sol::make_object<FileHandle>(lua->sol(), std::move(handle)));
|
values.push_back(sol::make_object<FileHandle>(lua, std::move(handle)));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
auto msg = "Can not open file: " + std::string(e.what());
|
auto msg = "Can not open file: " + std::string(e.what());
|
||||||
values.push_back(sol::nil);
|
values.push_back(sol::nil);
|
||||||
values.push_back(sol::make_object<std::string>(lua->sol(), msg));
|
values.push_back(sol::make_object<std::string>(lua, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
|
|
|
@ -102,7 +102,8 @@ namespace MWLua
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Cell>* cells3Store = &MWBase::Environment::get().getESMStore()->get<ESM::Cell>();
|
const MWWorld::Store<ESM::Cell>* cells3Store = &MWBase::Environment::get().getESMStore()->get<ESM::Cell>();
|
||||||
const MWWorld::Store<ESM4::Cell>* cells4Store = &MWBase::Environment::get().getESMStore()->get<ESM4::Cell>();
|
const MWWorld::Store<ESM4::Cell>* cells4Store = &MWBase::Environment::get().getESMStore()->get<ESM4::Cell>();
|
||||||
sol::usertype<CellsStore> cells = context.mLua->sol().new_usertype<CellsStore>("Cells");
|
auto view = context.sol();
|
||||||
|
sol::usertype<CellsStore> cells = view.new_usertype<CellsStore>("Cells");
|
||||||
cells[sol::meta_function::length]
|
cells[sol::meta_function::length]
|
||||||
= [cells3Store, cells4Store](const CellsStore&) { return cells3Store->getSize() + cells4Store->getSize(); };
|
= [cells3Store, cells4Store](const CellsStore&) { return cells3Store->getSize() + cells4Store->getSize(); };
|
||||||
cells[sol::meta_function::index]
|
cells[sol::meta_function::index]
|
||||||
|
@ -124,14 +125,14 @@ namespace MWLua
|
||||||
cellRecord->mId, /*forceLoad=*/false) };
|
cellRecord->mId, /*forceLoad=*/false) };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cells[sol::meta_function::pairs] = context.mLua->sol()["ipairsForArray"].template get<sol::function>();
|
cells[sol::meta_function::pairs] = view["ipairsForArray"].template get<sol::function>();
|
||||||
cells[sol::meta_function::ipairs] = context.mLua->sol()["ipairsForArray"].template get<sol::function>();
|
cells[sol::meta_function::ipairs] = view["ipairsForArray"].template get<sol::function>();
|
||||||
api["cells"] = CellsStore{};
|
api["cells"] = CellsStore{};
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initWorldPackage(const Context& context)
|
sol::table initWorldPackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::table api(context.mLua->unsafeState(), sol::create);
|
||||||
|
|
||||||
addCoreTimeBindings(api, context);
|
addCoreTimeBindings(api, context);
|
||||||
addWorldTimeBindings(api, context);
|
addWorldTimeBindings(api, context);
|
||||||
|
|
|
@ -176,121 +176,125 @@ namespace LuaUtil
|
||||||
if (sProfilerEnabled)
|
if (sProfilerEnabled)
|
||||||
lua_sethook(mLuaHolder.get(), &countHook, LUA_MASKCOUNT, countHookStep);
|
lua_sethook(mLuaHolder.get(), &countHook, LUA_MASKCOUNT, countHookStep);
|
||||||
|
|
||||||
mSol.open_libraries(sol::lib::base, sol::lib::coroutine, sol::lib::math, sol::lib::bit32, sol::lib::string,
|
protectedCall([&](LuaView& view) {
|
||||||
sol::lib::table, sol::lib::os, sol::lib::debug);
|
auto& sol = view.sol();
|
||||||
|
sol.open_libraries(sol::lib::base, sol::lib::coroutine, sol::lib::math, sol::lib::bit32, sol::lib::string,
|
||||||
|
sol::lib::table, sol::lib::os, sol::lib::debug);
|
||||||
|
|
||||||
#ifndef NO_LUAJIT
|
#ifndef NO_LUAJIT
|
||||||
mSol.open_libraries(sol::lib::jit);
|
sol.open_libraries(sol::lib::jit);
|
||||||
#endif // NO_LUAJIT
|
#endif // NO_LUAJIT
|
||||||
|
|
||||||
mSol["math"]["randomseed"](static_cast<unsigned>(std::time(nullptr)));
|
sol["math"]["randomseed"](static_cast<unsigned>(std::time(nullptr)));
|
||||||
mSol["math"]["randomseed"] = [] {};
|
sol["math"]["randomseed"] = [] {};
|
||||||
|
|
||||||
mSol["utf8"] = LuaUtf8::initUtf8Package(mSol);
|
sol["utf8"] = LuaUtf8::initUtf8Package(sol);
|
||||||
|
|
||||||
mSol["writeToLog"] = [](std::string_view s) { Log(Debug::Level::Info) << s; };
|
sol["writeToLog"] = [](std::string_view s) { Log(Debug::Level::Info) << s; };
|
||||||
|
|
||||||
mSol["setEnvironment"]
|
sol["setEnvironment"]
|
||||||
= [](const sol::environment& env, const sol::function& fn) { sol::set_environment(env, fn); };
|
= [](const sol::environment& env, const sol::function& fn) { sol::set_environment(env, fn); };
|
||||||
mSol["loadFromVFS"] = [this](std::string_view packageName) {
|
sol["loadFromVFS"] = [this](std::string_view packageName) {
|
||||||
return loadScriptAndCache(packageNameToVfsPath(packageName, mVFS));
|
return loadScriptAndCache(packageNameToVfsPath(packageName, mVFS));
|
||||||
};
|
};
|
||||||
mSol["loadInternalLib"] = [this](std::string_view packageName) { return loadInternalLib(packageName); };
|
sol["loadInternalLib"] = [this](std::string_view packageName) { return loadInternalLib(packageName); };
|
||||||
|
|
||||||
// Some fixes for compatibility between different Lua versions
|
// Some fixes for compatibility between different Lua versions
|
||||||
if (mSol["unpack"] == sol::nil)
|
if (sol["unpack"] == sol::nil)
|
||||||
mSol["unpack"] = mSol["table"]["unpack"];
|
sol["unpack"] = sol["table"]["unpack"];
|
||||||
else if (mSol["table"]["unpack"] == sol::nil)
|
else if (sol["table"]["unpack"] == sol::nil)
|
||||||
mSol["table"]["unpack"] = mSol["unpack"];
|
sol["table"]["unpack"] = sol["unpack"];
|
||||||
if (LUA_VERSION_NUM <= 501)
|
if (LUA_VERSION_NUM <= 501)
|
||||||
{
|
{
|
||||||
mSol.script(R"(
|
sol.script(R"(
|
||||||
local _pairs = pairs
|
local _pairs = pairs
|
||||||
local _ipairs = ipairs
|
local _ipairs = ipairs
|
||||||
pairs = function(v) return (rawget(getmetatable(v) or {}, '__pairs') or _pairs)(v) end
|
pairs = function(v) return (rawget(getmetatable(v) or {}, '__pairs') or _pairs)(v) end
|
||||||
ipairs = function(v) return (rawget(getmetatable(v) or {}, '__ipairs') or _ipairs)(v) end
|
ipairs = function(v) return (rawget(getmetatable(v) or {}, '__ipairs') or _ipairs)(v) end
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
sol.script(R"(
|
||||||
|
local printToLog = function(...)
|
||||||
|
local strs = {}
|
||||||
|
for i = 1, select('#', ...) do
|
||||||
|
strs[i] = tostring(select(i, ...))
|
||||||
|
end
|
||||||
|
return writeToLog(table.concat(strs, '\t'))
|
||||||
|
end
|
||||||
|
printGen = function(name) return function(...) return printToLog(name, ...) end end
|
||||||
|
|
||||||
|
function requireGen(env, loaded, loadFn)
|
||||||
|
return function(packageName)
|
||||||
|
local p = loaded[packageName]
|
||||||
|
if p == nil then
|
||||||
|
local loader = loadFn(packageName)
|
||||||
|
setEnvironment(env, loader)
|
||||||
|
p = loader(packageName)
|
||||||
|
loaded[packageName] = p
|
||||||
|
end
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function createStrictIndexFn(tbl)
|
||||||
|
return function(_, key)
|
||||||
|
local res = tbl[key]
|
||||||
|
if res ~= nil then
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
error('Key not found: '..tostring(key), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function pairsForReadOnly(v)
|
||||||
|
local nextFn, t, firstKey = pairs(getmetatable(v).t)
|
||||||
|
return function(_, k) return nextFn(t, k) end, v, firstKey
|
||||||
|
end
|
||||||
|
function ipairsForReadOnly(v)
|
||||||
|
local nextFn, t, firstKey = ipairs(getmetatable(v).t)
|
||||||
|
return function(_, k) return nextFn(t, k) end, v, firstKey
|
||||||
|
end
|
||||||
|
function lenForReadOnly(v)
|
||||||
|
return #getmetatable(v).t
|
||||||
|
end
|
||||||
|
local function nextForArray(array, index)
|
||||||
|
index = (index or 0) + 1
|
||||||
|
if index <= #array then
|
||||||
|
return index, array[index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function ipairsForArray(array)
|
||||||
|
return nextForArray, array, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
getmetatable('').__metatable = false
|
||||||
|
getSafeMetatable = function(v)
|
||||||
|
if type(v) ~= 'table' then error('getmetatable is allowed only for tables', 2) end
|
||||||
|
return getmetatable(v)
|
||||||
|
end
|
||||||
)");
|
)");
|
||||||
}
|
|
||||||
|
|
||||||
mSol.script(R"(
|
mSandboxEnv = sol::table(sol, sol::create);
|
||||||
local printToLog = function(...)
|
mSandboxEnv["_VERSION"] = sol["_VERSION"];
|
||||||
local strs = {}
|
for (const std::string& s : safeFunctions)
|
||||||
for i = 1, select('#', ...) do
|
{
|
||||||
strs[i] = tostring(select(i, ...))
|
if (sol[s] == sol::nil)
|
||||||
end
|
throw std::logic_error("Lua function not found: " + s);
|
||||||
return writeToLog(table.concat(strs, '\t'))
|
mSandboxEnv[s] = sol[s];
|
||||||
end
|
}
|
||||||
printGen = function(name) return function(...) return printToLog(name, ...) end end
|
for (const std::string& s : safePackages)
|
||||||
|
{
|
||||||
function requireGen(env, loaded, loadFn)
|
if (sol[s] == sol::nil)
|
||||||
return function(packageName)
|
throw std::logic_error("Lua package not found: " + s);
|
||||||
local p = loaded[packageName]
|
mCommonPackages[s] = mSandboxEnv[s] = makeReadOnly(sol[s]);
|
||||||
if p == nil then
|
}
|
||||||
local loader = loadFn(packageName)
|
mSandboxEnv["getmetatable"] = sol["getSafeMetatable"];
|
||||||
setEnvironment(env, loader)
|
mCommonPackages["os"] = mSandboxEnv["os"]
|
||||||
p = loader(packageName)
|
= makeReadOnly(tableFromPairs<std::string_view, sol::function>(sol,
|
||||||
loaded[packageName] = p
|
{ { "date", sol["os"]["date"] }, { "difftime", sol["os"]["difftime"] },
|
||||||
end
|
{ "time", sol["os"]["time"] } }));
|
||||||
return p
|
});
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function createStrictIndexFn(tbl)
|
|
||||||
return function(_, key)
|
|
||||||
local res = tbl[key]
|
|
||||||
if res ~= nil then
|
|
||||||
return res
|
|
||||||
else
|
|
||||||
error('Key not found: '..tostring(key), 2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function pairsForReadOnly(v)
|
|
||||||
local nextFn, t, firstKey = pairs(getmetatable(v).t)
|
|
||||||
return function(_, k) return nextFn(t, k) end, v, firstKey
|
|
||||||
end
|
|
||||||
function ipairsForReadOnly(v)
|
|
||||||
local nextFn, t, firstKey = ipairs(getmetatable(v).t)
|
|
||||||
return function(_, k) return nextFn(t, k) end, v, firstKey
|
|
||||||
end
|
|
||||||
function lenForReadOnly(v)
|
|
||||||
return #getmetatable(v).t
|
|
||||||
end
|
|
||||||
local function nextForArray(array, index)
|
|
||||||
index = (index or 0) + 1
|
|
||||||
if index <= #array then
|
|
||||||
return index, array[index]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function ipairsForArray(array)
|
|
||||||
return nextForArray, array, 0
|
|
||||||
end
|
|
||||||
|
|
||||||
getmetatable('').__metatable = false
|
|
||||||
getSafeMetatable = function(v)
|
|
||||||
if type(v) ~= 'table' then error('getmetatable is allowed only for tables', 2) end
|
|
||||||
return getmetatable(v)
|
|
||||||
end
|
|
||||||
)");
|
|
||||||
|
|
||||||
mSandboxEnv = sol::table(mSol, sol::create);
|
|
||||||
mSandboxEnv["_VERSION"] = mSol["_VERSION"];
|
|
||||||
for (const std::string& s : safeFunctions)
|
|
||||||
{
|
|
||||||
if (mSol[s] == sol::nil)
|
|
||||||
throw std::logic_error("Lua function not found: " + s);
|
|
||||||
mSandboxEnv[s] = mSol[s];
|
|
||||||
}
|
|
||||||
for (const std::string& s : safePackages)
|
|
||||||
{
|
|
||||||
if (mSol[s] == sol::nil)
|
|
||||||
throw std::logic_error("Lua package not found: " + s);
|
|
||||||
mCommonPackages[s] = mSandboxEnv[s] = makeReadOnly(mSol[s]);
|
|
||||||
}
|
|
||||||
mSandboxEnv["getmetatable"] = mSol["getSafeMetatable"];
|
|
||||||
mCommonPackages["os"] = mSandboxEnv["os"]
|
|
||||||
= makeReadOnly(tableFromPairs<std::string_view, sol::function>({ { "date", mSol["os"]["date"] },
|
|
||||||
{ "difftime", mSol["os"]["difftime"] }, { "time", mSol["os"]["time"] } }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table makeReadOnly(const sol::table& table, bool strictIndex)
|
sol::table makeReadOnly(const sol::table& table, bool strictIndex)
|
||||||
|
@ -333,6 +337,7 @@ namespace LuaUtil
|
||||||
sol::protected_function_result LuaState::runInNewSandbox(const std::string& path, const std::string& namePrefix,
|
sol::protected_function_result LuaState::runInNewSandbox(const std::string& path, const std::string& namePrefix,
|
||||||
const std::map<std::string, sol::object>& packages, const sol::object& hiddenData)
|
const std::map<std::string, sol::object>& packages, const sol::object& hiddenData)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
sol::protected_function script = loadScriptAndCache(path);
|
sol::protected_function script = loadScriptAndCache(path);
|
||||||
|
|
||||||
sol::environment env(mSol, sol::create, mSandboxEnv);
|
sol::environment env(mSol, sol::create, mSandboxEnv);
|
||||||
|
@ -366,6 +371,7 @@ namespace LuaUtil
|
||||||
|
|
||||||
sol::environment LuaState::newInternalLibEnvironment()
|
sol::environment LuaState::newInternalLibEnvironment()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
sol::environment env(mSol, sol::create, mSandboxEnv);
|
sol::environment env(mSol, sol::create, mSandboxEnv);
|
||||||
sol::table loaded(mSol, sol::create);
|
sol::table loaded(mSol, sol::create);
|
||||||
for (const std::string& s : safePackages)
|
for (const std::string& s : safePackages)
|
||||||
|
|
|
@ -34,6 +34,36 @@ namespace LuaUtil
|
||||||
bool mLogMemoryUsage = false;
|
bool mLogMemoryUsage = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LuaState;
|
||||||
|
class LuaView
|
||||||
|
{
|
||||||
|
sol::state_view mSol;
|
||||||
|
|
||||||
|
LuaView(const LuaView&) = delete;
|
||||||
|
|
||||||
|
LuaView(lua_State* L)
|
||||||
|
: mSol(L)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LuaState;
|
||||||
|
// Returns underlying sol::state.
|
||||||
|
sol::state_view& sol() { return mSol; }
|
||||||
|
|
||||||
|
// A shortcut to create a new Lua table.
|
||||||
|
sol::table newTable() { return sol::table(mSol, sol::create); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Key, typename Value>
|
||||||
|
sol::table tableFromPairs(lua_State* L, std::initializer_list<std::pair<Key, Value>> list)
|
||||||
|
{
|
||||||
|
sol::table res(L, sol::create);
|
||||||
|
for (const auto& [k, v] : list)
|
||||||
|
res[k] = v;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// Holds Lua state.
|
// Holds Lua state.
|
||||||
// Provides additional features:
|
// Provides additional features:
|
||||||
// - Load scripts from the virtual filesystem;
|
// - Load scripts from the virtual filesystem;
|
||||||
|
@ -54,26 +84,53 @@ namespace LuaUtil
|
||||||
LuaState(const LuaState&) = delete;
|
LuaState(const LuaState&) = delete;
|
||||||
LuaState(LuaState&&) = delete;
|
LuaState(LuaState&&) = delete;
|
||||||
|
|
||||||
// Returns underlying sol::state.
|
// Pushing to the stack from outside a Lua context crashes the engine if no memory can be allocated to grow the
|
||||||
sol::state_view& sol() { return mSol; }
|
// stack
|
||||||
|
template <class Lambda>
|
||||||
|
[[nodiscard]] int invokeProtectedCall(Lambda&& f) const
|
||||||
|
{
|
||||||
|
if (!lua_checkstack(mSol.lua_state(), 2))
|
||||||
|
return LUA_ERRMEM;
|
||||||
|
lua_pushcfunction(mSol.lua_state(), [](lua_State* L) {
|
||||||
|
void* f = lua_touserdata(L, 1);
|
||||||
|
LuaView view(L);
|
||||||
|
(*static_cast<Lambda*>(f))(view);
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
lua_pushlightuserdata(mSol.lua_state(), &f);
|
||||||
|
return lua_pcall(mSol.lua_state(), 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Lambda>
|
||||||
|
void protectedCall(Lambda&& f) const
|
||||||
|
{
|
||||||
|
int result = invokeProtectedCall(std::forward<Lambda>(f));
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case LUA_OK:
|
||||||
|
break;
|
||||||
|
case LUA_ERRMEM:
|
||||||
|
throw std::runtime_error("Lua error: out of memory");
|
||||||
|
case LUA_ERRRUN:
|
||||||
|
{
|
||||||
|
sol::optional<std::string> error = sol::stack::check_get<std::string>(mSol.lua_state());
|
||||||
|
if (error)
|
||||||
|
throw std::runtime_error(*error);
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Lua error: " + std::to_string(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that constructing a sol::state_view is only safe from a Lua context. Use protectedCall to get one
|
||||||
|
lua_State* unsafeState() const { return mSol.lua_state(); }
|
||||||
|
|
||||||
// Can be used by a C++ function that is called from Lua to get the Lua traceback.
|
// Can be used by a C++ function that is called from Lua to get the Lua traceback.
|
||||||
// Makes no sense if called not from Lua code.
|
// Makes no sense if called not from Lua code.
|
||||||
// Note: It is a slow function, should be used for debug purposes only.
|
// Note: It is a slow function, should be used for debug purposes only.
|
||||||
std::string debugTraceback() { return mSol["debug"]["traceback"]().get<std::string>(); }
|
std::string debugTraceback() { return mSol["debug"]["traceback"]().get<std::string>(); }
|
||||||
|
|
||||||
// A shortcut to create a new Lua table.
|
|
||||||
sol::table newTable() { return sol::table(mSol, sol::create); }
|
|
||||||
|
|
||||||
template <typename Key, typename Value>
|
|
||||||
sol::table tableFromPairs(std::initializer_list<std::pair<Key, Value>> list)
|
|
||||||
{
|
|
||||||
sol::table res(mSol, sol::create);
|
|
||||||
for (const auto& [k, v] : list)
|
|
||||||
res[k] = v;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers a package that will be available from every sandbox via `require(name)`.
|
// Registers a package that will be available from every sandbox via `require(name)`.
|
||||||
// The package can be either a sol::table with an API or a sol::function. If it is a function,
|
// The package can be either a sol::table with an API or a sol::function. If it is a function,
|
||||||
// it will be evaluated (once per sandbox) the first time when requested. If the package
|
// it will be evaluated (once per sandbox) the first time when requested. If the package
|
||||||
|
|
|
@ -24,8 +24,10 @@ namespace LuaUtil
|
||||||
{
|
{
|
||||||
sInstanceCount++;
|
sInstanceCount++;
|
||||||
registerEngineHandlers({ &mUpdateHandlers });
|
registerEngineHandlers({ &mUpdateHandlers });
|
||||||
mPublicInterfaces = sol::table(lua->sol(), sol::create);
|
lua->protectedCall([&](LuaView& view) {
|
||||||
addPackage("openmw.interfaces", mPublicInterfaces);
|
mPublicInterfaces = sol::table(view.sol(), sol::create);
|
||||||
|
addPackage("openmw.interfaces", mPublicInterfaces);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptsContainer::printError(int scriptId, std::string_view msg, const std::exception& e)
|
void ScriptsContainer::printError(int scriptId, std::string_view msg, const std::exception& e)
|
||||||
|
@ -41,26 +43,31 @@ namespace LuaUtil
|
||||||
bool ScriptsContainer::addCustomScript(int scriptId, std::string_view initData)
|
bool ScriptsContainer::addCustomScript(int scriptId, std::string_view initData)
|
||||||
{
|
{
|
||||||
assert(mLua.getConfiguration().isCustomScript(scriptId));
|
assert(mLua.getConfiguration().isCustomScript(scriptId));
|
||||||
std::optional<sol::function> onInit, onLoad;
|
bool ok = false;
|
||||||
bool ok = addScript(scriptId, onInit, onLoad);
|
mLua.protectedCall([&](LuaView& view) {
|
||||||
if (ok && onInit)
|
std::optional<sol::function> onInit, onLoad;
|
||||||
callOnInit(scriptId, *onInit, initData);
|
bool ok = addScript(view, scriptId, onInit, onLoad);
|
||||||
|
if (ok && onInit)
|
||||||
|
callOnInit(view, scriptId, *onInit, initData);
|
||||||
|
});
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptsContainer::addAutoStartedScripts()
|
void ScriptsContainer::addAutoStartedScripts()
|
||||||
{
|
{
|
||||||
for (const auto& [scriptId, data] : mAutoStartScripts)
|
mLua.protectedCall([&](LuaView& view) {
|
||||||
{
|
for (const auto& [scriptId, data] : mAutoStartScripts)
|
||||||
std::optional<sol::function> onInit, onLoad;
|
{
|
||||||
bool ok = addScript(scriptId, onInit, onLoad);
|
std::optional<sol::function> onInit, onLoad;
|
||||||
if (ok && onInit)
|
bool ok = addScript(view, scriptId, onInit, onLoad);
|
||||||
callOnInit(scriptId, *onInit, data);
|
if (ok && onInit)
|
||||||
}
|
callOnInit(view, scriptId, *onInit, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptsContainer::addScript(
|
bool ScriptsContainer::addScript(
|
||||||
int scriptId, std::optional<sol::function>& onInit, std::optional<sol::function>& onLoad)
|
LuaView& view, int scriptId, std::optional<sol::function>& onInit, std::optional<sol::function>& onLoad)
|
||||||
{
|
{
|
||||||
assert(scriptId >= 0 && scriptId < static_cast<int>(mLua.getConfiguration().size()));
|
assert(scriptId >= 0 && scriptId < static_cast<int>(mLua.getConfiguration().size()));
|
||||||
if (mScripts.count(scriptId) != 0)
|
if (mScripts.count(scriptId) != 0)
|
||||||
|
@ -73,7 +80,7 @@ namespace LuaUtil
|
||||||
debugName.push_back(']');
|
debugName.push_back(']');
|
||||||
|
|
||||||
Script& script = mScripts[scriptId];
|
Script& script = mScripts[scriptId];
|
||||||
script.mHiddenData = mLua.newTable();
|
script.mHiddenData = view.newTable();
|
||||||
script.mHiddenData[sScriptIdKey] = ScriptId{ this, scriptId };
|
script.mHiddenData[sScriptIdKey] = ScriptId{ this, scriptId };
|
||||||
script.mHiddenData[sScriptDebugNameKey] = debugName;
|
script.mHiddenData[sScriptDebugNameKey] = debugName;
|
||||||
script.mPath = path;
|
script.mPath = path;
|
||||||
|
@ -298,32 +305,34 @@ namespace LuaUtil
|
||||||
auto it = mEventHandlers.find(eventName);
|
auto it = mEventHandlers.find(eventName);
|
||||||
if (it == mEventHandlers.end())
|
if (it == mEventHandlers.end())
|
||||||
return;
|
return;
|
||||||
sol::object data;
|
mLua.protectedCall([&](LuaView& view) {
|
||||||
try
|
sol::object data;
|
||||||
{
|
|
||||||
data = LuaUtil::deserialize(mLua.sol(), eventData, mSerializer);
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
Log(Debug::Error) << mNamePrefix << " can not parse eventData for '" << eventName << "': " << e.what();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
EventHandlerList& list = it->second;
|
|
||||||
for (int i = list.size() - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
const Handler& h = list[i];
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sol::object res = LuaUtil::call({ this, h.mScriptId }, h.mFn, data);
|
data = LuaUtil::deserialize(view.sol(), eventData, mSerializer);
|
||||||
if (res.is<bool>() && !res.as<bool>())
|
|
||||||
break; // Skip other handlers if 'false' was returned.
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << mNamePrefix << "[" << scriptPath(h.mScriptId) << "] eventHandler[" << eventName
|
Log(Debug::Error) << mNamePrefix << " can not parse eventData for '" << eventName << "': " << e.what();
|
||||||
<< "] failed. " << e.what();
|
return;
|
||||||
}
|
}
|
||||||
}
|
EventHandlerList& list = it->second;
|
||||||
|
for (int i = list.size() - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
const Handler& h = list[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sol::object res = LuaUtil::call({ this, h.mScriptId }, h.mFn, data);
|
||||||
|
if (res.is<bool>() && !res.as<bool>())
|
||||||
|
break; // Skip other handlers if 'false' was returned.
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << mNamePrefix << "[" << scriptPath(h.mScriptId) << "] eventHandler[" << eventName
|
||||||
|
<< "] failed. " << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptsContainer::registerEngineHandlers(std::initializer_list<EngineHandlerList*> handlers)
|
void ScriptsContainer::registerEngineHandlers(std::initializer_list<EngineHandlerList*> handlers)
|
||||||
|
@ -332,11 +341,11 @@ namespace LuaUtil
|
||||||
mEngineHandlers[h->mName] = h;
|
mEngineHandlers[h->mName] = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptsContainer::callOnInit(int scriptId, const sol::function& onInit, std::string_view data)
|
void ScriptsContainer::callOnInit(LuaView& view, int scriptId, const sol::function& onInit, std::string_view data)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LuaUtil::call({ this, scriptId }, onInit, deserialize(mLua.sol(), data, mSerializer));
|
LuaUtil::call({ this, scriptId }, onInit, deserialize(view.sol(), data, mSerializer));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -418,57 +427,61 @@ namespace LuaUtil
|
||||||
<< "]; this script is not allowed here";
|
<< "]; this script is not allowed here";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [scriptId, scriptInfo] : scripts)
|
mLua.protectedCall([&](LuaView& view) {
|
||||||
{
|
for (const auto& [scriptId, scriptInfo] : scripts)
|
||||||
std::optional<sol::function> onInit, onLoad;
|
|
||||||
if (!addScript(scriptId, onInit, onLoad))
|
|
||||||
continue;
|
|
||||||
if (scriptInfo.mSavedData == nullptr)
|
|
||||||
{
|
{
|
||||||
if (onInit)
|
std::optional<sol::function> onInit, onLoad;
|
||||||
callOnInit(scriptId, *onInit, scriptInfo.mInitData);
|
if (!addScript(view, scriptId, onInit, onLoad))
|
||||||
continue;
|
continue;
|
||||||
}
|
if (scriptInfo.mSavedData == nullptr)
|
||||||
if (onLoad)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
sol::object state = deserialize(mLua.sol(), scriptInfo.mSavedData->mData, mSavedDataDeserializer);
|
if (onInit)
|
||||||
sol::object initializationData = deserialize(mLua.sol(), scriptInfo.mInitData, mSerializer);
|
callOnInit(view, scriptId, *onInit, scriptInfo.mInitData);
|
||||||
LuaUtil::call({ this, scriptId }, *onLoad, state, initializationData);
|
continue;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
if (onLoad)
|
||||||
{
|
{
|
||||||
printError(scriptId, "onLoad failed", e);
|
try
|
||||||
|
{
|
||||||
|
sol::object state
|
||||||
|
= deserialize(view.sol(), scriptInfo.mSavedData->mData, mSavedDataDeserializer);
|
||||||
|
sol::object initializationData = deserialize(view.sol(), scriptInfo.mInitData, mSerializer);
|
||||||
|
LuaUtil::call({ this, scriptId }, *onLoad, state, initializationData);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
printError(scriptId, "onLoad failed", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
for (const ESM::LuaTimer& savedTimer : scriptInfo.mSavedData->mTimers)
|
||||||
for (const ESM::LuaTimer& savedTimer : scriptInfo.mSavedData->mTimers)
|
{
|
||||||
{
|
Timer timer;
|
||||||
Timer timer;
|
timer.mCallback = savedTimer.mCallbackName;
|
||||||
timer.mCallback = savedTimer.mCallbackName;
|
timer.mSerializable = true;
|
||||||
timer.mSerializable = true;
|
timer.mScriptId = scriptId;
|
||||||
timer.mScriptId = scriptId;
|
timer.mTime = savedTimer.mTime;
|
||||||
timer.mTime = savedTimer.mTime;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
timer.mArg = sol::main_object(
|
timer.mArg = sol::main_object(
|
||||||
deserialize(mLua.sol(), savedTimer.mCallbackArgument, mSavedDataDeserializer));
|
deserialize(view.sol(), savedTimer.mCallbackArgument, mSavedDataDeserializer));
|
||||||
// It is important if the order of content files was changed. The deserialize-serialize procedure
|
// It is important if the order of content files was changed. The deserialize-serialize
|
||||||
// updates refnums, so timer.mSerializedArg may be not equal to savedTimer.mCallbackArgument.
|
// procedure updates refnums, so timer.mSerializedArg may be not equal to
|
||||||
timer.mSerializedArg = serialize(timer.mArg, mSerializer);
|
// savedTimer.mCallbackArgument.
|
||||||
|
timer.mSerializedArg = serialize(timer.mArg, mSerializer);
|
||||||
|
|
||||||
if (savedTimer.mType == TimerType::GAME_TIME)
|
if (savedTimer.mType == TimerType::GAME_TIME)
|
||||||
mGameTimersQueue.push_back(std::move(timer));
|
mGameTimersQueue.push_back(std::move(timer));
|
||||||
else
|
else
|
||||||
mSimulationTimersQueue.push_back(std::move(timer));
|
mSimulationTimersQueue.push_back(std::move(timer));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
printError(scriptId, "can not load timer", e);
|
printError(scriptId, "can not load timer", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
std::make_heap(mSimulationTimersQueue.begin(), mSimulationTimersQueue.end());
|
std::make_heap(mSimulationTimersQueue.begin(), mSimulationTimersQueue.end());
|
||||||
std::make_heap(mGameTimersQueue.begin(), mGameTimersQueue.end());
|
std::make_heap(mGameTimersQueue.begin(), mGameTimersQueue.end());
|
||||||
|
|
|
@ -232,14 +232,15 @@ namespace LuaUtil
|
||||||
void addMemoryUsage(int scriptId, int64_t memoryDelta);
|
void addMemoryUsage(int scriptId, int64_t memoryDelta);
|
||||||
|
|
||||||
// Add to container without calling onInit/onLoad.
|
// Add to container without calling onInit/onLoad.
|
||||||
bool addScript(int scriptId, std::optional<sol::function>& onInit, std::optional<sol::function>& onLoad);
|
bool addScript(
|
||||||
|
LuaView& view, int scriptId, std::optional<sol::function>& onInit, std::optional<sol::function>& onLoad);
|
||||||
|
|
||||||
// Returns script by id (throws an exception if doesn't exist)
|
// Returns script by id (throws an exception if doesn't exist)
|
||||||
Script& getScript(int scriptId);
|
Script& getScript(int scriptId);
|
||||||
|
|
||||||
void printError(int scriptId, std::string_view msg, const std::exception& e);
|
void printError(int scriptId, std::string_view msg, const std::exception& e);
|
||||||
const std::string& scriptPath(int scriptId) const { return mLua.getConfiguration()[scriptId].mScriptPath; }
|
const std::string& scriptPath(int scriptId) const { return mLua.getConfiguration()[scriptId].mScriptPath; }
|
||||||
void callOnInit(int scriptId, const sol::function& onInit, std::string_view data);
|
void callOnInit(LuaView& view, int scriptId, const sol::function& onInit, std::string_view data);
|
||||||
void callTimer(const Timer& t);
|
void callTimer(const Timer& t);
|
||||||
void updateTimerQueue(std::vector<Timer>& timerQueue, double time);
|
void updateTimerQueue(std::vector<Timer>& timerQueue, double time);
|
||||||
static void insertTimer(std::vector<Timer>& timerQueue, Timer&& t);
|
static void insertTimer(std::vector<Timer>& timerQueue, Timer&& t);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
#include "luastate.hpp"
|
||||||
|
|
||||||
namespace sol
|
namespace sol
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
|
@ -17,13 +19,14 @@ namespace LuaUtil
|
||||||
{
|
{
|
||||||
LuaStorage::Value LuaStorage::Section::sEmpty;
|
LuaStorage::Value LuaStorage::Section::sEmpty;
|
||||||
|
|
||||||
void LuaStorage::registerLifeTime(LuaUtil::LuaState& luaState, sol::table& res)
|
void LuaStorage::registerLifeTime(LuaUtil::LuaView& view, sol::table& res)
|
||||||
{
|
{
|
||||||
res["LIFE_TIME"] = LuaUtil::makeStrictReadOnly(luaState.tableFromPairs<std::string_view, Section::LifeTime>({
|
res["LIFE_TIME"] = LuaUtil::makeStrictReadOnly(tableFromPairs<std::string_view, Section::LifeTime>(view.sol(),
|
||||||
{ "Persistent", Section::LifeTime::Persistent },
|
{
|
||||||
{ "GameSession", Section::LifeTime::GameSession },
|
{ "Persistent", Section::LifeTime::Persistent },
|
||||||
{ "Temporary", Section::LifeTime::Temporary },
|
{ "GameSession", Section::LifeTime::GameSession },
|
||||||
}));
|
{ "Temporary", Section::LifeTime::Temporary },
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object LuaStorage::Value::getCopy(lua_State* L) const
|
sol::object LuaStorage::Value::getCopy(lua_State* L) const
|
||||||
|
@ -112,26 +115,26 @@ namespace LuaUtil
|
||||||
runCallbacks(sol::nullopt);
|
runCallbacks(sol::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::Section::asTable()
|
sol::table LuaStorage::Section::asTable(lua_State* L)
|
||||||
{
|
{
|
||||||
checkIfActive();
|
checkIfActive();
|
||||||
sol::table res(mStorage->mLua, sol::create);
|
sol::table res(L, sol::create);
|
||||||
for (const auto& [k, v] : mValues)
|
for (const auto& [k, v] : mValues)
|
||||||
res[k] = v.getCopy(mStorage->mLua);
|
res[k] = v.getCopy(L);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaStorage::initLuaBindings(lua_State* L)
|
void LuaStorage::initLuaBindings(LuaUtil::LuaView& view)
|
||||||
{
|
{
|
||||||
sol::state_view lua(L);
|
sol::usertype<SectionView> sview = view.sol().new_usertype<SectionView>("Section");
|
||||||
sol::usertype<SectionView> sview = lua.new_usertype<SectionView>("Section");
|
|
||||||
sview["get"] = [](sol::this_state s, const SectionView& section, std::string_view key) {
|
sview["get"] = [](sol::this_state s, const SectionView& section, std::string_view key) {
|
||||||
return section.mSection->get(key).getReadOnly(s);
|
return section.mSection->get(key).getReadOnly(s);
|
||||||
};
|
};
|
||||||
sview["getCopy"] = [](sol::this_state s, const SectionView& section, std::string_view key) {
|
sview["getCopy"] = [](sol::this_state s, const SectionView& section, std::string_view key) {
|
||||||
return section.mSection->get(key).getCopy(s);
|
return section.mSection->get(key).getCopy(s);
|
||||||
};
|
};
|
||||||
sview["asTable"] = [](const SectionView& section) { return section.mSection->asTable(); };
|
sview["asTable"]
|
||||||
|
= [](sol::this_state lua, const SectionView& section) { return section.mSection->asTable(lua); };
|
||||||
sview["subscribe"] = [](const SectionView& section, const sol::table& callback) {
|
sview["subscribe"] = [](const SectionView& section, const sol::table& callback) {
|
||||||
std::vector<Callback>& callbacks
|
std::vector<Callback>& callbacks
|
||||||
= section.mForMenuScripts ? section.mSection->mMenuScriptsCallbacks : section.mSection->mCallbacks;
|
= section.mForMenuScripts ? section.mSection->mMenuScriptsCallbacks : section.mSection->mCallbacks;
|
||||||
|
@ -165,53 +168,57 @@ namespace LuaUtil
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initGlobalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage)
|
sol::table LuaStorage::initGlobalPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage)
|
||||||
{
|
{
|
||||||
sol::table res(luaState.sol(), sol::create);
|
sol::table res(view.sol(), sol::create);
|
||||||
registerLifeTime(luaState, res);
|
registerLifeTime(view, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"] = [globalStorage](sol::this_state lua, std::string_view section) {
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getMutableSection(section); };
|
return globalStorage->getMutableSection(lua, section);
|
||||||
res["allGlobalSections"] = [globalStorage]() { return globalStorage->getAllSections(); };
|
};
|
||||||
|
res["allGlobalSections"] = [globalStorage](sol::this_state lua) { return globalStorage->getAllSections(lua); };
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initLocalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage)
|
sol::table LuaStorage::initLocalPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage)
|
||||||
{
|
{
|
||||||
sol::table res(luaState.sol(), sol::create);
|
sol::table res(view.sol(), sol::create);
|
||||||
registerLifeTime(luaState, res);
|
registerLifeTime(view, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"] = [globalStorage](sol::this_state lua, std::string_view section) {
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
return globalStorage->getReadOnlySection(lua, section);
|
||||||
|
};
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initPlayerPackage(
|
sol::table LuaStorage::initPlayerPackage(
|
||||||
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
LuaUtil::LuaView& view, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
||||||
{
|
{
|
||||||
sol::table res(luaState.sol(), sol::create);
|
sol::table res(view.sol(), sol::create);
|
||||||
registerLifeTime(luaState, res);
|
registerLifeTime(view, res);
|
||||||
|
|
||||||
res["globalSection"]
|
res["globalSection"] = [globalStorage](sol::this_state lua, std::string_view section) {
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
return globalStorage->getReadOnlySection(lua, section);
|
||||||
res["playerSection"]
|
};
|
||||||
= [playerStorage](std::string_view section) { return playerStorage->getMutableSection(section); };
|
res["playerSection"] = [playerStorage](sol::this_state lua, std::string_view section) {
|
||||||
res["allPlayerSections"] = [playerStorage]() { return playerStorage->getAllSections(); };
|
return playerStorage->getMutableSection(lua, section);
|
||||||
|
};
|
||||||
|
res["allPlayerSections"] = [playerStorage](sol::this_state lua) { return playerStorage->getAllSections(lua); };
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::initMenuPackage(
|
sol::table LuaStorage::initMenuPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
||||||
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage)
|
|
||||||
{
|
{
|
||||||
sol::table res(luaState.sol(), sol::create);
|
sol::table res(view.sol(), sol::create);
|
||||||
registerLifeTime(luaState, res);
|
registerLifeTime(view, res);
|
||||||
|
|
||||||
res["playerSection"] = [playerStorage](std::string_view section) {
|
res["playerSection"] = [playerStorage](sol::this_state lua, std::string_view section) {
|
||||||
return playerStorage->getMutableSection(section, /*forMenuScripts=*/true);
|
return playerStorage->getMutableSection(lua, section, /*forMenuScripts=*/true);
|
||||||
};
|
};
|
||||||
res["globalSection"]
|
res["globalSection"] = [globalStorage](sol::this_state lua, std::string_view section) {
|
||||||
= [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); };
|
return globalStorage->getReadOnlySection(lua, section);
|
||||||
res["allPlayerSections"] = [playerStorage]() { return playerStorage->getAllSections(); };
|
};
|
||||||
|
res["allPlayerSections"] = [playerStorage](sol::this_state lua) { return playerStorage->getAllSections(lua); };
|
||||||
return LuaUtil::makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +241,7 @@ namespace LuaUtil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaStorage::load(const std::filesystem::path& path)
|
void LuaStorage::load(lua_State* L, const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
assert(mData.empty()); // Shouldn't be used before loading
|
assert(mData.empty()); // Shouldn't be used before loading
|
||||||
try
|
try
|
||||||
|
@ -246,7 +253,7 @@ namespace LuaUtil
|
||||||
|
|
||||||
std::ifstream fin(path, std::fstream::binary);
|
std::ifstream fin(path, std::fstream::binary);
|
||||||
std::string serializedData((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
|
std::string serializedData((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
|
||||||
sol::table data = deserialize(mLua, serializedData);
|
sol::table data = deserialize(L, serializedData);
|
||||||
for (const auto& [sectionName, sectionTable] : data)
|
for (const auto& [sectionName, sectionTable] : data)
|
||||||
{
|
{
|
||||||
const std::shared_ptr<Section>& section = getSection(cast<std::string_view>(sectionName));
|
const std::shared_ptr<Section>& section = getSection(cast<std::string_view>(sectionName));
|
||||||
|
@ -260,13 +267,13 @@ namespace LuaUtil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaStorage::save(const std::filesystem::path& path) const
|
void LuaStorage::save(lua_State* L, const std::filesystem::path& path) const
|
||||||
{
|
{
|
||||||
sol::table data(mLua, sol::create);
|
sol::table data(L, sol::create);
|
||||||
for (const auto& [sectionName, section] : mData)
|
for (const auto& [sectionName, section] : mData)
|
||||||
{
|
{
|
||||||
if (section->mLifeTime == Section::Persistent && !section->mValues.empty())
|
if (section->mLifeTime == Section::Persistent && !section->mValues.empty())
|
||||||
data[sectionName] = section->asTable();
|
data[sectionName] = section->asTable(L);
|
||||||
}
|
}
|
||||||
std::string serializedData = serialize(data);
|
std::string serializedData = serialize(data);
|
||||||
Log(Debug::Info) << "Saving Lua storage \"" << path << "\" (" << serializedData.size() << " bytes)";
|
Log(Debug::Info) << "Saving Lua storage \"" << path << "\" (" << serializedData.size() << " bytes)";
|
||||||
|
@ -287,19 +294,19 @@ namespace LuaUtil
|
||||||
return newIt->second;
|
return newIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object LuaStorage::getSection(std::string_view sectionName, bool readOnly, bool forMenuScripts)
|
sol::object LuaStorage::getSection(lua_State* L, std::string_view sectionName, bool readOnly, bool forMenuScripts)
|
||||||
{
|
{
|
||||||
checkIfActive();
|
checkIfActive();
|
||||||
const std::shared_ptr<Section>& section = getSection(sectionName);
|
const std::shared_ptr<Section>& section = getSection(sectionName);
|
||||||
return sol::make_object<SectionView>(mLua, SectionView{ section, readOnly, forMenuScripts });
|
return sol::make_object<SectionView>(L, SectionView{ section, readOnly, forMenuScripts });
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaStorage::getAllSections(bool readOnly)
|
sol::table LuaStorage::getAllSections(lua_State* L, bool readOnly)
|
||||||
{
|
{
|
||||||
checkIfActive();
|
checkIfActive();
|
||||||
sol::table res(mLua, sol::create);
|
sol::table res(L, sol::create);
|
||||||
for (const auto& [sectionName, _] : mData)
|
for (const auto& [sectionName, _] : mData)
|
||||||
res[sectionName] = getSection(sectionName, readOnly);
|
res[sectionName] = getSection(L, sectionName, readOnly);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,35 +10,34 @@
|
||||||
|
|
||||||
namespace LuaUtil
|
namespace LuaUtil
|
||||||
{
|
{
|
||||||
|
class LuaView;
|
||||||
|
|
||||||
class LuaStorage
|
class LuaStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void initLuaBindings(lua_State* L);
|
static void initLuaBindings(LuaUtil::LuaView& view);
|
||||||
static sol::table initGlobalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
|
static sol::table initGlobalPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage);
|
||||||
static sol::table initLocalPackage(LuaUtil::LuaState& luaState, LuaStorage* globalStorage);
|
static sol::table initLocalPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage);
|
||||||
static sol::table initPlayerPackage(
|
static sol::table initPlayerPackage(
|
||||||
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
LuaUtil::LuaView& view, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
||||||
static sol::table initMenuPackage(
|
static sol::table initMenuPackage(LuaUtil::LuaView& view, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
||||||
LuaUtil::LuaState& luaState, LuaStorage* globalStorage, LuaStorage* playerStorage);
|
|
||||||
|
|
||||||
explicit LuaStorage(lua_State* lua)
|
explicit LuaStorage() {}
|
||||||
: mLua(lua)
|
|
||||||
, mActive(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearTemporaryAndRemoveCallbacks();
|
void clearTemporaryAndRemoveCallbacks();
|
||||||
void load(const std::filesystem::path& path);
|
void load(lua_State* L, const std::filesystem::path& path);
|
||||||
void save(const std::filesystem::path& path) const;
|
void save(lua_State* L, const std::filesystem::path& path) const;
|
||||||
|
|
||||||
sol::object getSection(std::string_view sectionName, bool readOnly, bool forMenuScripts = false);
|
sol::object getSection(lua_State* L, std::string_view sectionName, bool readOnly, bool forMenuScripts = false);
|
||||||
sol::object getMutableSection(std::string_view sectionName, bool forMenuScripts = false)
|
sol::object getMutableSection(lua_State* L, std::string_view sectionName, bool forMenuScripts = false)
|
||||||
{
|
{
|
||||||
return getSection(sectionName, false, forMenuScripts);
|
return getSection(L, sectionName, false, forMenuScripts);
|
||||||
}
|
}
|
||||||
sol::object getReadOnlySection(std::string_view sectionName) { return getSection(sectionName, true); }
|
sol::object getReadOnlySection(lua_State* L, std::string_view sectionName)
|
||||||
sol::table getAllSections(bool readOnly = false);
|
{
|
||||||
|
return getSection(L, sectionName, true);
|
||||||
|
}
|
||||||
|
sol::table getAllSections(lua_State* L, bool readOnly = false);
|
||||||
|
|
||||||
void setSingleValue(std::string_view section, std::string_view key, const sol::object& value)
|
void setSingleValue(std::string_view section, std::string_view key, const sol::object& value)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +94,7 @@ namespace LuaUtil
|
||||||
const Value& get(std::string_view key) const;
|
const Value& get(std::string_view key) const;
|
||||||
void set(std::string_view key, const sol::object& value);
|
void set(std::string_view key, const sol::object& value);
|
||||||
void setAll(const sol::optional<sol::table>& values);
|
void setAll(const sol::optional<sol::table>& values);
|
||||||
sol::table asTable();
|
sol::table asTable(lua_State* L);
|
||||||
void runCallbacks(sol::optional<std::string_view> changedKey);
|
void runCallbacks(sol::optional<std::string_view> changedKey);
|
||||||
void throwIfCallbackRecursionIsTooDeep();
|
void throwIfCallbackRecursionIsTooDeep();
|
||||||
|
|
||||||
|
@ -119,17 +118,16 @@ namespace LuaUtil
|
||||||
|
|
||||||
const std::shared_ptr<Section>& getSection(std::string_view sectionName);
|
const std::shared_ptr<Section>& getSection(std::string_view sectionName);
|
||||||
|
|
||||||
lua_State* mLua;
|
|
||||||
std::map<std::string_view, std::shared_ptr<Section>> mData;
|
std::map<std::string_view, std::shared_ptr<Section>> mData;
|
||||||
const Listener* mListener = nullptr;
|
const Listener* mListener = nullptr;
|
||||||
std::set<const Section*> mRunningCallbacks;
|
std::set<const Section*> mRunningCallbacks;
|
||||||
bool mActive;
|
bool mActive = false;
|
||||||
void checkIfActive() const
|
void checkIfActive() const
|
||||||
{
|
{
|
||||||
if (!mActive)
|
if (!mActive)
|
||||||
throw std::logic_error("Trying to access inactive storage");
|
throw std::logic_error("Trying to access inactive storage");
|
||||||
}
|
}
|
||||||
static void registerLifeTime(LuaUtil::LuaState& luaState, sol::table& res);
|
static void registerLifeTime(LuaUtil::LuaView& view, sol::table& res);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue