예제 #1
0
    void ActiveSpells::update() const
    {
        bool rebuild = false;

        MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();

        if (mLastUpdate!=now)
        {
            TContainer::iterator iter (mSpells.begin());
            while (iter!=mSpells.end())
                if (!timeToExpire (iter))
                {
                    mSpells.erase (iter++);
                    rebuild = true;
                }
                else
                    ++iter;

            mLastUpdate = now;
        }

        if (mSpellsChanged)
        {
            mSpellsChanged = false;
            rebuild = true;
        }

        if (rebuild)
        {
            mEffects = MagicEffects();

            for (TIterator iter (begin()); iter!=end(); ++iter)
            {
                const ESM::EffectList& effects = getEffectList (iter->first);

                const MWWorld::TimeStamp& start = iter->second.first;
                float magnitude = iter->second.second;

                for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
                    iter!=effects.list.end(); ++iter)
                {
                    if (iter->duration)
                    {
                        MWWorld::TimeStamp end = start;
                        end += static_cast<double> (iter->duration)*
                            MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);

                        if (end>now)
                        {
                            EffectParam param;
                            param.mMagnitude = static_cast<int> (
                                (iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin);
                            mEffects.add (*iter, param);
                        }
                    }
                }
            }
        }
    }
예제 #2
0
파일: spells.cpp 프로젝트: devnexen/openmw
    void Spells::readState(const ESM::SpellState &state)
    {
        for (ESM::SpellState::TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it)
        {
            // Discard spells that are no longer available due to changed content files
            const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (spell)
            {
                mSpells[spell].mEffectRands = it->second.mEffectRands;
                mSpells[spell].mPurgedEffects = it->second.mPurgedEffects;

                if (it->first == state.mSelectedSpell)
                    mSelectedSpell = it->first;
            }
        }

        for (std::map<std::string, ESM::TimeStamp>::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it)
        {
            const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (!spell)
                continue;
            mUsedPowers[spell] = MWWorld::TimeStamp(it->second);
        }

        for (std::map<std::string, std::vector<ESM::SpellState::PermanentSpellEffectInfo> >::const_iterator it =
            state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it)
        {
            const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (!spell)
                continue;

            mPermanentSpellEffects[spell] = MagicEffects();
            for (std::vector<ESM::SpellState::PermanentSpellEffectInfo>::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt)
            {
                mPermanentSpellEffects[spell].add(EffectKey(effectIt->mId, effectIt->mArg), effectIt->mMagnitude);
            }
        }

        mCorprusSpells.clear();
        for (std::map<std::string, ESM::SpellState::CorprusStats>::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it)
        {
            const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (!spell) // Discard unavailable corprus spells
                continue;
            mCorprusSpells[spell].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings;
            mCorprusSpells[spell].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening);
        }

        mSpellsChanged = true;
    }
예제 #3
0
    void Spells::readState(const ESM::SpellState &state)
    {
        for (TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it)
        {
            // Discard spells that are no longer available due to changed content files
            const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (spell)
            {
                mSpells[it->first] = it->second;

                if (it->first == state.mSelectedSpell)
                    mSelectedSpell = it->first;
            }
        }

        // No need to discard spells here (doesn't really matter if non existent ids are kept)
        for (std::map<std::string, ESM::TimeStamp>::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it)
            mUsedPowers[it->first] = MWWorld::TimeStamp(it->second);

        for (std::map<std::string, std::vector<ESM::SpellState::PermanentSpellEffectInfo> >::const_iterator it =
            state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it)
        {
            const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
            if (!spell)
                continue;

            mPermanentSpellEffects[it->first] = MagicEffects();
            for (std::vector<ESM::SpellState::PermanentSpellEffectInfo>::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt)
            {
                mPermanentSpellEffects[it->first].add(EffectKey(effectIt->mId, effectIt->mArg), effectIt->mMagnitude);
            }
        }

        mCorprusSpells.clear();
        for (std::map<std::string, ESM::SpellState::CorprusStats>::const_iterator it = state.mCorprusSpells.begin(); it != state.mCorprusSpells.end(); ++it)
        {
            if (mSpells.find(it->first) != mSpells.end()) // Discard unavailable corprus spells
            {
                mCorprusSpells[it->first].mWorsenings = state.mCorprusSpells.at(it->first).mWorsenings;
                mCorprusSpells[it->first].mNextWorsening = MWWorld::TimeStamp(state.mCorprusSpells.at(it->first).mNextWorsening);
            }
        }
    }
예제 #4
0
파일: spells.cpp 프로젝트: devnexen/openmw
    void Spells::rebuildEffects() const
    {
        mEffects = MagicEffects();
        mSourcedEffects.clear();

        for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
        {
            const ESM::Spell *spell = iter->first;

            if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight ||
                spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse)
            {
                int i=0;
                for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it)
                {
                    if (iter->second.mPurgedEffects.find(i) != iter->second.mPurgedEffects.end())
                        continue; // effect was purged

                    float random = 1.f;
                    if (iter->second.mEffectRands.find(i) != iter->second.mEffectRands.end())
                        random = iter->second.mEffectRands.at(i);

                    float magnitude = it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random;
                    mEffects.add (*it, magnitude);
                    mSourcedEffects[spell].add(MWMechanics::EffectKey(*it), magnitude);

                    ++i;
                }
            }
        }

        for (std::map<SpellKey, MagicEffects>::const_iterator it = mPermanentSpellEffects.begin(); it != mPermanentSpellEffects.end(); ++it)
        {
            mEffects += it->second;
            mSourcedEffects[it->first] += it->second;
        }
    }
예제 #5
0
    void ActiveSpells::rebuildEffects() const
    {
        MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();

        mEffects = MagicEffects();

        for (TIterator iter (begin()); iter!=end(); ++iter)
        {
            const MWWorld::TimeStamp& start = iter->second.mTimeStamp;

            const std::vector<ActiveEffect>& effects = iter->second.mEffects;

            for (std::vector<ActiveEffect>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt)
            {
                int duration = effectIt->mDuration;
                MWWorld::TimeStamp end = start;
                end += static_cast<double> (duration)*
                    MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);

                if (end>now)
                    mEffects.add(MWMechanics::EffectKey(effectIt->mEffectId, effectIt->mArg), MWMechanics::EffectParam(effectIt->mMagnitude));
            }
        }
    }
예제 #6
0
    void Spells::worsenCorprus(const std::string &corpSpellId)
    {
        mCorprusSpells[corpSpellId].mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp() + CorprusStats::sWorseningPeriod;
        mCorprusSpells[corpSpellId].mWorsenings++;

        // update worsened effects
        mPermanentSpellEffects[corpSpellId] = MagicEffects();
        const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(corpSpellId);
        int i=0;
        for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt, ++i)
        {
            const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mEffectID);
            if ((effectIt->mEffectID != ESM::MagicEffect::Corprus) && (magicEffect->mData.mFlags & ESM::MagicEffect::UncappedDamage)) // APPLIED_ONCE
            {
                float random = 1.f;
                if (mSpells[corpSpellId].find(i) != mSpells[corpSpellId].end())
                    random = mSpells[corpSpellId].at(i);

                float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
                magnitude *= std::max(1, mCorprusSpells[corpSpellId].mWorsenings);
                mPermanentSpellEffects[corpSpellId].add(MWMechanics::EffectKey(*effectIt), MWMechanics::EffectParam(magnitude));
            }
        }
    }
예제 #7
0
    void MechanicsManager::buildPlayer()
    {
        MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();

        MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
        MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr);

        const ESM::NPC *player = ptr.get<ESM::NPC>()->base;

        // reset
        creatureStats.mLevel = player->npdt52.level;
        creatureStats.mSpells.clear();
        creatureStats.mMagicEffects = MagicEffects();

        for (int i=0; i<27; ++i)
            npcStats.mSkill[i].setBase (player->npdt52.skills[i]);

        creatureStats.mAttributes[0].setBase (player->npdt52.strength);
        creatureStats.mAttributes[1].setBase (player->npdt52.intelligence);
        creatureStats.mAttributes[2].setBase (player->npdt52.willpower);
        creatureStats.mAttributes[3].setBase (player->npdt52.agility);
        creatureStats.mAttributes[4].setBase (player->npdt52.speed);
        creatureStats.mAttributes[5].setBase (player->npdt52.endurance);
        creatureStats.mAttributes[6].setBase (player->npdt52.personality);
        creatureStats.mAttributes[7].setBase (player->npdt52.luck);

        // race
        if (mRaceSelected)
        {
            const ESM::Race *race =
                MWBase::Environment::get().getWorld()->getStore().races.find (
                MWBase::Environment::get().getWorld()->getPlayer().getRace());

            bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale();

            for (int i=0; i<8; ++i)
            {
                const ESM::Race::MaleFemale *attribute = 0;
                switch (i)
                {
                    case 0: attribute = &race->data.strength; break;
                    case 1: attribute = &race->data.intelligence; break;
                    case 2: attribute = &race->data.willpower; break;
                    case 3: attribute = &race->data.agility; break;
                    case 4: attribute = &race->data.speed; break;
                    case 5: attribute = &race->data.endurance; break;
                    case 6: attribute = &race->data.personality; break;
                    case 7: attribute = &race->data.luck; break;
                }

                creatureStats.mAttributes[i].setBase (
                    static_cast<int> (male ? attribute->male : attribute->female));
            }

            for (int i=0; i<7; ++i)
            {
                int index = race->data.bonus[i].skill;

                if (index>=0 && index<27)
                {
                    npcStats.mSkill[index].setBase (
                        npcStats.mSkill[index].getBase() + race->data.bonus[i].bonus);
                }
            }

            for (std::vector<std::string>::const_iterator iter (race->powers.list.begin());
                iter!=race->powers.list.end(); ++iter)
            {
                creatureStats.mSpells.add (*iter);
            }
        }

        // birthsign
        if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty())
        {
            const ESM::BirthSign *sign =
                MWBase::Environment::get().getWorld()->getStore().birthSigns.find (
                MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());

            for (std::vector<std::string>::const_iterator iter (sign->powers.list.begin());
                iter!=sign->powers.list.end(); ++iter)
            {
                creatureStats.mSpells.add (*iter);
            }
        }

        // class
        if (mClassSelected)
        {
            const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass();

            for (int i=0; i<2; ++i)
            {
                int attribute = class_.data.attribute[i];
                if (attribute>=0 && attribute<8)
                {
                    creatureStats.mAttributes[attribute].setBase (
                        creatureStats.mAttributes[attribute].getBase() + 10);
                }
            }

            for (int i=0; i<2; ++i)
            {
                int bonus = i==0 ? 10 : 25;

                for (int i2=0; i2<5; ++i2)
                {
                    int index = class_.data.skills[i2][i];

                    if (index>=0 && index<27)
                    {
                        npcStats.mSkill[index].setBase (
                            npcStats.mSkill[index].getBase() + bonus);
                    }
                }
            }

            typedef ESMS::IndexListT<ESM::Skill>::MapType ContainerType;
            const ContainerType& skills = MWBase::Environment::get().getWorld()->getStore().skills.list;

            for (ContainerType::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
            {
                if (iter->second.data.specialization==class_.data.specialization)
                {
                    int index = iter->first;

                    if (index>=0 && index<27)
                    {
                        npcStats.mSkill[index].setBase (
                            npcStats.mSkill[index].getBase() + 5);
                    }
                }
            }
        }

        // forced update and current value adjustments
        mActors.updateActor (ptr, 0);

        for (int i=0; i<3; ++i)
            creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified());
    }
예제 #8
0
    void MechanicsManager::buildPlayer()
    {
        MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();

        MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
        MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr);

        const ESM::NPC *player = ptr.get<ESM::NPC>()->base;

        // reset
        creatureStats.setLevel(player->mNpdt52.mLevel);
        creatureStats.getSpells().clear();
        creatureStats.setMagicEffects(MagicEffects());

        for (int i=0; i<27; ++i)
            npcStats.getSkill (i).setBase (player->mNpdt52.mSkills[i]);

        creatureStats.getAttribute(0).setBase (player->mNpdt52.mStrength);
        creatureStats.getAttribute(1).setBase (player->mNpdt52.mIntelligence);
        creatureStats.getAttribute(2).setBase (player->mNpdt52.mWillpower);
        creatureStats.getAttribute(3).setBase (player->mNpdt52.mAgility);
        creatureStats.getAttribute(4).setBase (player->mNpdt52.mSpeed);
        creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance);
        creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality);
        creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck);

        // race
        if (mRaceSelected)
        {
            const ESM::Race *race =
                MWBase::Environment::get().getWorld()->getStore().races.find (
                MWBase::Environment::get().getWorld()->getPlayer().getRace());

            bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale();

            for (int i=0; i<8; ++i)
            {
                const ESM::Race::MaleFemale *attribute = 0;
                switch (i)
                {
                    case 0: attribute = &race->mData.mStrength; break;
                    case 1: attribute = &race->mData.mIntelligence; break;
                    case 2: attribute = &race->mData.mWillpower; break;
                    case 3: attribute = &race->mData.mAgility; break;
                    case 4: attribute = &race->mData.mSpeed; break;
                    case 5: attribute = &race->mData.mEndurance; break;
                    case 6: attribute = &race->mData.mPersonality; break;
                    case 7: attribute = &race->mData.mLuck; break;
                }

                creatureStats.getAttribute(i).setBase (
                    static_cast<int> (male ? attribute->mMale : attribute->mFemale));
            }

            for (int i=0; i<27; ++i)
            {
                int bonus = 0;
                
                for (int i2=0; i2<7; ++i2)
                    if (race->mData.mBonus[i2].mSkill==i)
                    {
                        bonus = race->mData.mBonus[i2].mBonus;
                        break;
                    }
            
                npcStats.getSkill (i).setBase (5 + bonus);
            }

            for (std::vector<std::string>::const_iterator iter (race->mPowers.mList.begin());
                iter!=race->mPowers.mList.end(); ++iter)
            {
                creatureStats.getSpells().add (*iter);
            }
        }

        // birthsign
        if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty())
        {
            const ESM::BirthSign *sign =
                MWBase::Environment::get().getWorld()->getStore().birthSigns.find (
                MWBase::Environment::get().getWorld()->getPlayer().getBirthsign());

            for (std::vector<std::string>::const_iterator iter (sign->mPowers.mList.begin());
                iter!=sign->mPowers.mList.end(); ++iter)
            {
                creatureStats.getSpells().add (*iter);
            }
        }

        // class
        if (mClassSelected)
        {
            const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass();

            for (int i=0; i<2; ++i)
            {
                int attribute = class_.mData.mAttribute[i];
                if (attribute>=0 && attribute<8)
                {
                    creatureStats.getAttribute(attribute).setBase (
                        creatureStats.getAttribute(attribute).getBase() + 10);
                }
            }

            for (int i=0; i<2; ++i)
            {
                int bonus = i==0 ? 10 : 25;

                for (int i2=0; i2<5; ++i2)
                {
                    int index = class_.mData.mSkills[i2][i];

                    if (index>=0 && index<27)
                    {
                        npcStats.getSkill (index).setBase (
                            npcStats.getSkill (index).getBase() + bonus);
                    }
                }
            }

            typedef ESMS::IndexListT<ESM::Skill>::MapType ContainerType;
            const ContainerType& skills = MWBase::Environment::get().getWorld()->getStore().skills.list;

            for (ContainerType::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
            {
                if (iter->second.mData.mSpecialization==class_.mData.mSpecialization)
                {
                    int index = iter->first;

                    if (index>=0 && index<27)
                    {
                        npcStats.getSkill (index).setBase (
                            npcStats.getSkill (index).getBase() + 5);
                    }
                }
            }
        }

        // forced update and current value adjustments
        mActors.updateActor (ptr, 0);

        for (int i=0; i<2; ++i)
        {
            DynamicStat<float> stat = creatureStats.getDynamic (i);
            stat.setCurrent (stat.getModified());
            creatureStats.setDynamic (i, stat);
        }
    }