macos_ci_fix
Kindi 1 year ago
parent ff16ee2d64
commit 83ebaf27cc

@ -61,8 +61,8 @@ add_openmw_dir (mwscript
add_openmw_dir (mwlua
luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant
context globalscripts localscripts playerscripts luabindings objectbindings cellbindings mwscriptbindings
camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing types/levelledlist types/terminal types/itemstats
camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings itemdata
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing types/levelledlist types/terminal
worker magicbindings factionbindings
)

@ -0,0 +1,129 @@
#include "itemdata.hpp"
#include "context.hpp"
#include "luamanagerimp.hpp"
#include "../mwworld/class.hpp"
#include "objectvariant.hpp"
namespace
{
using SelfObject = MWLua::SelfObject;
using Index = const SelfObject::CachedStat::Index&;
constexpr std::array properties = { "condition", /*"enchantmentCharge", "soul", "owner", etc..*/ };
void invalidPropErr(std::string_view prop, const MWWorld::Ptr& ptr)
{
throw std::runtime_error(std::string(prop) + " does not exist for item "
+ std::string(ptr.getClass().getName(ptr)) + "(" + std::string(ptr.getTypeDescription()) + ")");
}
}
namespace MWLua
{
static void addStatUpdateAction(MWLua::LuaManager* manager, const SelfObject& obj)
{
if (!obj.mStatsCache.empty())
return; // was already added before
manager->addAction(
[obj = Object(obj)] {
LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts();
if (scripts)
scripts->applyStatsCache();
},
"StatUpdateAction");
}
class ItemData
{
ObjectVariant mObject;
public:
ItemData(ObjectVariant object)
: mObject(object)
{
}
sol::object get(const Context& context, std::string_view prop) const
{
if (mObject.isSelfObject())
{
SelfObject* self = mObject.asSelfObject();
auto it = self->mStatsCache.find({ &ItemData::setValue, std::monostate{}, prop });
if (it != self->mStatsCache.end())
return it->second;
}
return sol::make_object(context.mLua->sol(), getValue(context, prop));
}
void set(const Context& context, std::string_view prop, const sol::object& value) const
{
SelfObject* obj = mObject.asSelfObject();
addStatUpdateAction(context.mLuaManager, *obj);
obj->mStatsCache[SelfObject::CachedStat{ &ItemData::setValue, std::monostate{}, prop }] = value;
}
sol::object getValue(const Context& context, std::string_view prop) const
{
if (prop == "condition")
{
MWWorld::Ptr o = mObject.ptr();
if (o.getClass().isLight(o))
return sol::make_object(context.mLua->sol(), o.getClass().getRemainingUsageTime(o));
else if (o.getClass().hasItemHealth(o))
return sol::make_object(context.mLua->sol(), o.getClass().getItemHealth(o));
}
return sol::lua_nil;
}
static void setValue(Index i, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value)
{
if (prop == "condition")
{
double cond = value.as<double>();
if (ptr.getClass().isLight(ptr))
ptr.getClass().setRemainingUsageTime(ptr, cond);
else if (ptr.getClass().hasItemHealth(ptr))
ptr.getCellRef().setCharge(std::max(0, static_cast<int>(cond)));
else /*ignore or error?*/
invalidPropErr(prop, ptr);
}
}
};
}
namespace sol
{
template <>
struct is_automagical<MWLua::ItemData> : std::false_type
{
};
}
namespace MWLua
{
void addItemDataBindings(sol::table& item, const Context& context)
{
item["itemData"] = [](const sol::object& object) -> sol::optional<ItemData> {
ObjectVariant o(object);
if (o.ptr().getClass().isItem(o.ptr()) || o.ptr().mRef->getType() == ESM::REC_LIGH)
return ItemData(std::move(o));
return {};
};
sol::usertype<ItemData> itemData = context.mLua->sol().new_usertype<ItemData>("ItemData");
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>() + "'");
};
for (std::string_view prop : properties)
{
itemData[prop] = sol::property([context, prop](const ItemData& stat) { return stat.get(context, prop); },
[context, prop](const ItemData& stat, const sol::object& value) { stat.set(context, prop, value); });
}
}
}

