Merge remote-tracking branch 'scrawl/master'

deque
Marc Zinnschlag 11 years ago
commit 02b7712d7c

@ -541,11 +541,11 @@ namespace MWClass
float moveSpeed;
if(normalizedEncumbrance >= 1.0f)
moveSpeed = 0.0f;
else if(canFly(ptr) || (mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
else if(canFly(ptr) || (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 &&
world->isLevitationEnabled()))
{
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
mageffects.get(ESM::MagicEffect::Levitate).mMagnitude);
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat());
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
flySpeed = std::max(0.0f, flySpeed);
@ -556,7 +556,7 @@ namespace MWClass
float swimSpeed = walkSpeed;
if(running)
swimSpeed = runSpeed;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) *
gmst.fSwimRunAthleticsMult->getFloat();
moveSpeed = swimSpeed;
@ -617,7 +617,7 @@ namespace MWClass
float Creature::getArmorRating (const MWWorld::Ptr& ptr) const
{
// Note this is currently unused. Creatures do not use armor mitigation.
return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude;
return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude();
}
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
@ -632,9 +632,9 @@ namespace MWClass
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).mMagnitude;
weight -= stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Feather)).getMagnitude();
weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).mMagnitude;
weight += stats.getMagicEffects().get (MWMechanics::EffectKey (ESM::MagicEffect::Burden)).getMagnitude();
if (weight<0)
weight = 0;

@ -180,7 +180,7 @@ namespace MWClass
std::string text;
if (!gold)
if (!gold && !ref->mBase->mData.mIsKey)
{
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");

@ -565,7 +565,7 @@ namespace MWClass
damage = stats.getSkill(weapskill).getModified();
damage *= minstrike + ((maxstrike-minstrike)*stats.getAttackStrength());
healthdmg = (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0)
healthdmg = (otherstats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0)
|| otherstats.getKnockedDown();
if(stats.isWerewolf())
{
@ -922,11 +922,11 @@ namespace MWClass
float moveSpeed;
if(normalizedEncumbrance >= 1.0f)
moveSpeed = 0.0f;
else if(mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
else if(mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 &&
world->isLevitationEnabled())
{
float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() +
mageffects.get(ESM::MagicEffect::Levitate).mMagnitude);
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat());
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
flySpeed = std::max(0.0f, flySpeed);
@ -937,7 +937,7 @@ namespace MWClass
float swimSpeed = walkSpeed;
if(running)
swimSpeed = runSpeed;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
gmst.fSwimRunAthleticsMult->getFloat();
moveSpeed = swimSpeed;
@ -975,7 +975,7 @@ namespace MWClass
float x = gmst.fJumpAcrobaticsBase->getFloat() +
std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->getFloat());
x += 3.0f * b * gmst.fJumpAcroMultiplier->getFloat();
x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64;
x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64;
x *= encumbranceTerm;
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run))
@ -998,7 +998,7 @@ namespace MWClass
{
const float acrobaticsSkill = ptr.getClass().getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude;
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude();
const float fallAcroBase = store.find("fFallAcroBase")->getFloat();
const float fallAcroMult = store.find("fFallAcroMult")->getFloat();
const float fallDistanceBase = store.find("fFallDistanceBase")->getFloat();
@ -1104,8 +1104,8 @@ namespace MWClass
if(!stats.isWerewolf())
{
weight = getContainerStore(ptr).getWeight();
weight -= stats.getMagicEffects().get(ESM::MagicEffect::Feather).mMagnitude;
weight += stats.getMagicEffects().get(ESM::MagicEffect::Burden).mMagnitude;
weight -= stats.getMagicEffects().get(ESM::MagicEffect::Feather).getMagnitude();
weight += stats.getMagicEffects().get(ESM::MagicEffect::Burden).getMagnitude();
if(weight < 0.0f)
weight = 0.0f;
}
@ -1170,7 +1170,7 @@ namespace MWClass
}
}
float shield = stats.getMagicEffects().get(ESM::MagicEffect::Shield).mMagnitude;
float shield = stats.getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude();
return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3f
+ (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet]

@ -290,6 +290,9 @@ namespace MWDialogue
std::string title;
if (dialogue.mType==ESM::Dialogue::Persuasion)
{
// Determine GMST from dialogue topic. GMSTs are:
// sAdmireSuccess, sAdmireFail, sIntimidateSuccess, sIntimidateFail,
// sTauntSuccess, sTauntFail, sBribeSuccess, sBribeFail
std::string modifiedTopic = "s" + topic;
modifiedTopic.erase (std::remove (modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end());

@ -492,7 +492,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_PcCorprus:
return player.getClass().getCreatureStats (player).
getMagicEffects().get (ESM::MagicEffect::Corprus).mMagnitude!=0;
getMagicEffects().get (ESM::MagicEffect::Corprus).getMagnitude()!=0;
case SelectWrapper::Function_PcExpelled:
{
@ -508,7 +508,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
case SelectWrapper::Function_PcVampire:
return player.getClass().getCreatureStats(player).getMagicEffects().
get(ESM::MagicEffect::Vampirism).mMagnitude > 0;
get(ESM::MagicEffect::Vampirism).getMagnitude() > 0;
case SelectWrapper::Function_TalkedToPc:

@ -229,9 +229,6 @@ namespace MWGui
else
dragItem (NULL, count);
}
// item might have been unequipped
notifyContentChanged();
}
void InventoryWindow::ensureSelectedItemUnequipped()
@ -269,6 +266,7 @@ namespace MWGui
{
ensureSelectedItemUnequipped();
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
notifyContentChanged();
}
void InventoryWindow::sellItem(MyGUI::Widget* sender, int count)
@ -292,6 +290,7 @@ namespace MWGui
}
mItemView->update();
notifyContentChanged();
}
void InventoryWindow::updateItemView()

