Beispiel #1
7
void
shHero::payMelnorme (shMonster *trader)
{
    if (trader->isHostile ()) {
        int result;
        shMenu *amends = I->newMenu ("Make amends:", 0);
        amends->addIntItem ('a', "Apologize", 1, 1);
        amends->addIntItem ('p', "Pay reparations", 2, 1);
        amends->getIntResult (&result);
        delete amends;
        switch (result) {
            case -1:
                return;
            case 1:
                if (trader->mHP == trader->mMaxHP) {
                    if (tryToTranslate (trader)) {
                        I->p ("\"We believe you.\"");
                    } else {
                        I->p ("%s mumbles soothingly.", THE (trader));
                    }
                    pacifyMelnorme (trader);
                } else {
                    if (tryToTranslate (trader)) {
                        I->p ("\"It is not enough.\"");
                    } else {
                        I->p ("%s mumbles stalwartly.", THE (trader));
                    }
                }
                return;
            case 2:
            {
                int demand = (trader->mMaxHP - trader->mHP) * 10;
                demand = maxi (50, demand);
                if (demand <= countMoney ()) {
                    if (I->yn ("Pay %s %d buckazoids?", THE (trader), demand)) {
                        I->p ("%s accepts the money.", THE (trader));
                        pacifyMelnorme (trader);
                        loseMoney (demand);
                        trader->gainMoney (demand);
                    }
                } else {
                    I->p ("%s demands %d buckazoids but you don't"
                          " have that much.", THE (trader), demand);
                }
            }
        }
        return;
    }
    static int (shObject::*tests[])(void) =
    {
        &shObject::isBugginessKnown,
        &shObject::isChargeKnown,
        &shObject::isEnhancementKnown,
        &shObject::isAppearanceKnown
    };
    static void (shObject::*actions[])(void) =
    {
        &shObject::setBugginessKnown,
        &shObject::setChargeKnown,
        &shObject::setEnhancementKnown,
        &shObject::setAppearanceKnown
    };
    int (shObject::*test) (void);
    void (shObject::*action) (void);
    reorganizeInventory ();
    shMenu *menu = I->newMenu ("Melnorme Services Menu", 0);
    char buf[200];
    shObjectVector v;
    int price = 1000, services = 0;
    int price1 = 40 - Hero.mAbil.mPsi; /* Bugginess. */
    int price2 = 225 - 5 * Hero.mAbil.mPsi; /* Knowledge. */
    int price3 = price1 / 2; /* Remaining. */
    if (!trader->is (kGenerous)) {
        /* Ward against drinking a lot of nano cola. */
        price1 = maxi (10, price1);
        price2 = maxi (100, price2);
        price3 = maxi (10, price3);
    } else {
        price1 = 10;
        price2 = 100;
        price3 = 10;
    }

    if (tryToTranslate (trader)) {
        /* Make all services known. */
        for (int i = 0; i < kMelnMaxService; ++i) {
            MelnormeServiceData[i].mNameKnown = 1;
        }
    }

    char letter = 'a';
    for (int i = 0; i < kMelnMaxService; ++i) {
        int serv = trader->mMelnorme.mPermute[i];

        /* Offer only eligible services. */
        if (serv == kMelnRandomIdentify) {
            if (trader->mMelnorme.mKnowledgeExhausted or
                !hasTranslation ())
                continue;
            price = price2;
            ++services;
        } else if (serv >= kMelnRevealBugginess and
                   serv <= kMelnRevealAppearance)
        {
            test = tests[serv - kMelnRevealBugginess];
            v.reset ();
            unselectObjectsByFunction (&v, Hero.mInventory, test);
            if (!v.count ()) continue;
            if (serv == kMelnRevealBugginess) {
                price = price1;
            } else {
                price = price3;
            }
            ++services;
        }
        snprintf (buf, sizeof (buf), "%s ($%d)",
                  MelnormeServiceData[serv].mNameKnown
                      ? MelnormeServiceNames[serv]
                      : MelnormeServiceData[serv].mDesc,
                  price);
        menu->addIntItem (letter++, buf, serv);
    }

    if (!services) {
        if (tryToTranslate (trader)) {
            I->p ("Unfortunately I cannot help you at the moment.");
        } else {
            I->p ("%s mumbles something in sad voice.", THE (trader));
        }
        return;
    }

    int choice;
    if (!menu->getIntResult (&choice))
        return;
    delete menu;

    price = choice == kMelnRandomIdentify ? price2 :
            choice == kMelnRevealBugginess ? price1 : price3;
    if (countMoney () < price) {
        I->p ("You don't have enough money for that.");
        return;
    }
    loseMoney (price);
    trader->gainMoney (price);

    shObject *obj = NULL;
    if (choice == kMelnRandomIdentify) {
        int n = kObjNumIlks;
        int tries = 10;
        int success = 0;
        while (tries--) {
            int i = RNG (n);
            shObjectIlk *ilk = &AllIlks[i];
            if (!(ilk->mFlags & kIdentified) and ilk->mProbability != ABSTRACT) {
                char *buf = GetBuf ();
                strncpy (buf, ilk->mReal.mName, SHBUFLEN);
                makePlural (buf, SHBUFLEN);
                ilk->mFlags |= kIdentified;
                I->p ("%s tells you how to recognize %s.", THE (trader), buf);
                success = 1;
                break;
            }
        }
        if (!success) {
            I->p ("%s offers you several facts but you know all of them.", THE (trader));
            I->p ("\"It seems you know all I do.\"");
            trader->mMelnorme.mKnowledgeExhausted = 1;
            I->p ("%s returns your money.");
            trader->loseMoney (price);
            gainMoney (price);
        }
        MelnormeServiceData[choice].mNameKnown = 1;
    } else if (choice >= kMelnRevealBugginess and
               choice <= kMelnRevealAppearance)
    {
        v.reset ();
        test = tests[choice - kMelnRevealBugginess];
        unselectObjectsByFunction (&v, Hero.mInventory, test);
        obj = quickPickItem (&v, "perform service on", 0);
        if (obj) {
            if (hasTranslation () or RNG (4)) { /* 75% - lets be generous. */
                action = actions[choice - kMelnRevealBugginess];
                (obj->*action) ();
                if (!hasTranslation ()) {
                    I->p ("You manage to understand %s.", THE (trader));
                }
                MelnormeServiceData[choice].mNameKnown = 1;
                I->p ("%c - %s", obj->mLetter, obj->inv ());
            } else {
                I->p ("This time you fail to understand %s.", THE (trader));
            }
        }
    }
    I->drawSideWin ();
}
/// Returns true if this is the identity operation.
bool SymmetryOperation::isIdentity() const {
  return !hasTranslation() && m_matrix == Kernel::IntMatrix(3, 3, true);
}