mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 12:39:55 +00:00
Inventory bindings
This commit is contained in:
parent
bdccf161c4
commit
f5722f9ba0
@ -32,6 +32,10 @@ namespace MWLua
|
|||||||
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
|
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
|
||||||
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
|
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
|
||||||
selfAPI["setDirectControl"] = [](SelfObject& self, bool v) { self.mControls.controlledFromLua = v; };
|
selfAPI["setDirectControl"] = [](SelfObject& self, bool v) { self.mControls.controlledFromLua = v; };
|
||||||
|
selfAPI["setEquipment"] = [](const GObject& obj, const sol::table& equipment)
|
||||||
|
{
|
||||||
|
throw std::logic_error("Not implemented");
|
||||||
|
};
|
||||||
selfAPI["getCombatTarget"] = [worldView=context.mWorldView](SelfObject& self) -> sol::optional<LObject>
|
selfAPI["getCombatTarget"] = [worldView=context.mWorldView](SelfObject& self) -> sol::optional<LObject>
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/queries/luabindings.hpp>
|
#include <components/queries/luabindings.hpp>
|
||||||
|
|
||||||
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
#include "eventqueue.hpp"
|
#include "eventqueue.hpp"
|
||||||
#include "worldview.hpp"
|
#include "worldview.hpp"
|
||||||
|
|
||||||
@ -19,19 +21,41 @@ namespace MWLua
|
|||||||
|
|
||||||
sol::table initCorePackage(const Context& context)
|
sol::table initCorePackage(const Context& context)
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
auto* lua = context.mLua;
|
||||||
|
sol::table api(lua->sol(), sol::create);
|
||||||
api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData)
|
api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData)
|
||||||
{
|
{
|
||||||
context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)});
|
context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)});
|
||||||
};
|
};
|
||||||
api["getGameTimeInSeconds"] = [world=context.mWorldView]() { return world->getGameTimeInSeconds(); };
|
api["getGameTimeInSeconds"] = [world=context.mWorldView]() { return world->getGameTimeInSeconds(); };
|
||||||
api["getGameTimeInHours"] = [world=context.mWorldView]() { return world->getGameTimeInHours(); };
|
api["getGameTimeInHours"] = [world=context.mWorldView]() { return world->getGameTimeInHours(); };
|
||||||
api["OBJECT_TYPE"] = definitionList(*context.mLua,
|
api["OBJECT_TYPE"] = definitionList(*lua,
|
||||||
{
|
{
|
||||||
"Activator", "Armor", "Book", "Clothing", "Creature", "Door", "Ingredient",
|
"Activator", "Armor", "Book", "Clothing", "Creature", "Door", "Ingredient",
|
||||||
"Light", "Miscellaneous", "NPC", "Player", "Potion", "Static", "Weapon"
|
"Light", "Miscellaneous", "NPC", "Player", "Potion", "Static", "Weapon"
|
||||||
});
|
});
|
||||||
return context.mLua->makeReadOnly(api);
|
api["EQUIPMENT_SLOT"] = lua->makeReadOnly(lua->sol().create_table_with(
|
||||||
|
"Helmet", MWWorld::InventoryStore::Slot_Helmet,
|
||||||
|
"Cuirass", MWWorld::InventoryStore::Slot_Cuirass,
|
||||||
|
"Greaves", MWWorld::InventoryStore::Slot_Greaves,
|
||||||
|
"LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron,
|
||||||
|
"RightPauldron", MWWorld::InventoryStore::Slot_RightPauldron,
|
||||||
|
"LeftGauntlet", MWWorld::InventoryStore::Slot_LeftGauntlet,
|
||||||
|
"RightGauntlet", MWWorld::InventoryStore::Slot_RightGauntlet,
|
||||||
|
"Boots", MWWorld::InventoryStore::Slot_Boots,
|
||||||
|
"Shirt", MWWorld::InventoryStore::Slot_Shirt,
|
||||||
|
"Pants", MWWorld::InventoryStore::Slot_Pants,
|
||||||
|
"Skirt", MWWorld::InventoryStore::Slot_Skirt,
|
||||||
|
"Robe", MWWorld::InventoryStore::Slot_Robe,
|
||||||
|
"LeftRing", MWWorld::InventoryStore::Slot_LeftRing,
|
||||||
|
"RightRing", MWWorld::InventoryStore::Slot_RightRing,
|
||||||
|
"Amulet", MWWorld::InventoryStore::Slot_Amulet,
|
||||||
|
"Belt", MWWorld::InventoryStore::Slot_Belt,
|
||||||
|
"CarriedRight", MWWorld::InventoryStore::Slot_CarriedRight,
|
||||||
|
"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft,
|
||||||
|
"Ammunition", MWWorld::InventoryStore::Slot_Ammunition
|
||||||
|
));
|
||||||
|
return lua->makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initWorldPackage(const Context& context)
|
sol::table initWorldPackage(const Context& context)
|
||||||
@ -57,6 +81,7 @@ namespace MWLua
|
|||||||
// TODO: Use sqlite to search objects that are not in the scene
|
// TODO: Use sqlite to search objects that are not in the scene
|
||||||
// return GObjectList{worldView->selectObjects(query, false)};
|
// return GObjectList{worldView->selectObjects(query, false)};
|
||||||
};
|
};
|
||||||
|
// TODO: add world.placeNewObject(recordId, cell, pos, [rot])
|
||||||
return context.mLua->makeReadOnly(api);
|
return context.mLua->makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,21 @@
|
|||||||
|
|
||||||
#include "../mwclass/door.hpp"
|
#include "../mwclass/door.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
#include "eventqueue.hpp"
|
#include "eventqueue.hpp"
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
|
namespace MWLua
|
||||||
|
{
|
||||||
|
template <typename ObjectT>
|
||||||
|
struct Inventory
|
||||||
|
{
|
||||||
|
ObjectT mObj;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace sol
|
namespace sol
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
@ -18,6 +30,10 @@ namespace sol
|
|||||||
struct is_automagical<MWLua::LObjectList> : std::false_type {};
|
struct is_automagical<MWLua::LObjectList> : std::false_type {};
|
||||||
template <>
|
template <>
|
||||||
struct is_automagical<MWLua::GObjectList> : std::false_type {};
|
struct is_automagical<MWLua::GObjectList> : std::false_type {};
|
||||||
|
template <>
|
||||||
|
struct is_automagical<MWLua::Inventory<MWLua::LObject>> : std::false_type {};
|
||||||
|
template <>
|
||||||
|
struct is_automagical<MWLua::Inventory<MWLua::GObject>> : std::false_type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
@ -88,6 +104,7 @@ namespace MWLua
|
|||||||
return o.ptr().getRefData().getPosition().asRotationVec3();
|
return o.ptr().getRefData().getPosition().asRotationVec3();
|
||||||
});
|
});
|
||||||
objectT["type"] = sol::readonly_property(&ObjectT::type);
|
objectT["type"] = sol::readonly_property(&ObjectT::type);
|
||||||
|
objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getRefData().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(); };
|
||||||
objectT[sol::meta_function::to_string] = &ObjectT::toString;
|
objectT[sol::meta_function::to_string] = &ObjectT::toString;
|
||||||
objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData)
|
objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData)
|
||||||
@ -101,6 +118,13 @@ namespace MWLua
|
|||||||
{
|
{
|
||||||
luaManager->addLocalScript(object.ptr(), path);
|
luaManager->addLocalScript(object.ptr(), path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
objectT["teleport"] = [luaManager=context.mLuaManager](const GObject& object, std::string_view cell,
|
||||||
|
const osg::Vec3f& pos, const sol::optional<osg::Vec3f>& rot)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
throw std::logic_error("Not implemented");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +151,110 @@ namespace MWLua
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ObjectT>
|
||||||
|
static void addInventoryBindings(sol::usertype<ObjectT>& objectT, const std::string& prefix, const Context& context)
|
||||||
|
{
|
||||||
|
using InventoryT = Inventory<ObjectT>;
|
||||||
|
sol::usertype<InventoryT> inventoryT = context.mLua->sol().new_usertype<InventoryT>(prefix + "Inventory");
|
||||||
|
|
||||||
|
objectT["getEquipment"] = [context](const ObjectT& o)
|
||||||
|
{
|
||||||
|
const MWWorld::Ptr& ptr = o.ptr();
|
||||||
|
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
|
||||||
|
sol::table equipment(context.mLua->sol(), sol::create);
|
||||||
|
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||||
|
{
|
||||||
|
auto it = store.getSlot(slot);
|
||||||
|
if (it == store.end())
|
||||||
|
continue;
|
||||||
|
context.mWorldView->getObjectRegistry()->registerPtr(*it);
|
||||||
|
equipment[slot] = ObjectT(getId(*it), context.mWorldView->getObjectRegistry());
|
||||||
|
}
|
||||||
|
return equipment;
|
||||||
|
};
|
||||||
|
objectT["isEquipped"] = [](const ObjectT& actor, const ObjectT& item)
|
||||||
|
{
|
||||||
|
const MWWorld::Ptr& ptr = actor.ptr();
|
||||||
|
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
|
||||||
|
return store.isEquipped(item.ptr());
|
||||||
|
};
|
||||||
|
|
||||||
|
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() + "]"; };
|
||||||
|
|
||||||
|
auto getWithMask = [context](const InventoryT& inventory, int mask)
|
||||||
|
{
|
||||||
|
const MWWorld::Ptr& ptr = inventory.mObj.ptr();
|
||||||
|
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr);
|
||||||
|
ObjectIdList list = std::make_shared<std::vector<ObjectId>>();
|
||||||
|
auto it = store.begin(mask);
|
||||||
|
while (it.getType() != -1)
|
||||||
|
{
|
||||||
|
const MWWorld::Ptr& item = *(it++);
|
||||||
|
context.mWorldView->getObjectRegistry()->registerPtr(item);
|
||||||
|
list->push_back(getId(item));
|
||||||
|
}
|
||||||
|
return ObjectList<ObjectT>{list};
|
||||||
|
};
|
||||||
|
|
||||||
|
inventoryT["getAll"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_All); };
|
||||||
|
inventoryT["getPotions"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Potion); };
|
||||||
|
inventoryT["getApparatuses"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Apparatus); };
|
||||||
|
inventoryT["getArmor"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Armor); };
|
||||||
|
inventoryT["getBooks"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Book); };
|
||||||
|
inventoryT["getClothing"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Clothing); };
|
||||||
|
inventoryT["getIngredients"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Ingredient); };
|
||||||
|
inventoryT["getLights"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Light); };
|
||||||
|
inventoryT["getLockpicks"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Lockpick); };
|
||||||
|
inventoryT["getMiscellaneous"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Miscellaneous); };
|
||||||
|
inventoryT["getProbes"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Probe); };
|
||||||
|
inventoryT["getRepairKits"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Repair); };
|
||||||
|
inventoryT["getWeapons"] =
|
||||||
|
[getWithMask](const InventoryT& inventory) { return getWithMask(inventory, MWWorld::ContainerStore::Type_Weapon); };
|
||||||
|
|
||||||
|
inventoryT["countOf"] = [](const InventoryT& inventory, const std::string& recordId)
|
||||||
|
{
|
||||||
|
const MWWorld::Ptr& ptr = inventory.mObj.ptr();
|
||||||
|
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr);
|
||||||
|
return store.count(recordId);
|
||||||
|
};
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<ObjectT, GObject>)
|
||||||
|
{ // Only for global scripts
|
||||||
|
// TODO
|
||||||
|
objectT["moveInto"] = [](const GObject& obj, const InventoryT& inventory) {};
|
||||||
|
objectT["setEquipment"] = [](const GObject& obj, const sol::table& equipment) {};
|
||||||
|
|
||||||
|
// obj.inventory:drop(obj2, [count])
|
||||||
|
// obj.inventory:drop(recordId, [count])
|
||||||
|
// obj.inventory:addNew(recordId, [count])
|
||||||
|
// obj.inventory:remove(obj/recordId, [count])
|
||||||
|
inventoryT["drop"] = [](const InventoryT& inventory) {};
|
||||||
|
inventoryT["addNew"] = [](const InventoryT& inventory) {};
|
||||||
|
inventoryT["remove"] = [](const InventoryT& inventory) {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class ObjectT>
|
template <class ObjectT>
|
||||||
static void initObjectBindings(const std::string& prefix, const Context& context)
|
static void initObjectBindings(const std::string& prefix, const Context& context)
|
||||||
{
|
{
|
||||||
sol::usertype<ObjectT> objectT = context.mLua->sol().new_usertype<ObjectT>(prefix + "Object");
|
sol::usertype<ObjectT> objectT = context.mLua->sol().new_usertype<ObjectT>(prefix + "Object");
|
||||||
addBasicBindings<ObjectT>(objectT, context);
|
addBasicBindings<ObjectT>(objectT, context);
|
||||||
addDoorBindings<ObjectT>(objectT, context);
|
addDoorBindings<ObjectT>(objectT, context);
|
||||||
|
addInventoryBindings<ObjectT>(objectT, prefix, context);
|
||||||
|
|
||||||
registerObjectList<ObjectT>(prefix, context);
|
registerObjectList<ObjectT>(prefix, context);
|
||||||
}
|
}
|
||||||
@ -148,4 +270,3 @@ namespace MWLua
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user