mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Merge pull request #2309 from akortunov/enchant_animations
Add an option to use casting animations for magic items
This commit is contained in:
commit
e9f6c11cc9
7 changed files with 78 additions and 28 deletions
|
@ -70,6 +70,7 @@
|
|||
Feature #4859: Make water reflections more configurable
|
||||
Feature #4887: Add openmw command option to set initial random seed
|
||||
Feature #4890: Make Distant Terrain configurable
|
||||
Feature #4962: Add casting animations for magic items
|
||||
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
||||
Task #4695: Optimize Distant Terrain memory consumption
|
||||
|
||||
|
|
|
@ -1195,7 +1195,7 @@ bool CharacterController::updateCreatureState()
|
|||
if (!spellid.empty() && canCast)
|
||||
{
|
||||
MWMechanics::CastSpell cast(mPtr, nullptr, false, mCastingManualSpell);
|
||||
cast.playSpellCastingEffects(spellid);
|
||||
cast.playSpellCastingEffects(spellid, false);
|
||||
|
||||
if (!mAnimation->hasAnimation("spellcast"))
|
||||
{
|
||||
|
@ -1515,23 +1515,53 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
stats.getSpells().setSelectedSpell(selectedSpell);
|
||||
}
|
||||
std::string spellid = stats.getSpells().getSelectedSpell();
|
||||
bool isMagicItem = false;
|
||||
bool canCast = mCastingManualSpell || MWBase::Environment::get().getWorld()->startSpellCast(mPtr);
|
||||
|
||||
if(!spellid.empty() && canCast)
|
||||
if (spellid.empty())
|
||||
{
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||
if (inv.getSelectedEnchantItem() != inv.end())
|
||||
{
|
||||
const MWWorld::Ptr& enchantItem = *inv.getSelectedEnchantItem();
|
||||
spellid = enchantItem.getClass().getEnchantment(enchantItem);
|
||||
isMagicItem = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const bool useCastingAnimations = Settings::Manager::getBool("use magic item animations", "Game");
|
||||
if (isMagicItem && !useCastingAnimations)
|
||||
{
|
||||
// Enchanted items by default do not use casting animations
|
||||
MWBase::Environment::get().getWorld()->castSpell(mPtr);
|
||||
resetIdle = false;
|
||||
}
|
||||
else if(!spellid.empty() && canCast)
|
||||
{
|
||||
MWMechanics::CastSpell cast(mPtr, nullptr, false, mCastingManualSpell);
|
||||
cast.playSpellCastingEffects(spellid);
|
||||
cast.playSpellCastingEffects(spellid, isMagicItem);
|
||||
|
||||
std::vector<ESM::ENAMstruct> effects;
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
const ESM::Spell *spell = store.get<ESM::Spell>().find(spellid);
|
||||
const ESM::ENAMstruct &lastEffect = spell->mEffects.mList.back();
|
||||
const ESM::MagicEffect *effect;
|
||||
if (isMagicItem)
|
||||
{
|
||||
const ESM::Enchantment *enchantment = store.get<ESM::Enchantment>().find(spellid);
|
||||
effects = enchantment->mEffects.mList;
|
||||
}
|
||||
else
|
||||
{
|
||||
const ESM::Spell *spell = store.get<ESM::Spell>().find(spellid);
|
||||
effects = spell->mEffects.mList;
|
||||
}
|
||||
|
||||
effect = store.get<ESM::MagicEffect>().find(lastEffect.mEffectID); // use last effect of list for color of VFX_Hands
|
||||
const ESM::MagicEffect *effect = store.get<ESM::MagicEffect>().find(effects.back().mEffectID); // use last effect of list for color of VFX_Hands
|
||||
|
||||
const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Hands");
|
||||
|
||||
for (size_t iter = 0; iter < spell->mEffects.mList.size(); ++iter) // play hands vfx for each effect
|
||||
for (size_t iter = 0; iter < effects.size(); ++iter) // play hands vfx for each effect
|
||||
{
|
||||
if (mAnimation->getNode("Bip01 L Hand"))
|
||||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Bip01 L Hand", effect->mParticle);
|
||||
|
@ -1540,7 +1570,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
mAnimation->addEffect("meshes\\" + castStatic->mModel, -1, false, "Bip01 R Hand", effect->mParticle);
|
||||
}
|
||||
|
||||
const ESM::ENAMstruct &firstEffect = spell->mEffects.mList.at(0); // first effect used for casting animation
|
||||
const ESM::ENAMstruct &firstEffect = effects.at(0); // first effect used for casting animation
|
||||
|
||||
std::string startKey;
|
||||
std::string stopKey;
|
||||
|
@ -1574,17 +1604,6 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
|
|||
{
|
||||
resetIdle = false;
|
||||
}
|
||||
|
||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||
{
|
||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||
if (inv.getSelectedEnchantItem() != inv.end())
|
||||
{
|
||||
// Enchanted items cast immediately (no animation)
|
||||
MWBase::Environment::get().getWorld()->castSpell(mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(mWeaponType == WeapType_PickProbe)
|
||||
{
|
||||
|
|
|
@ -971,7 +971,7 @@ namespace MWMechanics
|
|||
|
||||
// A non-actor doesn't play its spell cast effects from a character controller, so play them here
|
||||
if (!mCaster.getClass().isActor())
|
||||
playSpellCastingEffects(mId);
|
||||
playSpellCastingEffects(mId, false);
|
||||
|
||||
inflict(mCaster, mCaster, spell->mEffects, ESM::RT_Self);
|
||||
|
||||
|
@ -1046,15 +1046,27 @@ namespace MWMechanics
|
|||
return true;
|
||||
}
|
||||
|
||||
void CastSpell::playSpellCastingEffects(const std::string &spellid)
|
||||
void CastSpell::playSpellCastingEffects(const std::string &spellid, bool enchantment)
|
||||
{
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
const ESM::Spell *spell = store.get<ESM::Spell>().find(spellid);
|
||||
if (enchantment)
|
||||
{
|
||||
const ESM::Enchantment *spell = store.get<ESM::Enchantment>().find(spellid);
|
||||
playSpellCastingEffects(spell->mEffects.mList);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const ESM::Spell *spell = store.get<ESM::Spell>().find(spellid);
|
||||
playSpellCastingEffects(spell->mEffects.mList);
|
||||
}
|
||||
}
|
||||
|
||||
void CastSpell::playSpellCastingEffects(const std::vector<ESM::ENAMstruct>& effects)
|
||||
{
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
std::vector<std::string> addedEffects;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->mEffects.mList.begin();
|
||||
iter != spell->mEffects.mList.end(); ++iter)
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter = effects.begin(); iter != effects.end(); ++iter)
|
||||
{
|
||||
const ESM::MagicEffect *effect;
|
||||
effect = store.get<ESM::MagicEffect>().find(iter->mEffectID);
|
||||
|
|
|
@ -83,6 +83,9 @@ namespace MWMechanics
|
|||
private:
|
||||
MWWorld::Ptr mCaster; // May be empty
|
||||
MWWorld::Ptr mTarget; // May be empty
|
||||
|
||||
void playSpellCastingEffects(const std::vector<ESM::ENAMstruct>& effects);
|
||||
|
||||
public:
|
||||
bool mStack;
|
||||
std::string mId; // ID of spell, potion, item etc
|
||||
|
@ -109,7 +112,7 @@ namespace MWMechanics
|
|||
/// @note Auto detects if spell, ingredient or potion
|
||||
bool cast (const std::string& id);
|
||||
|
||||
void playSpellCastingEffects(const std::string &spellid);
|
||||
void playSpellCastingEffects(const std::string &spellid, bool enchantment);
|
||||
|
||||
bool spellIncreasesSkill();
|
||||
|
||||
|
|
|
@ -1098,7 +1098,7 @@ namespace MWScript
|
|||
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr (targetId, false);
|
||||
|
||||
MWMechanics::CastSpell cast(ptr, target, false, true);
|
||||
cast.playSpellCastingEffects(spell->mId);
|
||||
cast.playSpellCastingEffects(spell->mId, false);
|
||||
cast.mHitPosition = target.getRefData().getPosition().asVec3();
|
||||
cast.mAlwaysSucceed = true;
|
||||
cast.cast(spell);
|
||||
|
|
|
@ -126,6 +126,18 @@ This is how Morrowind behaves.
|
|||
|
||||
This setting can be toggled in Advanced tab of the launcher.
|
||||
|
||||
use magic item animations
|
||||
-------------------------
|
||||
|
||||
:Type: boolean
|
||||
:Range: True/False
|
||||
:Default: False
|
||||
|
||||
If this setting is true, the engine will use casting animations for magic items, including scrolls.
|
||||
Otherwise, there will be no casting animations, just as in original engine
|
||||
|
||||
This setting can only be configured by editing the settings configuration file.
|
||||
|
||||
show effect duration
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -261,6 +261,9 @@ weapon sheathing = false
|
|||
# Allow non-standard ammunition solely to bypass normal weapon resistance or weakness
|
||||
only appropriate ammunition bypasses resistance = false
|
||||
|
||||
# Use casting animations for magic items, just as for spells
|
||||
use magic item animations = false
|
||||
|
||||
[General]
|
||||
|
||||
# Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).
|
||||
|
|
Loading…
Reference in a new issue