예제 #1
0
파일: tradewindow.cpp 프로젝트: wix0/openmw
    void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
    {
        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        // were there any items traded at all?
        MWWorld::ContainerStore& playerBought = mWindowManager.getInventoryWindow()->getBoughtItems();
        MWWorld::ContainerStore& merchantBought = getBoughtItems();
        if (playerBought.begin() == playerBought.end() && merchantBought.begin() == merchantBought.end())
        {
            // user notification
            MWBase::Environment::get().getWindowManager()->
                messageBox("#{sBarterDialog11}", std::vector<std::string>());
            return;
        }

        // check if the player can afford this
        if (mCurrentBalance < 0 && mWindowManager.getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance))
        {
            // user notification
            MWBase::Environment::get().getWindowManager()->
                messageBox("#{sBarterDialog1}", std::vector<std::string>());
            return;
        }

        // check if the merchant can afford this
        int merchantgold;
        if (mPtr.getTypeName() == typeid(ESM::NPC).name())
        {
            MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
            if (ref->mBase->mNpdt52.mGold == -10)
                merchantgold = ref->mBase->mNpdt12.mGold;
            else
                merchantgold = ref->mBase->mNpdt52.mGold;
        }
        else // ESM::Creature
        {
            MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
            merchantgold = ref->mBase->mData.mGold;
        }
        if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
        {
            // user notification
            MWBase::Environment::get().getWindowManager()->
                messageBox("#{sBarterDialog2}", std::vector<std::string>());
            return;
        }

        if(mCurrentBalance > mCurrentMerchantOffer)
        {
            //if npc is a creature: reject (no haggle)
            if (mPtr.getTypeName() != typeid(ESM::NPC).name())
            {
                MWBase::Environment::get().getWindowManager()->
                    messageBox("#{sNotifyMessage9}", std::vector<std::string>());
                return;
            }

            int a = abs(mCurrentMerchantOffer);
            int b = abs(mCurrentBalance);
            int d = 0;
            if (mCurrentMerchantOffer<0) d = int(100 * (a - b) / a);
            else d = int(100 * (b - a) / a);

            float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
                + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));

            MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
            MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr);
            MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
            MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
            MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr);

            float a1 = std::min(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.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 d1 = std::min(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100.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 pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
            float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
            float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat();
            if (mCurrentMerchantOffer<0) x += abs(int(pcTerm - npcTerm));
            else x += abs(int(npcTerm - pcTerm));

            int roll = std::rand()%100 + 1;
            if(roll > x) //trade refused
            {
                MWBase::Environment::get().getWindowManager()->
                    messageBox("#{sNotifyMessage9}", std::vector<std::string>());

                int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
                MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);
                return;
            }

            //skill use!
            MWWorld::Class::get(playerPtr).skillUsageSucceeded(playerPtr, ESM::Skill::Mercantile, 0);
    }

        int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
        MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);

        // success! make the item transfer.
        transferBoughtItems();
        mWindowManager.getInventoryWindow()->transferBoughtItems();

        // add or remove gold from the player.
        if (mCurrentBalance != 0)
            addOrRemoveGold(mCurrentBalance);

        std::string sound = "Item Gold Up";
        MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);

        mWindowManager.removeGuiMode(GM_Barter);
    }
