mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
		
						commit
						ee621245bb
					
				
					 42 changed files with 482 additions and 209 deletions
				
			
		| 
						 | 
					@ -137,8 +137,8 @@ namespace MWBase
 | 
				
			||||||
            virtual void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount) = 0;
 | 
					            virtual void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// Set value for the given ID.
 | 
					            /// Set value for the given ID.
 | 
				
			||||||
            virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value) = 0;
 | 
					            virtual void setValue (const std::string& id, const MWMechanics::AttributeValue& value) = 0;
 | 
				
			||||||
            virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value) = 0;
 | 
					            virtual void setValue (int parSkill, const MWMechanics::SkillValue& value) = 0;
 | 
				
			||||||
            virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value) = 0;
 | 
					            virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value) = 0;
 | 
				
			||||||
            virtual void setValue (const std::string& id, const std::string& value) = 0;
 | 
					            virtual void setValue (const std::string& id, const std::string& value) = 0;
 | 
				
			||||||
            virtual void setValue (const std::string& id, int value) = 0;
 | 
					            virtual void setValue (const std::string& id, int value) = 0;
 | 
				
			||||||
| 
						 | 
					@ -236,8 +236,8 @@ namespace MWBase
 | 
				
			||||||
            virtual void onFrame (float frameDuration) = 0;
 | 
					            virtual void onFrame (float frameDuration) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
 | 
					            /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
 | 
				
			||||||
            virtual std::map<int, MWMechanics::Stat<float> > getPlayerSkillValues() = 0;
 | 
					            virtual std::map<int, MWMechanics::SkillValue > getPlayerSkillValues() = 0;
 | 
				
			||||||
            virtual std::map<int, MWMechanics::Stat<int> > getPlayerAttributeValues() = 0;
 | 
					            virtual std::map<int, MWMechanics::AttributeValue > getPlayerAttributeValues() = 0;
 | 
				
			||||||
            virtual SkillList getPlayerMinorSkills() = 0;
 | 
					            virtual SkillList getPlayerMinorSkills() = 0;
 | 
				
			||||||
            virtual SkillList getPlayerMajorSkills() = 0;
 | 
					            virtual SkillList getPlayerMajorSkills() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,7 +242,11 @@ namespace MWClass
 | 
				
			||||||
            item.get<ESM::Miscellaneous>();
 | 
					            item.get<ESM::Miscellaneous>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc)
 | 
					        return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc)
 | 
				
			||||||
                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001");
 | 
					                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001")
 | 
				
			||||||
 | 
					                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_005")
 | 
				
			||||||
 | 
					                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_010")
 | 
				
			||||||
 | 
					                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_025")
 | 
				
			||||||
 | 
					                && !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_100");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const
 | 
					    float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,29 +179,29 @@ namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (int raceSkillIndex = 0; raceSkillIndex < 7; ++raceSkillIndex)
 | 
					            for (int raceSkillIndex = 0; raceSkillIndex < 7; ++raceSkillIndex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              if (race->mData.mBonus[raceSkillIndex].mSkill == skillIndex)
 | 
					                if (race->mData.mBonus[raceSkillIndex].mSkill == skillIndex)
 | 
				
			||||||
              {
 | 
					                {
 | 
				
			||||||
                  raceBonus = race->mData.mBonus[raceSkillIndex].mBonus;
 | 
					                    raceBonus = race->mData.mBonus[raceSkillIndex].mBonus;
 | 
				
			||||||
                  break;
 | 
					                    break;
 | 
				
			||||||
              }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (int k = 0; k < 5; ++k)
 | 
					            for (int k = 0; k < 5; ++k)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              // is this a minor or major skill?
 | 
					                // is this a minor or major skill?
 | 
				
			||||||
              if ((class_->mData.mSkills[k][0] == skillIndex) || (class_->mData.mSkills[k][1] == skillIndex))
 | 
					                if ((class_->mData.mSkills[k][0] == skillIndex) || (class_->mData.mSkills[k][1] == skillIndex))
 | 
				
			||||||
              {
 | 
					                {
 | 
				
			||||||
                majorMultiplier = 1.0f;
 | 
					                    majorMultiplier = 1.0f;
 | 
				
			||||||
                break;
 | 
					                    break;
 | 
				
			||||||
              }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // is this skill in the same Specialization as the class?
 | 
					            // is this skill in the same Specialization as the class?
 | 
				
			||||||
            const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skillIndex);
 | 
					            const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skillIndex);
 | 
				
			||||||
            if (skill->mData.mSpecialization == class_->mData.mSpecialization)
 | 
					            if (skill->mData.mSpecialization == class_->mData.mSpecialization)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              specMultiplier = 0.5f;
 | 
					                specMultiplier = 0.5f;
 | 
				
			||||||
              specBonus = 5;
 | 
					                specBonus = 5;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            npcStats.getSkill(skillIndex).setBase(
 | 
					            npcStats.getSkill(skillIndex).setBase(
 | 
				
			||||||
| 
						 | 
					@ -210,7 +210,7 @@ namespace
 | 
				
			||||||
                    + 5
 | 
					                    + 5
 | 
				
			||||||
                    + raceBonus
 | 
					                    + raceBonus
 | 
				
			||||||
                    + specBonus
 | 
					                    + specBonus
 | 
				
			||||||
                    + static_cast<int>((level-1) * (majorMultiplier + specMultiplier)), 100.0f));
 | 
					                    + static_cast<int>((level-1) * (majorMultiplier + specMultiplier)), 100));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -450,8 +450,8 @@ namespace MWClass
 | 
				
			||||||
                          (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
 | 
					                          (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
 | 
				
			||||||
                          (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
 | 
					                          (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
 | 
				
			||||||
        hitchance *= stats.getFatigueTerm();
 | 
					        hitchance *= stats.getFatigueTerm();
 | 
				
			||||||
        hitchance += mageffects.get(MWMechanics::EffectKey(ESM::MagicEffect::FortifyAttack)).mMagnitude -
 | 
					        hitchance += mageffects.get(ESM::MagicEffect::FortifyAttack).mMagnitude -
 | 
				
			||||||
                     mageffects.get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
 | 
					                     mageffects.get(ESM::MagicEffect::Blind).mMagnitude;
 | 
				
			||||||
        hitchance -= otherstats.getEvasion();
 | 
					        hitchance -= otherstats.getEvasion();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
 | 
					        if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
 | 
				
			||||||
| 
						 | 
					@ -848,10 +848,11 @@ namespace MWClass
 | 
				
			||||||
        float moveSpeed;
 | 
					        float moveSpeed;
 | 
				
			||||||
        if(normalizedEncumbrance >= 1.0f)
 | 
					        if(normalizedEncumbrance >= 1.0f)
 | 
				
			||||||
            moveSpeed = 0.0f;
 | 
					            moveSpeed = 0.0f;
 | 
				
			||||||
        else if(mageffects.get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude > 0)
 | 
					        else if(mageffects.get(ESM::MagicEffect::Levitate).mMagnitude > 0 &&
 | 
				
			||||||
 | 
					                world->isLevitationEnabled())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() +
 | 
					            float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() +
 | 
				
			||||||
                                    mageffects.get(MWMechanics::EffectKey(10/*levitate*/)).mMagnitude);
 | 
					                                    mageffects.get(ESM::MagicEffect::Levitate).mMagnitude);
 | 
				
			||||||
            flySpeed = fMinFlySpeed->getFloat() + flySpeed*(fMaxFlySpeed->getFloat() - fMinFlySpeed->getFloat());
 | 
					            flySpeed = fMinFlySpeed->getFloat() + flySpeed*(fMaxFlySpeed->getFloat() - fMinFlySpeed->getFloat());
 | 
				
			||||||
            flySpeed *= 1.0f - fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
 | 
					            flySpeed *= 1.0f - fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
 | 
				
			||||||
            flySpeed = std::max(0.0f, flySpeed);
 | 
					            flySpeed = std::max(0.0f, flySpeed);
 | 
				
			||||||
| 
						 | 
					@ -862,7 +863,7 @@ namespace MWClass
 | 
				
			||||||
            float swimSpeed = walkSpeed;
 | 
					            float swimSpeed = walkSpeed;
 | 
				
			||||||
            if(Npc::getStance(ptr, Run, false))
 | 
					            if(Npc::getStance(ptr, Run, false))
 | 
				
			||||||
                swimSpeed = runSpeed;
 | 
					                swimSpeed = runSpeed;
 | 
				
			||||||
            swimSpeed *= 1.0f + 0.01f * mageffects.get(MWMechanics::EffectKey(1/*swift swim*/)).mMagnitude;
 | 
					            swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude;
 | 
				
			||||||
            swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
 | 
					            swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
 | 
				
			||||||
                                                    fSwimRunAthleticsMult->getFloat();
 | 
					                                                    fSwimRunAthleticsMult->getFloat();
 | 
				
			||||||
            moveSpeed = swimSpeed;
 | 
					            moveSpeed = swimSpeed;
 | 
				
			||||||
| 
						 | 
					@ -896,7 +897,7 @@ namespace MWClass
 | 
				
			||||||
        float x = fJumpAcrobaticsBase->getFloat() +
 | 
					        float x = fJumpAcrobaticsBase->getFloat() +
 | 
				
			||||||
                  std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat());
 | 
					                  std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat());
 | 
				
			||||||
        x += 3.0f * b * fJumpAcroMultiplier->getFloat();
 | 
					        x += 3.0f * b * fJumpAcroMultiplier->getFloat();
 | 
				
			||||||
        x += mageffects.get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude * 64;
 | 
					        x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64;
 | 
				
			||||||
        x *= encumbranceTerm;
 | 
					        x *= encumbranceTerm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Npc::getStance(ptr, Run, false))
 | 
					        if(Npc::getStance(ptr, Run, false))
 | 
				
			||||||
| 
						 | 
					@ -919,7 +920,7 @@ namespace MWClass
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
 | 
					            const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
 | 
				
			||||||
            const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
 | 
					            const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
 | 
				
			||||||
            const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude;
 | 
					            const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude;
 | 
				
			||||||
            const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
 | 
					            const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
 | 
				
			||||||
            const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
 | 
					            const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
 | 
				
			||||||
            const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat();
 | 
					            const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat();
 | 
				
			||||||
| 
						 | 
					@ -1024,8 +1025,8 @@ namespace MWClass
 | 
				
			||||||
        if(!stats.isWerewolf())
 | 
					        if(!stats.isWerewolf())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            weight  = getContainerStore(ptr).getWeight();
 | 
					            weight  = getContainerStore(ptr).getWeight();
 | 
				
			||||||
            weight -= stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Feather)).mMagnitude;
 | 
					            weight -= stats.getMagicEffects().get(ESM::MagicEffect::Feather).mMagnitude;
 | 
				
			||||||
            weight += stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).mMagnitude;
 | 
					            weight += stats.getMagicEffects().get(ESM::MagicEffect::Burden).mMagnitude;
 | 
				
			||||||
            if(weight < 0.0f)
 | 
					            if(weight < 0.0f)
 | 
				
			||||||
                weight = 0.0f;
 | 
					                weight = 0.0f;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ namespace MWGui
 | 
				
			||||||
        mGenerateClassSpecializations[2] = 0;
 | 
					        mGenerateClassSpecializations[2] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
 | 
					    void CharacterCreation::setValue (const std::string& id, const MWMechanics::AttributeValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mReviewDialog)
 | 
					        if (mReviewDialog)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -113,7 +113,7 @@ namespace MWGui
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
 | 
					    void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (mReviewDialog)
 | 
					        if (mReviewDialog)
 | 
				
			||||||
            mReviewDialog->setSkillValue(parSkill, value);
 | 
					            mReviewDialog->setSkillValue(parSkill, value);
 | 
				
			||||||
