mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-29 18:32:36 +00:00
Merge branch 'sorewaai' into 'master'
Expose AI stats to Lua Closes #7860 See merge request OpenMW/openmw!3997
This commit is contained in:
commit
a7c6297240
@ -218,6 +218,7 @@
|
||||
Feature #7792: Support Timescale Clouds
|
||||
Feature #7795: Support MaxNumberRipples INI setting
|
||||
Feature #7805: Lua Menu context
|
||||
Feature #7860: Lua: Expose NPC AI settings (fight, alarm, flee)
|
||||
Task #5896: Do not use deprecated MyGUI properties
|
||||
Task #6085: Replace boost::filesystem with std::filesystem
|
||||
Task #6149: Dehardcode Lua API_REVISION
|
||||
|
@ -81,7 +81,7 @@ message(STATUS "Configuring OpenMW...")
|
||||
set(OPENMW_VERSION_MAJOR 0)
|
||||
set(OPENMW_VERSION_MINOR 49)
|
||||
set(OPENMW_VERSION_RELEASE 0)
|
||||
set(OPENMW_LUA_API_REVISION 58)
|
||||
set(OPENMW_LUA_API_REVISION 59)
|
||||
set(OPENMW_POSTPROCESSING_API_REVISION 1)
|
||||
|
||||
set(OPENMW_VERSION_COMMITHASH "")
|
||||
|
@ -31,7 +31,7 @@ namespace
|
||||
using Index = const SelfObject::CachedStat::Index&;
|
||||
|
||||
template <class T>
|
||||
auto addIndexedAccessor(Index index)
|
||||
auto addIndexedAccessor(auto index)
|
||||
{
|
||||
return [index](const sol::object& o) { return T::create(ObjectVariant(o), index); };
|
||||
}
|
||||
@ -425,6 +425,62 @@ namespace MWLua
|
||||
stats.setSkill(id, stat);
|
||||
}
|
||||
};
|
||||
|
||||
class AIStat
|
||||
{
|
||||
ObjectVariant mObject;
|
||||
MWMechanics::AiSetting mIndex;
|
||||
|
||||
AIStat(ObjectVariant object, MWMechanics::AiSetting index)
|
||||
: mObject(std::move(object))
|
||||
, mIndex(index)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
template <class G>
|
||||
sol::object get(const Context& context, std::string_view prop, G getter) const
|
||||
{
|
||||
return getValue(context, mObject, &AIStat::setValue, static_cast<int>(mIndex), prop,
|
||||
[this, getter](const MWWorld::Ptr& ptr) {
|
||||
return (ptr.getClass().getCreatureStats(ptr).getAiSetting(mIndex).*getter)();
|
||||
});
|
||||
}
|
||||
|
||||
int getModified(const Context& context) const
|
||||
{
|
||||
auto base = LuaUtil::cast<int>(get(context, "base", &MWMechanics::Stat<int>::getBase));
|
||||
auto modifier = LuaUtil::cast<int>(get(context, "modifier", &MWMechanics::Stat<int>::getModifier));
|
||||
return std::max(0, base + modifier);
|
||||
}
|
||||
|
||||
static std::optional<AIStat> create(ObjectVariant object, MWMechanics::AiSetting index)
|
||||
{
|
||||
if (!object.ptr().getClass().isActor())
|
||||
return {};
|
||||
return AIStat{ std::move(object), index };
|
||||
}
|
||||
|
||||
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
||||
{
|
||||
SelfObject* obj = mObject.asSelfObject();
|
||||
addStatUpdateAction(context.mLuaManager, *obj);
|
||||
obj->mStatsCache[SelfObject::CachedStat{ &AIStat::setValue, static_cast<int>(mIndex), prop }] = value;
|
||||
}
|
||||
|
||||
static void setValue(Index i, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value)
|
||||
{
|
||||
auto index = static_cast<MWMechanics::AiSetting>(std::get<int>(i));
|
||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
auto stat = stats.getAiSetting(index);
|
||||
int intValue = LuaUtil::cast<int>(value);
|
||||
if (prop == "base")
|
||||
stat.setBase(intValue);
|
||||
else if (prop == "modifier")
|
||||
stat.setModifier(intValue);
|
||||
stats.setAiSetting(index, stat);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace sol
|
||||
@ -465,6 +521,10 @@ namespace sol
|
||||
struct is_automagical<ESM::MagicSchool> : std::false_type
|
||||
{
|
||||
};
|
||||
template <>
|
||||
struct is_automagical<MWLua::AIStat> : std::false_type
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace MWLua
|
||||
@ -529,6 +589,17 @@ namespace MWLua
|
||||
stats["attributes"] = LuaUtil::makeReadOnly(attributes);
|
||||
for (const ESM::Attribute& attribute : MWBase::Environment::get().getESMStore()->get<ESM::Attribute>())
|
||||
attributes[ESM::RefId(attribute.mId).serializeText()] = addIndexedAccessor<AttributeStat>(attribute.mId);
|
||||
|
||||
auto aiStatT = context.mLua->sol().new_usertype<AIStat>("AIStat");
|
||||
addProp(context, aiStatT, "base", &MWMechanics::Stat<int>::getBase);
|
||||
addProp(context, aiStatT, "modifier", &MWMechanics::Stat<int>::getModifier);
|
||||
aiStatT["modified"] = sol::readonly_property([=](const AIStat& stat) { return stat.getModified(context); });
|
||||
sol::table ai(context.mLua->sol(), sol::create);
|
||||
stats["ai"] = LuaUtil::makeReadOnly(ai);
|
||||
ai["alarm"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Alarm);
|
||||
ai["fight"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Fight);
|
||||
ai["flee"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Flee);
|
||||
ai["hello"] = addIndexedAccessor<AIStat>(MWMechanics::AiSetting::Hello);
|
||||
}
|
||||
|
||||
void addNpcStatsBindings(sol::table& npc, const Context& context)
|
||||
|
@ -445,6 +445,12 @@
|
||||
-- @field #number modifier The skill's modifier.
|
||||
-- @field #number progress [0-1] The NPC's skill progress.
|
||||
|
||||
---
|
||||
-- @type AIStat
|
||||
-- @field #number base The stat's base value.
|
||||
-- @field #number modifier The stat's modifier.
|
||||
-- @field #number modified The actor's current ai value (read-only.)
|
||||
|
||||
---
|
||||
-- @type DynamicStats
|
||||
|
||||
@ -466,6 +472,33 @@
|
||||
-- @param openmw.core#GameObject actor
|
||||
-- @return #DynamicStat
|
||||
|
||||
---
|
||||
-- @type AIStats
|
||||
|
||||
---
|
||||
-- Alarm (returns @{#AIStat})
|
||||
-- @function [parent=#AIStats] alarm
|
||||
-- @param openmw.core#GameObject actor
|
||||
-- @return #AIStat
|
||||
|
||||
---
|
||||
-- Fight (returns @{#AIStat})
|
||||
-- @function [parent=#AIStats] fight
|
||||
-- @param openmw.core#GameObject actor
|
||||
-- @return #AIStat
|
||||
|
||||
---
|
||||
-- Flee (returns @{#AIStat})
|
||||
-- @function [parent=#AIStats] flee
|
||||
-- @param openmw.core#GameObject actor
|
||||
-- @return #AIStat
|
||||
|
||||
---
|
||||
-- Hello (returns @{#AIStat})
|
||||
-- @function [parent=#AIStats] hello
|
||||
-- @param openmw.core#GameObject actor
|
||||
-- @return #AIStat
|
||||
|
||||
---
|
||||
-- @type AttributeStats
|
||||
|
||||
@ -686,6 +719,7 @@
|
||||
-- @type ActorStats
|
||||
-- @field #DynamicStats dynamic
|
||||
-- @field #AttributeStats attributes
|
||||
-- @field #AIStats ai
|
||||
|
||||
---
|
||||
-- Level (returns @{#LevelStat})
|
||||
|
Loading…
x
Reference in New Issue
Block a user