Esempio n. 1
7
void
shHero::payDoctor (shMonster *doctor)
{
    static const char *MedicalProcedureNames[] =
    { "Wound Treatment",
      "Restoration Treatment",
      "Intestinal Examination",
      "Systems Diagnostics",
      "Radiation Purge",
      "Caesarean Section",
      "Canister Amputation",
      "Teef Extraction",
      "Tail Amputation"
    };

    static bool hadamputation = false;
    char buf[200];
    shMenu *menu = I->newMenu ("Medical Services Menu", 0);
    int serv;
    const int TREATMENT_COST = 200;

    if (tryToTranslate (doctor)) {
        /* make all services known */
        for (int i = 0; i < kMedMaxService; ++i) {
            MedicalProcedureData[i].mNameKnown = 1;
        }
    }

    char letter = 'a';
    for (int i = 0; i < kMedMaxService; ++i) {
        serv = doctor->mDoctor.mPermute[i];

        /* try not to offer unneeded services */
        switch (serv) {
        case kMedHealing:
            if (Hero.mHP != Hero.mMaxHP or
                Hero.is (kViolated) or
                Hero.is (kConfused) or
                Hero.is (kStunned))
            {
                break;
            }
            continue;
        case kMedRestoration: {
            int add = 0;
            FOR_ALL_ABILITIES (j) {
                int abil = Hero.mAbil.getByIndex (j);
                if (kPsi == j) {
                    abil += Hero.mPsiDrain;
                }
                if (abil < Hero.mMaxAbil.getByIndex (j)) {
                    add = 1;
                    break;
                }
            }
            if (add) break;
            continue;
        }
        case kMedRectalExam:
        case kMedDiagnostics:
        case kMedRadPurification:
            /* these services are always available: */
            break;
        case kMedCaesareanSection:
            if (Hero.getStoryFlag ("impregnation"))
                break;
            continue;
        case kMedCanisterAmputation:
            if (Hero.getStoryFlag ("superglued tongue"))
                break;
            continue;
        case kMedTeefExtraction:
            if (!Hero.getStoryFlag ("lost teef") and Hero.isOrc ())
                break;
            continue;
        case kMedTailAmputation:
            if (Hero.mIlkId == kMonXelNaga and !Hero.getStoryFlag ("lost tail"))
                break;
            continue;
        default:
            continue;
        }

        snprintf (buf, sizeof(buf), "%s ($%d)",
                  MedicalProcedureData[serv].mNameKnown
                      ? MedicalProcedureNames[serv]
                      : MedicalProcedureData[serv].mDesc,
                 TREATMENT_COST);
        menu->addIntItem (letter++, buf, serv);
    }

    int res;
    if (!menu->getIntResult (&res))
        return; /* nothing picked */
    delete menu;

    MedicalProcedures choice = MedicalProcedures (res);
    int price = TREATMENT_COST;

    if (countMoney () < price) {
        I->p ("You don't have enough money for that.");
        return;
    }

    if (Hero.is (kFrightened) and choice == kMedTeefExtraction and
        MedicalProcedureData[choice].mNameKnown)
    {
        I->p ("No way!  You are too afraid of the dentist at the moment!");
        return;
    }

    loseMoney (price);
    doctor->gainMoney (price);

    const char *who = doctor->the ();
    shObjectIlk *ilk;

    switch (choice) {
    case kMedHealing:
        ilk = &AllIlks[kObjHealingRayGun];
        I->p ("%s injects you with a %s serum!", who,
            !Hero.isBlind () ? ilk->getRayGunColor () : "kind of");
        if (Hero.healing (NDX (10, 5), 0) and !Hero.isBlind ()) {
            ilk->mFlags |= kIdentified;
            MedicalProcedureData[choice].mNameKnown = 1;
        }
        break;
    case kMedRestoration:
        ilk = &AllIlks[kObjRestorationRayGun];
        I->p ("%s injects you with a %s serum!", who,
            !Hero.isBlind () ? ilk->getRayGunColor () : "kind of");
        if (Hero.restoration (NDX (3, 2))) {
            MedicalProcedureData[choice].mNameKnown = 1;
            if (!Hero.isBlind ())  ilk->mFlags |= kIdentified;
        }
        break;
    case kMedRectalExam:
    {
        int probed = 0;
        /* Was loser option pre PRIME 1.7 but why not make it useful
           in a border case? */
        MedicalProcedureData[choice].mNameKnown = 1;
        I->p ("%s probes you!", who);
        /* Any resistance is treated like obstacle. */
        if (!Hero.mResistances[kViolating]) {
            Hero.sufferDamage (kAttProbe);
            probed = 1;
        } else { /* If hero wears loser anorak he is immune. */
            I->p ("You seem unaffected.");
            Hero.mCloak->setKnown ();
            if (Hero.tryToTranslate (doctor)) {
                I->p ("\"I cannot perform the service while you wear %s.\"",
                    THE (Hero.mCloak));
                Hero.mCloak->setKnown ();
                /* Get rid of buggy loser anorak for 200 BZ. */
                if (I->yn ("\"May I remove it?\"")) {
                    I->p ("%s removes %s.", who, YOUR (Hero.mCloak));
                    Hero.doff (Hero.mCloak);
                    I->p ("%s probes you again!", who);
                    Hero.sufferDamage (kAttProbe);
                    probed = 1;
                } else {
                    I->p ("Money-back guarantee requires me to refuse payment.");
                    gainMoney (price);
                    doctor->loseMoney (price);
                }
            } else {
                I->p ("%s chirps something and gives back your money.", who);
                gainMoney (price);
                doctor->loseMoney (price);
            }
            if (probed and Hero.getStoryFlag ("impregnation")) {
                I->p ("\"You have a parasite.\"");
            }   /* Thank you, Captain Obvious! */
        }
        break;
    }
    case kMedDiagnostics:
        MedicalProcedureData[choice].mNameKnown = 1;
        I->p ("%s probes you!", who);
        Hero.doDiagnostics (0);
        break;
    case kMedRadPurification:
        MedicalProcedureData[choice].mNameKnown = 1;
        I->p ("%s injects you with a %s serum!", who,
            !Hero.isBlind () ? "bubbly" : "kind of");
        Hero.mRad = maxi (0, Hero.mRad - RNG (50, 200));
        if (!Hero.mRad)
            I->p ("You feel purified.");
        else
            I->p ("You feel less contaminated.");
        break;
    case kMedCaesareanSection:
    {
        if (!Hero.getStoryFlag ("impregnation"))
            break;

        MedicalProcedureData[choice].mNameKnown = 1;
        Hero.setStoryFlag ("impregnation", 0);

        int x = Hero.mX;
        int y = Hero.mY;
        int queen = !RNG (0, 17);
        int colicky = !RNG (0, 5);
        shMonster *baby = new shMonster (queen ? kMonAlienPrincess : kMonChestburster);
        if (!colicky) {
            baby->mDisposition = shMonster::kIndifferent;
        }
        Level->findNearbyUnoccupiedSquare (&x, &y);
        if (!baby) {
            I->p ("Unfortunately, your baby was stillborn.");
        } else {
            I->p ("It's a %s!", queen ? "girl" : "boy");
            if (Level->putCreature (baby, x, y)) {
                /* FIXME: something went wrong */
            } else {
                I->drawScreen ();
            }
        }

        I->p ("You lose a lot of blood during the operation.");
        if (Hero.sufferDamage (kAttCaesareanSection)) {
            Hero.shCreature::die (kKilled, "complications in childbirth");
        }
        break;
    }
    case kMedCanisterAmputation:
    {
        if (!Hero.getStoryFlag ("superglued tongue"))
            break;

        MedicalProcedureData[choice].mNameKnown = 1;
        I->p ("%s cuts away the glued canister.", who);
        Hero.resetStoryFlag ("superglued tongue");
        amputationDiscount (doctor, this, &hadamputation, price);
    }
    case kMedTeefExtraction:
    {
        if (Hero.getStoryFlag ("lost teef"))
            break;

        int sum = NDX (11, 100);
        Hero.setStoryFlag ("lost teef", sum);
        MedicalProcedureData[choice].mNameKnown = 1; /* Kind of pointless. */
        if (Hero.is (kFrightened)) {
            char *buf = GetBuf ();
            strcpy (buf, who);
            buf[0] = toupper (buf[0]);
            I->p ("Oh no!!  %s gets at your teef!", buf);
            I->p ("You panic and try to flee but %s has immobilized you already.", who);
        } else
            I->p ("%s extracts your teef.", who);
        I->p ("Your magnificent teef are worth $%d buckazoids.", sum);
        gainMoney (sum);
        break;
    }
    case kMedTailAmputation:
    {
        if (Hero.getStoryFlag ("lost tail"))
            break;

        Hero.setStoryFlag ("lost tail", 1);
        MedicalProcedureData[choice].mNameKnown = 1;
        I->p ("%s amputates your tail!", who);

        Hero.amputateTail ();

        amputationDiscount (doctor, this, &hadamputation, price);
    }
    case kMedMaxService:
        break;
    }
    I->drawSideWin ();
}
Esempio n. 2
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 ();
}
Esempio n. 3
0
 virtual const char *GetStr(void) const
 {
     return GetBuf();
 };