| 
						 | 
					@ -229,8 +229,8 @@ namespace MWGui
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    std::map<int, MWMechanics::Stat<int> > attributes = MWBase::Environment::get().getWindowManager()->getPlayerAttributeValues();
 | 
					                    std::map<int, MWMechanics::AttributeValue > attributes = MWBase::Environment::get().getWindowManager()->getPlayerAttributeValues();
 | 
				
			||||||
                    for (std::map<int, MWMechanics::Stat<int> >::iterator it = attributes.begin();
 | 
					                    for (std::map<int, MWMechanics::AttributeValue >::iterator it = attributes.begin();
 | 
				
			||||||
                        it != attributes.end(); ++it)
 | 
					                        it != attributes.end(); ++it)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID> (it->first), it->second);
 | 
					                        mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID> (it->first), it->second);
 | 
				
			||||||
| 
						 | 
					@ -238,8 +238,8 @@ namespace MWGui
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    std::map<int, MWMechanics::Stat<float> > skills = MWBase::Environment::get().getWindowManager()->getPlayerSkillValues();
 | 
					                    std::map<int, MWMechanics::SkillValue > skills = MWBase::Environment::get().getWindowManager()->getPlayerSkillValues();
 | 
				
			||||||
                    for (std::map<int, MWMechanics::Stat<float> >::iterator it = skills.begin();
 | 
					                    for (std::map<int, MWMechanics::SkillValue >::iterator it = skills.begin();
 | 
				
			||||||
                        it != skills.end(); ++it)
 | 
					                        it != skills.end(); ++it)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        mReviewDialog->setSkillValue(static_cast<ESM::Skill::SkillEnum> (it->first), it->second);
 | 
					                        mReviewDialog->setSkillValue(static_cast<ESM::Skill::SkillEnum> (it->first), it->second);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,9 +31,9 @@ namespace MWGui
 | 
				
			||||||
    //Show a dialog
 | 
					    //Show a dialog
 | 
				
			||||||
    void spawnDialog(const char id);
 | 
					    void spawnDialog(const char id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
 | 
					    void setValue (const std::string& id, const MWMechanics::AttributeValue& value);
 | 
				
			||||||
    void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
					    void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
				
			||||||
    void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
 | 
					    void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value);
 | 
				
			||||||
    void configureSkills (const SkillList& major, const SkillList& minor);
 | 
					    void configureSkills (const SkillList& major, const SkillList& minor);
 | 
				
			||||||
    void doRenderUpdate();
 | 
					    void doRenderUpdate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,7 +166,7 @@ namespace MWGui
 | 
				
			||||||
            // increase attributes
 | 
					            // increase attributes
 | 
				
			||||||
            for (int i=0; i<3; ++i)
 | 
					            for (int i=0; i<3; ++i)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MWMechanics::Stat<int> attribute = creatureStats.getAttribute(mSpentAttributes[i]);
 | 
					                MWMechanics::AttributeValue attribute = creatureStats.getAttribute(mSpentAttributes[i]);
 | 
				
			||||||
                attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i]));
 | 
					                attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (attribute.getBase() >= 100)
 | 
					                if (attribute.getBase() >= 100)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ namespace MWGui
 | 
				
			||||||
            getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
 | 
					            getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
 | 
				
			||||||
            mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::sAttributeIds[idx]), attribute));
 | 
					            mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::sAttributeIds[idx]), attribute));
 | 
				
			||||||
            attribute->setAttributeId(ESM::Attribute::sAttributeIds[idx]);
 | 
					            attribute->setAttributeId(ESM::Attribute::sAttributeIds[idx]);
 | 
				
			||||||
            attribute->setAttributeValue(Widgets::MWAttribute::AttributeValue(0, 0));
 | 
					            attribute->setAttributeValue(Widgets::MWAttribute::AttributeValue());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Setup skills
 | 
					        // Setup skills
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
					        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mSkillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
 | 
					            mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue()));
 | 
				
			||||||
            mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
 | 
					            mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ namespace MWGui
 | 
				
			||||||
        mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
 | 
					        mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
 | 
					    void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::AttributeValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::map<int, Widgets::MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
 | 
					        std::map<int, Widgets::MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
 | 
				
			||||||
        if (attr == mAttributeWidgets.end())
 | 
					        if (attr == mAttributeWidgets.end())
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,7 @@ namespace MWGui
 | 
				
			||||||
        attr->second->setAttributeValue(value);
 | 
					        attr->second->setAttributeValue(value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
 | 
					    void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mSkillValues[skillId] = value;
 | 
					        mSkillValues[skillId] = value;
 | 
				
			||||||
        MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
 | 
					        MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
 | 
				
			||||||
| 
						 | 
					@ -279,9 +279,9 @@ namespace MWGui
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            assert(skillId >= 0 && skillId < ESM::Skill::Length);
 | 
					            assert(skillId >= 0 && skillId < ESM::Skill::Length);
 | 
				
			||||||
            const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
 | 
					            const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
 | 
				
			||||||
            const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
 | 
					            const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second;
 | 
				
			||||||
            float base = stat.getBase();
 | 
					            int base = stat.getBase();
 | 
				
			||||||
            float modified = stat.getModified();
 | 
					            int modified = stat.getModified();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string state = "normal";
 | 
					            std::string state = "normal";
 | 
				
			||||||
            if (modified > base)
 | 
					            if (modified > base)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,10 +38,10 @@ namespace MWGui
 | 
				
			||||||
        void setMagicka(const MWMechanics::DynamicStat<float>& value);
 | 
					        void setMagicka(const MWMechanics::DynamicStat<float>& value);
 | 
				
			||||||
        void setFatigue(const MWMechanics::DynamicStat<float>& value);
 | 
					        void setFatigue(const MWMechanics::DynamicStat<float>& value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value);
 | 
					        void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::AttributeValue& value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void configureSkills(const SkillList& major, const SkillList& minor);
 | 
					        void configureSkills(const SkillList& major, const SkillList& minor);
 | 
				
			||||||
        void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value);
 | 
					        void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void open();
 | 
					        virtual void open();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,7 @@ namespace MWGui
 | 
				
			||||||
        std::map<int, Widgets::MWAttributePtr> mAttributeWidgets;
 | 
					        std::map<int, Widgets::MWAttributePtr> mAttributeWidgets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SkillList mMajorSkills, mMinorSkills, mMiscSkills;
 | 
					        SkillList mMajorSkills, mMinorSkills, mMiscSkills;
 | 
				
			||||||
        std::map<int, MWMechanics::Stat<float> > mSkillValues;
 | 
					        std::map<int, MWMechanics::SkillValue > mSkillValues;
 | 
				
			||||||
        std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
 | 
					        std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
 | 
				
			||||||
        std::string mName, mRaceId, mBirthSignId;
 | 
					        std::string mName, mRaceId, mBirthSignId;
 | 
				
			||||||
        ESM::Class mKlass;
 | 
					        ESM::Class mKlass;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,8 @@ namespace MWGui
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void EffectSourceVisitor::visit (MWMechanics::EffectKey key,
 | 
					    void EffectSourceVisitor::visit (MWMechanics::EffectKey key,
 | 
				
			||||||
                                           const std::string& sourceName, float magnitude, float remainingTime)
 | 
					                                           const std::string& sourceName, const std::string& casterHandle,
 | 
				
			||||||
 | 
					                                     float magnitude, float remainingTime)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MagicEffectInfo newEffectSource;
 | 
					        MagicEffectInfo newEffectSource;
 | 
				
			||||||
        newEffectSource.mKey = key;
 | 
					        newEffectSource.mKey = key;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,8 @@ namespace MWGui
 | 
				
			||||||
        std::map <int, std::vector<MagicEffectInfo> > mEffectSources;
 | 
					        std::map <int, std::vector<MagicEffectInfo> > mEffectSources;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void visit (MWMechanics::EffectKey key,
 | 
					        virtual void visit (MWMechanics::EffectKey key,
 | 
				
			||||||
                                 const std::string& sourceName, float magnitude, float remainingTime = -1);
 | 
					                                 const std::string& sourceName, const std::string& casterHandle,
 | 
				
			||||||
 | 
					                            float magnitude, float remainingTime = -1);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class SpellIcons
 | 
					    class SpellIcons
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
					        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mSkillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>()));
 | 
					            mSkillValues.insert(std::pair<int, MWMechanics::SkillValue >(i, MWMechanics::SkillValue()));
 | 
				
			||||||
            mSkillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, (MyGUI::TextBox*)NULL));
 | 
					            mSkillWidgetMap.insert(std::pair<int, MyGUI::TextBox*>(i, (MyGUI::TextBox*)NULL));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ namespace MWGui
 | 
				
			||||||
        adjustWindowCaption();
 | 
					        adjustWindowCaption();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
 | 
					    void StatsWindow::setValue (const std::string& id, const MWMechanics::AttributeValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        static const char *ids[] =
 | 
					        static const char *ids[] =
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -179,7 +179,7 @@ namespace MWGui
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value)
 | 
					    void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mSkillValues[parSkill] = value;
 | 
					        mSkillValues[parSkill] = value;
 | 
				
			||||||
        MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
 | 
					        MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill];
 | 
				
			||||||
