Inventory bindings

dont-compose-content
Petr Mikheev 4 years ago
parent bdccf161c4
commit f5722f9ba0

@ -32,6 +32,10 @@ namespace MWLua
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
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>
{
const MWWorld::Ptr& ptr = self.ptr();

@ -3,6 +3,8 @@
#include <components/lua/luastate.hpp>
#include <components/queries/luabindings.hpp>
#include "../mwworld/inventorystore.hpp"
#include "eventqueue.hpp"
#include "worldview.hpp"
@ -19,19 +21,41 @@ namespace MWLua
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)
{
context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)});
};
api["getGameTimeInSeconds"] = [world=context.mWorldView]() { return world->getGameTimeInSeconds(); };
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",
"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)
@ -57,6 +81,7 @@ namespace MWLua
// TODO: Use sqlite to search objects that are not in the scene
// return GObjectList{worldView->selectObjects(query, false)};
};
// TODO: add world.placeNewObject(recordId, cell, pos, [rot])
return context.mLua->makeReadOnly(api);
}

@ -5,9 +5,21 @@
#include "../mwclass/door.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "eventqueue.hpp"
#include "luamanagerimp.hpp"
namespace MWLua
{
template <typename ObjectT>
struct Inventory
{
ObjectT mObj;
};
}
namespace sol
{
template <>
@ -18,6 +30,10 @@ namespace sol
struct is_automagical<MWLua::LObjectList> : std::false_type {};
template <>
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
@ -88,6 +104,7 @@ namespace MWLua
return o.ptr().getRefData().getPosition().asRotationVec3();
});
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::to_string] = &ObjectT::toString;
objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData)
@ -101,6 +118,13 @@ namespace MWLua
{
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>
static void initObjectBindings(const std::string& prefix, const Context& context)
{
sol::usertype<ObjectT> objectT = context.mLua->sol().new_usertype<ObjectT>(prefix + "Object");
addBasicBindings<ObjectT>(objectT, context);
addDoorBindings<ObjectT>(objectT, context);
addInventoryBindings<ObjectT>(objectT, prefix, context);
registerObjectList<ObjectT>(prefix, context);
}
@ -148,4 +270,3 @@ namespace MWLua
}
}

Loading…
Cancel
Save