@ -197,9 +197,9 @@ namespace MWGui
WindowModal::open();
int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 20; // padding between the text-widget und the button-widget
int textButtonPadding = 10; // padding between the text-widget und the button-widget
int buttonLeftPadding = 10; // padding between the buttons if horizontal
int buttonTopPadding = 5; // ^-- if vertical
int buttonTopPadding = 10; // ^-- if vertical
int buttonPadding = 5; // padding between button label and button itself
int buttonMainPadding = 10; // padding between buttons and bottom of the main widget
@ -219,6 +219,7 @@ namespace MWGui
int biggestButtonWidth = 0;
int buttonWidth = 0;
int buttonsWidth = 0;
int buttonsHeight = 0;
int buttonHeight = 0;
MyGUI::IntCoord dummyCoord(0, 0, 0, 0);
@ -236,64 +237,120 @@ namespace MWGui
mButtons.push_back(button);
buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding;
if (buttonsWidth != 0)
buttonsWidth += buttonLeftPadding;
buttonWidth = button->getTextSize().width + 2*buttonPadding;
buttonsWidth += buttonWidth;
buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding;
buttonHeight = button->getTextSize().height + 2*buttonPadding;
if (buttonsHeight != 0)
buttonsHeight += buttonTopPadding;
buttonsHeight += buttonHeight;
if(buttonWidth > biggestButtonWidth)
{
biggestButtonWidth = buttonWidth;
}
}
buttonsWidth += buttonLeftPadding;
MyGUI::IntSize mainWidgetSize;
// among each other
if(biggestButtonWidth > textSize.width) {
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
}
else {
if(buttonsWidth < textSize.width)
{
// on one line
mainWidgetSize.width = textSize.width + 3*textPadding;
}
mainWidgetSize.height = textPadding + textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
MyGUI::IntSize realSize = mainWidgetSize +
// To account for borders
(mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize());
int top = textButtonPadding + buttonTopPadding + textSize.height;
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - realSize.width)/2;
absPos.top = (gameWindowSize.height - realSize.height)/2;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
mMainWidget->setPosition(absPos);
mMainWidget->setSize(realSize);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
mMessageWidget->setCoord(messageWidgetCoord);
mMessageWidget->setSize(textSize);
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int left = (mainWidgetSize.width - buttonsWidth)/2;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonCord.left = left;
buttonCord.top = messageWidgetCoord.top + textSize.height + textButtonPadding;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + 2*buttonTopPadding;
left += buttonSize.width + buttonLeftPadding;
}
}
else
{
// among each other
if(biggestButtonWidth > textSize.width) {
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding*2;
}
else {
mainWidgetSize.width = textSize.width + 3*textPadding;
}
MyGUI::IntCoord buttonCord;
MyGUI::IntSize buttonSize(0, buttonHeight);
int top = textPadding + textSize.height + textButtonPadding;
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
buttonCord.top = top;
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2;
mainWidgetSize.height = top + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize);
(*button)->setCoord(buttonCord);
(*button)->setSize(buttonSize);
top += buttonSize.height + buttonTopPadding;
}
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
mainWidgetSize.height = textPadding + textSize.height + textButtonPadding + buttonsHeight + buttonMainPadding;
mMainWidget->setSize(mainWidgetSize +
// To account for borders
(mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize()));
mMainWidget->setPosition(absPos);
MyGUI::IntPoint absPos;
absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2;
absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2;
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
mMainWidget->setPosition(absPos);
MyGUI::IntCoord messageWidgetCoord;
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
messageWidgetCoord.top = textPadding;
messageWidgetCoord.width = textSize.width;
messageWidgetCoord.height = textSize.height;
mMessageWidget->setCoord(messageWidgetCoord);
}
// Set key focus to "Ok" button
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
std::vector<MyGUI::Button*>::const_iterator button;
for(button = mButtons.begin(); button != mButtons.end(); ++button)
{
if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok))