| 
						 | 
					@ -358,22 +358,20 @@ namespace MWGui
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            assert(skillId >= 0 && skillId < ESM::Skill::Length);
 | 
					            assert(skillId >= 0 && skillId < ESM::Skill::Length);
 | 
				
			||||||
            const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
 | 
					            const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
 | 
				
			||||||
            const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
 | 
					            const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second;
 | 
				
			||||||
            float base = stat.getBase();
 | 
					            int base = stat.getBase();
 | 
				
			||||||
            float modified = stat.getModified();
 | 
					            int modified = stat.getModified();
 | 
				
			||||||
            int progressPercent = (modified - float(static_cast<int>(modified))) * 100;
 | 
					            int progressPercent = stat.getProgress() * 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const MWWorld::ESMStore &esmStore =
 | 
					            const MWWorld::ESMStore &esmStore =
 | 
				
			||||||
                MWBase::Environment::get().getWorld()->getStore();
 | 
					                MWBase::Environment::get().getWorld()->getStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const ESM::Skill* skill = esmStore.get<ESM::Skill>().find(skillId);
 | 
					            const ESM::Skill* skill = esmStore.get<ESM::Skill>().find(skillId);
 | 
				
			||||||
            assert(skill);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
 | 
					            std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const ESM::Attribute* attr =
 | 
					            const ESM::Attribute* attr =
 | 
				
			||||||
                esmStore.get<ESM::Attribute>().find(skill->mData.mAttribute);
 | 
					                esmStore.get<ESM::Attribute>().find(skill->mData.mAttribute);
 | 
				
			||||||
            assert(attr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string state = "normal";
 | 
					            std::string state = "normal";
 | 
				
			||||||
            if (modified > base)
 | 
					            if (modified > base)
 | 
				
			||||||
| 
						 | 
					@ -484,7 +482,6 @@ namespace MWGui
 | 
				
			||||||
                        ESM::RankData rankData = faction->mData.mRankData[it->second+1];
 | 
					                        ESM::RankData rankData = faction->mData.mRankData[it->second+1];
 | 
				
			||||||
                        const ESM::Attribute* attr1 = store.get<ESM::Attribute>().find(faction->mData.mAttribute[0]);
 | 
					                        const ESM::Attribute* attr1 = store.get<ESM::Attribute>().find(faction->mData.mAttribute[0]);
 | 
				
			||||||
                        const ESM::Attribute* attr2 = store.get<ESM::Attribute>().find(faction->mData.mAttribute[1]);
 | 
					                        const ESM::Attribute* attr2 = store.get<ESM::Attribute>().find(faction->mData.mAttribute[1]);
 | 
				
			||||||
                        assert(attr1 && attr2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        text += "\n#BF9959#{" + attr1->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute1)
 | 
					                        text += "\n#BF9959#{" + attr1->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute1)
 | 
				
			||||||
                                + ", #{" + attr2->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute2);
 | 
					                                + ", #{" + attr2->mName + "}: " + boost::lexical_cast<std::string>(rankData.mAttribute2);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,11 @@ namespace MWGui
 | 
				
			||||||
            void setPlayerName(const std::string& playerName);
 | 
					            void setPlayerName(const std::string& playerName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// Set value for the given ID.
 | 
					            /// Set value for the given ID.
 | 
				
			||||||
            void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
 | 
					            void setValue (const std::string& id, const MWMechanics::AttributeValue& value);
 | 
				
			||||||
            void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
					            void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
				
			||||||
            void setValue (const std::string& id, const std::string& value);
 | 
					            void setValue (const std::string& id, const std::string& value);
 | 
				
			||||||
            void setValue (const std::string& id, int value);
 | 
					            void setValue (const std::string& id, int value);
 | 
				
			||||||
            void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
 | 
					            void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void configureSkills (const SkillList& major, const SkillList& minor);
 | 
					            void configureSkills (const SkillList& major, const SkillList& minor);
 | 
				
			||||||
            void setReputation (int reputation) { if (reputation != mReputation) mChanged = true; this->mReputation = reputation; }
 | 
					            void setReputation (int reputation) { if (reputation != mReputation) mChanged = true; this->mReputation = reputation; }
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ namespace MWGui
 | 
				
			||||||
            MyGUI::ScrollView* mSkillView;
 | 
					            MyGUI::ScrollView* mSkillView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SkillList mMajorSkills, mMinorSkills, mMiscSkills;
 | 
					            SkillList mMajorSkills, mMinorSkills, mMiscSkills;
 | 
				
			||||||
            std::map<int, MWMechanics::Stat<float> > mSkillValues;
 | 
					            std::map<int, MWMechanics::SkillValue > mSkillValues;
 | 
				
			||||||
            std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
 | 
					            std::map<int, MyGUI::TextBox*> mSkillWidgetMap;
 | 
				
			||||||
            std::map<std::string, MyGUI::Widget*> mFactionWidgetMap;
 | 
					            std::map<std::string, MyGUI::Widget*> mFactionWidgetMap;
 | 
				
			||||||
            FactionList mFactions; ///< Stores a list of factions and the current rank
 | 
					            FactionList mFactions; ///< Stores a list of factions and the current rank
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,10 +296,10 @@ namespace MWGui
 | 
				
			||||||
            const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
 | 
					            const MWMechanics::NpcStats &sellerStats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
 | 
				
			||||||
            const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
 | 
					            const MWMechanics::NpcStats &playerStats = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
 | 
					            float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
				
			||||||
            float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
					            float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
				
			||||||
            float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
					            float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
				
			||||||
            float d1 = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
 | 
					            float d1 = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
				
			||||||
            float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
					            float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
				
			||||||
            float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
					            float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float hourlyHealthDelta  = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;
 | 
					        float hourlyHealthDelta  = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0);
 | 
					        bool stunted = (stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0);
 | 
				
			||||||
        float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
 | 
					        float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
 | 
				
			||||||
        float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
 | 
					        float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,7 +178,7 @@ namespace MWGui
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (mAttributeValueWidget)
 | 
					            if (mAttributeValueWidget)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                AttributeValue::Type modified = mValue.getModified(), base = mValue.getBase();
 | 
					                int modified = mValue.getModified(), base = mValue.getBase();
 | 
				
			||||||
                static_cast<MyGUI::TextBox*>(mAttributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
 | 
					                static_cast<MyGUI::TextBox*>(mAttributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
 | 
				
			||||||
                if (modified > base)
 | 
					                if (modified > base)
 | 
				
			||||||
                    mAttributeValueWidget->_setWidgetState("increased");
 | 
					                    mAttributeValueWidget->_setWidgetState("increased");
 | 
				
			||||||
| 
						 | 
					@ -528,14 +528,9 @@ namespace MWGui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (mBarTextWidget)
 | 
					            if (mBarTextWidget)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (mValue >= 0 && mMax > 0)
 | 
					                std::stringstream out;
 | 
				
			||||||
                {
 | 
					                out << mValue << "/" << mMax;
 | 
				
			||||||
                    std::stringstream out;
 | 
					                static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption(out.str().c_str());
 | 
				
			||||||
                    out << mValue << "/" << mMax;
 | 
					 | 
				
			||||||
                    static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption(out.str().c_str());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    static_cast<MyGUI::TextBox*>(mBarTextWidget)->setCaption("");
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        void MWDynamicStat::setTitle(const std::string& text)
 | 
					        void MWDynamicStat::setTitle(const std::string& text)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,7 +133,7 @@ namespace MWGui
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
            MWAttribute();
 | 
					            MWAttribute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            typedef MWMechanics::Stat<int> AttributeValue;
 | 
					            typedef MWMechanics::AttributeValue AttributeValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void setAttributeId(int attributeId);
 | 
					            void setAttributeId(int attributeId);
 | 
				
			||||||
            void setAttributeValue(const AttributeValue& value);
 | 
					            void setAttributeValue(const AttributeValue& value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,12 +249,12 @@ namespace MWGui
 | 
				
			||||||
        // Setup player stats
 | 
					        // Setup player stats
 | 
				
			||||||
        for (int i = 0; i < ESM::Attribute::Length; ++i)
 | 
					        for (int i = 0; i < ESM::Attribute::Length; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mPlayerAttributes.insert(std::make_pair(ESM::Attribute::sAttributeIds[i], MWMechanics::Stat<int>()));
 | 
					            mPlayerAttributes.insert(std::make_pair(ESM::Attribute::sAttributeIds[i], MWMechanics::AttributeValue()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
					        for (int i = 0; i < ESM::Skill::Length; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            mPlayerSkillValues.insert(std::make_pair(ESM::Skill::sSkillIds[i], MWMechanics::Stat<float>()));
 | 
					            mPlayerSkillValues.insert(std::make_pair(ESM::Skill::sSkillIds[i], MWMechanics::SkillValue()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set up visibility
 | 
					        // Set up visibility
 | 
				
			||||||
| 
						 | 
					@ -544,7 +544,7 @@ namespace MWGui
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
 | 
					    void WindowManager::setValue (const std::string& id, const MWMechanics::AttributeValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mStatsWindow->setValue (id, value);
 | 
					        mStatsWindow->setValue (id, value);
 | 
				
			||||||
        mCharGen->setValue(id, value);
 | 
					        mCharGen->setValue(id, value);
 | 
				
			||||||
| 
						 | 
					@ -575,7 +575,7 @@ namespace MWGui
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void WindowManager::setValue (int parSkill, const MWMechanics::Stat<float>& value)
 | 
					    void WindowManager::setValue (int parSkill, const MWMechanics::SkillValue& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// \todo Don't use the skill enum as a parameter type (we will have to drop it anyway, once we
 | 
					        /// \todo Don't use the skill enum as a parameter type (we will have to drop it anyway, once we
 | 
				
			||||||
        /// allow custom skills.
 | 
					        /// allow custom skills.
 | 
				
			||||||
| 
						 | 
					@ -1178,12 +1178,12 @@ namespace MWGui
 | 
				
			||||||
        return mGuiModes.back();
 | 
					        return mGuiModes.back();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::map<int, MWMechanics::Stat<float> > WindowManager::getPlayerSkillValues()
 | 
					    std::map<int, MWMechanics::SkillValue > WindowManager::getPlayerSkillValues()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return mPlayerSkillValues;
 | 
					        return mPlayerSkillValues;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::map<int, MWMechanics::Stat<int> > WindowManager::getPlayerAttributeValues()
 | 
					    std::map<int, MWMechanics::AttributeValue > WindowManager::getPlayerAttributeValues()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return mPlayerAttributes;
 | 
					        return mPlayerAttributes;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,8 +152,8 @@ namespace MWGui
 | 
				
			||||||
    virtual void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount);
 | 
					    virtual void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ///< Set value for the given ID.
 | 
					    ///< Set value for the given ID.
 | 
				
			||||||
    virtual void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
 | 
					    virtual void setValue (const std::string& id, const MWMechanics::AttributeValue& value);
 | 
				
			||||||
    virtual void setValue (int parSkill, const MWMechanics::Stat<float>& value);
 | 
					    virtual void setValue (int parSkill, const MWMechanics::SkillValue& value);
 | 
				
			||||||
    virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
					    virtual void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
 | 
				
			||||||
    virtual void setValue (const std::string& id, const std::string& value);
 | 
					    virtual void setValue (const std::string& id, const std::string& value);
 | 
				
			||||||
    virtual void setValue (const std::string& id, int value);
 | 
					    virtual void setValue (const std::string& id, int value);
 | 
				
			||||||
| 
						 | 
					@ -229,8 +229,8 @@ namespace MWGui
 | 
				
			||||||
    virtual void onFrame (float frameDuration);
 | 
					    virtual void onFrame (float frameDuration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
 | 
					    /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
 | 
				
			||||||
    virtual std::map<int, MWMechanics::Stat<float> > getPlayerSkillValues();
 | 
					    virtual std::map<int, MWMechanics::SkillValue > getPlayerSkillValues();
 | 
				
			||||||
    virtual std::map<int, MWMechanics::Stat<int> > getPlayerAttributeValues();
 | 
					    virtual std::map<int, MWMechanics::AttributeValue > getPlayerAttributeValues();
 | 
				
			||||||
    virtual SkillList getPlayerMinorSkills();
 | 
					    virtual SkillList getPlayerMinorSkills();
 | 
				
			||||||
    virtual SkillList getPlayerMajorSkills();
 | 
					    virtual SkillList getPlayerMajorSkills();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,9 +346,9 @@ namespace MWGui
 | 
				
			||||||
    // Various stats about player as needed by window manager
 | 
					    // Various stats about player as needed by window manager
 | 
				
			||||||
    std::string mPlayerName;
 | 
					    std::string mPlayerName;
 | 
				
			||||||
    std::string mPlayerRaceId;
 | 
					    std::string mPlayerRaceId;
 | 
				
			||||||
    std::map<int, MWMechanics::Stat<int> > mPlayerAttributes;
 | 
					    std::map<int, MWMechanics::AttributeValue > mPlayerAttributes;
 | 
				
			||||||
    SkillList mPlayerMajorSkills, mPlayerMinorSkills;
 | 
					    SkillList mPlayerMajorSkills, mPlayerMinorSkills;
 | 
				
			||||||
    std::map<int, MWMechanics::Stat<float> > mPlayerSkillValues;
 | 
					    std::map<int, MWMechanics::SkillValue > mPlayerSkillValues;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MyGUI::Gui *mGui; // Gui
 | 
					    MyGUI::Gui *mGui; // Gui
 | 
				
			||||||
    std::vector<GuiMode> mGuiModes;
 | 
					    std::vector<GuiMode> mGuiModes;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,8 @@ namespace MWMechanics
 | 
				
			||||||
        return mSpells;
 | 
					        return mSpells;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ActiveSpells::addSpell(const std::string &id, bool stack, std::vector<Effect> effects, const std::string &displayName)
 | 
					    void ActiveSpells::addSpell(const std::string &id, bool stack, std::vector<Effect> effects,
 | 
				
			||||||
 | 
					                                const std::string &displayName, const std::string& casterHandle)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        bool exists = false;
 | 
					        bool exists = false;
 | 
				
			||||||
        for (TContainer::const_iterator it = begin(); it != end(); ++it)
 | 
					        for (TContainer::const_iterator it = begin(); it != end(); ++it)
 | 
				
			||||||
| 
						 | 
					@ -139,6 +140,7 @@ namespace MWMechanics
 | 
				
			||||||
        params.mTimeStamp = MWBase::Environment::get().getWorld()->getTimeStamp();
 | 
					        params.mTimeStamp = MWBase::Environment::get().getWorld()->getTimeStamp();
 | 
				
			||||||
        params.mEffects = effects;
 | 
					        params.mEffects = effects;
 | 
				
			||||||
        params.mDisplayName = displayName;
 | 
					        params.mDisplayName = displayName;
 | 
				
			||||||
 | 
					        params.mCasterHandle = casterHandle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!exists || stack)
 | 
					        if (!exists || stack)
 | 
				
			||||||
            mSpells.insert (std::make_pair(id, params));
 | 
					            mSpells.insert (std::make_pair(id, params));
 | 
				
			||||||
| 
						 | 
					@ -148,6 +150,12 @@ namespace MWMechanics
 | 
				
			||||||
        mSpellsChanged = true;
 | 
					        mSpellsChanged = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void ActiveSpells::removeEffects(const std::string &id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        mSpells.erase(Misc::StringUtils::lowerCase(id));
 | 
				
			||||||
 | 
					        mSpellsChanged = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const
 | 
					    void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (TContainer::const_iterator it = begin(); it != end(); ++it)
 | 
					        for (TContainer::const_iterator it = begin(); it != end(); ++it)
 | 
				
			||||||
| 
						 | 
					@ -164,14 +172,22 @@ namespace MWMechanics
 | 
				
			||||||
                float magnitude = effectIt->mMagnitude;
 | 
					                float magnitude = effectIt->mMagnitude;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (magnitude)
 | 
					                if (magnitude)
 | 
				
			||||||
                    visitor.visit(effectIt->mKey, name, magnitude, remainingTime);
 | 
					                    visitor.visit(effectIt->mKey, name, it->second.mCasterHandle, magnitude, remainingTime);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ActiveSpells::purgeAll()
 | 
					    void ActiveSpells::purgeAll(float chance)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mSpells.clear();
 | 
					        for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
 | 
				
			||||||
 | 
					            if (roll < chance)
 | 
				
			||||||
 | 
					                mSpells.erase(it++);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                ++it;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mSpellsChanged = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ActiveSpells::purgeEffect(short effectId)
 | 
					    void ActiveSpells::purgeEffect(short effectId)
 | 
				
			||||||
| 
						 | 
					@ -187,6 +203,6 @@ namespace MWMechanics
 | 
				
			||||||
                    effectIt++;
 | 
					                    effectIt++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        mSpellsChanged = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,8 +37,8 @@ namespace MWMechanics
 | 
				
			||||||
                MWWorld::TimeStamp mTimeStamp;
 | 
					                MWWorld::TimeStamp mTimeStamp;
 | 
				
			||||||
                std::string mDisplayName;
 | 
					                std::string mDisplayName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // TODO: To handle CASTER_LINKED flag (spell is purged when caster dies),
 | 
					                // Handle to the caster that that inflicted this spell on us
 | 
				
			||||||
                // we should probably store a handle to the caster here.
 | 
					                std::string mCasterHandle;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            typedef std::multimap<std::string, ActiveSpellParams > TContainer;
 | 
					            typedef std::multimap<std::string, ActiveSpellParams > TContainer;
 | 
				
			||||||
| 
						 | 
					@ -76,14 +76,19 @@ namespace MWMechanics
 | 
				
			||||||
            /// \param stack If false, the spell is not added if one with the same ID exists already.
 | 
					            /// \param stack If false, the spell is not added if one with the same ID exists already.
 | 
				
			||||||
            /// \param effects
 | 
					            /// \param effects
 | 
				
			||||||
            /// \param displayName Name for display in magic menu.
 | 
					            /// \param displayName Name for display in magic menu.
 | 
				
			||||||
 | 
					            /// \param casterHandle
 | 
				
			||||||
            ///
 | 
					            ///
 | 
				
			||||||
            void addSpell (const std::string& id, bool stack, std::vector<Effect> effects, const std::string& displayName);
 | 
					            void addSpell (const std::string& id, bool stack, std::vector<Effect> effects,
 | 
				
			||||||
 | 
					                           const std::string& displayName, const std::string& casterHandle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// Remove all active effects with this id
 | 
					            /// Removes the active effects from this spell/potion/.. with \a id
 | 
				
			||||||
 | 
					            void removeEffects (const std::string& id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// Remove all active effects with this effect id
 | 
				
			||||||
            void purgeEffect (short effectId);
 | 
					            void purgeEffect (short effectId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /// Remove all active effects
 | 
					            /// Remove all active effects, if roll succeeds (for each effect)
 | 
				
			||||||
            void purgeAll ();
 | 
					            void purgeAll (float chance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool isSpellActive (std::string id) const;
 | 
					            bool isSpellActive (std::string id) const;
 | 
				
			||||||
            ///< case insensitive
 | 
					            ///< case insensitive
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,6 +88,68 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MWMechanics
 | 
					namespace MWMechanics
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class SoulTrap : public MWMechanics::EffectSourceVisitor
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MWWorld::Ptr mCreature;
 | 
				
			||||||
 | 
					        MWWorld::Ptr mActor;
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        SoulTrap(MWWorld::Ptr trappedCreature)
 | 
				
			||||||
 | 
					            : mCreature(trappedCreature) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual void visit (MWMechanics::EffectKey key,
 | 
				
			||||||
 | 
					                                 const std::string& sourceName, const std::string& casterHandle,
 | 
				
			||||||
 | 
					                            float magnitude, float remainingTime = -1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (key.mId != ESM::MagicEffect::Soultrap)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            if (magnitude <= 0)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            MWBase::World* world = MWBase::Environment::get().getWorld();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            MWWorld::Ptr caster = world->searchPtrViaHandle(casterHandle);
 | 
				
			||||||
 | 
					            if (caster.isEmpty() || !caster.getClass().isActor())
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            static const float fSoulgemMult = world->getStore().get<ESM::GameSetting>().find("fSoulgemMult")->getFloat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            float creatureSoulValue = mCreature.get<ESM::Creature>()->mBase->mData.mSoul;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Use the smallest soulgem that is large enough to hold the soul
 | 
				
			||||||
 | 
					            MWWorld::ContainerStore& container = caster.getClass().getContainerStore(caster);
 | 
				
			||||||
 | 
					            MWWorld::ContainerStoreIterator gem = container.end();
 | 
				
			||||||
 | 
					            float gemCapacity = std::numeric_limits<float>().max();
 | 
				
			||||||
 | 
					            std::string soulgemFilter = "misc_soulgem"; // no other way to check for soulgems? :/
 | 
				
			||||||
 | 
					            for (MWWorld::ContainerStoreIterator it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous);
 | 
				
			||||||
 | 
					                 it != container.end(); ++it)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                const std::string& id = it->getCellRef().mRefID;
 | 
				
			||||||
 | 
					                if (id.size() >= soulgemFilter.size()
 | 
				
			||||||
 | 
					                        && id.substr(0,soulgemFilter.size()) == soulgemFilter)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    float thisGemCapacity = it->get<ESM::Miscellaneous>()->mBase->mData.mValue * fSoulgemMult;
 | 
				
			||||||
 | 
					                    if (thisGemCapacity >= creatureSoulValue && thisGemCapacity < gemCapacity
 | 
				
			||||||
 | 
					                            && it->getCellRef().mSoul.empty())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        gem = it;
 | 
				
			||||||
 | 
					                        gemCapacity = thisGemCapacity;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (gem == container.end())
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Set the soul on just one of the gems, not the whole stack
 | 
				
			||||||
 | 
					            gem->getContainerStore()->unstack(*gem, caster);
 | 
				
			||||||
 | 
					            gem->getCellRef().mSoul = mCreature.getCellRef().mRefID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (caster.getRefData().getHandle() == "player")
 | 
				
			||||||
 | 
					                MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
 | 
					    void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // magic effects
 | 
					        // magic effects
 | 
				
			||||||
| 
						 | 
					@ -216,7 +278,7 @@ namespace MWMechanics
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // the actor is sleeping, restore health and magicka
 | 
					            // the actor is sleeping, restore health and magicka
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
 | 
					            bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).mMagnitude > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            DynamicStat<float> health = stats.getHealth();
 | 
					            DynamicStat<float> health = stats.getHealth();
 | 
				
			||||||
            health.setCurrent (health.getCurrent() + 0.1 * endurance);
 | 
					            health.setCurrent (health.getCurrent() + 0.1 * endurance);
 | 
				
			||||||
| 
						 | 
					@ -255,7 +317,7 @@ namespace MWMechanics
 | 
				
			||||||
        // attributes
 | 
					        // attributes
 | 
				
			||||||
        for(int i = 0;i < ESM::Attribute::Length;++i)
 | 
					        for(int i = 0;i < ESM::Attribute::Length;++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Stat<int> stat = creatureStats.getAttribute(i);
 | 
					            AttributeValue stat = creatureStats.getAttribute(i);
 | 
				
			||||||
            stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).mMagnitude -
 | 
					            stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).mMagnitude -
 | 
				
			||||||
                             effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).mMagnitude -
 | 
					                             effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).mMagnitude -
 | 
				
			||||||
                             effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).mMagnitude);
 | 
					                             effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).mMagnitude);
 | 
				
			||||||
| 
						 | 
					@ -267,23 +329,23 @@ namespace MWMechanics
 | 
				
			||||||
        for(int i = 0;i < 3;++i)
 | 
					        for(int i = 0;i < 3;++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            DynamicStat<float> stat = creatureStats.getDynamic(i);
 | 
					            DynamicStat<float> stat = creatureStats.getDynamic(i);
 | 
				
			||||||
            stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyHealth+i)).mMagnitude -
 | 
					            stat.setModifier(effects.get(ESM::MagicEffect::FortifyHealth+i).mMagnitude -
 | 
				
			||||||
                             effects.get(EffectKey(ESM::MagicEffect::DrainHealth+i)).mMagnitude);
 | 
					                             effects.get(ESM::MagicEffect::DrainHealth+i).mMagnitude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            float currentDiff = creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::RestoreHealth+i)).mMagnitude
 | 
					            float currentDiff = creatureStats.getMagicEffects().get(ESM::MagicEffect::RestoreHealth+i).mMagnitude
 | 
				
			||||||
                    - creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::DamageHealth+i)).mMagnitude
 | 
					                    - creatureStats.getMagicEffects().get(ESM::MagicEffect::DamageHealth+i).mMagnitude
 | 
				
			||||||
                    - creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::AbsorbHealth+i)).mMagnitude;
 | 
					                    - creatureStats.getMagicEffects().get(ESM::MagicEffect::AbsorbHealth+i).mMagnitude;
 | 
				
			||||||
            stat.setCurrent(stat.getCurrent() + currentDiff * duration);
 | 
					            stat.setCurrent(stat.getCurrent() + currentDiff * duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            creatureStats.setDynamic(i, stat);
 | 
					            creatureStats.setDynamic(i, stat);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Apply disintegration (reduces item health)
 | 
					        // Apply disintegration (reduces item health)
 | 
				
			||||||
        float disintegrateWeapon = effects.get(EffectKey(ESM::MagicEffect::DisintegrateWeapon)).mMagnitude;
 | 
					        float disintegrateWeapon = effects.get(ESM::MagicEffect::DisintegrateWeapon).mMagnitude;
 | 
				
			||||||
        if (disintegrateWeapon > 0)
 | 
					        if (disintegrateWeapon > 0)
 | 
				
			||||||
            disintegrateSlot(ptr, MWWorld::InventoryStore::Slot_CarriedRight, disintegrateWeapon*duration);
 | 
					            disintegrateSlot(ptr, MWWorld::InventoryStore::Slot_CarriedRight, disintegrateWeapon*duration);
 | 
				
			||||||
        float disintegrateArmor = effects.get(EffectKey(ESM::MagicEffect::DisintegrateArmor)).mMagnitude;
 | 
					        float disintegrateArmor = effects.get(ESM::MagicEffect::DisintegrateArmor).mMagnitude;
 | 
				
			||||||
        if (disintegrateArmor > 0)
 | 
					        if (disintegrateArmor > 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // According to UESP
 | 
					            // According to UESP
 | 
				
			||||||
| 
						 | 
					@ -315,7 +377,7 @@ namespace MWMechanics
 | 
				
			||||||
        DynamicStat<float> health = creatureStats.getHealth();
 | 
					        DynamicStat<float> health = creatureStats.getHealth();
 | 
				
			||||||
        for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i)
 | 
					        for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            float magnitude = creatureStats.getMagicEffects().get(EffectKey(damageEffects[i])).mMagnitude;
 | 
					            float magnitude = creatureStats.getMagicEffects().get(damageEffects[i]).mMagnitude;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (damageEffects[i] == ESM::MagicEffect::SunDamage)
 | 
					            if (damageEffects[i] == ESM::MagicEffect::SunDamage)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -362,7 +424,7 @@ namespace MWMechanics
 | 
				
			||||||
        for (std::map<int, std::string>::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it)
 | 
					        for (std::map<int, std::string>::iterator it = boundItemsMap.begin(); it != boundItemsMap.end(); ++it)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end();
 | 
					            bool found = creatureStats.mBoundItems.find(it->first) != creatureStats.mBoundItems.end();
 | 
				
			||||||
            int magnitude = creatureStats.getMagicEffects().get(EffectKey(it->first)).mMagnitude;
 | 
					            int magnitude = creatureStats.getMagicEffects().get(it->first).mMagnitude;
 | 
				
			||||||
            if (found != (magnitude > 0))
 | 
					            if (found != (magnitude > 0))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                std::string item = "bound_" + it->second;
 | 
					                std::string item = "bound_" + it->second;
 | 
				
			||||||
| 
						 | 
					@ -410,7 +472,7 @@ namespace MWMechanics
 | 
				
			||||||
        for (std::map<int, std::string>::iterator it = summonMap.begin(); it != summonMap.end(); ++it)
 | 
					        for (std::map<int, std::string>::iterator it = summonMap.begin(); it != summonMap.end(); ++it)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bool found = creatureStats.mSummonedCreatures.find(it->first) != creatureStats.mSummonedCreatures.end();
 | 
					            bool found = creatureStats.mSummonedCreatures.find(it->first) != creatureStats.mSummonedCreatures.end();
 | 
				
			||||||
            int magnitude = creatureStats.getMagicEffects().get(EffectKey(it->first)).mMagnitude;
 | 
					            int magnitude = creatureStats.getMagicEffects().get(it->first).mMagnitude;
 | 
				
			||||||
            if (found != (magnitude > 0))
 | 
					            if (found != (magnitude > 0))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (magnitude > 0)
 | 
					                if (magnitude > 0)
 | 
				
			||||||
| 
						 | 
					@ -461,7 +523,7 @@ namespace MWMechanics
 | 
				
			||||||
        // skills
 | 
					        // skills
 | 
				
			||||||
        for(int i = 0;i < ESM::Skill::Length;++i)
 | 
					        for(int i = 0;i < ESM::Skill::Length;++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Stat<float>& skill = npcStats.getSkill(i);
 | 
					            SkillValue& skill = npcStats.getSkill(i);
 | 
				
			||||||
            skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).mMagnitude -
 | 
					            skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).mMagnitude -
 | 
				
			||||||
                             effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).mMagnitude -
 | 
					                             effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).mMagnitude -
 | 
				
			||||||
                             effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).mMagnitude);
 | 
					                             effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).mMagnitude);
 | 
				
			||||||
| 
						 | 
					@ -705,6 +767,13 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                iter->second->kill();
 | 
					                iter->second->kill();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Apply soultrap
 | 
				
			||||||
 | 
					                if (iter->first.getTypeName() == typeid(ESM::Creature).name())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    SoulTrap soulTrap (iter->first);
 | 
				
			||||||
 | 
					                    stats.getActiveSpells().visitEffectSources(soulTrap);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Reset magic effects and recalculate derived effects
 | 
					                // Reset magic effects and recalculate derived effects
 | 
				
			||||||
                // One case where we need this is to make sure bound items are removed upon death
 | 
					                // One case where we need this is to make sure bound items are removed upon death
 | 
				
			||||||
                stats.setMagicEffects(MWMechanics::MagicEffects());
 | 
					                stats.setMagicEffects(MWMechanics::MagicEffects());
 | 
				
			||||||
| 
						 | 
					@ -714,6 +783,7 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(cls.isEssential(iter->first))
 | 
					                if(cls.isEssential(iter->first))
 | 
				
			||||||
                    MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}");
 | 
					                    MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ namespace MWMechanics
 | 
				
			||||||
            - gmst.find ("fFatigueMult")->getFloat() * (1-normalised);
 | 
					            - gmst.find ("fFatigueMult")->getFloat() * (1-normalised);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const Stat<int> &CreatureStats::getAttribute(int index) const
 | 
					    const AttributeValue &CreatureStats::getAttribute(int index) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (index < 0 || index > 7) {
 | 
					        if (index < 0 || index > 7) {
 | 
				
			||||||
            throw std::runtime_error("attribute index is out of range");
 | 
					            throw std::runtime_error("attribute index is out of range");
 | 
				
			||||||
| 
						 | 
					@ -158,20 +158,20 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CreatureStats::setAttribute(int index, int base)
 | 
					    void CreatureStats::setAttribute(int index, int base)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWMechanics::Stat<int> current = getAttribute(index);
 | 
					        AttributeValue current = getAttribute(index);
 | 
				
			||||||
        current.setBase(base);
 | 
					        current.setBase(base);
 | 
				
			||||||
        setAttribute(index, current);
 | 
					        setAttribute(index, current);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CreatureStats::setAttribute(int index, const Stat<int> &value)
 | 
					    void CreatureStats::setAttribute(int index, const AttributeValue &value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (index < 0 || index > 7) {
 | 
					        if (index < 0 || index > 7) {
 | 
				
			||||||
            throw std::runtime_error("attribute index is out of range");
 | 
					            throw std::runtime_error("attribute index is out of range");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const Stat<int>& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
 | 
					        const AttributeValue& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (value.getModified() != currentValue.getModified())
 | 
					        if (value != currentValue)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (index != ESM::Attribute::Luck
 | 
					            if (index != ESM::Attribute::Luck
 | 
				
			||||||
                    && index != ESM::Attribute::Personality
 | 
					                    && index != ESM::Attribute::Personality
 | 
				
			||||||
| 
						 | 
					@ -228,8 +228,8 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CreatureStats::setMagicEffects(const MagicEffects &effects)
 | 
					    void CreatureStats::setMagicEffects(const MagicEffects &effects)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (effects.get(MWMechanics::EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude
 | 
					        if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).mMagnitude
 | 
				
			||||||
                != mMagicEffects.get(MWMechanics::EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude)
 | 
					                != mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).mMagnitude)
 | 
				
			||||||
            mRecalcDynamicStats = true;
 | 
					            mRecalcDynamicStats = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mMagicEffects = effects;
 | 
					        mMagicEffects = effects;
 | 
				
			||||||
| 
						 | 
					@ -266,8 +266,10 @@ namespace MWMechanics
 | 
				
			||||||
        if (mDead)
 | 
					        if (mDead)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (mDynamic[0].getCurrent()<1)
 | 
					            if (mDynamic[0].getCurrent()<1)
 | 
				
			||||||
                mDynamic[0].setCurrent (1);
 | 
					            {
 | 
				
			||||||
 | 
					                mDynamic[0].setModified(mDynamic[0].getModified(), 1);
 | 
				
			||||||
 | 
					                mDynamic[0].setCurrent(1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (mDynamic[0].getCurrent()>=1)
 | 
					            if (mDynamic[0].getCurrent()>=1)
 | 
				
			||||||
                mDead = false;
 | 
					                mDead = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -343,7 +345,7 @@ namespace MWMechanics
 | 
				
			||||||
        float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
 | 
					        float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
 | 
				
			||||||
                        (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
 | 
					                        (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
 | 
				
			||||||
        evasion *= getFatigueTerm();
 | 
					        evasion *= getFatigueTerm();
 | 
				
			||||||
        evasion += mMagicEffects.get(EffectKey(ESM::MagicEffect::Sanctuary)).mMagnitude;
 | 
					        evasion += mMagicEffects.get(ESM::MagicEffect::Sanctuary).mMagnitude;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return evasion;
 | 
					        return evasion;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ namespace MWMechanics
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    class CreatureStats
 | 
					    class CreatureStats
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Stat<int> mAttributes[8];
 | 
					        AttributeValue mAttributes[8];
 | 
				
			||||||
        DynamicStat<float> mDynamic[3]; // health, magicka, fatigue
 | 
					        DynamicStat<float> mDynamic[3]; // health, magicka, fatigue
 | 
				
			||||||
        int mLevel;
 | 
					        int mLevel;
 | 
				
			||||||
        Spells mSpells;
 | 
					        Spells mSpells;
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
        bool mIsWerewolf;
 | 
					        bool mIsWerewolf;
 | 
				
			||||||
        Stat<int> mWerewolfAttributes[8];
 | 
					        AttributeValue mWerewolfAttributes[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        CreatureStats();
 | 
					        CreatureStats();
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ namespace MWMechanics
 | 
				
			||||||
        bool canUsePower (const std::string& power) const;
 | 
					        bool canUsePower (const std::string& power) const;
 | 
				
			||||||
        void usePower (const std::string& power);
 | 
					        void usePower (const std::string& power);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const Stat<int> & getAttribute(int index) const;
 | 
					        const AttributeValue & getAttribute(int index) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const DynamicStat<float> & getHealth() const;
 | 
					        const DynamicStat<float> & getHealth() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MagicEffects & getMagicEffects();
 | 
					        MagicEffects & getMagicEffects();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setAttribute(int index, const Stat<int> &value);
 | 
					        void setAttribute(int index, const AttributeValue &value);
 | 
				
			||||||
        // Shortcut to set only the base
 | 
					        // Shortcut to set only the base
 | 
				
			||||||
        void setAttribute(int index, int base);
 | 
					        void setAttribute(int index, int base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,8 @@ namespace MWMechanics
 | 
				
			||||||
    struct EffectSourceVisitor
 | 
					    struct EffectSourceVisitor
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        virtual void visit (MWMechanics::EffectKey key,
 | 
					        virtual void visit (MWMechanics::EffectKey key,
 | 
				
			||||||
                                 const std::string& sourceName, float magnitude, float remainingTime = -1) = 0;
 | 
					                                 const std::string& sourceName, const std::string& casterHandle,
 | 
				
			||||||
 | 
					                            float magnitude, float remainingTime = -1) = 0;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// \brief Effects currently affecting a NPC or creature
 | 
					    /// \brief Effects currently affecting a NPC or creature
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -499,10 +499,10 @@ namespace MWMechanics
 | 
				
			||||||
        // otherwise one would get different prices when exiting and re-entering the dialogue window...
 | 
					        // otherwise one would get different prices when exiting and re-entering the dialogue window...
 | 
				
			||||||
        int clampedDisposition = std::max(0, std::min(getDerivedDisposition(ptr)
 | 
					        int clampedDisposition = std::max(0, std::min(getDerivedDisposition(ptr)
 | 
				
			||||||
            + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange(),100));
 | 
					            + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange(),100));
 | 
				
			||||||
        float a = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
 | 
					        float a = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
				
			||||||
        float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
					        float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
				
			||||||
        float c = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
					        float c = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
				
			||||||
        float d = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100.f);
 | 
					        float d = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
				
			||||||
        float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
					        float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
 | 
				
			||||||
        float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
					        float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ void MWMechanics::NpcStats::setMovementFlag (Flag flag, bool state)
 | 
				
			||||||
        mMovementFlags &= ~flag;
 | 
					        mMovementFlags &= ~flag;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index) const
 | 
					const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index<0 || index>=ESM::Skill::Length)
 | 
					    if (index<0 || index>=ESM::Skill::Length)
 | 
				
			||||||
        throw std::runtime_error ("skill index out of range");
 | 
					        throw std::runtime_error ("skill index out of range");
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@ const MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index) cons
 | 
				
			||||||
    return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
 | 
					    return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index)
 | 
					MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (index<0 || index>=ESM::Skill::Length)
 | 
					    if (index<0 || index>=ESM::Skill::Length)
 | 
				
			||||||
        throw std::runtime_error ("skill index out of range");
 | 
					        throw std::runtime_error ("skill index out of range");
 | 
				
			||||||
| 
						 | 
					@ -197,34 +197,25 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
 | 
				
			||||||
    if(mIsWerewolf)
 | 
					    if(mIsWerewolf)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    float base = getSkill (skillIndex).getBase();
 | 
					    MWMechanics::SkillValue value = getSkill (skillIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int level = static_cast<int> (base);
 | 
					    value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    base += getSkillGain (skillIndex, class_, usageType);
 | 
					    if (value.getProgress()>=1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (static_cast<int> (base)!=level)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // skill leveled up
 | 
					        // skill leveled up
 | 
				
			||||||
        increaseSkill(skillIndex, class_, false);
 | 
					        increaseSkill(skillIndex, class_, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        getSkill (skillIndex).setBase (base);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &class_, bool preserveProgress)
 | 
					void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &class_, bool preserveProgress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    float base = getSkill (skillIndex).getBase();
 | 
					    int base = getSkill (skillIndex).getBase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int level = static_cast<int> (base);
 | 
					    if (base >= 100)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (level >= 100)
 | 
					 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (preserveProgress)
 | 
					    base += 1;
 | 
				
			||||||
        base += 1;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        base = level+1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // if this is a major or minor skill of the class, increase level progress
 | 
					    // if this is a major or minor skill of the class, increase level progress
 | 
				
			||||||
    bool levelProgress = false;
 | 
					    bool levelProgress = false;
 | 
				
			||||||
| 
						 | 
					@ -260,6 +251,8 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getSkill (skillIndex).setBase (base);
 | 
					    getSkill (skillIndex).setBase (base);
 | 
				
			||||||
 | 
					    if (!preserveProgress)
 | 
				
			||||||
 | 
					        getSkill(skillIndex).setProgress(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int MWMechanics::NpcStats::getLevelProgress () const
 | 
					int MWMechanics::NpcStats::getLevelProgress () const
 | 
				
			||||||
| 
						 | 
					@ -387,7 +380,7 @@ void MWMechanics::NpcStats::setWerewolf (bool set)
 | 
				
			||||||
            // Oh, Bethesda. It's "Intelligence".
 | 
					            // Oh, Bethesda. It's "Intelligence".
 | 
				
			||||||
            std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") :
 | 
					            std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") :
 | 
				
			||||||
                                            ESM::Attribute::sAttributeNames[i]);
 | 
					                                            ESM::Attribute::sAttributeNames[i]);
 | 
				
			||||||
            mWerewolfAttributes[i].setModified(int(gmst.find(name)->getFloat()), 0);
 | 
					            mWerewolfAttributes[i].setBase(int(gmst.find(name)->getFloat()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(size_t i = 0;i < ESM::Skill::Length;i++)
 | 
					        for(size_t i = 0;i < ESM::Skill::Length;i++)
 | 
				
			||||||
| 
						 | 
					@ -401,7 +394,7 @@ void MWMechanics::NpcStats::setWerewolf (bool set)
 | 
				
			||||||
            // "Mercantile"! >_<
 | 
					            // "Mercantile"! >_<
 | 
				
			||||||
            std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
 | 
					            std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
 | 
				
			||||||
                                            ESM::Skill::sSkillNames[i]);
 | 
					                                            ESM::Skill::sSkillNames[i]);
 | 
				
			||||||
            mWerewolfSkill[i].setModified(int(gmst.find(name)->getFloat()), 0);
 | 
					            mWerewolfSkill[i].setBase(int(gmst.find(name)->getFloat()));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mIsWerewolf = set;
 | 
					    mIsWerewolf = set;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,8 +45,8 @@ namespace MWMechanics
 | 
				
			||||||
            DrawState_ mDrawState;
 | 
					            DrawState_ mDrawState;
 | 
				
			||||||
            int mDisposition;
 | 
					            int mDisposition;
 | 
				
			||||||
            unsigned int mMovementFlags;
 | 
					            unsigned int mMovementFlags;
 | 
				
			||||||
            Stat<float> mSkill[27];
 | 
					            SkillValue mSkill[27];
 | 
				
			||||||
            Stat<float> mWerewolfSkill[27];
 | 
					            SkillValue mWerewolfSkill[27];
 | 
				
			||||||
            int mBounty;
 | 
					            int mBounty;
 | 
				
			||||||
            std::set<std::string> mExpelled;
 | 
					            std::set<std::string> mExpelled;
 | 
				
			||||||
            std::map<std::string, int> mFactionReputation;
 | 
					            std::map<std::string, int> mFactionReputation;
 | 
				
			||||||
| 
						 | 
					@ -94,8 +94,8 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void setMovementFlag (Flag flag, bool state);
 | 
					            void setMovementFlag (Flag flag, bool state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const Stat<float>& getSkill (int index) const;
 | 
					            const SkillValue& getSkill (int index) const;
 | 
				
			||||||
            Stat<float>& getSkill (int index);
 | 
					            SkillValue& getSkill (int index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const std::map<std::string, int>& getFactionRanks() const;
 | 
					            const std::map<std::string, int>& getFactionRanks() const;
 | 
				
			||||||
            std::map<std::string, int>& getFactionRanks();
 | 
					            std::map<std::string, int>& getFactionRanks();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,21 +24,13 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
 | 
				
			||||||
    MWWorld::LiveCellRef<ESM::Repair> *ref =
 | 
					    MWWorld::LiveCellRef<ESM::Repair> *ref =
 | 
				
			||||||
        mTool.get<ESM::Repair>();
 | 
					        mTool.get<ESM::Repair>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // unstack tool if required
 | 
				
			||||||
 | 
					    player.getClass().getContainerStore(player).unstack(mTool, player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // reduce number of uses left
 | 
					    // reduce number of uses left
 | 
				
			||||||
    int uses = (mTool.getCellRef().mCharge != -1) ? mTool.getCellRef().mCharge : ref->mBase->mData.mUses;
 | 
					    int uses = (mTool.getCellRef().mCharge != -1) ? mTool.getCellRef().mCharge : ref->mBase->mData.mUses;
 | 
				
			||||||
    mTool.getCellRef().mCharge = uses-1;
 | 
					    mTool.getCellRef().mCharge = uses-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // unstack tool if required
 | 
					 | 
				
			||||||
    if (mTool.getRefData().getCount() > 1 && uses == ref->mBase->mData.mUses)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
 | 
					 | 
				
			||||||
        MWWorld::ContainerStoreIterator it = store.add(mTool, player);
 | 
					 | 
				
			||||||
        it->getRefData().setCount(mTool.getRefData().getCount()-1);
 | 
					 | 
				
			||||||
        it->getCellRef().mCharge = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        mTool.getRefData().setCount(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
 | 
					    MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
 | 
				
			||||||
    MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats(player);
 | 
					    MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,7 +135,8 @@ namespace MWMechanics
 | 
				
			||||||
                float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
 | 
					                float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
 | 
				
			||||||
                magnitude *= magnitudeMult;
 | 
					                magnitude *= magnitudeMult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (target.getClass().isActor() && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
 | 
					                bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration);
 | 
				
			||||||
 | 
					                if (target.getClass().isActor() && hasDuration)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    ActiveSpells::Effect effect;
 | 
					                    ActiveSpells::Effect effect;
 | 
				
			||||||
                    effect.mKey = MWMechanics::EffectKey(*effectIt);
 | 
					                    effect.mKey = MWMechanics::EffectKey(*effectIt);
 | 
				
			||||||
| 
						 | 
					@ -154,12 +155,23 @@ namespace MWMechanics
 | 
				
			||||||
                            ActiveSpells::Effect effect_ = effect;
 | 
					                            ActiveSpells::Effect effect_ = effect;
 | 
				
			||||||
                            effect_.mMagnitude *= -1;
 | 
					                            effect_.mMagnitude *= -1;
 | 
				
			||||||
                            effects.push_back(effect_);
 | 
					                            effects.push_back(effect_);
 | 
				
			||||||
                            caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true, effects, mSourceName);
 | 
					                            caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true,
 | 
				
			||||||
 | 
					                                        effects, mSourceName, caster.getRefData().getHandle());
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    applyInstantEffect(target, effectIt->mEffectID, magnitude);
 | 
					                    applyInstantEffect(target, EffectKey(*effectIt), magnitude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // HACK: Damage attribute/skill actually has a duration, even though the actual effect is instant and permanent.
 | 
				
			||||||
 | 
					                // This was probably just done to have the effect visible in the magic menu for a while
 | 
				
			||||||
 | 
					                // to notify the player they've been damaged?
 | 
				
			||||||
 | 
					                if (effectIt->mEffectID == ESM::MagicEffect::DamageAttribute
 | 
				
			||||||
 | 
					                        || effectIt->mEffectID == ESM::MagicEffect::DamageSkill
 | 
				
			||||||
 | 
					                        || effectIt->mEffectID == ESM::MagicEffect::RestoreAttribute
 | 
				
			||||||
 | 
					                        || effectIt->mEffectID == ESM::MagicEffect::RestoreSkill
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    applyInstantEffect(target, EffectKey(*effectIt), magnitude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)
 | 
					                if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -198,11 +210,13 @@ namespace MWMechanics
 | 
				
			||||||
            inflict(caster, target, reflectedEffects, range, true);
 | 
					            inflict(caster, target, reflectedEffects, range, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (appliedLastingEffects.size())
 | 
					        if (appliedLastingEffects.size())
 | 
				
			||||||
            target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects, mSourceName);
 | 
					            target.getClass().getCreatureStats(target).getActiveSpells().addSpell(mId, mStack, appliedLastingEffects,
 | 
				
			||||||
 | 
					                                                                                  mSourceName, caster.getRefData().getHandle());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, short effectId, float magnitude)
 | 
					    void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, MWMechanics::EffectKey effect, float magnitude)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        short effectId = effect.mId;
 | 
				
			||||||
        if (!target.getClass().isActor())
 | 
					        if (!target.getClass().isActor())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (effectId == ESM::MagicEffect::Lock)
 | 
					            if (effectId == ESM::MagicEffect::Lock)
 | 
				
			||||||
| 
						 | 
					@ -225,6 +239,28 @@ namespace MWMechanics
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (effectId == ESM::MagicEffect::DamageAttribute || effectId == ESM::MagicEffect::RestoreAttribute)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int attribute = effect.mArg;
 | 
				
			||||||
 | 
					                AttributeValue value = target.getClass().getCreatureStats(target).getAttribute(attribute);
 | 
				
			||||||
 | 
					                if (effectId == ESM::MagicEffect::DamageAttribute)
 | 
				
			||||||
 | 
					                    value.damage(magnitude);
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    value.restore(magnitude);
 | 
				
			||||||
 | 
					                target.getClass().getCreatureStats(target).setAttribute(attribute, value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (effectId == ESM::MagicEffect::DamageSkill || effectId == ESM::MagicEffect::RestoreSkill)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (target.getTypeName() != typeid(ESM::NPC).name())
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                int skill = effect.mArg;
 | 
				
			||||||
 | 
					                SkillValue& value = target.getClass().getNpcStats(target).getSkill(skill);
 | 
				
			||||||
 | 
					                if (effectId == ESM::MagicEffect::DamageSkill)
 | 
				
			||||||
 | 
					                    value.damage(magnitude);
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    value.restore(magnitude);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (effectId == ESM::MagicEffect::CurePoison)
 | 
					            if (effectId == ESM::MagicEffect::CurePoison)
 | 
				
			||||||
                target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
 | 
					                target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
 | 
				
			||||||
            else if (effectId == ESM::MagicEffect::CureParalyzation)
 | 
					            else if (effectId == ESM::MagicEffect::CureParalyzation)
 | 
				
			||||||
| 
						 | 
					@ -236,7 +272,7 @@ namespace MWMechanics
 | 
				
			||||||
            else if (effectId == ESM::MagicEffect::CureCorprusDisease)
 | 
					            else if (effectId == ESM::MagicEffect::CureCorprusDisease)
 | 
				
			||||||
                target.getClass().getCreatureStats(target).getSpells().purgeCorprusDisease();
 | 
					                target.getClass().getCreatureStats(target).getSpells().purgeCorprusDisease();
 | 
				
			||||||
            else if (effectId == ESM::MagicEffect::Dispel)
 | 
					            else if (effectId == ESM::MagicEffect::Dispel)
 | 
				
			||||||
                target.getClass().getCreatureStats(target).getActiveSpells().purgeAll();
 | 
					                target.getClass().getCreatureStats(target).getActiveSpells().purgeAll(magnitude);
 | 
				
			||||||
            else if (effectId == ESM::MagicEffect::RemoveCurse)
 | 
					            else if (effectId == ESM::MagicEffect::RemoveCurse)
 | 
				
			||||||
                target.getClass().getCreatureStats(target).getSpells().purgeCurses();
 | 
					                target.getClass().getCreatureStats(target).getSpells().purgeCurses();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -398,7 +434,8 @@ namespace MWMechanics
 | 
				
			||||||
            int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
 | 
					            int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
 | 
				
			||||||
            if (!fail && roll >= successChance)
 | 
					            if (!fail && roll >= successChance)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}");
 | 
					                if (mCaster.getRefData().getHandle() == "player")
 | 
				
			||||||
 | 
					                    MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}");
 | 
				
			||||||
                fail = true;
 | 
					                fail = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,7 +203,7 @@ namespace MWMechanics
 | 
				
			||||||
        void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,
 | 
					        void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,
 | 
				
			||||||
                      const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false);
 | 
					                      const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void applyInstantEffect (const MWWorld::Ptr& target, short effectId, float magnitude);
 | 
					        void applyInstantEffect (const MWWorld::Ptr& target, MWMechanics::EffectKey effect, float magnitude);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,13 +34,14 @@ namespace MWMechanics
 | 
				
			||||||
            random.resize(spell->mEffects.mList.size());
 | 
					            random.resize(spell->mEffects.mList.size());
 | 
				
			||||||
            for (unsigned int i=0; i<random.size();++i)
 | 
					            for (unsigned int i=0; i<random.size();++i)
 | 
				
			||||||
                random[i] = static_cast<float> (std::rand()) / RAND_MAX;
 | 
					                random[i] = static_cast<float> (std::rand()) / RAND_MAX;
 | 
				
			||||||
            mSpells.insert (std::make_pair (spellId, random));
 | 
					            mSpells.insert (std::make_pair (Misc::StringUtils::lowerCase(spellId), random));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Spells::remove (const std::string& spellId)
 | 
					    void Spells::remove (const std::string& spellId)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        TContainer::iterator iter = mSpells.find (spellId);
 | 
					        std::string lower = Misc::StringUtils::lowerCase(spellId);
 | 
				
			||||||
 | 
					        TContainer::iterator iter = mSpells.find (lower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (iter!=mSpells.end())
 | 
					        if (iter!=mSpells.end())
 | 
				
			||||||
            mSpells.erase (iter);
 | 
					            mSpells.erase (iter);
 | 
				
			||||||
| 
						 | 
					@ -192,7 +193,7 @@ namespace MWMechanics
 | 
				
			||||||
                 effectIt != list.mList.end(); ++effectIt, ++i)
 | 
					                 effectIt != list.mList.end(); ++effectIt, ++i)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * it->second[i];
 | 
					                float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * it->second[i];
 | 
				
			||||||
                visitor.visit(MWMechanics::EffectKey(*effectIt), spell->mName, magnitude);
 | 
					                visitor.visit(MWMechanics::EffectKey(*effectIt), spell->mName, "", magnitude);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,6 +205,46 @@ namespace MWMechanics
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return !(left==right);
 | 
					        return !(left==right);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class AttributeValue
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int mBase;
 | 
				
			||||||
 | 
					        int mModifier;
 | 
				
			||||||
 | 
					        int mDamage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        AttributeValue() : mBase(0), mModifier(0), mDamage(0) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int getModified() const { return std::max(0, mBase - mDamage + mModifier); }
 | 
				
			||||||
 | 
					        int getBase() const { return mBase; }
 | 
				
			||||||
 | 
					        int getModifier() const {  return mModifier; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void setBase(int base) { mBase = std::max(0, base); }
 | 
				
			||||||
 | 
					        void setModifier(int mod) { mModifier = mod; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void damage(int damage) { mDamage += damage; }
 | 
				
			||||||
 | 
					        void restore(int amount) { mDamage -= std::min(mDamage, amount); }
 | 
				
			||||||
 | 
					        int getDamage() const { return mDamage; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class SkillValue : public AttributeValue
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        float mProgress;
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        float getProgress() const { return mProgress; }
 | 
				
			||||||
 | 
					        void setProgress(float progress) { mProgress = progress; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline bool operator== (const AttributeValue& left, const AttributeValue& right)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return left.getBase() == right.getBase()
 | 
				
			||||||
 | 
					                && left.getModifier() == right.getModifier()
 | 
				
			||||||
 | 
					                && left.getDamage() == right.getDamage();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    inline bool operator!= (const AttributeValue& left, const AttributeValue& right)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return !(left == right);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -664,11 +664,12 @@ void NpcAnimation::showCarriedLeft(bool show)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Ogre::Vector3 glowColor = getEnchantmentColor(*iter);
 | 
					        Ogre::Vector3 glowColor = getEnchantmentColor(*iter);
 | 
				
			||||||
        std::string mesh = MWWorld::Class::get(*iter).getModel(*iter);
 | 
					        std::string mesh = MWWorld::Class::get(*iter).getModel(*iter);
 | 
				
			||||||
        addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
 | 
					        if (addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
 | 
				
			||||||
                                   mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor);
 | 
					                                   mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
        if (iter->getTypeName() == typeid(ESM::Light).name())
 | 
					            if (iter->getTypeName() == typeid(ESM::Light).name())
 | 
				
			||||||
            addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], iter->get<ESM::Light>()->mBase);
 | 
					                addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], iter->get<ESM::Light>()->mBase);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        removeIndividualPart(ESM::PRT_Shield);
 | 
					        removeIndividualPart(ESM::PRT_Shield);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,7 +328,7 @@ void RenderingManager::update (float duration, bool paused)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWWorld::Ptr player = world->getPlayer().getPlayer();
 | 
					    MWWorld::Ptr player = world->getPlayer().getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
 | 
					    int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
 | 
				
			||||||
    mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f)));
 | 
					    mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f)));
 | 
				
			||||||
    setAmbientMode();
 | 
					    setAmbientMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,7 +593,7 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour)
 | 
				
			||||||
    mAmbientColor = colour;
 | 
					    mAmbientColor = colour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
 | 
					    MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
 | 
				
			||||||
    int nightEye = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::NightEye)).mMagnitude;
 | 
					    int nightEye = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).mMagnitude;
 | 
				
			||||||
    Ogre::ColourValue final = colour;
 | 
					    Ogre::ColourValue final = colour;
 | 
				
			||||||
    final += Ogre::ColourValue(0.7,0.7,0.7,0) * std::min(1.f, (nightEye/100.f));
 | 
					    final += Ogre::ColourValue(0.7,0.7,0.7,0) * std::min(1.f, (nightEye/100.f));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -358,5 +358,14 @@ op 0x2000223: GetLineOfSightExplicit
 | 
				
			||||||
