Rewrite addvfx and spawnvfx to take a model path instead of a static. Mode vfx from core to world. Add event handlers for AddVfx and SpawnVfx.

pull/3236/head
Mads Buvik Sandvei 5 months ago
parent a2805de0bc
commit 09f6daf155

@ -70,26 +70,6 @@ namespace MWLua
return anim;
}
const ESM::Static* getStatic(const sol::object& staticOrID)
{
if (staticOrID.is<ESM::Static>())
return staticOrID.as<const ESM::Static*>();
else
{
ESM::RefId id = ESM::RefId::deserializeText(LuaUtil::cast<std::string_view>(staticOrID));
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find(id);
}
}
std::string getStaticModelOrThrow(const sol::object& staticOrID)
{
const ESM::Static* static_ = getStatic(staticOrID);
if (!static_)
throw std::runtime_error("Invalid static");
return Misc::ResourceHelpers::correctMeshPath(static_->mModel);
}
static AnimationPriorities getPriorityArgument(const sol::table& args)
{
auto asPriorityEnum = args.get<sol::optional<Priority>>("priority");
@ -277,19 +257,18 @@ namespace MWLua
};
api["addVfx"] = sol::overload(
[context](const sol::object& object, const sol::object& staticOrID) {
[context](const sol::object& object, const std::string& model) {
context.mLuaManager->addAction(
[object = ObjectVariant(object), model = getStaticModelOrThrow(staticOrID)] {
[object = ObjectVariant(object), model = model] {
MWRender::Animation* anim = getMutableAnimationOrThrow(object);
anim->addEffect(model, "");
},
"addVfxAction");
},
[context](const sol::object& object, const sol::object& staticOrID, const sol::table& options) {
[context](const sol::object& object, const std::string& model, const sol::table& options) {
context.mLuaManager->addAction(
[object = ObjectVariant(object), model = getStaticModelOrThrow(staticOrID),
effectId = options.get_or<std::string>("vfxId", ""), loop = options.get_or("loop", false),
boneName = options.get_or<std::string>("boneName", ""),
[object = ObjectVariant(object), model = model, effectId = options.get_or<std::string>("vfxId", ""),
loop = options.get_or("loop", false), boneName = options.get_or<std::string>("boneName", ""),
particleTexture = options.get_or<std::string>("particleTextureOverride", "")] {
MWRender::Animation* anim = getMutableAnimationOrThrow(ObjectVariant(object));
@ -319,28 +298,25 @@ namespace MWLua
return LuaUtil::makeReadOnly(api);
}
sol::table initCoreVfxBindings(const Context& context)
sol::table initWorldVfxBindings(const Context& context)
{
sol::state_view& lua = context.mLua->sol();
sol::table api(lua, sol::create);
auto world = MWBase::Environment::get().getWorld();
api["spawn"] = sol::overload(
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos) {
auto model = getStaticModelOrThrow(staticOrID);
[world, context](const std::string model, const osg::Vec3f& worldPos) {
context.mLuaManager->addAction(
[world, model = std::move(model), worldPos]() { world->spawnEffect(model, "", worldPos); },
[world, model = model, worldPos]() { world->spawnEffect(model, "", worldPos); },
"openmw.vfx.spawn");
},
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos, const sol::table& options) {
auto model = getStaticModelOrThrow(staticOrID);
[world, context](const std::string& model, const osg::Vec3f& worldPos, const sol::table& options) {
bool magicVfx = options.get_or("mwMagicVfx", true);
std::string texture = options.get_or<std::string>("particleTextureOverride", "");
float scale = options.get_or("scale", 1.f);
context.mLuaManager->addAction(
[world, model = std::move(model), texture = std::move(texture), worldPos, scale, magicVfx]() {
[world, model = model, texture = std::move(texture), worldPos, scale, magicVfx]() {
world->spawnEffect(model, texture, worldPos, scale, magicVfx);
},
"openmw.vfx.spawn");

@ -8,7 +8,7 @@ namespace MWLua
struct Context;
sol::table initAnimationPackage(const Context& context);
sol::table initCoreVfxBindings(const Context& context);
sol::table initWorldVfxBindings(const Context& context);
}
#endif // MWLUA_ANIMATIONBINDINGS_H

@ -19,7 +19,6 @@
#include "../mwworld/datetimemanager.hpp"
#include "../mwworld/esmstore.hpp"
#include "animationbindings.hpp"
#include "dialoguebindings.hpp"
#include "factionbindings.hpp"
#include "luaevents.hpp"
@ -137,7 +136,6 @@ namespace MWLua
};
api["sound"]
= context.cachePackage("openmw_core_sound", [context]() { return initCoreSoundBindings(context); });
api["vfx"] = initCoreVfxBindings(context);
}
else
{

@ -25,6 +25,7 @@
#include "luamanagerimp.hpp"
#include "animationbindings.hpp"
#include "corebindings.hpp"
#include "mwscriptbindings.hpp"
@ -219,6 +220,8 @@ namespace MWLua
"_runStandardUseAction");
};
api["vfx"] = initWorldVfxBindings(context);
return LuaUtil::makeReadOnly(api);
}
}

@ -141,5 +141,11 @@ return {
end
handlers[#handlers + 1] = handler
end,
},
eventHandlers = {
AddVfx = function(data)
anim.addVfx(self, data.model, data.options)
end,
}
}
}

@ -6,5 +6,12 @@ return {
Unpause = function(tag) world.unpause(tag) end,
SetGameTimeScale = function(scale) world.setGameTimeScale(scale) end,
SetSimulationTimeScale = function(scale) world.setSimulationTimeScale(scale) end,
SpawnVfx = function(data)
if data.options then
world.vfx.spawn(data.model, data.position, data.options)
else
world.vfx.spawn(data.model, data.position)
end
end,
},
}

@ -218,22 +218,34 @@
---
-- Plays a VFX on the actor.
-- Can be used only in local scripts on self.
-- Can be used only in local scripts on self. Can also be evoked by sending an AddVfx event to the target actor.
-- @function [parent=#animation] addVfx
-- @param openmw.core#GameObject actor
-- @param #any static @{openmw.core#StaticRecord} or #string ID
-- @param #string model #string model path (normally taken from a record such as @{openmw.types#StaticRecord.model} or similar)
-- @param #table options optional table of parameters. Can contain:
--
-- * `loop` - boolean, if true the effect will loop until removed (default: 0).
-- * `boneName` - name of the bone to attach the vfx to. (default: "")
-- * `particle` - name of the particle texture to use. (default: "")
-- * `particleTextureOverride` - name of the particle texture to use. (default: "")
-- * `vfxId` - a string ID that can be used to remove the effect later, using #removeVfx, and to avoid duplicate effects. The default value of "" can have duplicates. To avoid interaction with the engine, use unique identifiers unrelated to magic effect IDs. The engine uses this identifier to add and remove magic effects based on what effects are active on the actor. If this is set equal to the @{openmw.core#MagicEffectId} identifier of the magic effect being added, for example core.magic.EFFECT_TYPE.FireDamage, then the engine will remove it once the fire damage effect on the actor reaches 0. (Default: "").
--
-- @usage local mgef = core.magic.effects.records[myEffectName]
-- anim.addVfx(self, 'VFX_Hands', {boneName = 'Bip01 L Hand', particle = mgef.particle, loop = mgef.continuousVfx, vfxId = mgef.id..'_myuniquenamehere'})
-- anim.addVfx(self, 'VFX_Hands', {boneName = 'Bip01 L Hand', particleTextureOverride = mgef.particle, loop = mgef.continuousVfx, vfxId = mgef.id..'_myuniquenamehere'})
-- -- later:
-- anim.removeVfx(self, mgef.id..'_myuniquenamehere')
--
-- @usage -- Add vfx to another actor using an event
-- local mgef = core.magic.effects.records[myEffectName]
-- target:sendEvent('AddVfx', {
-- model = types.Static.record(mgef.hitStatic).model,
-- options = {
-- vfxId = mgef.id,
-- particuleTextureOverride = mgef.particle,
-- loop = false,
-- }
-- })
--
---
-- Removes a specific VFX

@ -1142,24 +1142,4 @@
-- @field #number favouredSkillValue Secondary skill value required to get this rank.
-- @field #number factionReaction Reaction of faction members if player is in this faction.
--- @{#VFX}: Visual effects
-- @field [parent=#core] #VFX vfx
---
-- Spawn a VFX at the given location in the world
-- @function [parent=#VFX] spawn
-- @param #any static openmw.core#StaticRecord or #string ID
-- @param openmw.util#Vector3 location
-- @param #table options optional table of parameters. Can contain:
--
-- * `mwMagicVfx` - Boolean that if true causes the textureOverride parameter to only affect nodes with the Nif::RC_NiTexturingProperty property set. (default: true).
-- * `particleTextureOverride` - Name of a particle texture that should override this effect's default texture. (default: "")
-- * `scale` - A number that scales the size of the vfx (Default: 1)
--
-- @usage -- Spawn a sanctuary effect near the player
-- local effect = core.magic.effects.records[core.magic.EFFECT_TYPE.Sanctuary]
-- pos = self.position + util.vector3(0, 100, 0)
-- core.vfx.spawn(effect.castingStatic, pos)
--
return nil

@ -180,4 +180,25 @@
-- @param #any record A record to be registered in the database. Must be one of the supported types.
-- @return #any A new record added to the database. The type is the same as the input's.
--- @{#VFX}: Visual effects
-- @field [parent=#world] #VFX vfx
---
-- Spawn a VFX at the given location in the world. Best invoked through the SpawnVfx global event
-- @function [parent=#VFX] spawn
-- @param #string model #string model path (normally taken from a record such as @{openmw.types#StaticRecord.model} or similar)
-- @param openmw.util#Vector3 position
-- @param #table options optional table of parameters. Can contain:
--
-- * `mwMagicVfx` - Boolean that if true causes the textureOverride parameter to only affect nodes with the Nif::RC_NiTexturingProperty property set. (default: true).
-- * `particleTextureOverride` - Name of a particle texture that should override this effect's default texture. (default: "")
-- * `scale` - A number that scales the size of the vfx (Default: 1)
--
-- @usage -- Spawn a sanctuary effect near the player
-- local effect = core.magic.effects.records[core.magic.EFFECT_TYPE.Sanctuary]
-- local pos = self.position + util.vector3(0, 100, 0)
-- local model = types.Static.record(effect.castingStatic).model
-- core.sendGlobalEvent('SpawnVfx', {model = model, position = pos})
--
return nil

Loading…
Cancel
Save