@ -146,7 +146,7 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0;
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0;
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
health = 0.1 * endurance;
@ -357,6 +357,7 @@ namespace MWMechanics
CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature);
if (creatureStats.isDead())
return;
MagicEffects now = creatureStats.getSpells().getMagicEffects();
if (creature.getTypeName()==typeid (ESM::NPC).name())
@ -367,11 +368,7 @@ namespace MWMechanics
now += creatureStats.getActiveSpells().getMagicEffects();
//MagicEffects diff = MagicEffects::diff (creatureStats.getMagicEffects(), now);
creatureStats.setMagicEffects(now);
// TODO apply diff to other stats
creatureStats.modifyMagicEffects(now);
}
void Actors::calculateDynamicStats (const MWWorld::Ptr& ptr)
@ -385,7 +382,7 @@ namespace MWMechanics
int endurance = creatureStats.getAttribute(ESM::Attribute::Endurance).getModified();
double magickaFactor =
creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude * 0.1 + 1;
creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1 + 1;
DynamicStat<float> magicka = creatureStats.getMagicka();
float diff = (static_cast<int>(magickaFactor*intelligence)) - magicka.getBase();
@ -473,9 +470,9 @@ namespace MWMechanics
for(int i = 0;i < ESM::Attribute::Length;++i)
{
AttributeValue stat = creatureStats.getAttribute(i);
stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).mMagnitude -
effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).mMagnitude -
effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).mMagnitude);
stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).getMagnitude() -
effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude() -
effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude());
creatureStats.setAttribute(i, stat);
}
@ -484,13 +481,13 @@ namespace MWMechanics
for(int i = 0;i < 3;++i)
{
DynamicStat<float> stat = creatureStats.getDynamic(i);
stat.setModifier(effects.get(ESM::MagicEffect::FortifyHealth+i).mMagnitude -
effects.get(ESM::MagicEffect::DrainHealth+i).mMagnitude);
stat.setModifier(effects.get(ESM::MagicEffect::FortifyHealth+i).getMagnitude() -
effects.get(ESM::MagicEffect::DrainHealth+i).getMagnitude());
float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+i).mMagnitude;
float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).getMagnitude()
- creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).getMagnitude()
- creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+i).getMagnitude();
stat.setCurrent(stat.getCurrent() + currentDiff * duration, i == 2);
creatureStats.setDynamic(i, stat);
@ -504,27 +501,27 @@ namespace MWMechanics
if (!creature || ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Creatures)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Fight);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::FrenzyHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid+creature).mMagnitude);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::FrenzyHumanoid+creature).getMagnitude()
- creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid+creature).getMagnitude());
creatureStats.setAiSetting(CreatureStats::AI_Fight, stat);
stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::DemoralizeHumanoid+creature).mMagnitude
- creatureStats.getMagicEffects().get(ESM::MagicEffect::RallyHumanoid+creature).mMagnitude);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::DemoralizeHumanoid+creature).getMagnitude()
- creatureStats.getMagicEffects().get(ESM::MagicEffect::RallyHumanoid+creature).getMagnitude());
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
if (creature && ptr.get<ESM::Creature>()->mBase->mData.mType == ESM::Creature::Undead)
{
Stat<int> stat = creatureStats.getAiSetting(CreatureStats::AI_Flee);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::TurnUndead).mMagnitude);
stat.setModifier(creatureStats.getMagicEffects().get(ESM::MagicEffect::TurnUndead).getMagnitude());
creatureStats.setAiSetting(CreatureStats::AI_Flee, stat);
}
// Apply disintegration (reduces item health)
float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).mMagnitude;
float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).getMagnitude();
if (disintegrateWeapon > 0)
disintegrateSlot(ptr, MWWorld::InventoryStore::Slot_CarriedRight, disintegrateWeapon*duration);
float disintegrateArmor = effects.get(ESM::MagicEffect::DisintegrateArmor).mMagnitude;
float disintegrateArmor = effects.get(ESM::MagicEffect::DisintegrateArmor).getMagnitude();
if (disintegrateArmor > 0)
{
// According to UESP
@ -556,7 +553,7 @@ namespace MWMechanics
DynamicStat<float> health = creatureStats.getHealth();
for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i)
{
float magnitude = creatureStats.getMagicEffects().get(damageEffects[i]).mMagnitude;
float magnitude = creatureStats.getMagicEffects().get(damageEffects[i]).getMagnitude();
if (damageEffects[i] == ESM::MagicEffect::SunDamage)
{
@ -647,7 +644,7 @@ namespace MWMechanics
for (std::map<int, std::string>::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it)
{
bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end();
int magnitude = creatureStats.getMagicEffects().get(it->first).mMagnitude;
int magnitude = creatureStats.getMagicEffects().get(it->first).getMagnitude();
if (found != (magnitude > 0))
{
std::string itemGmst = it->second;
@ -704,7 +701,7 @@ namespace MWMechanics
for (std::map<int, std::string>::iterator it = summonMap.begin(); it != summonMap.end(); ++it)
{
bool found = creatureMap.find(it->first) != creatureMap.end();
int magnitude = creatureStats.getMagicEffects().get(it->first).mMagnitude;
int magnitude = creatureStats.getMagicEffects().get(it->first).getMagnitude();
if (found != (magnitude > 0))
{
if (magnitude > 0)
@ -808,9 +805,9 @@ namespace MWMechanics
for(int i = 0;i < ESM::Skill::Length;++i)
{
SkillValue& skill = npcStats.getSkill(i);
skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).mMagnitude -
effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).mMagnitude -
effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).mMagnitude);
skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude() -
effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude() -
effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude());
}
}
@ -819,7 +816,7 @@ namespace MWMechanics
MWBase::World *world = MWBase::Environment::get().getWorld();
NpcStats &stats = ptr.getClass().getNpcStats(ptr);
if(world->isSubmerged(ptr) &&
stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).mMagnitude == 0)
stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0)
{
float timeLeft = 0.0f;
if(stats.getFatigue().getCurrent() == 0)
@ -1128,7 +1125,7 @@ namespace MWMechanics
for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{
if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get(
ESM::MagicEffect::Paralyze).mMagnitude > 0)
ESM::MagicEffect::Paralyze).getMagnitude() > 0)
iter->second->skipAnim();
iter->second->update(duration);
}
@ -1297,7 +1294,7 @@ namespace MWMechanics
// Reset magic effects and recalculate derived effects
// One case where we need this is to make sure bound items are removed upon death
stats.setMagicEffects(MWMechanics::MagicEffects());
stats.modifyMagicEffects(MWMechanics::MagicEffects());
stats.getActiveSpells().clear();
calculateCreatureStatModifiers(iter->first, 0);
@ -1463,5 +1460,7 @@ namespace MWMechanics
{
adjustMagicEffects(ptr);
calculateCreatureStatModifiers(ptr, 0.f);
if (ptr.getClass().isNpc())
calculateNpcStatModifiers(ptr);
}
}

@ -1639,7 +1639,7 @@ void CharacterController::updateContinuousVfx()
for (std::vector<int>::iterator it = effects.begin(); it != effects.end(); ++it)
{
if (mPtr.getClass().getCreatureStats(mPtr).isDead()
|| mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(*it)).mMagnitude <= 0)
|| mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(*it)).getMagnitude() <= 0)
mAnimation->removeEffect(*it);
}
}
@ -1649,14 +1649,14 @@ void CharacterController::updateVisibility()
if (!mPtr.getClass().isActor())
return;
float alpha = 1.f;
if (mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Invisibility).mMagnitude)
if (mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude())
{
if (mPtr.getRefData().getHandle() == "player")
alpha = 0.4f;
else
alpha = 0.f;
}
float chameleon = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Chameleon).mMagnitude;
float chameleon = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude();
if (chameleon)
{
alpha *= std::max(0.2f, (100.f - chameleon)/100.f);

@ -59,7 +59,7 @@ namespace MWMechanics
if (blockerStats.getKnockedDown() // Used for both knockout or knockdown
|| blockerStats.getHitRecovery()
|| blockerStats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0)
|| blockerStats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0)
return false;
// Don't block when in spellcasting state (shield is equipped, but not visible)
@ -144,8 +144,8 @@ namespace MWMechanics
void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage)
{
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
float resistance = std::min(100.f, stats.getMagicEffects().get(ESM::MagicEffect::ResistNormalWeapons).mMagnitude
- stats.getMagicEffects().get(ESM::MagicEffect::WeaknessToNormalWeapons).mMagnitude);
float resistance = std::min(100.f, stats.getMagicEffects().get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude()
- stats.getMagicEffects().get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude());
float multiplier = 1.f - resistance / 100.f;
@ -246,8 +246,8 @@ namespace MWMechanics
(stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
(stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
hitchance *= stats.getFatigueTerm();
hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude -
mageffects.get(ESM::MagicEffect::Blind).mMagnitude;
hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).getMagnitude() -
mageffects.get(ESM::MagicEffect::Blind).getMagnitude();
hitchance -= victim.getClass().getCreatureStats(victim).getEvasion();
return hitchance;
}
@ -256,7 +256,7 @@ namespace MWMechanics
{
for (int i=0; i<3; ++i)
{
float magnitude = victim.getClass().getCreatureStats(victim).getMagicEffects().get(ESM::MagicEffect::FireShield+i).mMagnitude;
float magnitude = victim.getClass().getCreatureStats(victim).getMagicEffects().get(ESM::MagicEffect::FireShield+i).getMagnitude();
if (!magnitude)
continue;

@ -211,13 +211,13 @@ namespace MWMechanics
mActiveSpells = active;
}
void CreatureStats::setMagicEffects(const MagicEffects &effects)
void CreatureStats::modifyMagicEffects(const MagicEffects &effects)
{
if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).mMagnitude
!= mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).mMagnitude)
if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier()
!= mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier())
mRecalcDynamicStats = true;
mMagicEffects = effects;
mMagicEffects.setModifiers(effects);
}
void CreatureStats::setAttackingOrSpell(bool attackingOrSpell)
@ -346,7 +346,7 @@ namespace MWMechanics
float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
(getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
evasion *= getFatigueTerm();
evasion += mMagicEffects.get(ESM::MagicEffect::Sanctuary).mMagnitude;
evasion += mMagicEffects.get(ESM::MagicEffect::Sanctuary).getMagnitude();
return evasion;
}
@ -516,6 +516,7 @@ namespace MWMechanics
mSpells.writeState(state.mSpells);
mActiveSpells.writeState(state.mActiveSpells);
mAiSequence.writeState(state.mAiSequence);
mMagicEffects.writeState(state.mMagicEffects);
state.mSummonedCreatureMap = mSummonedCreatures;
state.mSummonGraveyard = mSummonGraveyard;
@ -564,6 +565,7 @@ namespace MWMechanics
mSpells.readState(state.mSpells);
mActiveSpells.readState(state.mActiveSpells);
mAiSequence.readState(state.mAiSequence);
mMagicEffects.readState(state.mMagicEffects);
mSummonedCreatures = state.mSummonedCreatureMap;
mSummonGraveyard = state.mSummonGraveyard;

@ -141,7 +141,8 @@ namespace MWMechanics
void setActiveSpells(const ActiveSpells &active);
void setMagicEffects(const MagicEffects &effects);
/// Set Modifier for each magic effect according to \a effects. Does not touch Base values.
void modifyMagicEffects(const MagicEffects &effects);
void setAttackingOrSpell(bool attackingOrSpell);

@ -45,14 +45,14 @@ namespace MWMechanics
float resist = 0.f;
if (hasCorprusEffect)
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCorprusDisease).mMagnitude
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCorprusDisease).mMagnitude);
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude()
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude());
else if (spell->mData.mType == ESM::Spell::ST_Disease)
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).mMagnitude
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCommonDisease).mMagnitude);
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).getMagnitude()
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude());
else if (spell->mData.mType == ESM::Spell::ST_Blight)
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).mMagnitude
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToBlightDisease).mMagnitude);
resist = 1.f - 0.01 * (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).getMagnitude()
- actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude());
else
continue;

@ -6,6 +6,7 @@
#include <stdexcept>
#include <components/esm/effectlist.hpp>
#include <components/esm/magiceffects.hpp>
namespace MWMechanics
{
@ -40,20 +41,57 @@ namespace MWMechanics
return left.mArg<right.mArg;
}
EffectParam::EffectParam() : mMagnitude (0) {}
float EffectParam::getMagnitude() const
{
return mBase + mModifier;
}
void EffectParam::modifyBase(int diff)
{
mBase += diff;
}
int EffectParam::getBase() const
{
return mBase;
}
void EffectParam::setBase(int base)
{
mBase = base;
}
void EffectParam::setModifier(float mod)
{
mModifier = mod;
}
float EffectParam::getModifier() const
{
return mModifier;
}
EffectParam::EffectParam() : mModifier (0), mBase(0) {}
EffectParam& EffectParam::operator+= (const EffectParam& param)
{
mMagnitude += param.mMagnitude;
mModifier += param.mModifier;
mBase += param.mBase;
return *this;
}
EffectParam& EffectParam::operator-= (const EffectParam& param)
{
mMagnitude -= param.mMagnitude;
mModifier -= param.mModifier;
mBase -= param.mBase;
return *this;
}
void MagicEffects::remove(const EffectKey &key)
{
mCollection.erase(key);
}
void MagicEffects::add (const EffectKey& key, const EffectParam& param)
{
Collection::iterator iter = mCollection.find (key);
@ -68,6 +106,24 @@ namespace MWMechanics
}
}
void MagicEffects::modifyBase(const EffectKey &key, int diff)
{
mCollection[key].modifyBase(diff);
}
void MagicEffects::setModifiers(const MagicEffects &effects)
{
for (Collection::iterator it = mCollection.begin(); it != mCollection.end(); ++it)
{
it->second.setModifier(effects.get(it->first).getModifier());
}
for (Collection::const_iterator it = effects.begin(); it != effects.end(); ++it)
{
mCollection[it->first].setModifier(it->second.getModifier());
}
}
MagicEffects& MagicEffects::operator+= (const MagicEffects& effects)
{
if (this==&effects)
@ -137,4 +193,25 @@ namespace MWMechanics
return result;
}
void MagicEffects::writeState(ESM::MagicEffects &state) const
{
// Don't need to save Modifiers, they are recalculated every frame anyway.
for (Collection::const_iterator iter (begin()); iter!=end(); ++iter)
{
if (iter->second.getBase() != 0)
{
// Don't worry about mArg, never used by magic effect script instructions
state.mEffects.insert(std::make_pair(iter->first.mId, iter->second.getBase()));
}
}
}
void MagicEffects::readState(const ESM::MagicEffects &state)
{
for (std::map<int, int>::const_iterator it = state.mEffects.begin(); it != state.mEffects.end(); ++it)
{
mCollection[EffectKey(it->first)].setBase(it->second);
}
}
}

