Merge branch 'rewrite-vfx' into 'master'

[Lua] Rewrite addvfx and spawnvfx

See merge request OpenMW/openmw!4314
pull/3236/head
psi29a 5 months ago
commit 73ee8ccc4e

@ -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");
@ -276,27 +256,31 @@ namespace MWLua
return anim->getNode(bonename) != nullptr;
};
api["addVfx"] = sol::overload(
[context](const sol::object& object, const sol::object& staticOrID) {
context.mLuaManager->addAction(
[object = ObjectVariant(object), model = getStaticModelOrThrow(staticOrID)] {
MWRender::Animation* anim = getMutableAnimationOrThrow(object);
anim->addEffect(model, "");
},
"addVfxAction");
},
[context](const sol::object& object, const sol::object& staticOrID, const sol::table& options) {
api["addVfx"] = [context](
const sol::object& object, std::string_view model, sol::optional<sol::table> options) {
if (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", ""),
particleTexture = options.get_or<std::string>("particleTextureOverride", "")] {
[object = ObjectVariant(object), model = std::string(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));
anim->addEffect(model, effectId, loop, boneName, particleTexture);
},
"addVfxAction");
});
}
else
{
context.mLuaManager->addAction(
[object = ObjectVariant(object), model = std::string(model)] {
MWRender::Animation* anim = getMutableAnimationOrThrow(object);
anim->addEffect(model, "");
},
"addVfxAction");
}
};
api["removeVfx"] = [context](const sol::object& object, std::string_view effectId) {
context.mLuaManager->addAction(
@ -319,32 +303,31 @@ 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);
api["spawn"]
= [world, context](std::string_view model, const osg::Vec3f& worldPos, sol::optional<sol::table> options) {
if (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), worldPos]() { world->spawnEffect(model, "", worldPos); },
[world, model = std::string(model), texture = std::move(texture), worldPos, scale,
magicVfx]() { world->spawnEffect(model, texture, worldPos, scale, magicVfx); },
"openmw.vfx.spawn");
},
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos, const sol::table& options) {
auto model = getStaticModelOrThrow(staticOrID);
bool magicVfx = options.get_or("mwMagicVfx", true);
std::string texture = options.get_or<std::string>("particleTextureOverride", "");
float scale = options.get_or("scale", 1.f);
}
else
{
context.mLuaManager->addAction(
[world, model = std::move(model), texture = std::move(texture), worldPos, scale, magicVfx]() {
world->spawnEffect(model, texture, worldPos, scale, magicVfx);
},
[world, model = std::string(model), worldPos]() { world->spawnEffect(model, "", worldPos); },
"openmw.vfx.spawn");
});
}
};
return api;
}

@ -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,6 @@ 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) world.vfx.spawn(data.model, data.position, data.options) 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