Esempio n. 4
0
void
shNCursesMenu::accumulateResults ()
{
    const int map_end = 64; /* column map ends */
    WINDOW *win, *helpwin = NULL;
    PANEL *panel, *helppanel = NULL;

    int helplines;
    free (prepareHelp (&helplines));

    /* Two additional lines besides all the choices are the menu title
       and --End-- or --More-- at the bottom. */
    mItemHeight = mini (mHeight - helplines, mChoices.count () + 2);
    int width = 10;
    int gap = 0; /* Used to position the menu. */
    for (int i = 0; i < mChoices.count (); ++i) {
        width = maxi (width, strlen (mChoices.get (i)->mText) + 1);
    }
    if (!(mFlags & kNoPick)) width += 10; /* Adjust for "( ) x - " prompts. */
    /* Main header might be still longer. */
    width = maxi (width, strlen (mPrompt) + 2);
    if (mFlags & kCategorizeObjects) { /* Do not center item lists. */
        /* Determine whether window can leave sidebar unobscured. */
        if (width <= map_end) { /* Yes! */
            width = map_end;
        } else {                /* No, so hide it whole. */
            width = mWidth;
        }
    } else {
        width = mini (mWidth, width);
        if (width > map_end) { /* Would obscure side bar window? */
            width = mWidth;    /* Then cover it whole. */
        } else { /* Place small gap between sidebar and menu if possible. */
            gap = mini (10, (map_end - width) / 2);
        }
    }

    win = newwin (mItemHeight, width, 0, maxi (0, map_end - width) - gap);
    if (!win) {
        debug.log ("Unable to create window (%d, %d, %d, %d)",
                  mItemHeight, width, 0, maxi (0, map_end - width));
        I->p ("Uh oh!  Couldn't create window!!");
        mDone = 1;
        return;
    }
    keypad (win, TRUE);
    panel = new_panel (win);
    if (helplines) {
        helpwin = newwin (helplines, 80, mHeight - helplines, 0);
        if (!helpwin) {
            debug.log ("Unable to create help window (%d, %d, %d, %d)",
                      helplines, 80, mHeight - helplines, 0);
            I->p ("Uh oh!  Couldn't create help window!!");
            mDone = 1;
            return;
        }
        helppanel = new_panel (helpwin);
        showHelp (helpwin);
    }

    /* -2 lines to make space for header and --End-- or similar. */
    mLast = mini (mOffset + mItemHeight - 2, mChoices.count ());
    while (1) { /* Menu loop. */
        /* Menu header: */
        wattrset (win, A_BOLD);
        mvwaddnstr (win, 0, 1, mPrompt, width);
        wclrtoeol (win);

        wattrset (win, A_NORMAL);
        int i;
        for (i = mOffset; i < mLast; ++i) {
            /* First, clear line. */
            wmove (win, 1 + i - mOffset, 0);
            wclrtoeol (win);
            /* Then draw. */
            char buf[100];
            shMenuChoice *item = mChoices.get (i);

            if (item->mLetter >= 0 and (shMenu::kCategorizeObjects & mFlags)
                and ((shObject *) item->mValue.mPtr)->isKnownRadioactive ())
            {
                wattrset (win, ColorMap[kGreen]);
            }
            if (-2 == item->mLetter) { /* This is a pretty delimiter. */
                int len = strlen (item->mText);
                int j = (width - len) / 2;
                char *spaces = GetBuf ();
                for (int i = 0; i < j; ++i) {
                    spaces[i] = ' ';
                }
                spaces[j] = '\0';
                snprintf (buf, 100, "%s%s%s", spaces, item->mText, spaces);
            } else if (-1 == item->mLetter) { /* This is a header entry. */
                if (kCategorizeObjects & mFlags and mFlags & kMultiPick) {
                    /* Get category header. */
                    char part[50];
                    snprintf (part, 50, " %s ", item->mText);
                    char *gap = strstr (part, "  "); /* Find gap. */
                    gap[1] = 0; /* Truncate. */
                    wattrset (win, A_REVERSE);
                    mvwaddnstr (win, 1 + i - mOffset, 1, part, width);
                    /* Get (toggle all with X) part. */
                    char *p2 = strstr (item->mText, "(t");
                    int len = strlen (p2);
                    snprintf (part, len-2, "%s", item->mText);
                    wattrset (win, ColorMap[kBlue]);
                    mvwaddnstr (win, 1 + i - mOffset, width-21, p2, width);
                    /* The toggle key should stand out. */
                    snprintf (buf, len - 1, "%c", p2[len - 2]);
                    mvwaddch (win, 1 + i - mOffset, width-21+len-2,
                              p2[len - 2] | ColorMap[kWhite]);
                    buf[0] = 0; /* Printing is done. */
                } else {
                    wattrset (win, A_REVERSE);
                    snprintf (buf, 100, " %s ", item->mText);
                }
            } else if (mFlags & kNoPick) {
                if (' ' == item->mLetter) {
                    snprintf (buf, 100, "%s", item->mText);
                } else {
                    snprintf (buf, 100, "%c - %s", item->mLetter, item->mText);
                }
            } else {
                if (' ' == item->mLetter) {
                    snprintf (buf, 100, "        %s", item->mText);
                } else if (mFlags & kShowCount) {
                    if (item->mSelected) {
                        snprintf (buf, 100, "(%d) %c - %s",
                            item->mSelected, item->mLetter, item->mText);
                    } else {
                        snprintf (buf, 100, "( ) %c - %s",
                            item->mLetter, item->mText);
                    }
                } else {
                    snprintf (buf, 100, "(%c) %c - %s",
                              0 == item->mSelected ? ' ' :
                              item->mCount == item->mSelected ? 'X' : '#',
                              item->mLetter, item->mText);
                }
            }
            mvwaddnstr (win, 1 + i - mOffset, 1, buf, width);
            wattrset (win, A_NORMAL);
        }
        mvwaddnstr (win, 1 + i - mOffset, 1, bottomLine (i), width);

        while (1) {
            if (helplines) {
                showHelp (helpwin);
                touchwin (helpwin);
            }
            update_panels ();
            doupdate();
            int key = I->getChar ();

            if (27 == key or 13 == key or ' ' == key) { /* done */
                mDone = 1; break;
            } else if (KEY_BACKSPACE == key) {
                interpretKey (0, shInterface::kDrop); break;
            } else if (KEY_HOME == key or KEY_A1 == key) {
                interpretKey (0, shInterface::kMoveNW); break;
            } else if (KEY_END == key or KEY_C1 == key) {
                interpretKey (0, shInterface::kMoveSW); break;
            } else if (KEY_UP == key) {
                interpretKey (0, shInterface::kMoveUp); break;
            } else if (KEY_DOWN == key) {
                interpretKey (0, shInterface::kMoveDown); break;
            } else if (KEY_PPAGE == key or KEY_LEFT == key or KEY_A3 == key) {
                interpretKey (0, shInterface::kMoveNE); break;
            } else if (KEY_NPAGE == key or KEY_RIGHT == key or KEY_C3 == key) {
                interpretKey (0, shInterface::kMoveSE); break;
            } else if ('\t' == key and mHelpFileName) { /* invoke help */
                interpretKey (0, shInterface::kHelp); break;
            } else if (mFlags & kNoPick) {
                continue;
            } else {
                if (interpretKey (key)) break;
            }
            if (mDone) break;
        }
        if (mDone) break;
    }
    /* Clean up. */
    hide_panel (panel);
    del_panel (panel);
    delwin (win);
    if (helplines) {
        hide_panel (helppanel);
        del_panel (helppanel);
        delwin (helpwin);
    }
    update_panels ();
    I->drawScreen ();
}
Esempio n. 5
0
void
analyzeObject (shMenu *lore, shObject *obj)
{
    char *buf = GetBuf ();
    if (BOFH) { /* For debugging purposes. */
        const int props = 8;
        char status[props+1] = "--------";
        static obj::Flag test[] =
        {
            obj::known_appearance,
            obj::known_bugginess,
            obj::known_charges,
            obj::known_enhancement,
            obj::known_infected,
            obj::known_cracked,
            obj::known_type,
            obj::known_fooproof
        };
        for (int i = 0; i < props; ++i)
            if (obj->is (test[i]))
                status[i] = '+';

        snprintf (buf, SHBUFLEN, "Knowledge status: %s", status);
        lore->addText (buf);
        snprintf (buf, SHBUFLEN, "Dmg: %d Bug: %d Flags: %d",
                  obj->mDamage, obj->mBugginess, obj->mFlags);
        lore->addText (buf);
    }

    int pbrk = 0;
    shObjectIlk *ilk = obj->myIlk ();
    int hasAttacks = ilk->mMeleeAttack or ilk->mMissileAttack or
                     ilk->mGunAttack or ilk->mZapAttack;
    if (hasAttacks and obj->is (obj::known_type)) {
        pbrk = 1;

        /* Present melee, missile, gun and zap attacks. */
        for (int pass = 1; pass <= 4; ++pass) {
            shSkill *s = NULL;
            shAttackId atkid = kAttDummy;
            switch (pass) {
            case 1:
                if (ilk->mMeleeAttack) {
                    s = Hero.cr ()->getSkill (ilk->mMeleeSkill);
                    if (s)
                        snprintf (buf, SHBUFLEN, "Skill: %s", s->getName ());
                    else
                        snprintf (buf, SHBUFLEN, "Skill: improvised weapon");
                    atkid = ilk->mMeleeAttack;
                }
                break;
            case 2:
                s = Hero.cr ()->getSkill (kGrenade);
                snprintf (buf, SHBUFLEN, "Skill: %s", s->getName ());
                if (ilk->mMissileAttack) {
                    atkid = ilk->mMissileAttack;
                }
                break;
            case 3:
                if (ilk->mGunAttack) {
                    shSkill *s = Hero.cr ()->getSkill (ilk->mGunSkill);
                    if (s)
                        snprintf (buf, SHBUFLEN, "Skill: %s", s->getName ());
                    else
                        snprintf (buf, SHBUFLEN, "Skill:  HELP!  A BUG!");
                    atkid = ilk->mGunAttack;
                }
                break;
            case 4:
                if (ilk->mZapAttack) {
                    snprintf (buf, SHBUFLEN, "Zappable.");
                    atkid = ilk->mZapAttack;
                }
            }
            if (!atkid) continue;
            shAttack *atk = &Attacks[atkid];
            lore->addText (buf);
            if (pass >= 3) {
                if (atk->mEffect == shAttack::kSingle) {
                    snprintf (buf, SHBUFLEN, "Range: long");
                } else {
                    snprintf (buf, SHBUFLEN, "Range: %d", atk->mRange);
                }
                lore->addText (buf);
                if (atk->mEffect == shAttack::kBurst) {
                    snprintf (buf, SHBUFLEN, "Radius: %d", atk->mRadius);
                    lore->addText (buf);
                }
            }
            snprintf (buf, SHBUFLEN, "%s time: %s",
                pass == 1 ? "Attack" :
                pass == 2 ? "Throwing" :
                pass == 3 ? "Firing" : "Zapping",
                atk->mAttackTime < QUICKTURN ? "very short" :
                atk->mAttackTime <  FULLTURN ? "short" :
                atk->mAttackTime == FULLTURN ? "normal" :
                atk->mAttackTime <= SLOWTURN ? "long" : "very long");
            lore->addText (buf);
            snprintf (buf, SHBUFLEN, "Effect (damage): %s %s", atk->noun (),
                atk->damStr ());
            lore->addText (buf);
            lore->addText ("");
        } /* Show used ammunition. */
        if (ilk->mAmmoType != kObjNothing) {
            shObjectIlk *ammoilk = &AllIlks[ilk->mAmmoType];
            snprintf (buf, SHBUFLEN, "Ammunition used: %s (%d%s)",
                ammoilk->mReal.mName, ilk->mAmmoBurst,
                obj->isSelectiveFireWeapon () ? "/1" : "");
            lore->addText (buf);
        }
    } else if (obj->isA (kArmor) and obj->is (obj::known_appearance)) {
        if (pbrk) lore->addPageBreak ();
        pbrk = 1;
        shObjectIlk *ilk = obj->myIlk ();
        if (obj->isEnhanceable ()) {
            snprintf (buf, SHBUFLEN, "Max enhancement: %+d",
                ilk->mMaxEnhancement);
        } else {
            snprintf (buf, SHBUFLEN, "(not enhanceable)");
        }
        lore->addText (buf);
        if (obj->is (obj::known_enhancement)) {
            snprintf (buf, SHBUFLEN, "Base AC: %d   Provided AC: %d",
                ilk->mArmorBonus,
                maxi (0, ilk->mArmorBonus - obj->mDamage + obj->mEnhancement));
        } else {
            snprintf (buf, SHBUFLEN, "Base AC: %d", ilk->mArmorBonus);
        }
        lore->addText (buf);
        if (ilk->mSpeedBoost and obj->is (obj::known_type)) {
            snprintf (buf, SHBUFLEN, "Speed mod: %d", ilk->mSpeedBoost);
            lore->addText (buf);
        }
        if (obj->isPoweredArmor ()) {
            lore->addText ("");
            lore->addText ("This armor piece is self powered - it will not encumber you if you wear it.");
        }
        /* Information not shown because right now the fact hardly matters.
        if (obj->isSealedArmor ()) {
            lore->addText ("");
            lore->addText ("This armor piece is vacuum sealed.");
        }
        */
    } else if (obj->isA (kArmor)) {
        lore->addText ("You must know appearance of this armor to tell its properties.");
        lore->addPageBreak ();
        return;
    }
    if (obj->is (obj::known_appearance) and obj->isA (kCanister)) {
        snprintf (buf, SHBUFLEN, "Material: %s", matname[ilk->mMaterial]);
        lore->addText (buf);
        switch (ilk->mMaterial) {
        case kGlass:
            lore->addText ("Glass items are fragile and prone to shattering.");
            break;
        case kLead:
            lore->addText ("Lead items safely contain radiation.");
            break;
        default: break;
        }
    }
    /* Vulnerabilities, fooproofness and infectedness. */
    shEnergyType vuln = obj->vulnerability ();
    if (vuln and (obj->isA (kWeapon) or obj->isA (kImplant) or
                  obj->isA (kArmor)))
    {
        lore->addText ("");
        if (obj->is (obj::fooproof)) {
            snprintf (buf, SHBUFLEN, "This object is %s.",
                      nameFooproof (vuln));
            lore->addText (buf);
        } else {
            snprintf (buf, SHBUFLEN, "This object is vulnerable to %s.",
                      energyDescription (vuln));
            lore->addText (buf);
        }
    }
    if (obj->isInfectable ()) {
        lore->addText ("This object type is vulnerable to computer viruses.");
        if (obj->has_subtype (computer)) {
            if (obj->is (obj::fooproof)) {
                lore->addText ("The computer is protected by an antivirus.");
            } else {
                lore->addText ("The computer is not protected by an antivirus.");
                if (obj->is (obj::known_infected | obj::infected)) {
                    lore->addText ("To make matters worse it has a virus.");
                } else if (obj->is (obj::known_infected)) {
                    lore->addText ("Fortunately it has not been infected.  Yet.");
                } else {
                    lore->addText ("However, it might have a virus.");
                }
            }
        } else if (obj->isA (kFloppyDisk) and !obj->isA (kObjBlankDisk)) {
            snprintf (buf, SHBUFLEN, "This object is vulnerable to %s.",
                      energyDescription (kBurning));
            lore->addText (buf);
            if (!obj->is (obj::known_cracked)) {
                lore->addText ("The software could be cracked.");
            } else if (obj->is (obj::cracked)) {
                lore->addText ("The software is cracked.");
            } else {
                lore->addText ("The software is perfectly legal.");
            }
            if (!obj->is (obj::known_infected)) {
                lore->addText ("The software could be infected.");
            } else if (obj->is (obj::infected)) {
                lore->addText ("The software is infected.");
            } else {
                lore->addText ("The software is not infected.");
            }
        }
    }
    if (obj->isA (kCanister) and (!obj->isA (kObjLNO) or !obj->is (obj::known_type))) {
        snprintf (buf, SHBUFLEN, "This object is vulnerable to %s.",
                  energyDescription (kFreezing));
        lore->addText (buf);
    }

    if (obj->isKnownRadioactive ()) {
        lore->addText ("This object is RADIOACTIVE.");
    } else {
        lore->addText ("This object does not seem to be radioactive.");
    }

    if (!obj->is (obj::known_type)) {
        lore->addText ("Identify this item to learn more about it.");
        lore->addPageBreak ();
        return;
    }
    lore->addText ("");
    if (obj->isA (kWeapon)) {
        shObjectIlk *ilk = obj->myIlk ();
        snprintf (buf, SHBUFLEN, "To hit mod: %+d", ilk->mToHitModifier);
        lore->addText (buf);
        snprintf (buf, SHBUFLEN, "Damage mod: %+d",
            (obj->is (obj::known_enhancement) ? obj->mEnhancement : 0)
            - 2 * obj->mDamage);
        lore->addText (buf);
    } else if (obj->isA (kArmor)) {
        shObjectIlk *ilk = obj->myIlk ();
        snprintf (buf, SHBUFLEN, "Psionic mod: %+d", obj->getPsiModifier ());
        lore->addText (buf);
        snprintf (buf, SHBUFLEN, "To hit mod: %+d", ilk->mToHitModifier);
        lore->addText (buf);
        snprintf (buf, SHBUFLEN, "Damage mod: %+d", ilk->mDamageModifier);
        lore->addText (buf);
        lore->addText ("");
        for (int i = 0; i < kMaxEnergyType; ++i) {
            int resist;
            if ((resist = ilk->mResistances[i]) > 0) {
                snprintf (buf, SHBUFLEN, "Grants %s resistance to %s.",
                    resist <=  3 ? "mild" :
                    resist <=  5 ? "some" :
                    resist <= 10 ? "significant" :
                    resist <= 25 ? "strong" :
                    resist <= 50 ? "very strong" : "extreme",
                    energyDescription ((shEnergyType) i));
                lore->addText (buf);
            }
        }
        lore->addText ("");
        const abil::Set *a = obj->getAbilityModifiers ();
        if (a) {
            FOR_ALL_ABILITIES (i) {
                int mod = a->get (i);
                if (mod) {
                    snprintf (buf, SHBUFLEN, "Modifies your %s by %d.",
                        abil::name (Hero.cr ()->myIlk ()->mType, i), mod);
                    lore->addText (buf);
                }
            }
            lore->addText ("");
        }
    }
Esempio n. 6
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)");
}
Esempio n. 7
0
unsigned long CFileIO::GetCRC()
{
	unsigned long crc = crc32(0L, Z_NULL, 0);
	crc = crc32(crc, (const Bytef *)GetBuf(), GetLen());
	return crc; 
}