From 43bed7f0d2add7ccdd51a8cfad40b868b1dc1c08 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Thu, 10 Mar 2022 00:31:44 +0100 Subject: [PATCH] [Lua] Split obj.inventory into Actor.inventory(obj) and Container.content(obj) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwlua/luamanagerimp.cpp | 1 + apps/openmw/mwlua/object.hpp | 3 +++ apps/openmw/mwlua/objectbindings.cpp | 12 ++---------- apps/openmw/mwlua/types/actor.cpp | 12 ++++++------ apps/openmw/mwlua/types/container.cpp | 18 ++++++++++++++++++ apps/openmw/mwlua/types/types.cpp | 2 +- apps/openmw/mwlua/types/types.hpp | 1 + 8 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 apps/openmw/mwlua/types/container.cpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 6b439bde80..c29b33b28c 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -60,7 +60,7 @@ add_openmw_dir (mwlua luamanagerimp actions object worldview userdataserializer eventqueue query luabindings localscripts playerscripts objectbindings cellbindings asyncbindings settingsbindings camerabindings uibindings inputbindings nearbybindings - types/types types/door types/actor + types/types types/door types/actor types/container ) add_openmw_dir (mwsound diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 5b21d46427..9c5c210e4d 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -391,6 +391,7 @@ namespace MWLua { assert(mInitialized); assert(flag != ESM::LuaScriptCfg::sGlobal); + assert(ptr.getType() != ESM::REC_STAT); std::shared_ptr scripts; if (flag == ESM::LuaScriptCfg::sPlayer) { diff --git a/apps/openmw/mwlua/object.hpp b/apps/openmw/mwlua/object.hpp index 1685d7506d..499c21c7e7 100644 --- a/apps/openmw/mwlua/object.hpp +++ b/apps/openmw/mwlua/object.hpp @@ -118,6 +118,9 @@ namespace MWLua using GObjectList = ObjectList; using LObjectList = ObjectList; + template + struct Inventory { Obj mObj; }; + } #endif // MWLUA_OBJECT_H diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index 092a8d5151..6bcf355fde 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -12,15 +12,6 @@ #include "luamanagerimp.hpp" #include "types/types.hpp" -namespace MWLua -{ - template - struct Inventory - { - ObjectT mObj; - }; -} - namespace sol { template <> @@ -149,6 +140,8 @@ namespace MWLua throw std::runtime_error("Unknown script: " + std::string(path)); if (!(cfg[*scriptId].mFlags & ESM::LuaScriptCfg::sCustom)) throw std::runtime_error("Script without CUSTOM tag can not be added dynamically: " + std::string(path)); + if (object.ptr().getType() == ESM::REC_STAT) + throw std::runtime_error("Attaching scripts to Static is not allowed: " + std::string(path)); luaManager->addCustomLocalScript(object.ptr(), *scriptId); }; objectT["hasScript"] = [lua=context.mLua](const GObject& object, std::string_view path) @@ -200,7 +193,6 @@ namespace MWLua using InventoryT = Inventory; sol::usertype inventoryT = context.mLua->sol().new_usertype(prefix + "Inventory"); - objectT["inventory"] = sol::readonly_property([](const ObjectT& o) { return InventoryT{o}; }); inventoryT[sol::meta_function::to_string] = [](const InventoryT& inv) { return "Inventory[" + inv.mObj.toString() + "]"; }; diff --git a/apps/openmw/mwlua/types/actor.cpp b/apps/openmw/mwlua/types/actor.cpp index ba2c05a52d..d620472095 100644 --- a/apps/openmw/mwlua/types/actor.cpp +++ b/apps/openmw/mwlua/types/actor.cpp @@ -83,7 +83,11 @@ namespace MWLua return MWBase::Environment::get().getWorld()->isSwimming(o.ptr()); }; - actor["getEquipment"] = [context](const Object& o) + actor["inventory"] = sol::overload( + [](const LObject& o) { return Inventory{o}; }, + [](const GObject& o) { return Inventory{o}; } + ); + actor["equipment"] = [context](const Object& o) { const MWWorld::Ptr& ptr = o.ptr(); sol::table equipment(context.mLua->sol(), sol::create); @@ -109,12 +113,8 @@ namespace MWLua MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); return store.isEquipped(item.ptr()); }; - actor["setEquipment"] = [context](const sol::object& luaObj, const sol::table& equipment) + actor["setEquipment"] = [context](const SelfObject& obj, const sol::table& equipment) { - if (!luaObj.is() && !luaObj.is()) - throw std::runtime_error("Incorrect type of the first argument. " - "Can be either self (in local scripts) or game object (in global scripts)"); - const Object& obj = luaObj.as(); if (!obj.ptr().getClass().hasInventoryStore(obj.ptr())) { if (!equipment.empty()) diff --git a/apps/openmw/mwlua/types/container.cpp b/apps/openmw/mwlua/types/container.cpp new file mode 100644 index 0000000000..b603b6d3f4 --- /dev/null +++ b/apps/openmw/mwlua/types/container.cpp @@ -0,0 +1,18 @@ +#include "types.hpp" + +#include "../luabindings.hpp" + +namespace MWLua +{ + + static const MWWorld::Ptr& containerPtr(const Object& o) { return verifyType(ESM::REC_CONT, o.ptr()); } + + void addContainerBindings(sol::table container, const Context& context) + { + container["content"] = sol::overload( + [](const LObject& o) { containerPtr(o); return Inventory{o}; }, + [](const GObject& o) { containerPtr(o); return Inventory{o}; } + ); + } + +} diff --git a/apps/openmw/mwlua/types/types.cpp b/apps/openmw/mwlua/types/types.cpp index f91400d5ea..556c13963f 100644 --- a/apps/openmw/mwlua/types/types.cpp +++ b/apps/openmw/mwlua/types/types.cpp @@ -173,7 +173,7 @@ namespace MWLua addType(ObjectTypeName::Repair, {ESM::REC_REPA}, ObjectTypeName::Item); addType(ObjectTypeName::Activator, {ESM::REC_ACTI}); - addType(ObjectTypeName::Container, {ESM::REC_CONT}); + addContainerBindings(addType(ObjectTypeName::Container, {ESM::REC_CONT}), context); addDoorBindings(addType(ObjectTypeName::Door, {ESM::REC_DOOR}), context); addType(ObjectTypeName::Static, {ESM::REC_STAT}); diff --git a/apps/openmw/mwlua/types/types.hpp b/apps/openmw/mwlua/types/types.hpp index 63d3cb4db5..966e32ccf2 100644 --- a/apps/openmw/mwlua/types/types.hpp +++ b/apps/openmw/mwlua/types/types.hpp @@ -24,6 +24,7 @@ namespace MWLua sol::table initTypesPackage(const Context& context); // used in initTypesPackage + void addContainerBindings(sol::table door, const Context& context); void addDoorBindings(sol::table door, const Context& context); void addActorBindings(sol::table actor, const Context& context); }