@ -8,6 +8,8 @@ namespace ESM
{
struct ENAMstruct;
struct EffectList;
struct MagicEffects;
}
namespace MWMechanics
@ -28,12 +30,27 @@ namespace MWMechanics
struct EffectParam
{
// Note usually this would be int, but applying partial resistance might introduce decimal point.
float mMagnitude;
private:
// Note usually this would be int, but applying partial resistance might introduce a decimal point.
float mModifier;
int mBase;
public:
/// Get the total magnitude including base and modifier.
float getMagnitude() const;
void setModifier(float mod);
float getModifier() const;
/// Change mBase by \a diff
void modifyBase(int diff);
void setBase(int base);
int getBase() const;
EffectParam();
EffectParam(float magnitude) : mMagnitude(magnitude) {}
EffectParam(float magnitude) : mModifier(magnitude), mBase(0) {}
EffectParam& operator+= (const EffectParam& param);
@ -77,7 +94,16 @@ namespace MWMechanics
Collection::const_iterator end() const { return mCollection.end(); }
void readState (const ESM::MagicEffects& state);
void writeState (ESM::MagicEffects& state) const;
void add (const EffectKey& key, const EffectParam& param);
void remove (const EffectKey& key);
void modifyBase (const EffectKey& key, int diff);
/// Copy Modifier values from \a effects, but keep original mBase values.
void setModifiers(const MagicEffects& effects);
MagicEffects& operator+= (const MagicEffects& effects);

@ -68,7 +68,7 @@ namespace MWMechanics
// reset
creatureStats.setLevel(player->mNpdt52.mLevel);
creatureStats.getSpells().clear();
creatureStats.setMagicEffects(MagicEffects());
creatureStats.modifyMagicEffects(MagicEffects());
for (int i=0; i<27; ++i)
npcStats.getSkill (i).setBase (player->mNpdt52.mSkills[i]);
@ -613,7 +613,7 @@ namespace MWMechanics
if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat();
x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).mMagnitude;
x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude();
int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used
return effective_disposition;
@ -1144,7 +1144,7 @@ namespace MWMechanics
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
float invisibility = stats.getMagicEffects().get(ESM::MagicEffect::Invisibility).mMagnitude;
float invisibility = stats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude();
if (invisibility > 0)
return false;
@ -1176,13 +1176,13 @@ namespace MWMechanics
Ogre::Vector3 pos2 (observer.getRefData().getPosition().pos);
float distTerm = fSneakDistBase + fSneakDistMult * pos1.distance(pos2);
float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).mMagnitude;
float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude();
float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon + invisibility;
CreatureStats& observerStats = observer.getClass().getCreatureStats(observer);
int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude();
int obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind;

@ -76,7 +76,7 @@ namespace MWMechanics
{
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude)
if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).getMagnitude())
return 0;
float y = FLT_MAX;
@ -114,7 +114,7 @@ namespace MWMechanics
if (spell->mData.mFlags & ESM::Spell::F_Always)
return 100;
int castBonus = -stats.getMagicEffects().get(ESM::MagicEffect::Sound).mMagnitude;
int castBonus = -stats.getMagicEffects().get(ESM::MagicEffect::Sound).getMagnitude();
int actorWillpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
int actorLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
@ -158,16 +158,16 @@ namespace MWMechanics
float resistance = 0;
if (resistanceEffect != -1)
resistance += actorEffects->get(resistanceEffect).mMagnitude;
resistance += actorEffects->get(resistanceEffect).getMagnitude();
if (weaknessEffect != -1)
resistance -= actorEffects->get(weaknessEffect).mMagnitude;
resistance -= actorEffects->get(weaknessEffect).getMagnitude();
if (effectId == ESM::MagicEffect::FireDamage)
resistance += actorEffects->get(ESM::MagicEffect::FireShield).mMagnitude;
resistance += actorEffects->get(ESM::MagicEffect::FireShield).getMagnitude();
if (effectId == ESM::MagicEffect::ShockDamage)
resistance += actorEffects->get(ESM::MagicEffect::LightningShield).mMagnitude;
resistance += actorEffects->get(ESM::MagicEffect::LightningShield).getMagnitude();
if (effectId == ESM::MagicEffect::FrostDamage)
resistance += actorEffects->get(ESM::MagicEffect::FrostShield).mMagnitude;
resistance += actorEffects->get(ESM::MagicEffect::FrostShield).getMagnitude();
return resistance;
}
@ -306,8 +306,8 @@ namespace MWMechanics
if (spell && (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight))
{
float x = (spell->mData.mType == ESM::Spell::ST_Disease) ?
target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).mMagnitude
: target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).mMagnitude;
target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).getMagnitude()
: target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).getMagnitude();
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
if (roll <= x)
@ -339,7 +339,7 @@ namespace MWMechanics
bool absorbed = false;
if (spell && caster != target && target.getClass().isActor())
{
int absorb = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::SpellAbsorption).mMagnitude;
int absorb = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::SpellAbsorption).getMagnitude();
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
absorbed = (roll < absorb);
if (absorbed)
@ -388,7 +388,7 @@ namespace MWMechanics
// Try reflecting
if (!reflected && magnitudeMult > 0 && !caster.isEmpty() && caster != target && !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable))
{
int reflect = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::Reflect).mMagnitude;
int reflect = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::Reflect).getMagnitude();
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
bool isReflected = (roll < reflect);
if (isReflected)

