mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-19 15:09:43 +00:00
Lua bindings for modifying active effects/spells
This commit is contained in:
parent
44c3c40058
commit
698316fd2e
4 changed files with 122 additions and 11 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwmechanics/activespells.hpp"
|
||||
|
@ -46,6 +47,8 @@ namespace MWLua
|
|||
|
||||
bool isActor() const { return !mActor.ptr().isEmpty() && mActor.ptr().getClass().isActor(); }
|
||||
|
||||
bool isLObject() const { return mActor.isLObject(); }
|
||||
|
||||
void reset()
|
||||
{
|
||||
mIndex = 0;
|
||||
|
@ -521,6 +524,18 @@ namespace MWLua
|
|||
return false;
|
||||
};
|
||||
|
||||
// types.Actor.activeSpells(o):remove(id)
|
||||
activeSpellsT["remove"] = [](const ActorActiveSpells& spells, const sol::object& spellOrId) {
|
||||
if (spells.isLObject())
|
||||
throw std::runtime_error("Local scripts can modify effect only on the actor they are attached to.");
|
||||
|
||||
auto id = toSpellId(spellOrId);
|
||||
if (auto* store = spells.getStore())
|
||||
{
|
||||
store->removeEffects(spells.mActor.ptr(), id);
|
||||
}
|
||||
};
|
||||
|
||||
// pairs(types.Actor.activeEffects(o))
|
||||
// Note that the indexes are fake, and only for consistency with other lua pairs interfaces. You can't use them
|
||||
// for anything.
|
||||
|
@ -544,12 +559,8 @@ namespace MWLua
|
|||
});
|
||||
};
|
||||
|
||||
// types.Actor.activeEffects(o):getEffect(id, ?arg)
|
||||
activeEffectsT["getEffect"] = [](const ActorActiveEffects& effects, std::string_view idStr,
|
||||
sol::optional<std::string_view> argStr) -> sol::optional<ActiveEffect> {
|
||||
if (!effects.isActor())
|
||||
return sol::nullopt;
|
||||
|
||||
auto getEffectKey
|
||||
= [](std::string_view idStr, sol::optional<std::string_view> argStr) -> MWMechanics::EffectKey {
|
||||
auto id = ESM::MagicEffect::indexNameToIndex(idStr);
|
||||
auto* rec = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id);
|
||||
|
||||
|
@ -566,10 +577,73 @@ namespace MWLua
|
|||
key = MWMechanics::EffectKey(id, ESM::Skill::stringToSkillId(argStr.value()));
|
||||
}
|
||||
|
||||
return key;
|
||||
};
|
||||
|
||||
// types.Actor.activeEffects(o):getEffect(id, ?arg)
|
||||
activeEffectsT["getEffect"] = [getEffectKey](const ActorActiveEffects& effects, std::string_view idStr,
|
||||
sol::optional<std::string_view> argStr) -> sol::optional<ActiveEffect> {
|
||||
if (!effects.isActor())
|
||||
return sol::nullopt;
|
||||
|
||||
MWMechanics::EffectKey key = getEffectKey(idStr, argStr);
|
||||
|
||||
if (auto* store = effects.getStore())
|
||||
if (auto effect = store->get(key))
|
||||
return ActiveEffect{ key, effect.value() };
|
||||
return sol::nullopt;
|
||||
};
|
||||
|
||||
// types.Actor.activeEffects(o):removeEffect(id, ?arg)
|
||||
activeEffectsT["remove"] = [getEffectKey](const ActorActiveEffects& effects, std::string_view idStr,
|
||||
sol::optional<std::string_view> argStr) {
|
||||
if (!effects.isActor())
|
||||
return;
|
||||
|
||||
if (effects.isLObject())
|
||||
throw std::runtime_error("Local scripts can modify effect only on the actor they are attached to.");
|
||||
|
||||
MWMechanics::EffectKey key = getEffectKey(idStr, argStr);
|
||||
|
||||
// Note that, although this is member method of ActorActiveEffects and we are removing an effect (not a
|
||||
// spell), we still need to use the active spells store to purge this effect from active spells.
|
||||
auto ptr = effects.mActor.ptr();
|
||||
|
||||
// TODO: The current ActiveSpell API does not allow us to differentiate between skill/attribute parameters
|
||||
// of effects. So this cannot remove e.g. "Fortify Luck" without also removing all other fortify attribute
|
||||
// effects such as "Fortify Speed".
|
||||
auto& activeSpells = ptr.getClass().getCreatureStats(ptr).getActiveSpells();
|
||||
activeSpells.purgeEffect(ptr, key.mId, key.mArg);
|
||||
|
||||
// Now remove any leftover effects that have been added by script/console.
|
||||
effects.getStore()->remove(key);
|
||||
};
|
||||
|
||||
// types.Actor.activeEffects(o):set(value, id, ?arg)
|
||||
activeEffectsT["set"] = [getEffectKey](const ActorActiveEffects& effects, int value, std::string_view idStr,
|
||||
sol::optional<std::string_view> argStr) {
|
||||
if (!effects.isActor())
|
||||
return;
|
||||
|
||||
if (effects.isLObject())
|
||||
throw std::runtime_error("Local scripts can modify effect only on the actor they are attached to.");
|
||||
|
||||
MWMechanics::EffectKey key = getEffectKey(idStr, argStr);
|
||||
int currentValue = effects.getStore()->getOrDefault(key).getMagnitude();
|
||||
effects.getStore()->modifyBase(key, value - currentValue);
|
||||
};
|
||||
|
||||
// types.Actor.activeEffects(o):modify(value, id, ?arg)
|
||||
activeEffectsT["modify"] = [getEffectKey](const ActorActiveEffects& effects, int value, std::string_view idStr,
|
||||
sol::optional<std::string_view> argStr) {
|
||||
if (!effects.isActor())
|
||||
return;
|
||||
|
||||
if (effects.isLObject())
|
||||
throw std::runtime_error("Local scripts can modify effect only on the actor they are attached to.");
|
||||
|
||||
MWMechanics::EffectKey key = getEffectKey(idStr, argStr);
|
||||
effects.getStore()->modifyBase(key, value);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -521,9 +521,15 @@ namespace MWMechanics
|
|||
purge([=](const ActiveSpellParams& params) { return params.mId == id; }, ptr);
|
||||
}
|
||||
|
||||
void ActiveSpells::purgeEffect(const MWWorld::Ptr& ptr, short effectId)
|
||||
void ActiveSpells::purgeEffect(const MWWorld::Ptr& ptr, int effectId, int effectArg)
|
||||
{
|
||||
purge([=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) { return effect.mEffectId == effectId; },
|
||||
purge(
|
||||
[=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) {
|
||||
if (effectArg < 0)
|
||||
return effect.mEffectId == effectId;
|
||||
else
|
||||
return effect.mEffectId == effectId && effect.mArg == effectArg;
|
||||
},
|
||||
ptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace MWMechanics
|
|||
void removeEffects(const MWWorld::Ptr& ptr, const ESM::RefId& id);
|
||||
|
||||
/// Remove all active effects with this effect id
|
||||
void purgeEffect(const MWWorld::Ptr& ptr, short effectId);
|
||||
void purgeEffect(const MWWorld::Ptr& ptr, int effectId, int effectArg = -1);
|
||||
|
||||
void purge(EffectPredicate predicate, const MWWorld::Ptr& ptr);
|
||||
void purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr);
|
||||
|
|
|
@ -192,10 +192,35 @@
|
|||
-- Get a specific active effect on the actor.
|
||||
-- @function [parent=#ActorActiveEffects] getEffect
|
||||
-- @param self
|
||||
-- @param string effect ID
|
||||
-- @param string Optional skill or attribute ID
|
||||
-- @param #string effectId effect ID
|
||||
-- @param #string extraParam Optional skill or attribute ID
|
||||
-- @return #ActiveEffect if such an effect is active, nil otherwise
|
||||
|
||||
---
|
||||
-- Completely removes the active effect from the actor.
|
||||
-- This removes both the effects incurred by active spells and effect added by console, mwscript, or luascript.
|
||||
-- @function [parent=#ActorActiveEffects] remove
|
||||
-- @param self
|
||||
-- @param #string effectId effect ID
|
||||
-- @param #string extraParam Optional skill or attribute ID
|
||||
|
||||
---
|
||||
-- Permanently modifies the magnitude of an active effect to be exactly equal to the provided value. This adds the effect to the list of active effects if not already active.
|
||||
-- Note that although the modification is permanent, the magnitude will not stay equal to the value if any active spells with this effects are added/removed.
|
||||
-- @function [parent=#ActorActiveEffects] set
|
||||
-- @param self
|
||||
-- @param #number value
|
||||
-- @param #string effectId effect ID
|
||||
-- @param #string extraParam Optional skill or attribute ID
|
||||
|
||||
---
|
||||
-- Permanently modifies the magnitude of an active effect by increasing it by the provided value. This adds the effect to the list of active effects if not already active.
|
||||
-- @function [parent=#ActorActiveEffects] modify
|
||||
-- @param self
|
||||
-- @param #number value
|
||||
-- @param #string effectId effect ID
|
||||
-- @param #string extraParam Optional skill or attribute ID
|
||||
|
||||
---
|
||||
-- Return the active spells (@{#ActorActiveSpells}) currently affecting the given actor.
|
||||
-- @function [parent=#Actor] activeSpells
|
||||
|
@ -222,6 +247,12 @@
|
|||
-- @param #any spellOrId @{openmw.core#Spell} or string spell id
|
||||
-- @return true if spell is active, false otherwise
|
||||
|
||||
---
|
||||
-- Remove the given spell and all its effects from the given actor's active spells.
|
||||
-- @function [parent=#ActorActiveSpells] remove
|
||||
-- @param self
|
||||
-- @param #any spellOrId @{openmw.core#Spell} or string spell id
|
||||
|
||||
---
|
||||
-- Return the spells (@{#ActorSpells}) of the given actor.
|
||||
-- @function [parent=#Actor] spells
|
||||
|
|
Loading…
Reference in a new issue