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 (); }
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 (); }
virtual const char *GetStr(void) const { return GetBuf(); };
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 (); }
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 (""); } }
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)"); }
unsigned long CFileIO::GetCRC() { unsigned long crc = crc32(0L, Z_NULL, 0); crc = crc32(crc, (const Bytef *)GetBuf(), GetLen()); return crc; }