@ -300,7 +300,7 @@ void NpcAnimation::updateParts()
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
NpcType curType = Type_Normal;
if (cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).mMagnitude > 0)
if (cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() > 0)
curType = Type_Vampire;
if (cls.getNpcStats(mPtr).isWerewolf())
curType = Type_Werewolf;

@ -339,7 +339,7 @@ void RenderingManager::update (float duration, bool paused)
MWWorld::Ptr player = world->getPlayerPtr();
int blind = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
int blind = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude();
MWBase::Environment::get().getWindowManager()->setScreenFactor(std::max(0.f, 1.f-(blind / 100.f)));
setAmbientMode();
@ -611,7 +611,7 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
mAmbientColor = colour;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
int nightEye = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).mMagnitude;
int nightEye = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).getMagnitude();
Ogre::ColourValue final = colour;
final += Ogre::ColourValue(0.7,0.7,0.7,0) * std::min(1.f, (nightEye/100.f));

@ -421,5 +421,15 @@ op 0x200025c: ClearForceMoveJump
op 0x200025d: ClearForceMoveJump, explicit reference
op 0x200025e: ForceMoveJump
op 0x200025f: ForceMoveJump, explicit reference
op 0x2000260: GetForceJump
op 0x2000261: GetForceJump, explicit reference
op 0x2000262: GetForceMoveJump
op 0x2000263: GetForceMoveJump, explicit reference
op 0x2000264-0x200027b: GetMagicEffect
op 0x200027c-0x2000293: GetMagicEffect, explicit
op 0x2000294-0x20002ab: SetMagicEffect
op 0x20002ac-0x20002c3: SetMagicEffect, explicit
op 0x20002c4-0x20002db: ModMagicEffect
op 0x20002dc-0x20002f3: ModMagicEffect, explicit
opcodes 0x2000260-0x3ffffff unused
opcodes 0x20002f4-0x3ffffff unused

@ -356,7 +356,7 @@ namespace MWScript
key = ESM::MagicEffect::effectStringToId(effect);
runtime.push(ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(
MWMechanics::EffectKey(key)).mMagnitude > 0);
MWMechanics::EffectKey(key)).getMagnitude() > 0);
}
};

@ -1176,6 +1176,91 @@ namespace MWScript
}
};
template <class R>
class OpGetMagicEffect : public Interpreter::Opcode0
{
int mPositiveEffect;
int mNegativeEffect;
public:
OpGetMagicEffect (int positiveEffect, int negativeEffect)
: mPositiveEffect(positiveEffect)
, mNegativeEffect(negativeEffect)
{
}
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
float currentValue = stats.getMagicEffects().get(mPositiveEffect).getMagnitude();
if (mNegativeEffect != -1)
currentValue -= stats.getMagicEffects().get(mNegativeEffect).getMagnitude();
int ret = static_cast<int>(currentValue);
runtime.push(ret);
}
};
template <class R>
class OpSetMagicEffect : public Interpreter::Opcode0
{
int mPositiveEffect;
int mNegativeEffect;
public:
OpSetMagicEffect (int positiveEffect, int negativeEffect)
: mPositiveEffect(positiveEffect)
, mNegativeEffect(negativeEffect)
{
}
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
float currentValue = stats.getMagicEffects().get(mPositiveEffect).getMagnitude();
if (mNegativeEffect != -1)
currentValue -= stats.getMagicEffects().get(mNegativeEffect).getMagnitude();
currentValue = int(currentValue);
int arg = runtime[0].mInteger;
runtime.pop();
stats.getMagicEffects().modifyBase(mPositiveEffect, (arg - currentValue));
}
};
template <class R>
class OpModMagicEffect : public Interpreter::Opcode0
{
int mPositiveEffect;
int mNegativeEffect;
public:
OpModMagicEffect (int positiveEffect, int negativeEffect)
: mPositiveEffect(positiveEffect)
, mNegativeEffect(negativeEffect)
{
}
virtual void execute(Interpreter::Runtime &runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
int arg = runtime[0].mInteger;
runtime.pop();
stats.getMagicEffects().modifyBase(mPositiveEffect, arg);
}
};
struct MagicEffect
{
int mPositiveEffect;
int mNegativeEffect;
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
@ -1320,6 +1405,48 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit, new OpSetWerewolfAcrobatics<ExplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetStat, new OpGetStat<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetStatExplicit, new OpGetStat<ExplicitRef>);
static const MagicEffect sMagicEffects[] = {
{ ESM::MagicEffect::ResistMagicka, ESM::MagicEffect::WeaknessToMagicka },
{ ESM::MagicEffect::ResistFire, ESM::MagicEffect::WeaknessToFire },
{ ESM::MagicEffect::ResistFrost, ESM::MagicEffect::WeaknessToFrost },
{ ESM::MagicEffect::ResistShock, ESM::MagicEffect::WeaknessToShock },
{ ESM::MagicEffect::ResistCommonDisease, ESM::MagicEffect::WeaknessToCommonDisease },
{ ESM::MagicEffect::ResistBlightDisease, ESM::MagicEffect::WeaknessToBlightDisease },
{ ESM::MagicEffect::ResistCorprusDisease, ESM::MagicEffect::WeaknessToCorprusDisease },
{ ESM::MagicEffect::ResistPoison, ESM::MagicEffect::WeaknessToPoison },
{ ESM::MagicEffect::ResistParalysis, -1 },
{ ESM::MagicEffect::ResistNormalWeapons, ESM::MagicEffect::WeaknessToNormalWeapons },
{ ESM::MagicEffect::WaterBreathing, -1 },
{ ESM::MagicEffect::Chameleon, -1 },
{ ESM::MagicEffect::WaterWalking, -1 },
{ ESM::MagicEffect::SwiftSwim, -1 },
{ ESM::MagicEffect::Jump, -1 },
{ ESM::MagicEffect::Levitate, -1 },
{ ESM::MagicEffect::Shield, -1 },
{ ESM::MagicEffect::Sound, -1 },
{ ESM::MagicEffect::Silence, -1 },
{ ESM::MagicEffect::Blind, -1 },
{ ESM::MagicEffect::Paralyze, -1 },
{ ESM::MagicEffect::Invisibility, -1 },
{ ESM::MagicEffect::FortifyAttack, -1 },
{ ESM::MagicEffect::Sanctuary, -1 },
};
for (int i=0; i<24; ++i)
{
int positive = sMagicEffects[i].mPositiveEffect;
int negative = sMagicEffects[i].mNegativeEffect;
interpreter.installSegment5 (Compiler::Stats::opcodeGetMagicEffect+i, new OpGetMagicEffect<ImplicitRef> (positive, negative));
interpreter.installSegment5 (Compiler::Stats::opcodeGetMagicEffectExplicit+i, new OpGetMagicEffect<ExplicitRef> (positive, negative));
interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffect+i, new OpSetMagicEffect<ImplicitRef> (positive, negative));
interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffectExplicit+i, new OpSetMagicEffect<ExplicitRef> (positive, negative));
interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffect+i, new OpModMagicEffect<ImplicitRef> (positive, negative));
interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffectExplicit+i, new OpModMagicEffect<ExplicitRef> (positive, negative));
}
}
}
}

