mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 20:29:57 +00:00
Merge branch 'rewrite-vfx' into 'master'
[Lua] Rewrite addvfx and spawnvfx See merge request OpenMW/openmw!4314
This commit is contained in:
commit
73ee8ccc4e
9 changed files with 88 additions and 84 deletions
|
@ -70,26 +70,6 @@ namespace MWLua
|
||||||
return anim;
|
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)
|
static AnimationPriorities getPriorityArgument(const sol::table& args)
|
||||||
{
|
{
|
||||||
auto asPriorityEnum = args.get<sol::optional<Priority>>("priority");
|
auto asPriorityEnum = args.get<sol::optional<Priority>>("priority");
|
||||||
|
@ -276,27 +256,31 @@ namespace MWLua
|
||||||
return anim->getNode(bonename) != nullptr;
|
return anim->getNode(bonename) != nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
api["addVfx"] = sol::overload(
|
api["addVfx"] = [context](
|
||||||
[context](const sol::object& object, const sol::object& staticOrID) {
|
const sol::object& object, std::string_view model, sol::optional<sol::table> options) {
|
||||||
|
if (options)
|
||||||
|
{
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
[object = ObjectVariant(object), model = getStaticModelOrThrow(staticOrID)] {
|
[object = ObjectVariant(object), model = std::string(model),
|
||||||
MWRender::Animation* anim = getMutableAnimationOrThrow(object);
|
effectId = options->get_or<std::string>("vfxId", ""), loop = options->get_or("loop", false),
|
||||||
anim->addEffect(model, "");
|
boneName = options->get_or<std::string>("boneName", ""),
|
||||||
},
|
particleTexture = options->get_or<std::string>("particleTextureOverride", "")] {
|
||||||
"addVfxAction");
|
|
||||||
},
|
|
||||||
[context](const sol::object& object, const sol::object& staticOrID, 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", ""),
|
|
||||||
particleTexture = options.get_or<std::string>("particleTextureOverride", "")] {
|
|
||||||
MWRender::Animation* anim = getMutableAnimationOrThrow(ObjectVariant(object));
|
MWRender::Animation* anim = getMutableAnimationOrThrow(ObjectVariant(object));
|
||||||
|
|
||||||
anim->addEffect(model, effectId, loop, boneName, particleTexture);
|
anim->addEffect(model, effectId, loop, boneName, particleTexture);
|
||||||
},
|
},
|
||||||
"addVfxAction");
|
"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) {
|
api["removeVfx"] = [context](const sol::object& object, std::string_view effectId) {
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
|
@ -319,32 +303,31 @@ namespace MWLua
|
||||||
return LuaUtil::makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initCoreVfxBindings(const Context& context)
|
sol::table initWorldVfxBindings(const Context& context)
|
||||||
{
|
{
|
||||||
sol::state_view& lua = context.mLua->sol();
|
sol::state_view& lua = context.mLua->sol();
|
||||||
sol::table api(lua, sol::create);
|
sol::table api(lua, sol::create);
|
||||||
auto world = MWBase::Environment::get().getWorld();
|
auto world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
api["spawn"] = sol::overload(
|
api["spawn"]
|
||||||
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos) {
|
= [world, context](std::string_view model, const osg::Vec3f& worldPos, sol::optional<sol::table> options) {
|
||||||
auto model = getStaticModelOrThrow(staticOrID);
|
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(
|
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");
|
"openmw.vfx.spawn");
|
||||||
},
|
}
|
||||||
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos, const sol::table& options) {
|
else
|
||||||
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);
|
|
||||||
|
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
[world, model = std::move(model), texture = std::move(texture), worldPos, scale, magicVfx]() {
|
[world, model = std::string(model), worldPos]() { world->spawnEffect(model, "", worldPos); },
|
||||||
world->spawnEffect(model, texture, worldPos, scale, magicVfx);
|
|
||||||
},
|
|
||||||
"openmw.vfx.spawn");
|
"openmw.vfx.spawn");
|
||||||
});
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace MWLua
|
||||||
struct Context;
|
struct Context;
|
||||||
|
|
||||||
sol::table initAnimationPackage(const Context& context);
|
sol::table initAnimationPackage(const Context& context);
|
||||||
sol::table initCoreVfxBindings(const Context& context);
|
sol::table initWorldVfxBindings(const Context& context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MWLUA_ANIMATIONBINDINGS_H
|
#endif // MWLUA_ANIMATIONBINDINGS_H
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "../mwworld/datetimemanager.hpp"
|
#include "../mwworld/datetimemanager.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
#include "animationbindings.hpp"
|
|
||||||
#include "dialoguebindings.hpp"
|
#include "dialoguebindings.hpp"
|
||||||
#include "factionbindings.hpp"
|
#include "factionbindings.hpp"
|
||||||
#include "luaevents.hpp"
|
#include "luaevents.hpp"
|
||||||
|
@ -137,7 +136,6 @@ namespace MWLua
|
||||||
};
|
};
|
||||||
api["sound"]
|
api["sound"]
|
||||||
= context.cachePackage("openmw_core_sound", [context]() { return initCoreSoundBindings(context); });
|
= context.cachePackage("openmw_core_sound", [context]() { return initCoreSoundBindings(context); });
|
||||||
api["vfx"] = initCoreVfxBindings(context);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
|
#include "animationbindings.hpp"
|
||||||
#include "corebindings.hpp"
|
#include "corebindings.hpp"
|
||||||
#include "mwscriptbindings.hpp"
|
#include "mwscriptbindings.hpp"
|
||||||
|
|
||||||
|
@ -219,6 +220,8 @@ namespace MWLua
|
||||||
"_runStandardUseAction");
|
"_runStandardUseAction");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
api["vfx"] = initWorldVfxBindings(context);
|
||||||
|
|
||||||
return LuaUtil::makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,5 +141,11 @@ return {
|
||||||
end
|
end
|
||||||
handlers[#handlers + 1] = handler
|
handlers[#handlers + 1] = handler
|
||||||
end,
|
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,
|
Unpause = function(tag) world.unpause(tag) end,
|
||||||
SetGameTimeScale = function(scale) world.setGameTimeScale(scale) end,
|
SetGameTimeScale = function(scale) world.setGameTimeScale(scale) end,
|
||||||
SetSimulationTimeScale = function(scale) world.setSimulationTimeScale(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.
|
-- 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
|
-- @function [parent=#animation] addVfx
|
||||||
-- @param openmw.core#GameObject actor
|
-- @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:
|
-- @param #table options optional table of parameters. Can contain:
|
||||||
--
|
--
|
||||||
-- * `loop` - boolean, if true the effect will loop until removed (default: 0).
|
-- * `loop` - boolean, if true the effect will loop until removed (default: 0).
|
||||||
-- * `boneName` - name of the bone to attach the vfx to. (default: "")
|
-- * `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: "").
|
-- * `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]
|
-- @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:
|
-- -- later:
|
||||||
-- anim.removeVfx(self, mgef.id..'_myuniquenamehere')
|
-- 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
|
-- Removes a specific VFX
|
||||||
|
|
|
@ -1142,24 +1142,4 @@
|
||||||
-- @field #number favouredSkillValue Secondary skill value required to get this rank.
|
-- @field #number favouredSkillValue Secondary skill value required to get this rank.
|
||||||
-- @field #number factionReaction Reaction of faction members if player is in this faction.
|
-- @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
|
return nil
|
||||||
|
|
|
@ -180,4 +180,25 @@
|
||||||
-- @param #any record A record to be registered in the database. Must be one of the supported types.
|
-- @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.
|
-- @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
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue