mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-10 06:44:29 +00:00
Lua bindings for modifying active effects/spells
This commit is contained in:
parent
44c3c40058
commit
698316fd2e
@ -9,6 +9,7 @@
|
|||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwmechanics/activespells.hpp"
|
#include "../mwmechanics/activespells.hpp"
|
||||||
@ -46,6 +47,8 @@ namespace MWLua
|
|||||||
|
|
||||||
bool isActor() const { return !mActor.ptr().isEmpty() && mActor.ptr().getClass().isActor(); }
|
bool isActor() const { return !mActor.ptr().isEmpty() && mActor.ptr().getClass().isActor(); }
|
||||||
|
|
||||||
|
bool isLObject() const { return mActor.isLObject(); }
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
mIndex = 0;
|
mIndex = 0;
|
||||||
@ -521,6 +524,18 @@ namespace MWLua
|
|||||||
return false;
|
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))
|
// 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
|
// Note that the indexes are fake, and only for consistency with other lua pairs interfaces. You can't use them
|
||||||
// for anything.
|
// for anything.
|
||||||
@ -544,12 +559,8 @@ namespace MWLua
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// types.Actor.activeEffects(o):getEffect(id, ?arg)
|
auto getEffectKey
|
||||||
activeEffectsT["getEffect"] = [](const ActorActiveEffects& effects, std::string_view idStr,
|
= [](std::string_view idStr, sol::optional<std::string_view> argStr) -> MWMechanics::EffectKey {
|
||||||
sol::optional<std::string_view> argStr) -> sol::optional<ActiveEffect> {
|
|
||||||
if (!effects.isActor())
|
|
||||||
return sol::nullopt;
|
|
||||||
|
|
||||||
auto id = ESM::MagicEffect::indexNameToIndex(idStr);
|
auto id = ESM::MagicEffect::indexNameToIndex(idStr);
|
||||||
auto* rec = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id);
|
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()));
|
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* store = effects.getStore())
|
||||||
if (auto effect = store->get(key))
|
if (auto effect = store->get(key))
|
||||||
return ActiveEffect{ key, effect.value() };
|
return ActiveEffect{ key, effect.value() };
|
||||||
return sol::nullopt;
|
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);
|
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);
|
ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ namespace MWMechanics
|
|||||||
void removeEffects(const MWWorld::Ptr& ptr, const ESM::RefId& id);
|
void removeEffects(const MWWorld::Ptr& ptr, const ESM::RefId& id);
|
||||||
|
|
||||||
/// Remove all active effects with this effect 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(EffectPredicate predicate, const MWWorld::Ptr& ptr);
|
||||||
void purge(ParamsPredicate 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.
|
-- Get a specific active effect on the actor.
|
||||||
-- @function [parent=#ActorActiveEffects] getEffect
|
-- @function [parent=#ActorActiveEffects] getEffect
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @param string effect ID
|
-- @param #string effectId effect ID
|
||||||
-- @param string Optional skill or attribute ID
|
-- @param #string extraParam Optional skill or attribute ID
|
||||||
-- @return #ActiveEffect if such an effect is active, nil otherwise
|
-- @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.
|
-- Return the active spells (@{#ActorActiveSpells}) currently affecting the given actor.
|
||||||
-- @function [parent=#Actor] activeSpells
|
-- @function [parent=#Actor] activeSpells
|
||||||
@ -222,6 +247,12 @@
|
|||||||
-- @param #any spellOrId @{openmw.core#Spell} or string spell id
|
-- @param #any spellOrId @{openmw.core#Spell} or string spell id
|
||||||
-- @return true if spell is active, false otherwise
|
-- @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.
|
-- Return the spells (@{#ActorSpells}) of the given actor.
|
||||||
-- @function [parent=#Actor] spells
|
-- @function [parent=#Actor] spells
|
||||||
|
Loading…
x
Reference in New Issue
Block a user