Example #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 ();
}
Example #2
0
/* Replace substrings within asterisks. */
const char *
processLoreLine (const char *src, const char *arg = NULL)
{
    const char *what;
    const char *with;
    do {
        with = NULL;
        if ((what = strstr (src, "*arg*"))) {
            with = arg;
        } else if ((what = strstr (src, "*Arg*"))) {
            char *tmp = GetBuf ();
            strncpy (tmp, arg, SHBUFLEN);
            tmp[0] = toupper (tmp[0]);
            with = tmp;
        } else if ((what = strstr (src, "*args*"))) {
            char *tmp = GetBuf ();
            strncpy (tmp, arg, SHBUFLEN);
            makePlural (tmp, SHBUFLEN);
            with = tmp;
        } else if ((what = strstr (src, "*Args*"))) {
            char *tmp = GetBuf ();
            strncpy (tmp, arg, SHBUFLEN);
            tmp[0] = toupper (tmp[0]);
            makePlural (tmp, SHBUFLEN);
            with = tmp;
        } else if ((what = strstr (src, "*randomrace*"))) {
            with = randomRace ();
        } else if ((what = strstr (src, "*randomworld*"))) {
            with = randomWorld ();
        } else if ((what = strstr (src, "*profession*"))) {
            with = Hero.mProfession->mName;
        } else if ((what = strstr (src, "*heroname*"))) {
            with = Hero.cr ()->mName;
        }
        if (what) {
            char *buf = GetBuf ();
            char *line = GetBuf ();
            int length = (what - src);
            strncpy (buf, src, length);
            buf[length] = '\0'; /* Buf might have had contents. */
            ++what;
            while (*what != '*') ++what;
            ++what;
            snprintf (line, SHBUFLEN, "%s%s%s", buf, with, what);
            src = line;
        }
    } while (what);
    return src;
}
Example #3
0
void
fakeProgramLore (shMenu *lore, const char *ilkname)
{ /* Inspired by BOSS floppy disk labels. */
    static const char *noun[] =
    {
        "Programs","Routines","Subroutines","Functions","Procedures",
        "Libraries","Modules","Classes","Binaries","Units","Systems","Addons",
        "Patches","Packages","Software","Executables","Commands","Scripts"
    };
    const int numnouns = sizeof (noun) / sizeof (char *);
    static const char *verb[] =
    {
        "annihilate","analyze","assemble","augment","avoid","build","cleanse",
        "compile","construct","copy","crack","create","delete","detect",
        "derezz","destroy","elude","enhance","enslave","empower","extract",
        "fool","fork","generate","kill","probe","scan","sneak past","spawn",
        "subjugate","summon","survive","terrify","tickle","torture","transform",
        "transport","trash","terminate","unpack","verify"
    };
    const int numverbs = sizeof (verb) / sizeof (char *);
    static const char *numeral[] =
    {
        "a bunch of","a pack of","a lot of","a few","several","some","many",
        "lots of","two","three","four","five","ten","dozens of","tens of",
        "horde of","multitude of"
    };
    const int numnumerals = sizeof (numeral) / sizeof (char *);
    static const char *adjective[] =
    {
        "addictive","alien","amazing","beautiful","bloodthirsty","chaotic",
        "confused","curious","cute","deadly","elite","entrenched","evil",
        "famous","fortified","fresh","friendly","golden","gorgeous","hostile",
        "indifferent","lame","loathsome","lost","meek","molecular","new",
        "obsolete","outdated","peaceful","post-warranty","powerful",
        "radioactive","rainbow","super","tame","unidentified","unwilling",
        "vile","wary","wild"
    };
    const int numadjectives = sizeof (adjective) / sizeof (char *);
    char *buf = GetBuf ();
    char *plural = GetBuf ();
    snprintf (buf, SHBUFLEN, "Download CRACKED software for your %s!", ilkname);
    lore->addText (buf);
    lore->addText ("");
    for (int i = 0; i < 6; ++i) {
        const char *name = NULL;
        if (RNG (2)) {
            int id = RNG (kObjEnergyCell, kObjWreck);
            shObjectIlk *obj = &AllIlks[id];
            if (obj) {
                name = !RNG (20) ? obj->mVague.mName  :
                        RNG  (2) ? obj->mAppearance.mName : obj->mReal.mName;
            } else {
                debug.log ("Error picking a random item (id:%d)", id);
            }
        } else {
            int id = RNG (kMonEarthling, kMonShodan);
            shMonsterIlk *mon = &MonIlks[id];
            if (mon) {
                name = mon->mName;
                if (id == kMonCreepingCredits) {
                    /* Name already in plural. */
                    char *tmp = GetBuf ();
                    strncpy (tmp, name, SHBUFLEN);
                    tmp[15] = '\0'; /* Delete 's'. */
                    name = tmp;
                }
            } else {
                debug.log ("Error picking a random monster (id:%d)", id);
            }
        }
        if (!name) continue; /* Skip a line on error. */
        snprintf (plural, SHBUFLEN, "%s", name);
        makePlural (plural, SHBUFLEN);
        if (RNG (2)) {
            snprintf (buf, SHBUFLEN, "%s %s %s %s %s %s.",
                noun [RNG (numnouns)], RNG (2) ? "to" : "that",
                verb [RNG (numverbs)], numeral [RNG (numnumerals)],
                adjective [RNG (numadjectives)], plural);
        } else {
            snprintf (buf, SHBUFLEN, "%s %s %s %s %s.",
                noun [RNG (numnouns)], RNG (2) ? "to" : "that",
                verb [RNG (numverbs)], adjective [RNG (numadjectives)], plural);
        }
        if (strlen (buf) > 75) {
            --i; /* Retry. */
        } else {
            lore->addText (buf);
        }
    }
    lore->addText ("");
    lore->addText ("(All software provided as is)");
}