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); }