예제 #2
0
    void CharacterCreation::spawnDialog(const char id)
    {
        switch (id)
        {
            case GM_Name:
                MWBase::Environment::get().getWindowManager()->removeDialog(mNameDialog);
                mNameDialog = 0;
                mNameDialog = new TextInputDialog();
                mNameDialog->setTextLabel(MWBase::Environment::get().getWindowManager()->getGameSettingString("sName", "Name"));
                mNameDialog->setTextInput(mPlayerName);
                mNameDialog->setNextButtonShow(mCreationStage >= CSE_NameChosen);
                mNameDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone);
                mNameDialog->setVisible(true);
                break;

            case GM_Race:
                MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog);
                mRaceDialog = 0;
                mRaceDialog = new RaceDialog();
                mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen);
                mRaceDialog->setRaceId(mPlayerRaceId);
                mRaceDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone);
                mRaceDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogBack);
                mRaceDialog->setVisible(true);
                if (mCreationStage < CSE_NameChosen)
                    mCreationStage = CSE_NameChosen;
                break;

            case GM_Class:
                MWBase::Environment::get().getWindowManager()->removeDialog(mClassChoiceDialog);
                mClassChoiceDialog = 0;
                mClassChoiceDialog = new ClassChoiceDialog();
                mClassChoiceDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassChoice);
                mClassChoiceDialog->setVisible(true);
                if (mCreationStage < CSE_RaceChosen)
                    mCreationStage = CSE_RaceChosen;
                break;

            case GM_ClassPick:
                MWBase::Environment::get().getWindowManager()->removeDialog(mPickClassDialog);
                mPickClassDialog = 0;
                mPickClassDialog = new PickClassDialog();
                mPickClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen);
                mPickClassDialog->setClassId(mPlayerClass.mName);
                mPickClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogDone);
                mPickClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogBack);
                mPickClassDialog->setVisible(true);
                if (mCreationStage < CSE_RaceChosen)
                    mCreationStage = CSE_RaceChosen;
                break;

            case GM_Birth:
                MWBase::Environment::get().getWindowManager()->removeDialog(mBirthSignDialog);
                mBirthSignDialog = 0;
                mBirthSignDialog = new BirthDialog();
                mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
                mBirthSignDialog->setBirthId(mPlayerBirthSignId);
                mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone);
                mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack);
                mBirthSignDialog->setVisible(true);
                if (mCreationStage < CSE_ClassChosen)
                    mCreationStage = CSE_ClassChosen;
                break;

            case GM_ClassCreate:
                MWBase::Environment::get().getWindowManager()->removeDialog(mCreateClassDialog);
                mCreateClassDialog = 0;
                mCreateClassDialog = new CreateClassDialog();
                mCreateClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen);
                mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone);
                mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack);
                mCreateClassDialog->setVisible(true);
                if (mCreationStage < CSE_RaceChosen)
                    mCreationStage = CSE_RaceChosen;
                break;
            case GM_ClassGenerate:
                mGenerateClassStep = 0;
                mGenerateClass = "";
                mGenerateClassSpecializations[0] = 0;
                mGenerateClassSpecializations[1] = 0;
                mGenerateClassSpecializations[2] = 0;
                showClassQuestionDialog();
                if (mCreationStage < CSE_RaceChosen)
                    mCreationStage = CSE_RaceChosen;
                break;
            case GM_Review:
                MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
                mReviewDialog = 0;
                mReviewDialog = new ReviewDialog();
                mReviewDialog->setPlayerName(mPlayerName);
                mReviewDialog->setRace(mPlayerRaceId);
                mReviewDialog->setClass(mPlayerClass);
                mReviewDialog->setBirthSign(mPlayerBirthSignId);

                {
                    MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
                    MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player);

                    mReviewDialog->setHealth ( stats.getHealth()  );
                    mReviewDialog->setMagicka( stats.getMagicka() );
                    mReviewDialog->setFatigue( stats.getFatigue() );
                }

                {
                    std::map<int, MWMechanics::Stat<int> > attributes = MWBase::Environment::get().getWindowManager()->getPlayerAttributeValues();
                    for (std::map<int, MWMechanics::Stat<int> >::iterator it = attributes.begin();
                        it != attributes.end(); ++it)
                    {
                        mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID> (it->first), it->second);
                    }
                }

                {
                    std::map<int, MWMechanics::Stat<float> > skills = MWBase::Environment::get().getWindowManager()->getPlayerSkillValues();
                    for (std::map<int, MWMechanics::Stat<float> >::iterator it = skills.begin();
                        it != skills.end(); ++it)
                    {
                        mReviewDialog->setSkillValue(static_cast<ESM::Skill::SkillEnum> (it->first), it->second);
                    }
                    mReviewDialog->configureSkills(MWBase::Environment::get().getWindowManager()->getPlayerMajorSkills(), MWBase::Environment::get().getWindowManager()->getPlayerMinorSkills());
                }

                mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone);
                mReviewDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogBack);
                mReviewDialog->eventActivateDialog += MyGUI::newDelegate(this, &CharacterCreation::onReviewActivateDialog);
                mReviewDialog->setVisible(true);
                if (mCreationStage < CSE_BirthSignChosen)
                    mCreationStage = CSE_BirthSignChosen;
                break;
        }
    }
예제 #3
0
    void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
    {
        // we need to sleep for a specific time, and since that isn't calculated yet, we'll do it here
        // I'm making the assumption here that the # of hours rested is calculated when rest is started
        // TODO: the rougher logic here (calculating the hourly deltas) should really go into helper funcs elsewhere
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
        MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player);
        const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();

        float hourlyHealthDelta  = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;

        bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0);
        float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
        float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();

        // this massive duplication is why it has to be put into helper functions instead
        float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat();
        float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat();
        float fEndFatigueMult = store.get<ESM::GameSetting>().find("fEndFatigueMult")->getFloat();
        float capacity = MWWorld::Class::get(player).getCapacity(player);
        float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
        float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
        if (normalizedEncumbrance > 1)
            normalizedEncumbrance = 1;
        float hourlyFatigueDelta = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
        hourlyFatigueDelta *= 3600 * fEndFatigueMult * stats.getAttribute(ESM::Attribute::Endurance).getModified();

        float healthHours  = hourlyHealthDelta  >= 0.0
                             ? (stats.getHealth().getBase() - stats.getHealth().getCurrent()) / hourlyHealthDelta
                             : 1.0f;
        float magickaHours = stunted ? 0.0 :
                              hourlyMagickaDelta >= 0.0
                              ? (stats.getMagicka().getBase() - stats.getMagicka().getCurrent()) / hourlyMagickaDelta
                              : 1.0f;
        float fatigueHours = hourlyFatigueDelta >= 0.0
                             ? (stats.getFatigue().getBase() - stats.getFatigue().getCurrent()) / hourlyFatigueDelta
                             : 1.0f;

        int autoHours = int(std::ceil( std::max(std::max(healthHours, magickaHours), std::max(fatigueHours, 1.0f)) )); // this should use a variadic max if possible

        startWaiting(autoHours);
    }