@ -0,0 +1,13 @@
#ifndef MWLUA_ITEMDATA_H
#define MWLUA_ITEMDATA_H
#include <sol/forward.hpp>
namespace MWLua
{
struct Context;
void addItemDataBindings(sol::table& item, const Context& context);
}
#endif // MWLUA_ITEMDATA_H

@ -22,7 +22,7 @@ namespace MWLua
class CachedStat
{
public:
using Index = std::variant<int, ESM::RefId>;
using Index = std::variant<int, ESM::RefId, std::monostate>;
using Setter = void (*)(const Index&, std::string_view, const MWWorld::Ptr&, const sol::object&);
CachedStat(Setter setter, Index index, std::string_view prop)

@ -1,31 +1,22 @@
#include "itemstats.hpp"
#include <sol/sol.hpp>
namespace sol
{
template <>
struct is_automagical<MWLua::ItemStat> : std::false_type
{
};
}
#include "../../mwworld/class.hpp"
#include "../itemdata.hpp"
#include "types.hpp"
namespace MWLua
{
void addItemBindings(sol::table item, const Context& context)
{
sol::usertype<ItemStat> ItemStats = context.mLua->sol().new_usertype<ItemStat>("ItemStat");
ItemStats[sol::meta_function::new_index] = [](const ItemStat& i, const sol::variadic_args args) {
throw std::runtime_error("Unknown itemStat property '" + args.get<std::string>() + "'");
};
ItemStats["condition"] = sol::property([](const ItemStat& i) { return i.getCondition(); },
[](const ItemStat& i, float cond) { i.setCondition(cond); });
item["getEnchantmentCharge"]
= [](const Object& object) { return object.ptr().getCellRef().getEnchantmentCharge(); };
item["setEnchantmentCharge"]
= [](const GObject& object, float charge) { object.ptr().getCellRef().setEnchantmentCharge(charge); };
item["isRestocking"]
= [](const Object& object) -> bool { return object.ptr().getRefData().getCount(false) < 0; };
item["itemStats"] = [](const sol::object& object) { return ItemStat(object); };
addItemDataBindings(item, context);
}
}

@ -1,33 +0,0 @@
#include "itemstats.hpp"
namespace MWLua
{
ItemStat::ItemStat(const sol::object& object)
: mObject(ObjectVariant(object))
{
}
sol::optional<double> ItemStat::getCondition() const
{
MWWorld::Ptr o = mObject.ptr();
if (o.getClass().isLight(o))
return o.getClass().getRemainingUsageTime(o);
else if (o.getClass().hasItemHealth(o))
return o.getClass().getItemHealth(o);
else
return sol::nullopt;
}
void ItemStat::setCondition(float cond) const
{
if (!mObject.isGObject())
throw std::runtime_error("This property can only be set in global scripts");
MWWorld::Ptr o = mObject.ptr();
if (o.getClass().isLight(o))
return o.getClass().setRemainingUsageTime(o, cond);
else if (o.getClass().hasItemHealth(o))
o.getCellRef().setCharge(std::max(0, static_cast<int>(cond)));
else
throw std::runtime_error("'condition' property does not exist for " + std::string(o.getClass().getName(o))
+ "(" + std::string(o.getTypeDescription()) + ")");
};
}

@ -1,29 +0,0 @@
#ifndef MWLUA_ITEMSTATS_H
#define MWLUA_ITEMSTATS_H
#include <sol/sol.hpp>
#include "../../mwworld/class.hpp"
#include "../objectvariant.hpp"
#include "types.hpp"
namespace MWLua
{
class ItemStat
{
public:
ItemStat(const sol::object& object);
sol::optional<double> getCondition() const;
void setCondition(float cond) const;
/*
* set,get, enchantmentCharge, soul? etc..
*/
ObjectVariant mObject;
};
}
#endif // MWLUA_ITEMSTATS_H
Loading…
Cancel
Save