mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 05:10:26 +00:00
Add many more godmode checks to harmful magic (bug #5633)
This commit is contained in:
parent
f8293536e6
commit
39678c74bf
9 changed files with 67 additions and 25 deletions
|
@ -941,7 +941,8 @@ namespace MWClass
|
||||||
// TODO: This function is called several times per frame for each NPC.
|
// TODO: This function is called several times per frame for each NPC.
|
||||||
// It would be better to calculate it only once per frame for each NPC and save the result in CreatureStats.
|
// It would be better to calculate it only once per frame for each NPC and save the result in CreatureStats.
|
||||||
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||||
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead())
|
bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead())
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -990,7 +991,8 @@ namespace MWClass
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||||
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead())
|
bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead())
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
|
|
|
@ -778,7 +778,8 @@ namespace MWGui
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player);
|
const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player);
|
||||||
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery())
|
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ItemModel::ModelIndex selected = -1;
|
ItemModel::ModelIndex selected = -1;
|
||||||
|
|
|
@ -340,7 +340,8 @@ namespace MWGui
|
||||||
|| playerStats.getKnockedDown()
|
|| playerStats.getKnockedDown()
|
||||||
|| playerStats.getHitRecovery();
|
|| playerStats.getHitRecovery();
|
||||||
|
|
||||||
bool isReturnNeeded = playerStats.isParalyzed() || playerStats.isDead();
|
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
bool isReturnNeeded = (!godmode && playerStats.isParalyzed()) || playerStats.isDead();
|
||||||
|
|
||||||
if (isReturnNeeded && key->type != Type_Item)
|
if (isReturnNeeded && key->type != Type_Item)
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,8 +241,9 @@ namespace MWGui
|
||||||
if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player))
|
if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player);
|
const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player);
|
||||||
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery())
|
if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), ""));
|
mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), ""));
|
||||||
|
|
|
@ -918,6 +918,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr);
|
CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||||
const MagicEffects &effects = creatureStats.getMagicEffects();
|
const MagicEffects &effects = creatureStats.getMagicEffects();
|
||||||
|
bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
|
||||||
bool wasDead = creatureStats.isDead();
|
bool wasDead = creatureStats.isDead();
|
||||||
|
|
||||||
|
@ -969,8 +970,11 @@ namespace MWMechanics
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
DynamicStat<float> stat = creatureStats.getDynamic(i);
|
DynamicStat<float> stat = creatureStats.getDynamic(i);
|
||||||
stat.setCurrentModifier(effects.get(ESM::MagicEffect::FortifyHealth + i).getMagnitude() -
|
float fortify = effects.get(ESM::MagicEffect::FortifyHealth + i).getMagnitude();
|
||||||
effects.get(ESM::MagicEffect::DrainHealth + i).getMagnitude(),
|
float drain = 0.f;
|
||||||
|
if (!godmode)
|
||||||
|
drain = effects.get(ESM::MagicEffect::DrainHealth + i).getMagnitude();
|
||||||
|
stat.setCurrentModifier(fortify - drain,
|
||||||
// Magicka can be decreased below zero due to a fortify effect wearing off
|
// Magicka can be decreased below zero due to a fortify effect wearing off
|
||||||
// Fatigue can be decreased below zero meaning the actor will be knocked out
|
// Fatigue can be decreased below zero meaning the actor will be knocked out
|
||||||
i == 1 || i == 2);
|
i == 1 || i == 2);
|
||||||
|
@ -982,9 +986,14 @@ namespace MWMechanics
|
||||||
for(int i = 0;i < ESM::Attribute::Length;++i)
|
for(int i = 0;i < ESM::Attribute::Length;++i)
|
||||||
{
|
{
|
||||||
AttributeValue stat = creatureStats.getAttribute(i);
|
AttributeValue stat = creatureStats.getAttribute(i);
|
||||||
stat.setModifier(static_cast<int>(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).getMagnitude() -
|
float fortify = effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).getMagnitude();
|
||||||
effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude() -
|
float drain = 0.f, absorb = 0.f;
|
||||||
effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude()));
|
if (!godmode)
|
||||||
|
{
|
||||||
|
drain = effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude();
|
||||||
|
absorb = effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude();
|
||||||
|
}
|
||||||
|
stat.setModifier(static_cast<int>(fortify - drain - absorb));
|
||||||
|
|
||||||
creatureStats.setAttribute(i, stat);
|
creatureStats.setAttribute(i, stat);
|
||||||
}
|
}
|
||||||
|
@ -1214,14 +1223,20 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
NpcStats &npcStats = ptr.getClass().getNpcStats(ptr);
|
NpcStats &npcStats = ptr.getClass().getNpcStats(ptr);
|
||||||
const MagicEffects &effects = npcStats.getMagicEffects();
|
const MagicEffects &effects = npcStats.getMagicEffects();
|
||||||
|
bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
|
||||||
// skills
|
// skills
|
||||||
for(int i = 0;i < ESM::Skill::Length;++i)
|
for(int i = 0;i < ESM::Skill::Length;++i)
|
||||||
{
|
{
|
||||||
SkillValue& skill = npcStats.getSkill(i);
|
SkillValue& skill = npcStats.getSkill(i);
|
||||||
skill.setModifier(static_cast<int>(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude() -
|
float fortify = effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude();
|
||||||
effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude() -
|
float drain = 0.f, absorb = 0.f;
|
||||||
effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude()));
|
if (!godmode)
|
||||||
|
{
|
||||||
|
drain = effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude();
|
||||||
|
absorb = effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude();
|
||||||
|
}
|
||||||
|
skill.setModifier(static_cast<int>(fortify - drain - absorb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1827,6 +1842,7 @@ namespace MWMechanics
|
||||||
if (!playerHitAttemptActor.isInCell())
|
if (!playerHitAttemptActor.isInCell())
|
||||||
player.getClass().getCreatureStats(player).setHitAttemptActorId(-1);
|
player.getClass().getCreatureStats(player).setHitAttemptActorId(-1);
|
||||||
}
|
}
|
||||||
|
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
|
||||||
// AI and magic effects update
|
// AI and magic effects update
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
||||||
|
@ -2007,7 +2023,7 @@ namespace MWMechanics
|
||||||
iter->first.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor);
|
iter->first.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor);
|
||||||
|
|
||||||
const bool isDead = iter->first.getClass().getCreatureStats(iter->first).isDead();
|
const bool isDead = iter->first.getClass().getCreatureStats(iter->first).isDead();
|
||||||
if (!isDead && iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
if (!isDead && (!godmode || !isPlayer) && iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
||||||
ctrl->skipAnim();
|
ctrl->skipAnim();
|
||||||
|
|
||||||
// Handle player last, in case a cell transition occurs by casting a teleportation spell
|
// Handle player last, in case a cell transition occurs by casting a teleportation spell
|
||||||
|
|
|
@ -1929,7 +1929,7 @@ void CharacterController::update(float duration, bool animationOnly)
|
||||||
else if(!cls.getCreatureStats(mPtr).isDead())
|
else if(!cls.getCreatureStats(mPtr).isDead())
|
||||||
{
|
{
|
||||||
bool onground = world->isOnGround(mPtr);
|
bool onground = world->isOnGround(mPtr);
|
||||||
bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown());
|
bool incapacitated = ((!godmode && cls.getCreatureStats(mPtr).isParalyzed()) || cls.getCreatureStats(mPtr).getKnockedDown());
|
||||||
bool inwater = world->isSwimming(mPtr);
|
bool inwater = world->isSwimming(mPtr);
|
||||||
bool flying = world->isFlying(mPtr);
|
bool flying = world->isFlying(mPtr);
|
||||||
bool solid = world->isActorCollisionEnabled(mPtr);
|
bool solid = world->isActorCollisionEnabled(mPtr);
|
||||||
|
|
|
@ -68,11 +68,14 @@ namespace MWMechanics
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool receivedMagicDamage = false;
|
bool receivedMagicDamage = false;
|
||||||
|
bool godmode = actor == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
|
||||||
switch (effectKey.mId)
|
switch (effectKey.mId)
|
||||||
{
|
{
|
||||||
case ESM::MagicEffect::DamageAttribute:
|
case ESM::MagicEffect::DamageAttribute:
|
||||||
{
|
{
|
||||||
|
if (godmode)
|
||||||
|
break;
|
||||||
AttributeValue attr = creatureStats.getAttribute(effectKey.mArg);
|
AttributeValue attr = creatureStats.getAttribute(effectKey.mArg);
|
||||||
attr.damage(magnitude);
|
attr.damage(magnitude);
|
||||||
creatureStats.setAttribute(effectKey.mArg, attr);
|
creatureStats.setAttribute(effectKey.mArg, attr);
|
||||||
|
@ -91,6 +94,8 @@ namespace MWMechanics
|
||||||
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::RestoreHealth, magnitude);
|
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::RestoreHealth, magnitude);
|
||||||
break;
|
break;
|
||||||
case ESM::MagicEffect::DamageHealth:
|
case ESM::MagicEffect::DamageHealth:
|
||||||
|
if (godmode)
|
||||||
|
break;
|
||||||
receivedMagicDamage = true;
|
receivedMagicDamage = true;
|
||||||
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::DamageHealth, -magnitude);
|
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::DamageHealth, -magnitude);
|
||||||
break;
|
break;
|
||||||
|
@ -98,25 +103,32 @@ namespace MWMechanics
|
||||||
case ESM::MagicEffect::DamageMagicka:
|
case ESM::MagicEffect::DamageMagicka:
|
||||||
case ESM::MagicEffect::DamageFatigue:
|
case ESM::MagicEffect::DamageFatigue:
|
||||||
{
|
{
|
||||||
|
if (godmode)
|
||||||
|
break;
|
||||||
int index = effectKey.mId-ESM::MagicEffect::DamageHealth;
|
int index = effectKey.mId-ESM::MagicEffect::DamageHealth;
|
||||||
static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game");
|
static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game");
|
||||||
adjustDynamicStat(creatureStats, index, -magnitude, index == 2 && uncappedDamageFatigue);
|
adjustDynamicStat(creatureStats, index, -magnitude, index == 2 && uncappedDamageFatigue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESM::MagicEffect::AbsorbHealth:
|
case ESM::MagicEffect::AbsorbHealth:
|
||||||
|
if (!godmode || magnitude <= 0)
|
||||||
|
{
|
||||||
if (magnitude > 0.f)
|
if (magnitude > 0.f)
|
||||||
receivedMagicDamage = true;
|
receivedMagicDamage = true;
|
||||||
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude);
|
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::MagicEffect::AbsorbMagicka:
|
case ESM::MagicEffect::AbsorbMagicka:
|
||||||
case ESM::MagicEffect::AbsorbFatigue:
|
case ESM::MagicEffect::AbsorbFatigue:
|
||||||
|
if (!godmode || magnitude <= 0)
|
||||||
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude);
|
adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::MagicEffect::DisintegrateArmor:
|
case ESM::MagicEffect::DisintegrateArmor:
|
||||||
{
|
{
|
||||||
|
if (godmode)
|
||||||
|
break;
|
||||||
static const std::array<int, 9> priorities
|
static const std::array<int, 9> priorities
|
||||||
{
|
{
|
||||||
MWWorld::InventoryStore::Slot_CarriedLeft,
|
MWWorld::InventoryStore::Slot_CarriedLeft,
|
||||||
|
@ -138,13 +150,14 @@ namespace MWMechanics
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESM::MagicEffect::DisintegrateWeapon:
|
case ESM::MagicEffect::DisintegrateWeapon:
|
||||||
|
if (!godmode)
|
||||||
disintegrateSlot(actor, MWWorld::InventoryStore::Slot_CarriedRight, magnitude);
|
disintegrateSlot(actor, MWWorld::InventoryStore::Slot_CarriedRight, magnitude);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::MagicEffect::SunDamage:
|
case ESM::MagicEffect::SunDamage:
|
||||||
{
|
{
|
||||||
// isInCell shouldn't be needed, but updateActor called during game start
|
// isInCell shouldn't be needed, but updateActor called during game start
|
||||||
if (!actor.isInCell() || !actor.getCell()->isExterior())
|
if (!actor.isInCell() || !actor.getCell()->isExterior() || godmode)
|
||||||
break;
|
break;
|
||||||
float time = MWBase::Environment::get().getWorld()->getTimeStamp().getHour();
|
float time = MWBase::Environment::get().getWorld()->getTimeStamp().getHour();
|
||||||
float timeDiff = std::min(7.f, std::max(0.f, std::abs(time - 13)));
|
float timeDiff = std::min(7.f, std::max(0.f, std::abs(time - 13)));
|
||||||
|
@ -169,6 +182,8 @@ namespace MWMechanics
|
||||||
case ESM::MagicEffect::FrostDamage:
|
case ESM::MagicEffect::FrostDamage:
|
||||||
case ESM::MagicEffect::Poison:
|
case ESM::MagicEffect::Poison:
|
||||||
{
|
{
|
||||||
|
if (godmode)
|
||||||
|
break;
|
||||||
adjustDynamicStat(creatureStats, 0, -magnitude);
|
adjustDynamicStat(creatureStats, 0, -magnitude);
|
||||||
receivedMagicDamage = true;
|
receivedMagicDamage = true;
|
||||||
break;
|
break;
|
||||||
|
@ -179,6 +194,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (!actor.getClass().isNpc())
|
if (!actor.getClass().isNpc())
|
||||||
break;
|
break;
|
||||||
|
if (godmode && effectKey.mId == ESM::MagicEffect::DamageSkill)
|
||||||
|
break;
|
||||||
NpcStats &npcStats = actor.getClass().getNpcStats(actor);
|
NpcStats &npcStats = actor.getClass().getNpcStats(actor);
|
||||||
SkillValue& skill = npcStats.getSkill(effectKey.mArg);
|
SkillValue& skill = npcStats.getSkill(effectKey.mArg);
|
||||||
if (effectKey.mId == ESM::MagicEffect::RestoreSkill)
|
if (effectKey.mId == ESM::MagicEffect::RestoreSkill)
|
||||||
|
|
|
@ -230,7 +230,8 @@ namespace MWWorld
|
||||||
|
|
||||||
MWWorld::Ptr player = getPlayer();
|
MWWorld::Ptr player = getPlayer();
|
||||||
const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
|
const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
|
||||||
if (playerStats.isParalyzed() || playerStats.getKnockedDown() || playerStats.isDead())
|
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
|
||||||
|
if ((!godmode && playerStats.isParalyzed()) || playerStats.getKnockedDown() || playerStats.isDead())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWWorld::Ptr toActivate = MWBase::Environment::get().getWorld()->getFacedObject();
|
MWWorld::Ptr toActivate = MWBase::Environment::get().getWorld()->getFacedObject();
|
||||||
|
|
|
@ -1863,10 +1863,13 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
mRendering->getCamera()->setSneakOffset(0.f);
|
mRendering->getCamera()->setSneakOffset(0.f);
|
||||||
|
|
||||||
int blind = static_cast<int>(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude());
|
int blind = 0;
|
||||||
|
auto& magicEffects = player.getClass().getCreatureStats(player).getMagicEffects();
|
||||||
|
if (!mGodMode)
|
||||||
|
blind = static_cast<int>(magicEffects.get(ESM::MagicEffect::Blind).getMagnitude());
|
||||||
MWBase::Environment::get().getWindowManager()->setBlindness(std::max(0, std::min(100, blind)));
|
MWBase::Environment::get().getWindowManager()->setBlindness(std::max(0, std::min(100, blind)));
|
||||||
|
|
||||||
int nightEye = static_cast<int>(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).getMagnitude());
|
int nightEye = static_cast<int>(magicEffects.get(ESM::MagicEffect::NightEye).getMagnitude());
|
||||||
mRendering->setNightEyeFactor(std::min(1.f, (nightEye/100.f)));
|
mRendering->setNightEyeFactor(std::min(1.f, (nightEye/100.f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue