diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 36937ac7e..db6079f18 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -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; diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index c1000f3db..1b4719c6e 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -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}"); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 662672204..d20127067 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -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(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] diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 6c801f755..f09b81b40 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -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()); diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 500aa5099..2d75576f0 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -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: diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 93c598d28..a044d014f 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -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() diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index c4b204de7..d6839d9a9 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -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::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::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::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::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { if(Misc::StringUtils::ciEqual((*button)->getCaption(), ok)) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index be3a90e0c..fbc840df8 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -146,7 +146,7 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); - 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 magicka = creatureStats.getMagicka(); float diff = (static_cast(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 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()->mBase->mData.mType == ESM::Creature::Creatures) { Stat 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()->mBase->mData.mType == ESM::Creature::Undead) { Stat 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 health = creatureStats.getHealth(); for (unsigned int i=0; i::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::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); } } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index e0e8057f2..641bd3f6b 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1639,7 +1639,7 @@ void CharacterController::updateContinuousVfx() for (std::vector::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); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index c04e2c62d..d3cb678be 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -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; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index fc7481410..6c0356a04 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -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; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index a36d28fd3..037f37cc9 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -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); diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index 05ce1c7ae..fa97f1541 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -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; diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index 5be0854ab..0b19df0a8 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace MWMechanics { @@ -40,20 +41,57 @@ namespace MWMechanics return left.mArgsecond.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::const_iterator it = state.mEffects.begin(); it != state.mEffects.end(); ++it) + { + mCollection[EffectKey(it->first)].setBase(it->second); + } + } } diff --git a/apps/openmw/mwmechanics/magiceffects.hpp b/apps/openmw/mwmechanics/magiceffects.hpp index 4fd5e159a..0a8392dab 100644 --- a/apps/openmw/mwmechanics/magiceffects.hpp +++ b/apps/openmw/mwmechanics/magiceffects.hpp @@ -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); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index ed21fa8a8..d0f11b892 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -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().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; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index f53aceaef..377455cac 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -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 (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 (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 (RAND_MAX) + 1) * 100; // [0, 99] bool isReflected = (roll < reflect); if (isReflected) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 23b761646..7467bd776 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -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; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ed6b56f37..46ff57cb0 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -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)); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index f600117a9..7397355e3 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -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 diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index b487ac70f..52957b00f 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -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); } }; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 7150704ca..49a483f27 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1176,6 +1176,91 @@ namespace MWScript } }; + template + 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(currentValue); + runtime.push(ret); + } + }; + + template + 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 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); interpreter.installSegment5 (Compiler::Stats::opcodeGetStat, new OpGetStat); interpreter.installSegment5 (Compiler::Stats::opcodeGetStatExplicit, new OpGetStat); + + 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 (positive, negative)); + interpreter.installSegment5 (Compiler::Stats::opcodeGetMagicEffectExplicit+i, new OpGetMagicEffect (positive, negative)); + + interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffect+i, new OpSetMagicEffect (positive, negative)); + interpreter.installSegment5 (Compiler::Stats::opcodeSetMagicEffectExplicit+i, new OpSetMagicEffect (positive, negative)); + + interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffect+i, new OpModMagicEffect (positive, negative)); + interpreter.installSegment5 (Compiler::Stats::opcodeModMagicEffectExplicit+i, new OpModMagicEffect (positive, negative)); + } } } } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 891440023..dcbe707b7 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -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() diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 0d6cef565..1b46f5206 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -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), diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 881f01285..89741dc74 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -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; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index fff5b1080..96ccc281a 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -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 diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 73877f459..a2dc97a1a 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -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::const_iterator it = mSummonedCreatureMap.begin(); it != mSummonedCreatureMap.end(); ++it) { diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp index 610be0246..8f4d4df7b 100644 --- a/components/esm/creaturestats.hpp +++ b/components/esm/creaturestats.hpp @@ -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 mAttributes[8]; StatState mDynamic[3]; + MagicEffects mMagicEffects; + AiSequence::AiSequence mAiSequence; bool mHasAiSettings; diff --git a/components/esm/magiceffects.cpp b/components/esm/magiceffects.cpp new file mode 100644 index 000000000..898e7e4b1 --- /dev/null +++ b/components/esm/magiceffects.cpp @@ -0,0 +1,29 @@ +#include "magiceffects.hpp" + +#include "esmwriter.hpp" +#include "esmreader.hpp" + +namespace ESM +{ + +void MagicEffects::save(ESMWriter &esm) const +{ + for (std::map::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)); + } +} + +} diff --git a/components/esm/magiceffects.hpp b/components/esm/magiceffects.hpp new file mode 100644 index 000000000..2a6052caa --- /dev/null +++ b/components/esm/magiceffects.hpp @@ -0,0 +1,23 @@ +#ifndef COMPONENTS_ESM_MAGICEFFECTS_H +#define COMPONENTS_ESM_MAGICEFFECTS_H + +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + // format 0, saved games only + struct MagicEffects + { + // + std::map mEffects; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; + +} + +#endif diff --git a/files/mygui/openmw_count_window.layout b/files/mygui/openmw_count_window.layout index 4e24277af..5f3a30af4 100644 --- a/files/mygui/openmw_count_window.layout +++ b/files/mygui/openmw_count_window.layout @@ -1,18 +1,18 @@ - + - + - + - + @@ -21,7 +21,7 @@ - +