@ -640,7 +640,7 @@ void MWWorld::InventoryStore::rechargeItems(float duration)
void MWWorld::InventoryStore::purgeEffect(short effectId)
{
mMagicEffects.add(MWMechanics::EffectKey(effectId), -mMagicEffects.get(MWMechanics::EffectKey(effectId)).mMagnitude);
mMagicEffects.remove(MWMechanics::EffectKey(effectId));
}
void MWWorld::InventoryStore::clear()

@ -816,7 +816,7 @@ namespace MWWorld
const MWMechanics::MagicEffects& effects = iter->first.getClass().getCreatureStats(iter->first).getMagicEffects();
bool waterCollision = false;
if (effects.get(ESM::MagicEffect::WaterWalking).mMagnitude
if (effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()
&& cell->hasWater()
&& !world->isUnderwater(iter->first.getCell(),
Ogre::Vector3(iter->first.getRefData().getPosition().pos)))
@ -832,7 +832,7 @@ namespace MWWorld
0xff, OEngine::Physic::CollisionType_Actor);
// 100 points of slowfall reduce gravity by 90% (this is just a guess)
float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).mMagnitude / 100.f) * 0.9f), 0.9f);
float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).getMagnitude() / 100.f) * 0.9f), 0.9f);
Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum,
world->isFlying(iter->first),

@ -372,6 +372,14 @@ namespace MWWorld
gmst["sHard"] = ESM::Variant("Hard");
gmst["sDeleteNote"] = ESM::Variant("Delete Note");
gmst["sEditNote"] = ESM::Variant("Edit Note");
gmst["sAdmireSuccess"] = ESM::Variant("Admire Success");
gmst["sAdmireFail"] = ESM::Variant("Admire Fail");
gmst["sIntimidateSuccess"] = ESM::Variant("Intimidate Success");
gmst["sIntimidateFail"] = ESM::Variant("Intimidate Fail");
gmst["sTauntSuccess"] = ESM::Variant("Taunt Success");
gmst["sTauntFail"] = ESM::Variant("Taunt Fail");
gmst["sBribeSuccess"] = ESM::Variant("Bribe Success");
gmst["sBribeFail"] = ESM::Variant("Bribe Fail");
// Werewolf (BM)
gmst["fWereWolfRunMult"] = ESM::Variant(1.f);
@ -1536,7 +1544,7 @@ namespace MWWorld
{
float telekinesisRangeBonus =
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects()
.get(ESM::MagicEffect::Telekinesis).mMagnitude;
.get(ESM::MagicEffect::Telekinesis).getMagnitude();
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);
float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus;
@ -1803,7 +1811,7 @@ namespace MWWorld
World::isFlying(const MWWorld::Ptr &ptr) const
{
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).mMagnitude > 0);
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0);
if(!ptr.getClass().isActor())
return false;
@ -1814,7 +1822,7 @@ namespace MWWorld
if (ptr.getClass().canFly(ptr))
return !isParalyzed;
if(stats.getMagicEffects().get(ESM::MagicEffect::Levitate).mMagnitude > 0
if(stats.getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0
&& isLevitationEnabled())
return true;
@ -1832,7 +1840,7 @@ namespace MWWorld
return false;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(stats.getMagicEffects().get(ESM::MagicEffect::SlowFall).mMagnitude > 0)
if(stats.getMagicEffects().get(ESM::MagicEffect::SlowFall).getMagnitude() > 0)
return true;
return false;
@ -2653,11 +2661,11 @@ namespace MWWorld
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
float dist=0;
if (type == World::Detect_Creature)
dist = effects.get(ESM::MagicEffect::DetectAnimal).mMagnitude;
dist = effects.get(ESM::MagicEffect::DetectAnimal).getMagnitude();
else if (type == World::Detect_Key)
dist = effects.get(ESM::MagicEffect::DetectKey).mMagnitude;
dist = effects.get(ESM::MagicEffect::DetectKey).getMagnitude();
else if (type == World::Detect_Enchantment)
dist = effects.get(ESM::MagicEffect::DetectEnchantment).mMagnitude;
dist = effects.get(ESM::MagicEffect::DetectEnchantment).getMagnitude();
if (!dist)
return;

@ -42,7 +42,7 @@ add_component_dir (esm
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
npcstats creaturestats weatherstate quickkeys fogstate spellstate activespells creaturelevliststate doorstate projectilestate
aisequence
aisequence magiceffects
)
add_component_dir (esmterrain

@ -370,6 +370,16 @@ namespace Compiler
"mercantile", "speechcraft", "handtohand"
};
static const char *magicEffects[numberOfMagicEffects] =
{
"resistmagicka", "resistfire", "resistfrost", "resistshock",
"resistdisease", "resistblight", "resistcorprus", "resistpoison",
"resistparalysis", "resistnormalweapons", "waterbreathing", "chameleon",
"waterwalking", "swimspeed", "superjump", "flying",
"armorbonus", "castpenalty", "silence", "blindness",
"paralysis", "invisible", "attackbonus", "defendbonus"
};
std::string get ("get");
std::string set ("set");
std::string mod ("mod");
@ -418,6 +428,18 @@ namespace Compiler
opcodeModSkill+i, opcodeModSkillExplicit+i);
}
for (int i=0; i<numberOfMagicEffects; ++i)
{
extensions.registerFunction (get + magicEffects[i], 'l', "",
opcodeGetMagicEffect+i, opcodeGetMagicEffectExplicit+i);
extensions.registerInstruction (set + magicEffects[i], "l",
opcodeSetMagicEffect+i, opcodeSetMagicEffectExplicit+i);
extensions.registerInstruction(mod + magicEffects[i], "l",
opcodeModMagicEffect+i, opcodeModMagicEffectExplicit+i);
}
extensions.registerFunction ("getpccrimelevel", 'f', "", opcodeGetPCCrimeLevel);
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);

