mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merge branch 'ondeath' into 'master'
Handle running stats extensions on non-actors gracefully (#7770) Closes #7770 See merge request OpenMW/openmw!3760
This commit is contained in:
commit
53e3dd0a70
2 changed files with 120 additions and 24 deletions
|
@ -128,6 +128,7 @@
|
|||
Bug #7742: Governing attribute training limit should use the modified attribute
|
||||
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
||||
Bug #7761: Rain and ambient loop sounds are mutually exclusive
|
||||
Bug #7770: Sword of the Perithia: Script execution failure
|
||||
Feature #2566: Handle NAM9 records for manual cell references
|
||||
Feature #3537: Shader-based water ripples
|
||||
Feature #5173: Support for NiFogProperty
|
||||
|
|
|
@ -85,7 +85,9 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).getLevel();
|
||||
Interpreter::Type_Integer value = -1;
|
||||
if (ptr.getClass().isActor())
|
||||
value = ptr.getClass().getCreatureStats(ptr).getLevel();
|
||||
|
||||
runtime.push(value);
|
||||
}
|
||||
|
@ -102,7 +104,8 @@ namespace MWScript
|
|||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
ptr.getClass().getCreatureStats(ptr).setLevel(value);
|
||||
if (ptr.getClass().isActor())
|
||||
ptr.getClass().getCreatureStats(ptr).setLevel(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -121,7 +124,9 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Float value = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex).getModified();
|
||||
Interpreter::Type_Float value = 0.f;
|
||||
if (ptr.getClass().isActor())
|
||||
value = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex).getModified();
|
||||
|
||||
runtime.push(value);
|
||||
}
|
||||
|
@ -145,6 +150,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
|
||||
attribute.setBase(value, true);
|
||||
ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
|
||||
|
@ -169,6 +177,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
|
||||
modStat(attribute, value);
|
||||
ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
|
||||
|
@ -189,14 +200,14 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
Interpreter::Type_Float value;
|
||||
Interpreter::Type_Float value = 0.f;
|
||||
|
||||
if (mIndex == 0 && ptr.getClass().hasItemHealth(ptr))
|
||||
{
|
||||
// health is a special case
|
||||
value = static_cast<Interpreter::Type_Float>(ptr.getClass().getItemMaxHealth(ptr));
|
||||
}
|
||||
else
|
||||
else if (ptr.getClass().isActor())
|
||||
{
|
||||
value = ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex).getCurrent();
|
||||
// GetMagicka shouldn't return negative values
|
||||
|
@ -225,6 +236,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::DynamicStat<float> stat(ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex));
|
||||
|
||||
stat.setBase(value);
|
||||
|
@ -254,6 +268,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float diff = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
// workaround broken endgame scripts that kill dagoth ur
|
||||
if (!R::implicit && ptr.getCellRef().getRefId() == "dagoth_ur_1")
|
||||
{
|
||||
|
@ -301,6 +318,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float diff = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
||||
Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
|
||||
|
@ -336,6 +356,13 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
{
|
||||
runtime.push(0.f);
|
||||
return;
|
||||
}
|
||||
|
||||
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
||||
runtime.push(stats.getDynamic(mIndex).getRatio());
|
||||
|
@ -357,6 +384,12 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
{
|
||||
runtime.push(0.f);
|
||||
return;
|
||||
}
|
||||
|
||||
Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mId);
|
||||
|
||||
runtime.push(value);
|
||||
|
@ -381,6 +414,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isNpc())
|
||||
return;
|
||||
|
||||
MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats(ptr);
|
||||
|
||||
stats.getSkill(mId).setBase(value, true);
|
||||
|
@ -405,6 +441,9 @@ namespace MWScript
|
|||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isNpc())
|
||||
return;
|
||||
|
||||
MWMechanics::SkillValue& skill = ptr.getClass().getNpcStats(ptr).getSkill(mId);
|
||||
modStat(skill, value);
|
||||
}
|
||||
|
@ -465,6 +504,9 @@ namespace MWScript
|
|||
ESM::RefId id = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getESMStore()->get<ESM::Spell>().find(id);
|
||||
|
||||
MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
@ -491,6 +533,9 @@ namespace MWScript
|
|||
ESM::RefId id = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||
creatureStats.getSpells().remove(id);
|
||||
|
||||
|
@ -514,7 +559,8 @@ namespace MWScript
|
|||
ESM::RefId spellid = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
|
||||
runtime.pop();
|
||||
|
||||
ptr.getClass().getCreatureStats(ptr).getActiveSpells().removeEffects(ptr, spellid);
|
||||
if (ptr.getClass().isActor())
|
||||
ptr.getClass().getCreatureStats(ptr).getActiveSpells().removeEffects(ptr, spellid);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -529,7 +575,8 @@ namespace MWScript
|
|||
Interpreter::Type_Integer effectId = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
ptr.getClass().getCreatureStats(ptr).getActiveSpells().purgeEffect(ptr, effectId);
|
||||
if (ptr.getClass().isActor())
|
||||
ptr.getClass().getCreatureStats(ptr).getActiveSpells().purgeEffect(ptr, effectId);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -845,7 +892,10 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
runtime.push(ptr.getClass().getCreatureStats(ptr).hasCommonDisease());
|
||||
if (ptr.getClass().isActor())
|
||||
runtime.push(ptr.getClass().getCreatureStats(ptr).hasCommonDisease());
|
||||
else
|
||||
runtime.push(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -857,7 +907,10 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
runtime.push(ptr.getClass().getCreatureStats(ptr).hasBlightDisease());
|
||||
if (ptr.getClass().isActor())
|
||||
runtime.push(ptr.getClass().getCreatureStats(ptr).hasBlightDisease());
|
||||
else
|
||||
runtime.push(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -872,9 +925,16 @@ namespace MWScript
|
|||
ESM::RefId race = ESM::RefId::stringRefId(runtime.getStringLiteral(runtime[0].mInteger));
|
||||
runtime.pop();
|
||||
|
||||
const ESM::RefId& npcRace = ptr.get<ESM::NPC>()->mBase->mRace;
|
||||
if (ptr.getClass().isNpc())
|
||||
{
|
||||
const ESM::RefId& npcRace = ptr.get<ESM::NPC>()->mBase->mRace;
|
||||
|
||||
runtime.push(race == npcRace);
|
||||
runtime.push(race == npcRace);
|
||||
}
|
||||
else
|
||||
{
|
||||
runtime.push(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1043,10 +1103,15 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).hasDied();
|
||||
Interpreter::Type_Integer value = 0;
|
||||
if (ptr.getClass().isActor())
|
||||
{
|
||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
value = stats.hasDied();
|
||||
|
||||
if (value)
|
||||
ptr.getClass().getCreatureStats(ptr).clearHasDied();
|
||||
if (value)
|
||||
stats.clearHasDied();
|
||||
}
|
||||
|
||||
runtime.push(value);
|
||||
}
|
||||
|
@ -1060,10 +1125,15 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).hasBeenMurdered();
|
||||
Interpreter::Type_Integer value = 0;
|
||||
if (ptr.getClass().isActor())
|
||||
{
|
||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
value = stats.hasBeenMurdered();
|
||||
|
||||
if (value)
|
||||
ptr.getClass().getCreatureStats(ptr).clearHasBeenMurdered();
|
||||
if (value)
|
||||
stats.clearHasBeenMurdered();
|
||||
}
|
||||
|
||||
runtime.push(value);
|
||||
}
|
||||
|
@ -1077,7 +1147,9 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).getKnockedDownOneFrame();
|
||||
Interpreter::Type_Integer value = 0;
|
||||
if (ptr.getClass().isActor())
|
||||
value = ptr.getClass().getCreatureStats(ptr).getKnockedDownOneFrame();
|
||||
|
||||
runtime.push(value);
|
||||
}
|
||||
|
@ -1090,7 +1162,10 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf());
|
||||
if (ptr.getClass().isNpc())
|
||||
runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf());
|
||||
else
|
||||
runtime.push(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1101,7 +1176,8 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set);
|
||||
if (ptr.getClass().isNpc())
|
||||
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1112,7 +1188,8 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr);
|
||||
if (ptr.getClass().isNpc())
|
||||
MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1124,6 +1201,9 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
if (ptr == MWMechanics::getPlayer())
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->resurrect(ptr);
|
||||
|
@ -1192,6 +1272,12 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
{
|
||||
runtime.push(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
|
||||
float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude();
|
||||
if (mNegativeEffect != -1)
|
||||
|
@ -1226,6 +1312,13 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
int arg = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
|
||||
float currentValue = effects.getOrDefault(mPositiveEffect).getMagnitude();
|
||||
if (mNegativeEffect != -1)
|
||||
|
@ -1239,8 +1332,6 @@ namespace MWScript
|
|||
if (mPositiveEffect == ESM::MagicEffect::ResistFrost)
|
||||
currentValue += effects.getOrDefault(ESM::MagicEffect::FrostShield).getMagnitude();
|
||||
|
||||
int arg = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
effects.modifyBase(mPositiveEffect, (arg - static_cast<int>(currentValue)));
|
||||
}
|
||||
};
|
||||
|
@ -1261,10 +1352,14 @@ namespace MWScript
|
|||
void execute(Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
||||
int arg = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
if (!ptr.getClass().isActor())
|
||||
return;
|
||||
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
stats.getMagicEffects().modifyBase(mPositiveEffect, arg);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue