mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Merge branch 'awholelottanothing' into 'master'
Don't crash on spells or enchantments without effects Closes #7712 See merge request OpenMW/openmw!3643
This commit is contained in:
commit
ad8392b7d1
7 changed files with 71 additions and 65 deletions
|
@ -103,6 +103,7 @@
|
||||||
Bug #7665: Alchemy menu is missing the ability to deselect and choose different qualities of an apparatus
|
Bug #7665: Alchemy menu is missing the ability to deselect and choose different qualities of an apparatus
|
||||||
Bug #7675: Successful lock spell doesn't produce a sound
|
Bug #7675: Successful lock spell doesn't produce a sound
|
||||||
Bug #7679: Scene luminance value flashes when toggling shaders
|
Bug #7679: Scene luminance value flashes when toggling shaders
|
||||||
|
Bug #7712: Casting doesn't support spells and enchantments with no effects
|
||||||
Feature #3537: Shader-based water ripples
|
Feature #3537: Shader-based water ripples
|
||||||
Feature #5492: Let rain and snow collide with statics
|
Feature #5492: Let rain and snow collide with statics
|
||||||
Feature #6149: Dehardcode Lua API_REVISION
|
Feature #6149: Dehardcode Lua API_REVISION
|
||||||
|
|
|
@ -423,17 +423,21 @@ namespace MWGui
|
||||||
mSpellBox->setUserString("Spell", spellId.serialize());
|
mSpellBox->setUserString("Spell", spellId.serialize());
|
||||||
mSpellBox->setUserData(MyGUI::Any::Null);
|
mSpellBox->setUserData(MyGUI::Any::Null);
|
||||||
|
|
||||||
// use the icon of the first effect
|
if (!spell->mEffects.mList.empty())
|
||||||
const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(
|
{
|
||||||
spell->mEffects.mList.front().mEffectID);
|
// use the icon of the first effect
|
||||||
|
const ESM::MagicEffect* effect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().find(
|
||||||
std::string icon = effect->mIcon;
|
spell->mEffects.mList.front().mEffectID);
|
||||||
std::replace(icon.begin(), icon.end(), '/', '\\');
|
std::string icon = effect->mIcon;
|
||||||
int slashPos = icon.rfind('\\');
|
std::replace(icon.begin(), icon.end(), '/', '\\');
|
||||||
icon.insert(slashPos + 1, "b_");
|
size_t slashPos = icon.rfind('\\');
|
||||||
icon = Misc::ResourceHelpers::correctIconPath(icon, MWBase::Environment::get().getResourceSystem()->getVFS());
|
icon.insert(slashPos + 1, "b_");
|
||||||
|
icon = Misc::ResourceHelpers::correctIconPath(
|
||||||
mSpellImage->setSpellIcon(icon);
|
icon, MWBase::Environment::get().getResourceSystem()->getVFS());
|
||||||
|
mSpellImage->setSpellIcon(icon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mSpellImage->setSpellIcon({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
||||||
|
|
|
@ -202,7 +202,7 @@ namespace MWGui
|
||||||
setIcon(ptr);
|
setIcon(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpellWidget::setSpellIcon(const std::string& icon)
|
void SpellWidget::setSpellIcon(std::string_view icon)
|
||||||
{
|
{
|
||||||
if (mFrame && !mCurrentFrame.empty())
|
if (mFrame && !mCurrentFrame.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
MYGUI_RTTI_DERIVED(SpellWidget)
|
MYGUI_RTTI_DERIVED(SpellWidget)
|
||||||
public:
|
public:
|
||||||
void setSpellIcon(const std::string& icon);
|
void setSpellIcon(std::string_view icon);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,13 +237,15 @@ namespace MWGui
|
||||||
params.mNoTarget = false;
|
params.mNoTarget = false;
|
||||||
effects.push_back(params);
|
effects.push_back(params);
|
||||||
}
|
}
|
||||||
if (MWMechanics::spellIncreasesSkill(
|
// display school of spells that contribute to skill progress
|
||||||
spell)) // display school of spells that contribute to skill progress
|
if (MWMechanics::spellIncreasesSkill(spell))
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
ESM::RefId id = MWMechanics::getSpellSchool(spell, MWMechanics::getPlayer());
|
||||||
const auto& school
|
if (!id.empty())
|
||||||
= store->get<ESM::Skill>().find(MWMechanics::getSpellSchool(spell, player))->mSchool;
|
{
|
||||||
info.text = "#{sSchool}: " + MyGUI::TextIterator::toTagsString(school->mName).asUTF8();
|
const auto& school = store->get<ESM::Skill>().find(id)->mSchool;
|
||||||
|
info.text = "#{sSchool}: " + MyGUI::TextIterator::toTagsString(school->mName).asUTF8();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto cost = focus->getUserString("SpellCost");
|
auto cost = focus->getUserString("SpellCost");
|
||||||
if (!cost.empty() && cost != "0")
|
if (!cost.empty() && cost != "0")
|
||||||
|
|
|
@ -1605,18 +1605,19 @@ namespace MWMechanics
|
||||||
effects = &spell->mEffects.mList;
|
effects = &spell->mEffects.mList;
|
||||||
cast.playSpellCastingEffects(spell);
|
cast.playSpellCastingEffects(spell);
|
||||||
}
|
}
|
||||||
if (mCanCast)
|
if (!effects->empty())
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(
|
if (mCanCast)
|
||||||
effects->back().mEffectID); // use last effect of list for color of VFX_Hands
|
|
||||||
|
|
||||||
const ESM::Static* castStatic
|
|
||||||
= world->getStore().get<ESM::Static>().find(ESM::RefId::stringRefId("VFX_Hands"));
|
|
||||||
|
|
||||||
const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
|
|
||||||
|
|
||||||
if (!effects->empty())
|
|
||||||
{
|
{
|
||||||
|
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
|
||||||
|
= world->getStore().get<ESM::Static>().find(ESM::RefId::stringRefId("VFX_Hands"));
|
||||||
|
|
||||||
|
const VFS::Manager* const vfs
|
||||||
|
= MWBase::Environment::get().getResourceSystem()->getVFS();
|
||||||
|
|
||||||
if (mAnimation->getNode("Bip01 L Hand"))
|
if (mAnimation->getNode("Bip01 L Hand"))
|
||||||
mAnimation->addEffect(
|
mAnimation->addEffect(
|
||||||
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false,
|
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false,
|
||||||
|
@ -1627,44 +1628,44 @@ namespace MWMechanics
|
||||||
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false,
|
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false,
|
||||||
"Bip01 R Hand", effect->mParticle);
|
"Bip01 R Hand", effect->mParticle);
|
||||||
}
|
}
|
||||||
}
|
// first effect used for casting animation
|
||||||
|
const ESM::ENAMstruct& firstEffect = effects->front();
|
||||||
|
|
||||||
const ESM::ENAMstruct& firstEffect = effects->at(0); // first effect used for casting animation
|
std::string startKey;
|
||||||
|
std::string stopKey;
|
||||||
std::string startKey;
|
if (isRandomAttackAnimation(mCurrentWeapon))
|
||||||
std::string stopKey;
|
|
||||||
if (isRandomAttackAnimation(mCurrentWeapon))
|
|
||||||
{
|
|
||||||
startKey = "start";
|
|
||||||
stopKey = "stop";
|
|
||||||
if (mCanCast)
|
|
||||||
world->castSpell(
|
|
||||||
mPtr, mCastingManualSpell); // No "release" text key to use, so cast immediately
|
|
||||||
mCastingManualSpell = false;
|
|
||||||
mCanCast = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (firstEffect.mRange)
|
|
||||||
{
|
{
|
||||||
case 0:
|
startKey = "start";
|
||||||
mAttackType = "self";
|
stopKey = "stop";
|
||||||
break;
|
if (mCanCast)
|
||||||
case 1:
|
world->castSpell(
|
||||||
mAttackType = "touch";
|
mPtr, mCastingManualSpell); // No "release" text key to use, so cast immediately
|
||||||
break;
|
mCastingManualSpell = false;
|
||||||
case 2:
|
mCanCast = false;
|
||||||
mAttackType = "target";
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
switch (firstEffect.mRange)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
mAttackType = "self";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mAttackType = "touch";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mAttackType = "target";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
startKey = mAttackType + " start";
|
||||||
|
stopKey = mAttackType + " stop";
|
||||||
}
|
}
|
||||||
|
|
||||||
startKey = mAttackType + " start";
|
mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false,
|
||||||
stopKey = mAttackType + " stop";
|
1, startKey, stopKey, 0.0f, 0);
|
||||||
|
mUpperBodyState = UpperBodyState::Casting;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false, 1,
|
|
||||||
startKey, stopKey, 0.0f, 0);
|
|
||||||
mUpperBodyState = UpperBodyState::Casting;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -524,11 +524,9 @@ namespace MWWorld
|
||||||
|
|
||||||
const ESM::Enchantment* enchantment
|
const ESM::Enchantment* enchantment
|
||||||
= MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().search(enchantmentName);
|
= MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().search(enchantmentName);
|
||||||
if (!enchantment)
|
if (!enchantment || enchantment->mEffects.mList.empty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
assert(enchantment->mEffects.mList.size());
|
|
||||||
|
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().search(
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getESMStore()->get<ESM::MagicEffect>().search(
|
||||||
enchantment->mEffects.mList.front().mEffectID);
|
enchantment->mEffects.mList.front().mEffectID);
|
||||||
if (!magicEffect)
|
if (!magicEffect)
|
||||||
|
|
Loading…
Reference in a new issue