@ -322,6 +322,8 @@ namespace Compiler
const int numberOfDynamics = 3;
const int numberOfSkills = 27;
const int numberOfMagicEffects = 24;
const int opcodeGetAttribute = 0x2000027;
const int opcodeGetAttributeExplicit = 0x200002f;
const int opcodeSetAttribute = 0x2000037;
@ -347,6 +349,13 @@ namespace Compiler
const int opcodeModSkill = 0x20000fa;
const int opcodeModSkillExplicit = 0x2000115;
const int opcodeGetMagicEffect = 0x2000264;
const int opcodeGetMagicEffectExplicit = 0x200027c;
const int opcodeSetMagicEffect = 0x2000294;
const int opcodeSetMagicEffectExplicit = 0x20002ac;
const int opcodeModMagicEffect = 0x20002c4;
const int opcodeModMagicEffectExplicit = 0x20002dc;
const int opcodeGetPCCrimeLevel = 0x20001ec;
const int opcodeSetPCCrimeLevel = 0x20001ed;
const int opcodeModPCCrimeLevel = 0x20001ee;

@ -86,6 +86,7 @@ void ESM::CreatureStats::load (ESMReader &esm)
mSpells.load(esm);
mActiveSpells.load(esm);
mAiSequence.load(esm);
mMagicEffects.load(esm);
while (esm.isNextSub("SUMM"))
{
@ -196,6 +197,7 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
mSpells.save(esm);
mActiveSpells.save(esm);
mAiSequence.save(esm);
mMagicEffects.save(esm);
for (std::map<int, int>::const_iterator it = mSummonedCreatureMap.begin(); it != mSummonedCreatureMap.end(); ++it)
{

@ -11,6 +11,7 @@
#include "spellstate.hpp"
#include "activespells.hpp"
#include "magiceffects.hpp"
#include "aisequence.hpp"
namespace ESM
@ -24,6 +25,8 @@ namespace ESM
StatState<int> mAttributes[8];
StatState<float> mDynamic[3];
MagicEffects mMagicEffects;
AiSequence::AiSequence mAiSequence;
bool mHasAiSettings;

@ -0,0 +1,29 @@
#include "magiceffects.hpp"
#include "esmwriter.hpp"
#include "esmreader.hpp"
namespace ESM
{
void MagicEffects::save(ESMWriter &esm) const
{
for (std::map<int, int>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{
esm.writeHNT("EFID", it->first);
esm.writeHNT("BASE", it->second);
}
}
void MagicEffects::load(ESMReader &esm)
{
while (esm.isNextSub("EFID"))
{
int id, base;
esm.getHT(id);
esm.getHNT(base, "BASE");
mEffects.insert(std::make_pair(id, base));
}
}
}

@ -0,0 +1,23 @@
#ifndef COMPONENTS_ESM_MAGICEFFECTS_H
#define COMPONENTS_ESM_MAGICEFFECTS_H
#include <map>
namespace ESM
{
class ESMReader;
class ESMWriter;
// format 0, saved games only
struct MagicEffects
{
// <Effect Id, Base value>
std::map<int, int> mEffects;
void load (ESMReader &esm);
void save (ESMWriter &esm) const;
};
}
#endif

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 600 125" name="_Main">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 600 128" name="_Main">
<Property key="Visible" value="false"/>
<Widget type="TextBox" skin="SandText" position="4 0 592 24" name="LabelText" align="Left Top HStretch">
<Widget type="TextBox" skin="SandText" position="4 4 592 24" name="LabelText" align="Left Top HStretch">
<Property key="TextAlign" value="Center"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="4 30 532 24" name="ItemText" align="Left Top HStretch">
<Widget type="TextBox" skin="SandText" position="4 30 507 24" name="ItemText" align="Left Top HStretch">
<Property key="TextAlign" value="Right"/>
</Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="540 30 32 24" name="ItemEdit" align="Right Top">
<Widget type="EditBox" skin="MW_TextEdit" position="520 30 52 24" name="ItemEdit" align="Right Top">
<Property key="TextAlign" value="Center"/>
</Widget>
@ -21,7 +21,7 @@
</Widget>
<Widget type="HBox" position="0 90 572 24" align="Right Bottom">
<Widget type="HBox" position="0 86 572 24" align="Right Bottom">
<Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>

Loading…
Cancel
Save