op 0x2000224: ToggleAI
 | 
					op 0x2000224: ToggleAI
 | 
				
			||||||
op 0x2000225: ToggleAIExplicit
 | 
					op 0x2000225: ToggleAIExplicit
 | 
				
			||||||
op 0x2000226: COE
 | 
					op 0x2000226: COE
 | 
				
			||||||
 | 
					op 0x2000227: Cast
 | 
				
			||||||
opcodes 0x2000227-0x3ffffff unused
 | 
					op 0x2000228: Cast, explicit
 | 
				
			||||||
 | 
					op 0x2000229: ExplodeSpell
 | 
				
			||||||
 | 
					op 0x200022a: ExplodeSpell, explicit
 | 
				
			||||||
 | 
					op 0x200022b: RemoveSpellEffects
 | 
				
			||||||
 | 
					op 0x200022c: RemoveSpellEffects, explicit
 | 
				
			||||||
 | 
					op 0x200022d: RemoveEffects
 | 
				
			||||||
 | 
					op 0x200022e: RemoveEffects, explicit
 | 
				
			||||||
 | 
					op 0x200022f: Resurrect
 | 
				
			||||||
 | 
					op 0x2000230: Resurrect, explicit
 | 
				
			||||||
 | 
					opcodes 0x200022f-0x3ffffff unused
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../mwmechanics/npcstats.hpp"
 | 
					#include "../mwmechanics/npcstats.hpp"
 | 
				
			||||||
#include "../mwmechanics/creaturestats.hpp"
 | 
					#include "../mwmechanics/creaturestats.hpp"
 | 
				
			||||||
 | 
					#include "../mwmechanics/spellcasting.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "interpretercontext.hpp"
 | 
					#include "interpretercontext.hpp"
 | 
				
			||||||
#include "ref.hpp"
 | 
					#include "ref.hpp"
 | 
				
			||||||
| 
						 | 
					@ -700,6 +701,42 @@ namespace MWScript
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template <class R>
 | 
				
			||||||
 | 
					        class OpCast : public Interpreter::Opcode0
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        public:
 | 
				
			||||||
 | 
					            virtual void execute (Interpreter::Runtime& runtime)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                std::string spell = runtime.getStringLiteral (runtime[0].mInteger);
 | 
				
			||||||
 | 
					                runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                std::string targetId = ::Misc::StringUtils::lowerCase(runtime.getStringLiteral (runtime[0].mInteger));
 | 
				
			||||||
 | 
					                runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr (targetId, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                MWMechanics::CastSpell cast(ptr, target);
 | 
				
			||||||
 | 
					                cast.cast(spell);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template <class R>
 | 
				
			||||||
 | 
					        class OpExplodeSpell : public Interpreter::Opcode0
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        public:
 | 
				
			||||||
 | 
					            virtual void execute (Interpreter::Runtime& runtime)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                std::string spell = runtime.getStringLiteral (runtime[0].mInteger);
 | 
				
			||||||
 | 
					                runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                MWMechanics::CastSpell cast(ptr, ptr);
 | 
				
			||||||
 | 
					                cast.cast(spell);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void installOpcodes (Interpreter::Interpreter& interpreter)
 | 
					        void installOpcodes (Interpreter::Interpreter& interpreter)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -761,6 +798,10 @@ namespace MWScript
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode);
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode);
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation<false>);
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation<false>);
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation<true>);
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation<true>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeCast, new OpCast<ImplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeCastExplicit, new OpCast<ExplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeExplodeSpell, new OpExplodeSpell<ImplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Misc::opcodeExplodeSpellExplicit, new OpExplodeSpell<ExplicitRef>);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,8 +124,8 @@ namespace MWScript
 | 
				
			||||||
                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
					                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
				
			||||||
                    runtime.pop();
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWMechanics::Stat<int> attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
 | 
					                    MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
 | 
				
			||||||
                    attribute.setModified (value, 0);
 | 
					                    attribute.setBase (value - (attribute.getModified() - attribute.getBase()));
 | 
				
			||||||
                    ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | 
					                    ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -146,15 +146,11 @@ namespace MWScript
 | 
				
			||||||
                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
					                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
				
			||||||
                    runtime.pop();
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWMechanics::Stat<int> attribute = MWWorld::Class::get(ptr)
 | 
					                    MWMechanics::AttributeValue attribute = MWWorld::Class::get(ptr)
 | 
				
			||||||
                        .getCreatureStats(ptr)
 | 
					                        .getCreatureStats(ptr)
 | 
				
			||||||
                        .getAttribute(mIndex);
 | 
					                        .getAttribute(mIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    value +=
 | 
					                    attribute.setBase (std::min(100, attribute.getBase() + value));
 | 
				
			||||||
                            attribute.getModified();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    attribute
 | 
					 | 
				
			||||||
                        .setModified (value, 0, 100);
 | 
					 | 
				
			||||||
                    ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | 
					                    ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -346,12 +342,10 @@ namespace MWScript
 | 
				
			||||||
                    const ESM::Class& class_ =
 | 
					                    const ESM::Class& class_ =
 | 
				
			||||||
                        *MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (ref->mBase->mClass);
 | 
					                        *MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (ref->mBase->mClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    float level = 0;
 | 
					                    float level = stats.getSkill(mIndex).getBase();
 | 
				
			||||||
                    float progress = std::modf (stats.getSkill (mIndex).getBase(), &level);
 | 
					                    float progress = stats.getSkill(mIndex).getProgress();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    float modifier = stats.getSkill (mIndex).getModifier();
 | 
					                    int newLevel = value - (stats.getSkill(mIndex).getModified() - stats.getSkill(mIndex).getBase());
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    int newLevel = static_cast<int> (value-modifier);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (newLevel<0)
 | 
					                    if (newLevel<0)
 | 
				
			||||||
                        newLevel = 0;
 | 
					                        newLevel = 0;
 | 
				
			||||||
| 
						 | 
					@ -362,8 +356,8 @@ namespace MWScript
 | 
				
			||||||
                    if (progress>=1)
 | 
					                    if (progress>=1)
 | 
				
			||||||
                        progress = 0.999999999;
 | 
					                        progress = 0.999999999;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    stats.getSkill (mIndex).set (newLevel + progress);
 | 
					                    stats.getSkill (mIndex).setBase (newLevel);
 | 
				
			||||||
                    stats.getSkill (mIndex).setModifier (modifier);
 | 
					                    stats.getSkill (mIndex).setProgress(progress);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,11 +377,10 @@ namespace MWScript
 | 
				
			||||||
                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
					                    Interpreter::Type_Integer value = runtime[0].mInteger;
 | 
				
			||||||
                    runtime.pop();
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    value += MWWorld::Class::get (ptr).getNpcStats (ptr).getSkill (mIndex).
 | 
					                    MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats(ptr);
 | 
				
			||||||
                        getModified();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    MWWorld::Class::get (ptr).getNpcStats (ptr).getSkill (mIndex).
 | 
					                    stats.getSkill(mIndex).
 | 
				
			||||||
                        setModified (value, 0, 100);
 | 
					                        setBase (std::min(100, stats.getSkill(mIndex).getBase() + value));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -466,6 +459,38 @@ namespace MWScript
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template<class R>
 | 
				
			||||||
 | 
					        class OpRemoveSpellEffects : public Interpreter::Opcode0
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                virtual void execute (Interpreter::Runtime& runtime)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    std::string spellid = runtime.getStringLiteral (runtime[0].mInteger);
 | 
				
			||||||
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    MWWorld::Class::get (ptr).getCreatureStats (ptr).getActiveSpells().removeEffects(spellid);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template<class R>
 | 
				
			||||||
 | 
					        class OpRemoveEffects : public Interpreter::Opcode0
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                virtual void execute (Interpreter::Runtime& runtime)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Interpreter::Type_Integer effectId = runtime[0].mInteger;
 | 
				
			||||||
 | 
					                    runtime.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    MWWorld::Class::get (ptr).getCreatureStats (ptr).getActiveSpells().purgeEffect(effectId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        template<class R>
 | 
					        template<class R>
 | 
				
			||||||
        class OpGetSpell : public Interpreter::Opcode0
 | 
					        class OpGetSpell : public Interpreter::Opcode0
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -1079,6 +1104,18 @@ namespace MWScript
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template <class R>
 | 
				
			||||||
 | 
					        class OpResurrect : public Interpreter::Opcode0
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                virtual void execute (Interpreter::Runtime& runtime)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    MWWorld::Ptr ptr = R()(runtime);
 | 
				
			||||||
 | 
					                    ptr.getClass().getCreatureStats(ptr).resurrect();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void installOpcodes (Interpreter::Interpreter& interpreter)
 | 
					        void installOpcodes (Interpreter::Interpreter& interpreter)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
 | 
					            for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
 | 
				
			||||||
| 
						 | 
					@ -1142,6 +1179,15 @@ namespace MWScript
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>);
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>);
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellExplicit,
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellExplicit,
 | 
				
			||||||
                new OpRemoveSpell<ExplicitRef>);
 | 
					                new OpRemoveSpell<ExplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellEffects, new OpRemoveSpellEffects<ImplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellEffectsExplicit,
 | 
				
			||||||
 | 
					                new OpRemoveSpellEffects<ExplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeResurrect, new OpResurrect<ImplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeResurrectExplicit,
 | 
				
			||||||
 | 
					                new OpResurrect<ExplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveEffects, new OpRemoveEffects<ImplicitRef>);
 | 
				
			||||||
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeRemoveEffectsExplicit,
 | 
				
			||||||
 | 
					                new OpRemoveEffects<ExplicitRef>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Stats::opcodeGetSpell, new OpGetSpell<ImplicitRef>);
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeGetSpell, new OpGetSpell<ImplicitRef>);
 | 
				
			||||||
            interpreter.installSegment5 (Compiler::Stats::opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
 | 
					            interpreter.installSegment5 (Compiler::Stats::opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -607,7 +607,7 @@ void MWWorld::InventoryStore::visitEffectSources(MWMechanics::EffectSourceVisito
 | 
				
			||||||
            const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID][i];
 | 
					            const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID][i];
 | 
				
			||||||
            float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom;
 | 
					            float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom;
 | 
				
			||||||
            magnitude *= params.mMultiplier;
 | 
					            magnitude *= params.mMultiplier;
 | 
				
			||||||
            visitor.visit(MWMechanics::EffectKey(*effectIt), (**iter).getClass().getName(**iter), magnitude);
 | 
					            visitor.visit(MWMechanics::EffectKey(*effectIt), (**iter).getClass().getName(**iter), "", magnitude);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ++i;
 | 
					            ++i;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1606,7 +1606,8 @@ namespace MWWorld
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
 | 
					        const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
 | 
				
			||||||
        if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Levitate)).mMagnitude > 0)
 | 
					        if(stats.getMagicEffects().get(ESM::MagicEffect::Levitate).mMagnitude > 0
 | 
				
			||||||
 | 
					                && isLevitationEnabled())
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO: Check if flying creature
 | 
					        // TODO: Check if flying creature
 | 
				
			||||||
| 
						 | 
					@ -1625,7 +1626,7 @@ namespace MWWorld
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
 | 
					        const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
 | 
				
			||||||
        if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::SlowFall)).mMagnitude > 0)
 | 
					        if(stats.getMagicEffects().get(ESM::MagicEffect::SlowFall).mMagnitude > 0)
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
| 
						 | 
					@ -1999,7 +2000,7 @@ namespace MWWorld
 | 
				
			||||||
        const Store<ESM::GameSetting> &gmst = getStore().get<ESM::GameSetting>();
 | 
					        const Store<ESM::GameSetting> &gmst = getStore().get<ESM::GameSetting>();
 | 
				
			||||||
        MWMechanics::NpcStats &stats = Class::get(actor).getNpcStats(actor);
 | 
					        MWMechanics::NpcStats &stats = Class::get(actor).getNpcStats(actor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0);
 | 
					        stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getFloat());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool World::getGodModeState()
 | 
					    bool World::getGodModeState()
 | 
				
			||||||
| 
						 | 
					@ -2389,11 +2390,11 @@ namespace MWWorld
 | 
				
			||||||
        const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
 | 
					        const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
 | 
				
			||||||
        float dist=0;
 | 
					        float dist=0;
 | 
				
			||||||
        if (type == World::Detect_Creature)
 | 
					        if (type == World::Detect_Creature)
 | 
				
			||||||
            dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectAnimal)).mMagnitude;
 | 
					            dist = effects.get(ESM::MagicEffect::DetectAnimal).mMagnitude;
 | 
				
			||||||
        else if (type == World::Detect_Key)
 | 
					        else if (type == World::Detect_Key)
 | 
				
			||||||
            dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectKey)).mMagnitude;
 | 
					            dist = effects.get(ESM::MagicEffect::DetectKey).mMagnitude;
 | 
				
			||||||
        else if (type == World::Detect_Enchantment)
 | 
					        else if (type == World::Detect_Enchantment)
 | 
				
			||||||
            dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectEnchantment)).mMagnitude;
 | 
					            dist = effects.get(ESM::MagicEffect::DetectEnchantment).mMagnitude;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!dist)
 | 
					        if (!dist)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -222,6 +222,8 @@ namespace Compiler
 | 
				
			||||||
            extensions.registerInstruction ("activate", "", opcodeActivate);
 | 
					            extensions.registerInstruction ("activate", "", opcodeActivate);
 | 
				
			||||||
            extensions.registerInstruction ("lock", "/l", opcodeLock, opcodeLockExplicit);
 | 
					            extensions.registerInstruction ("lock", "/l", opcodeLock, opcodeLockExplicit);
 | 
				
			||||||
            extensions.registerInstruction ("unlock", "", opcodeUnlock, opcodeUnlockExplicit);
 | 
					            extensions.registerInstruction ("unlock", "", opcodeUnlock, opcodeUnlockExplicit);
 | 
				
			||||||
 | 
					            extensions.registerInstruction ("cast", "SS", opcodeCast, opcodeCastExplicit);
 | 
				
			||||||
 | 
					            extensions.registerInstruction ("explodespell", "S", opcodeExplodeSpell, opcodeExplodeSpellExplicit);
 | 
				
			||||||
            extensions.registerInstruction ("togglecollisionboxes", "", opcodeToggleCollisionBoxes);
 | 
					            extensions.registerInstruction ("togglecollisionboxes", "", opcodeToggleCollisionBoxes);
 | 
				
			||||||
            extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
 | 
					            extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
 | 
				
			||||||
            extensions.registerInstruction ("tcb", "", opcodeToggleCollisionBoxes);
 | 
					            extensions.registerInstruction ("tcb", "", opcodeToggleCollisionBoxes);
 | 
				
			||||||
