mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 10:09:39 +00:00
Add some more safety checks to spellcasting
This commit is contained in:
parent
f2c193ce3d
commit
2f13a17a39
3 changed files with 24 additions and 16 deletions
|
@ -29,7 +29,7 @@ namespace
|
||||||
|
|
||||||
const std::string& faction = item.getCellRef().mFaction;
|
const std::string& faction = item.getCellRef().mFaction;
|
||||||
bool isFactionOwned = false;
|
bool isFactionOwned = false;
|
||||||
if (!faction.empty())
|
if (!faction.empty() && ptr.getClass().isNpc())
|
||||||
{
|
{
|
||||||
const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
|
const std::map<std::string, int>& factions = ptr.getClass().getNpcStats(ptr).getFactionRanks();
|
||||||
if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end())
|
if (factions.find(Misc::StringUtils::lowerCase(faction)) == factions.end())
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace MWMechanics
|
||||||
float x = (willpower + 0.1 * luck) * stats.getFatigueTerm();
|
float x = (willpower + 0.1 * luck) * stats.getFatigueTerm();
|
||||||
|
|
||||||
// This makes spells that are easy to cast harder to resist and vice versa
|
// This makes spells that are easy to cast harder to resist and vice versa
|
||||||
if (spell != NULL && caster.getClass().isActor())
|
if (spell != NULL && !caster.isEmpty() && caster.getClass().isActor())
|
||||||
{
|
{
|
||||||
float castChance = getSpellSuccessChance(spell, caster);
|
float castChance = getSpellSuccessChance(spell, caster);
|
||||||
if (castChance > 0)
|
if (castChance > 0)
|
||||||
|
@ -226,6 +226,8 @@ namespace MWMechanics
|
||||||
bool firstAppliedEffect = true;
|
bool firstAppliedEffect = true;
|
||||||
bool anyHarmfulEffect = false;
|
bool anyHarmfulEffect = false;
|
||||||
|
|
||||||
|
bool castByPlayer = (!caster.isEmpty() && caster.getRefData().getHandle() == "player");
|
||||||
|
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (effects.mList.begin());
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (effects.mList.begin());
|
||||||
effectIt!=effects.mList.end(); ++effectIt)
|
effectIt!=effects.mList.end(); ++effectIt)
|
||||||
{
|
{
|
||||||
|
@ -238,7 +240,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
if (!MWBase::Environment::get().getWorld()->isLevitationEnabled() && effectIt->mEffectID == ESM::MagicEffect::Levitate)
|
if (!MWBase::Environment::get().getWorld()->isLevitationEnabled() && effectIt->mEffectID == ESM::MagicEffect::Levitate)
|
||||||
{
|
{
|
||||||
if (caster.getRefData().getHandle() == "player")
|
if (castByPlayer)
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -249,13 +251,13 @@ namespace MWMechanics
|
||||||
effectIt->mEffectID == ESM::MagicEffect::Mark ||
|
effectIt->mEffectID == ESM::MagicEffect::Mark ||
|
||||||
effectIt->mEffectID == ESM::MagicEffect::Recall))
|
effectIt->mEffectID == ESM::MagicEffect::Recall))
|
||||||
{
|
{
|
||||||
if (caster.getRefData().getHandle() == "player")
|
if (castByPlayer)
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is healing someone, show the target's HP bar
|
// If player is healing someone, show the target's HP bar
|
||||||
if (caster.getRefData().getHandle() == "player" && target != caster
|
if (castByPlayer && target != caster
|
||||||
&& effectIt->mEffectID == ESM::MagicEffect::RestoreHealth
|
&& effectIt->mEffectID == ESM::MagicEffect::RestoreHealth
|
||||||
&& target.getClass().isActor())
|
&& target.getClass().isActor())
|
||||||
MWBase::Environment::get().getWindowManager()->setEnemy(target);
|
MWBase::Environment::get().getWindowManager()->setEnemy(target);
|
||||||
|
@ -266,7 +268,7 @@ namespace MWMechanics
|
||||||
anyHarmfulEffect = true;
|
anyHarmfulEffect = true;
|
||||||
|
|
||||||
// If player is attempting to cast a harmful spell, show the target's HP bar
|
// If player is attempting to cast a harmful spell, show the target's HP bar
|
||||||
if (caster.getRefData().getHandle() == "player" && target != caster)
|
if (castByPlayer && target != caster)
|
||||||
MWBase::Environment::get().getWindowManager()->setEnemy(target);
|
MWBase::Environment::get().getWindowManager()->setEnemy(target);
|
||||||
|
|
||||||
// Try absorbing if it's a spell
|
// Try absorbing if it's a spell
|
||||||
|
@ -342,17 +344,20 @@ namespace MWMechanics
|
||||||
|
|
||||||
// For absorb effects, also apply the effect to the caster - but with a negative
|
// For absorb effects, also apply the effect to the caster - but with a negative
|
||||||
// magnitude, since we're transfering stats from the target to the caster
|
// magnitude, since we're transfering stats from the target to the caster
|
||||||
for (int i=0; i<5; ++i)
|
if (!caster.isEmpty() && caster.getClass().isActor())
|
||||||
{
|
{
|
||||||
if (effectIt->mEffectID == ESM::MagicEffect::AbsorbAttribute+i)
|
for (int i=0; i<5; ++i)
|
||||||
{
|
{
|
||||||
std::vector<ActiveSpells::ActiveEffect> effects;
|
if (effectIt->mEffectID == ESM::MagicEffect::AbsorbAttribute+i)
|
||||||
ActiveSpells::ActiveEffect effect_ = effect;
|
{
|
||||||
effect_.mMagnitude *= -1;
|
std::vector<ActiveSpells::ActiveEffect> effects;
|
||||||
effects.push_back(effect_);
|
ActiveSpells::ActiveEffect effect_ = effect;
|
||||||
// Also make sure to set casterActorId = target, so that the effect on the caster gets purged when the target dies
|
effect_.mMagnitude *= -1;
|
||||||
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true,
|
effects.push_back(effect_);
|
||||||
effects, mSourceName, target.getClass().getCreatureStats(target).getActorId());
|
// Also make sure to set casterActorId = target, so that the effect on the caster gets purged when the target dies
|
||||||
|
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true,
|
||||||
|
effects, mSourceName, target.getClass().getCreatureStats(target).getActorId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +446,8 @@ namespace MWMechanics
|
||||||
if (target.getCellRef().mLockLevel > 0)
|
if (target.getCellRef().mLockLevel > 0)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
|
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
|
||||||
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
|
if (!caster.isEmpty() && caster.getClass().isActor())
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
|
||||||
}
|
}
|
||||||
target.getCellRef().mLockLevel = -abs(target.getCellRef().mLockLevel); //unlocks the door
|
target.getCellRef().mLockLevel = -abs(target.getCellRef().mLockLevel); //unlocks the door
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,11 @@ namespace MWMechanics
|
||||||
bool cast (const std::string& id);
|
bool cast (const std::string& id);
|
||||||
|
|
||||||
/// @note \a target can be any type of object, not just actors.
|
/// @note \a target can be any type of object, not just actors.
|
||||||
|
/// @note \a caster can be any type of object, or even an empty object.
|
||||||
void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,
|
void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,
|
||||||
const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false, bool exploded=false);
|
const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false, bool exploded=false);
|
||||||
|
|
||||||
|
/// @note \a caster can be any type of object, or even an empty object.
|
||||||
void applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const MWMechanics::EffectKey& effect, float magnitude);
|
void applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const MWMechanics::EffectKey& effect, float magnitude);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue