示例#1
0
文件: hud.cpp 项目: AAlderman/openmw
    void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
    {
        int current = std::max(0, static_cast<int>(value.getCurrent()));
        int modified = static_cast<int>(value.getModified());

        MyGUI::Widget* w;
        std::string valStr = MyGUI::utility::toString(current) + "/" + MyGUI::utility::toString(modified);
        if (id == "HBar")
        {
            mHealth->setProgressRange(modified);
            mHealth->setProgressPosition(current);
            getWidget(w, "HealthFrame");
            w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
        }
        else if (id == "MBar")
        {
            mMagicka->setProgressRange (modified);
            mMagicka->setProgressPosition (current);
            getWidget(w, "MagickaFrame");
            w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
        }
        else if (id == "FBar")
        {
            mStamina->setProgressRange (modified);
            mStamina->setProgressPosition (current);
            getWidget(w, "FatigueFrame");
            w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
        }
    }
示例#2
0
文件: layouts.cpp 项目: dhardy/openmw
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
    static const char *ids[] =
    {
        "HBar", "MBar", "FBar",
        0
    };

    for (int i=0; ids[i]; ++i)
        if (ids[i]==id)
        {
            std::string id (ids[i]);
            setBar (id, id + "T", value.getCurrent(), value.getModified());
        }
}
示例#3
0
文件: combat.cpp 项目: dteviot/openmw
 void applyFatigueLoss(const MWWorld::Ptr &attacker, const MWWorld::Ptr &weapon, float attackStrength)
 {
     // somewhat of a guess, but using the weapon weight makes sense
     const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
     const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat();
     const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
     const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
     CreatureStats& stats = attacker.getClass().getCreatureStats(attacker);
     MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
     const float normalizedEncumbrance = attacker.getClass().getNormalizedEncumbrance(attacker);
     float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
     if (!weapon.isEmpty())
         fatigueLoss += weapon.getClass().getWeight(weapon) * attackStrength * fWeaponFatigueMult;
     fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
     stats.setFatigue(fatigue);
 }
示例#4
0
    void applyElementalShields(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim)
    {
        for (int i=0; i<3; ++i)
        {
            float magnitude = victim.getClass().getCreatureStats(victim).getMagicEffects().get(ESM::MagicEffect::FireShield+i).getMagnitude();

            if (!magnitude)
                continue;

            CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
            float saveTerm = attacker.getClass().getSkill(attacker, ESM::Skill::Destruction)
                    + 0.2f * attackerStats.getAttribute(ESM::Attribute::Willpower).getModified()
                    + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified();

            int fatigueMax = attackerStats.getFatigue().getModified();
            int fatigueCurrent = attackerStats.getFatigue().getCurrent();

            float normalisedFatigue = fatigueMax==0 ? 1 : std::max (0.0f, static_cast<float> (fatigueCurrent)/fatigueMax);

            saveTerm *= 1.25f * normalisedFatigue;

            float roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
            float x = std::max(0.f, saveTerm - roll);

            int element = ESM::MagicEffect::FireDamage;
            if (i == 1)
                element = ESM::MagicEffect::ShockDamage;
            if (i == 2)
                element = ESM::MagicEffect::FrostDamage;

            float elementResistance = MWMechanics::getEffectResistanceAttribute(element, &attackerStats.getMagicEffects());

            x = std::min(100.f, x + elementResistance);

            static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fElementalShieldMult")->getFloat();
            x = fElementalShieldMult * magnitude * (1.f - 0.01f * x);

            // Note swapped victim and attacker, since the attacker takes the damage here.
            x = scaleDamage(x, victim, attacker);

            MWMechanics::DynamicStat<float> health = attackerStats.getHealth();
            health.setCurrent(health.getCurrent() - x);
            attackerStats.setHealth(health);
        }
    }
示例#5
0
文件: hud.cpp 项目: zeidrich/openmw
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
    static const char *ids[] =
    {
        "HBar", "MBar", "FBar", 0
    };

    for (int i=0; ids[i]; ++i)
        if (ids[i]==id)
        {
            MyGUI::Widget* w;
            std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
            switch (i)
            {
                case 0:
                    mHealth->setProgressRange (value.getModified());
                    mHealth->setProgressPosition (value.getCurrent());
                    getWidget(w, "HealthFrame");
                    w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
                    break;
                case 1:
                    mMagicka->setProgressRange (value.getModified());
                    mMagicka->setProgressPosition (value.getCurrent());
                    getWidget(w, "MagickaFrame");
                    w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
                    break;
                case 2:
                    mStamina->setProgressRange (value.getModified());
                    mStamina->setProgressPosition (value.getCurrent());
                    getWidget(w, "FatigueFrame");
                    w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
                    break;
            }
        }
}
示例#6
0
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
    static const char *ids[] =
    {
        "HBar", "MBar", "FBar", 0
    };

    for (int i=0; ids[i]; ++i)
        if (ids[i]==id)
        {
            switch (i)
            {
                case 0:
                    health->setProgressRange (value.getModified());
                    health->setProgressPosition (value.getCurrent());
                    break;
                case 1:
                    magicka->setProgressRange (value.getModified());
                    magicka->setProgressPosition (value.getCurrent());
                    break;
                case 2:
                    stamina->setProgressRange (value.getModified());
                    stamina->setProgressPosition (value.getCurrent());
                    break;
            }
        }
}
示例#7
0
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
    static const char *ids[] =
    {
        "HBar", "MBar", "FBar",
        0
    };

    for (int i=0; ids[i]; ++i)
    {
        if (ids[i]==id)
        {
            std::string id (ids[i]);
            setBar (id, id + "T", value.getCurrent(), value.getModified());

            // health, magicka, fatigue tooltip
            MyGUI::Widget* w;
            std::string valStr =  boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
            if (i==0)
            {
                getWidget(w, "Health");
                w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
            }
            else if (i==1)
            {
                getWidget(w, "Magicka");
                w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
            }
            else if (i==2)
            {
                getWidget(w, "Fatigue");
                w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
            }
        }
    }
}
    bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage, float attackStrength)
    {
        if (!blocker.getClass().hasInventoryStore(blocker))
            return false;

        MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker);

        if (blockerStats.getKnockedDown() // Used for both knockout or knockdown
                || blockerStats.getHitRecovery()
                || blockerStats.isParalyzed())
            return false;

        if (!MWBase::Environment::get().getMechanicsManager()->isReadyToBlock(blocker))
            return false;

        MWWorld::InventoryStore& inv = blocker.getClass().getInventoryStore(blocker);
        MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
        if (shield == inv.end() || shield->getTypeName() != typeid(ESM::Armor).name())
            return false;

        if (!blocker.getRefData().getBaseNode())
            return false; // shouldn't happen

        float angleDegrees = osg::RadiansToDegrees(
                    signedAngleRadians (
                    (attacker.getRefData().getPosition().asVec3() - blocker.getRefData().getPosition().asVec3()),
                    blocker.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0),
                    osg::Vec3f(0,0,1)));

        const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
        if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->getFloat())
            return false;
        if (angleDegrees > gmst.find("fCombatBlockRightAngle")->getFloat())
            return false;

        MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);

        float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
            + 0.1f * blockerStats.getAttribute(ESM::Attribute::Luck).getModified();
        float enemySwing = attackStrength;
        float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->getFloat() + gmst.find("fSwingBlockBase")->getFloat();

        float blockerTerm = blockTerm * swingTerm;
        if (blocker.getClass().getMovementSettings(blocker).mPosition[1] <= 0)
            blockerTerm *= gmst.find("fBlockStillBonus")->getFloat();
        blockerTerm *= blockerStats.getFatigueTerm();

        int attackerSkill = 0;
        if (weapon.isEmpty())
            attackerSkill = attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand);
        else
            attackerSkill = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon));
        float attackerTerm = attackerSkill + 0.2f * attackerStats.getAttribute(ESM::Attribute::Agility).getModified()
                + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified();
        attackerTerm *= attackerStats.getFatigueTerm();

        int x = int(blockerTerm - attackerTerm);
//        int iBlockMaxChance = gmst.find("iBlockMaxChance")->getInt();
//        int iBlockMinChance = gmst.find("iBlockMinChance")->getInt();
//        x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));
//
//        if (Misc::Rng::roll0to99() < x)
//        {
//            // Reduce shield durability by incoming damage
//            int shieldhealth = shield->getClass().getItemHealth(*shield);
//
//            shieldhealth -= std::min(shieldhealth, int(damage));
//            shield->getCellRef().setCharge(shieldhealth);
//            if (shieldhealth == 0)
//                inv.unequipItem(*shield, blocker);
//
//            // Reduce blocker fatigue
//            const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat();
//            const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
//            const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
//            MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
//            float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker);
//            normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
//            float fatigueLoss = fFatigueBlockBase + normalizedEncumbrance * fFatigueBlockMult;
//            if (!weapon.isEmpty())
//                fatigueLoss += weapon.getClass().getWeight(weapon) * attackStrength * fWeaponFatigueBlockMult;
//            fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
//            blockerStats.setFatigue(fatigue);
//
//            blockerStats.setBlock(true);
//
//            if (blocker == getPlayer())
//                blocker.getClass().skillUsageSucceeded(blocker, ESM::Skill::Block, 0);
//
//            return true;
//        }
        
        
        
        
        
        // manual blocking
        if (blocker.getClass().getCreatureStats(blocker).getBlockManually())
        {
            // Reduce shield durability by incoming damage
            int shieldhealth = shield->getClass().getItemHealth(*shield);

            shieldhealth -= std::min(shieldhealth, int(10 * damage /blockerStats.getAttribute(ESM::Skill::Block).getBase()));
            shield->getCellRef().setCharge(shieldhealth);
            if (shieldhealth == 0)
                inv.unequipItem(*shield, blocker);

            // Reduce blocker fatigue
            const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat();
            const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
            const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
            MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
            float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker);
            normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
            float fatigueLoss = fFatigueBlockBase + normalizedEncumbrance * fFatigueBlockMult;
            if (!weapon.isEmpty())
                fatigueLoss += (weapon.getClass().getWeight(weapon) * attackStrength * fWeaponFatigueBlockMult) - x;
            fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
            blockerStats.setFatigue(fatigue);

            blockerStats.setBlock(true);

            if (blocker == getPlayer())
                blocker.getClass().skillUsageSucceeded(blocker, ESM::Skill::Block, 0);
            
            blocker.getClass().getCreatureStats(blocker).setBlockManually(false);

            return true;
        }
        
        
        
        
        
        
        return false;
    }
示例#9
0
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
{
    mFatigue->setValue(value.getCurrent(), value.getModified());
    std::string valStr =  boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
    mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
}
示例#10
0
文件: combat.cpp 项目: Chiur/openmw
    bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage)
    {
        if (!blocker.getClass().hasInventoryStore(blocker))
            return false;

        if (blocker.getClass().getCreatureStats(blocker).getKnockedDown()
                || blocker.getClass().getCreatureStats(blocker).getHitRecovery())
            return false;

        MWWorld::InventoryStore& inv = blocker.getClass().getInventoryStore(blocker);
        MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
        if (shield == inv.end() || shield->getTypeName() != typeid(ESM::Armor).name())
            return false;

        Ogre::Degree angle = signedAngle (Ogre::Vector3(attacker.getRefData().getPosition().pos) - Ogre::Vector3(blocker.getRefData().getPosition().pos),
                                          blocker.getRefData().getBaseNode()->getOrientation().yAxis(), Ogre::Vector3(0,0,1));

        const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
        if (angle.valueDegrees() < gmst.find("fCombatBlockLeftAngle")->getFloat())
            return false;
        if (angle.valueDegrees() > gmst.find("fCombatBlockRightAngle")->getFloat())
            return false;

        MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker);
        if (blockerStats.getDrawState() == DrawState_Spell)
            return false;

        MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);

        float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2 * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
            + 0.1 * blockerStats.getAttribute(ESM::Attribute::Luck).getModified();
        float enemySwing = attackerStats.getAttackStrength();
        float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->getFloat() + gmst.find("fSwingBlockBase")->getFloat();

        float blockerTerm = blockTerm * swingTerm;
        if (blocker.getClass().getMovementSettings(blocker).mPosition[1] <= 0)
            blockerTerm *= gmst.find("fBlockStillBonus")->getFloat();
        blockerTerm *= blockerStats.getFatigueTerm();

        float attackerSkill = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon));
        float attackerTerm = attackerSkill + 0.2 * attackerStats.getAttribute(ESM::Attribute::Agility).getModified()
                + 0.1 * attackerStats.getAttribute(ESM::Attribute::Luck).getModified();
        attackerTerm *= attackerStats.getFatigueTerm();

        int x = int(blockerTerm - attackerTerm);
        int iBlockMaxChance = gmst.find("iBlockMaxChance")->getInt();
        int iBlockMinChance = gmst.find("iBlockMinChance")->getInt();
        x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));

        int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
        if (roll < x)
        {
            // Reduce shield durability by incoming damage
            if (shield->getCellRef().mCharge == -1)
                shield->getCellRef().mCharge = shield->getClass().getItemMaxHealth(*shield);
            shield->getCellRef().mCharge -= std::min(shield->getCellRef().mCharge, int(damage));
            if (!shield->getCellRef().mCharge)
                inv.unequipItem(*shield, blocker);

            // Reduce blocker fatigue
            const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat();
            const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
            const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
            MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
            float normalizedEncumbrance = blocker.getClass().getEncumbrance(blocker) / blocker.getClass().getCapacity(blocker);
            normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
            float fatigueLoss = fFatigueBlockBase + normalizedEncumbrance * fFatigueBlockMult;
            fatigueLoss += weapon.getClass().getWeight(weapon) * attackerStats.getAttackStrength() * fWeaponFatigueBlockMult;
            fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
            blockerStats.setFatigue(fatigue);

            blockerStats.setBlock(true);

            if (blocker.getClass().isNpc())
                blocker.getClass().skillUsageSucceeded(blocker, ESM::Skill::Block, 0);

            return true;
        }
        return false;
    }
示例#11
0
 void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
 {
     mFatigue->setValue(static_cast<int>(value.getCurrent()), static_cast<int>(value.getModified()));
     std::string valStr =  MyGUI::utility::toString(value.getCurrent()) + "/" + MyGUI::utility::toString(value.getModified());
     mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
 }
示例#12
0
文件: review.cpp 项目: dhardy/openmw
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value)
{
    fatigue->setValue(value.getCurrent(), value.getModified());
}
示例#13
0
文件: review.cpp 项目: dhardy/openmw
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value)
{
    magicka->setValue(value.getCurrent(), value.getModified());
}
示例#14
0
文件: review.cpp 项目: dhardy/openmw
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value)
{
    health->setValue(value.getCurrent(), value.getModified());
}
示例#15
0
文件: actors.cpp 项目: emoose/openmw
    void Actors::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
        bool paused)
    {
        mDuration += duration;

        if (mDuration>=0.25)
        {
            float totalDuration = mDuration;
            mDuration = 0;
            
            std::set<MWWorld::Ptr>::iterator iter (mActors.begin());

            while (iter!=mActors.end())
            {
                if (!MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
                {
                    updateActor (*iter, totalDuration);

                    if (iter->getTypeName()==typeid (ESM::NPC).name())
                        updateNpc (*iter, totalDuration, paused);
                }

                if (MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
                {
                    // workaround: always keep player alive for now
                    // \todo remove workaround, once player death can be handled
                    if (iter->getRefData().getHandle()=="player")
                    {
                        MWMechanics::DynamicStat<float> stat (
                            MWWorld::Class::get (*iter).getCreatureStats (*iter).getHealth());
                            
                        if (stat.getModified()<1)
                        {
                            stat.setModified (1, 0);
                            MWWorld::Class::get (*iter).getCreatureStats (*iter).setHealth (stat);
                        }

                        MWWorld::Class::get (*iter).getCreatureStats (*iter).resurrect();
                        ++iter;
                        continue;
                    }

                    ++mDeathCount[MWWorld::Class::get (*iter).getId (*iter)];

                    MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0);

                    if (MWWorld::Class::get (*iter).isEssential (*iter))
                        MWBase::Environment::get().getWindowManager()->messageBox (
                            "#{sKilledEssential}", std::vector<std::string>());

                    mActors.erase (iter++);
                }
                else
                    ++iter;
            }
        }

        for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
            ++iter)
        {
            Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);

            if (vector!=Ogre::Vector3::ZERO)
                movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
        }
    }