| 
						 | 
					@ -389,6 +391,12 @@ namespace Compiler
 | 
				
			||||||
            extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit);
 | 
					            extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit);
 | 
				
			||||||
            extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
 | 
					            extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
 | 
				
			||||||
                opcodeRemoveSpellExplicit);
 | 
					                opcodeRemoveSpellExplicit);
 | 
				
			||||||
 | 
					            extensions.registerInstruction ("removespelleffects", "c", opcodeRemoveSpellEffects,
 | 
				
			||||||
 | 
					                opcodeRemoveSpellEffectsExplicit);
 | 
				
			||||||
 | 
					            extensions.registerInstruction ("removeeffects", "l", opcodeRemoveEffects,
 | 
				
			||||||
 | 
					                opcodeRemoveEffectsExplicit);
 | 
				
			||||||
 | 
					            extensions.registerInstruction ("resurrect", "", opcodeResurrect,
 | 
				
			||||||
 | 
					                opcodeResurrectExplicit);
 | 
				
			||||||
            extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit);
 | 
					            extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank);
 | 
					            extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -228,6 +228,10 @@ namespace Compiler
 | 
				
			||||||
        const int opcodeToggleGodMode = 0x200021f;
 | 
					        const int opcodeToggleGodMode = 0x200021f;
 | 
				
			||||||
        const int opcodeDisableLevitation = 0x2000220;
 | 
					        const int opcodeDisableLevitation = 0x2000220;
 | 
				
			||||||
        const int opcodeEnableLevitation = 0x2000221;
 | 
					        const int opcodeEnableLevitation = 0x2000221;
 | 
				
			||||||
 | 
					        const int opcodeCast = 0x2000227;
 | 
				
			||||||
 | 
					        const int opcodeCastExplicit = 0x2000228;
 | 
				
			||||||
 | 
					        const int opcodeExplodeSpell = 0x2000229;
 | 
				
			||||||
 | 
					        const int opcodeExplodeSpellExplicit = 0x200022a;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    namespace Sky
 | 
					    namespace Sky
 | 
				
			||||||
| 
						 | 
					@ -365,6 +369,13 @@ namespace Compiler
 | 
				
			||||||
        const int opcodeIsWerewolfExplicit = 0x20001fe;
 | 
					        const int opcodeIsWerewolfExplicit = 0x20001fe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const int opcodeGetWerewolfKills = 0x20001e2;
 | 
					        const int opcodeGetWerewolfKills = 0x20001e2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const int opcodeRemoveSpellEffects = 0x200022b;
 | 
				
			||||||
 | 
					        const int opcodeRemoveSpellEffectsExplicit = 0x200022c;
 | 
				
			||||||
 | 
					        const int opcodeRemoveEffects = 0x200022d;
 | 
				
			||||||
 | 
					        const int opcodeRemoveEffectsExplicit = 0x200022e;
 | 
				
			||||||
 | 
					        const int opcodeResurrect = 0x200022f;
 | 
				
			||||||
 | 
					        const int opcodeResurrectExplicit = 0x2000230;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    namespace Transformation
 | 
					    namespace Transformation
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -854,7 +854,7 @@ class NIFObjectLoader
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr());
 | 
					                const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                partsys->setDefaultDimensions(partctrl->size, partctrl->size);
 | 
					                partsys->setDefaultDimensions(partctrl->size*2, partctrl->size*2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(!partctrl->emitter.empty())
 | 
					                if(!partctrl->emitter.empty())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue