boolean init;
boolean artif;
{
- int mndx, tryct;
- struct obj *otmp;
- char let = objects[otyp].oc_class;
-
- otmp = newobj();
- *otmp = zeroobj;
- otmp->age = monstermoves;
- otmp->o_id = context.ident++;
- if (!otmp->o_id) otmp->o_id = context.ident++; /* ident overflowed */
- otmp->quan = 1L;
- otmp->oclass = let;
- otmp->otyp = otyp;
- otmp->where = OBJ_FREE;
- otmp->dknown = index(dknowns, let) ? 0 : 1;
- if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||
- otmp->otyp == SHIELD_OF_REFLECTION)
- otmp->dknown = 0;
- if (!objects[otmp->otyp].oc_uses_known)
- otmp->known = 1;
- otmp->lknown = 0;
- otmp->cknown = 0;
- otmp->corpsenm = NON_PM;
-
- if (init) switch (let) {
- case WEAPON_CLASS:
- otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L;
- if(!rn2(11)) {
- otmp->spe = rne(3);
- otmp->blessed = rn2(2);
- } else if(!rn2(10)) {
- curse(otmp);
- otmp->spe = -rne(3);
- } else blessorcurse(otmp, 10);
- if (is_poisonable(otmp) && !rn2(100))
- otmp->opoisoned = 1;
-
- if (artif && !rn2(20))
- otmp = mk_artifact(otmp, (aligntyp)A_NONE);
- break;
- case FOOD_CLASS:
- otmp->oeaten = 0;
- switch(otmp->otyp) {
- case CORPSE:
- /* possibly overridden by mkcorpstat() */
- tryct = 50;
- do otmp->corpsenm = undead_to_corpse(rndmonnum());
- while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0));
- if (tryct == 0) {
- /* perhaps rndmonnum() only wants to make G_NOCORPSE monsters on
- this level; let's create an adventurer's corpse instead, then */
- otmp->corpsenm = PM_HUMAN;
- }
- /* timer set below */
- break;
- case EGG:
- otmp->corpsenm = NON_PM; /* generic egg */
- if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) {
- mndx = can_be_hatched(rndmonnum());
- if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
- otmp->corpsenm = mndx; /* typed egg */
- break;
- }
- }
- /* timer set below */
- break;
- case TIN:
- otmp->corpsenm = NON_PM; /* empty (so far) */
- if (!rn2(6))
- set_tin_variety(otmp, SPINACH_TIN);
- else for (tryct = 200; tryct > 0; --tryct) {
- mndx = undead_to_corpse(rndmonnum());
- if (mons[mndx].cnutrit &&
- !(mvitals[mndx].mvflags & G_NOCORPSE)) {
- otmp->corpsenm = mndx;
- set_tin_variety(otmp, RANDOM_TIN);
- break;
- }
- }
- blessorcurse(otmp, 10);
- break;
- case SLIME_MOLD:
- otmp->spe = context.current_fruit;
- flags.made_fruit = TRUE;
- break;
- case KELP_FROND:
- otmp->quan = (long) rnd(2);
- break;
- }
- if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING &&
- otmp->otyp != KELP_FROND && !rn2(6))
- otmp->quan = 2L;
- break;
- case GEM_CLASS:
- otmp->corpsenm = 0; /* LOADSTONE hack */
- if (otmp->otyp == LOADSTONE) curse(otmp);
- else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6);
- else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L;
- else otmp->quan = 1L;
- break;
- case TOOL_CLASS:
- switch(otmp->otyp) {
- case TALLOW_CANDLE:
- case WAX_CANDLE: otmp->spe = 1;
- otmp->age = 20L * /* 400 or 200 */
- (long)objects[otmp->otyp].oc_cost;
- otmp->lamplit = 0;
- otmp->quan = 1L +
- (long)(rn2(2) ? rn2(7) : 0);
- blessorcurse(otmp, 5);
- break;
- case BRASS_LANTERN:
- case OIL_LAMP: otmp->spe = 1;
- otmp->age = (long) rn1(500,1000);
- otmp->lamplit = 0;
- blessorcurse(otmp, 5);
- break;
- case MAGIC_LAMP: otmp->spe = 1;
- otmp->lamplit = 0;
- blessorcurse(otmp, 2);
- break;
- case CHEST:
- case LARGE_BOX: otmp->olocked = !!(rn2(5));
- otmp->otrapped = !(rn2(10));
- case ICE_BOX:
- case SACK:
- case OILSKIN_SACK:
- case BAG_OF_HOLDING: mkbox_cnts(otmp);
- break;
- case LEASH: otmp->leashmon = 0;
- break;
- case EXPENSIVE_CAMERA:
- case TINNING_KIT:
- case MAGIC_MARKER: otmp->spe = rn1(70,30);
- break;
- case CAN_OF_GREASE: otmp->spe = rnd(25);
- blessorcurse(otmp, 10);
- break;
- case CRYSTAL_BALL: otmp->spe = rnd(5);
- blessorcurse(otmp, 2);
- break;
- case HORN_OF_PLENTY:
- case BAG_OF_TRICKS: otmp->spe = rnd(20);
- break;
- case FIGURINE: { int tryct2 = 0;
- do
- otmp->corpsenm = rndmonnum();
- while(is_human(&mons[otmp->corpsenm])
- && tryct2++ < 30);
- blessorcurse(otmp, 4);
- break;
- }
- case BELL_OF_OPENING: otmp->spe = 3;
- break;
- case MAGIC_FLUTE:
- case MAGIC_HARP:
- case FROST_HORN:
- case FIRE_HORN:
- case DRUM_OF_EARTHQUAKE:
- otmp->spe = rn1(5,4);
- break;
- }
- break;
- case AMULET_CLASS:
- if (otmp->otyp == AMULET_OF_YENDOR) context.made_amulet = TRUE;
- if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION ||
- otmp->otyp == AMULET_OF_CHANGE ||
- otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
- curse(otmp);
- } else blessorcurse(otmp, 10);
- case VENOM_CLASS:
- case CHAIN_CLASS:
- case BALL_CLASS:
- break;
- case POTION_CLASS:
- otmp->fromsink = 0;
- if (otmp->otyp == POT_OIL)
- otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
- /* fall through */
- case SCROLL_CLASS:
+ int mndx, tryct;
+ struct obj *otmp;
+ char let = objects[otyp].oc_class;
+
+ otmp = newobj();
+ *otmp = zeroobj;
+ otmp->age = monstermoves;
+ otmp->o_id = context.ident++;
+ if (!otmp->o_id) otmp->o_id = context.ident++; /* ident overflowed */
+ otmp->quan = 1L;
+ otmp->oclass = let;
+ otmp->otyp = otyp;
+ otmp->where = OBJ_FREE;
+ otmp->dknown = index(dknowns, let) ? 0 : 1;
+ if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||
+ otmp->otyp == SHIELD_OF_REFLECTION)
+ otmp->dknown = 0;
+ if (!objects[otmp->otyp].oc_uses_known)
+ otmp->known = 1;
+ otmp->lknown = 0;
+ otmp->cknown = 0;
+ otmp->corpsenm = NON_PM;
+
+ if (init) switch (let) {
+ case WEAPON_CLASS:
+ otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L;
+ if(!rn2(11)) {
+ otmp->spe = rne(3);
+ otmp->blessed = rn2(2);
+ } else if(!rn2(10)) {
+ curse(otmp);
+ otmp->spe = -rne(3);
+ } else blessorcurse(otmp, 10);
+ if (is_poisonable(otmp) && !rn2(100))
+ otmp->opoisoned = 1;
+
+ if (artif && !rn2(20))
+ otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+ break;
+ case FOOD_CLASS:
+ otmp->oeaten = 0;
+ switch(otmp->otyp) {
+ case CORPSE:
+ /* possibly overridden by mkcorpstat() */
+ tryct = 50;
+ do otmp->corpsenm = undead_to_corpse(rndmonnum());
+ while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0));
+ if (tryct == 0) {
+ /* perhaps rndmonnum() only wants to make G_NOCORPSE monsters on
+ this level; let's create an adventurer's corpse instead, then */
+ otmp->corpsenm = PM_HUMAN;
+ }
+ /* timer set below */
+ break;
+ case EGG:
+ otmp->corpsenm = NON_PM; /* generic egg */
+ if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) {
+ mndx = can_be_hatched(rndmonnum());
+ if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
+ otmp->corpsenm = mndx; /* typed egg */
+ break;
+ }
+ }
+ /* timer set below */
+ break;
+ case TIN:
+ otmp->corpsenm = NON_PM; /* empty (so far) */
+ if (!rn2(6))
+ set_tin_variety(otmp, SPINACH_TIN);
+ else for (tryct = 200; tryct > 0; --tryct) {
+ mndx = undead_to_corpse(rndmonnum());
+ if (mons[mndx].cnutrit &&
+ !(mvitals[mndx].mvflags & G_NOCORPSE)) {
+ otmp->corpsenm = mndx;
+ set_tin_variety(otmp, RANDOM_TIN);
+ break;
+ }
+ }
+ blessorcurse(otmp, 10);
+ break;
+ case SLIME_MOLD:
+ otmp->spe = context.current_fruit;
+ flags.made_fruit = TRUE;
+ break;
+ case KELP_FROND:
+ otmp->quan = (long) rnd(2);
+ break;
+ }
+ if (Is_pudding(otmp)) {
+ otmp->globby = 1;
+ otmp->known = otmp->bknown = otmp->rknown = otmp->dknown = 1;
+ otmp->corpsenm = PM_GRAY_OOZE + (otmp->otyp - GLOB_OF_GRAY_OOZE);
+ /* this ensures that they don't fail merging because of
+ * BUC status or other irrelevancies */
+ } else {
+ if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING
+ && otmp->otyp != KELP_FROND && !rn2(6)) {
+ otmp->quan = 2L;
+ }
+ }
+ break;
+ case GEM_CLASS:
+ otmp->corpsenm = 0; /* LOADSTONE hack */
+ if (otmp->otyp == LOADSTONE) curse(otmp);
+ else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6);
+ else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L;
+ else otmp->quan = 1L;
+ break;
+ case TOOL_CLASS:
+ switch(otmp->otyp) {
+ case TALLOW_CANDLE:
+ case WAX_CANDLE: otmp->spe = 1;
+ otmp->age = 20L * /* 400 or 200 */
+ (long)objects[otmp->otyp].oc_cost;
+ otmp->lamplit = 0;
+ otmp->quan = 1L +
+ (long)(rn2(2) ? rn2(7) : 0);
+ blessorcurse(otmp, 5);
+ break;
+ case BRASS_LANTERN:
+ case OIL_LAMP: otmp->spe = 1;
+ otmp->age = (long) rn1(500,1000);
+ otmp->lamplit = 0;
+ blessorcurse(otmp, 5);
+ break;
+ case MAGIC_LAMP: otmp->spe = 1;
+ otmp->lamplit = 0;
+ blessorcurse(otmp, 2);
+ break;
+ case CHEST:
+ case LARGE_BOX: otmp->olocked = !!(rn2(5));
+ otmp->otrapped = !(rn2(10));
+ case ICE_BOX:
+ case SACK:
+ case OILSKIN_SACK:
+ case BAG_OF_HOLDING: mkbox_cnts(otmp);
+ break;
+ case LEASH: otmp->leashmon = 0;
+ break;
+ case EXPENSIVE_CAMERA:
+ case TINNING_KIT:
+ case MAGIC_MARKER: otmp->spe = rn1(70,30);
+ break;
+ case CAN_OF_GREASE: otmp->spe = rnd(25);
+ blessorcurse(otmp, 10);
+ break;
+ case CRYSTAL_BALL: otmp->spe = rnd(5);
+ blessorcurse(otmp, 2);
+ break;
+ case HORN_OF_PLENTY:
+ case BAG_OF_TRICKS: otmp->spe = rnd(20);
+ break;
+ case FIGURINE: { int tryct2 = 0;
+ do
+ otmp->corpsenm = rndmonnum();
+ while(is_human(&mons[otmp->corpsenm])
+ && tryct2++ < 30);
+ blessorcurse(otmp, 4);
+ break;
+ }
+ case BELL_OF_OPENING: otmp->spe = 3;
+ break;
+ case MAGIC_FLUTE:
+ case MAGIC_HARP:
+ case FROST_HORN:
+ case FIRE_HORN:
+ case DRUM_OF_EARTHQUAKE:
+ otmp->spe = rn1(5,4);
+ break;
+ }
+ break;
+ case AMULET_CLASS:
+ if (otmp->otyp == AMULET_OF_YENDOR) context.made_amulet = TRUE;
+ if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION ||
+ otmp->otyp == AMULET_OF_CHANGE ||
+ otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
+ curse(otmp);
+ } else blessorcurse(otmp, 10);
+ case VENOM_CLASS:
+ case CHAIN_CLASS:
+ case BALL_CLASS:
+ break;
+ case POTION_CLASS:
+ otmp->fromsink = 0;
+ if (otmp->otyp == POT_OIL)
+ otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
+ /* fall through */
+ case SCROLL_CLASS:
#ifdef MAIL
- if (otmp->otyp != SCR_MAIL)
+ if (otmp->otyp != SCR_MAIL)
#endif
- blessorcurse(otmp, 4);
- break;
- case SPBOOK_CLASS:
- otmp->spestudied = 0;
- blessorcurse(otmp, 17);
- break;
- case ARMOR_CLASS:
- if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS ||
- otmp->otyp == LEVITATION_BOOTS ||
- otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT ||
- otmp->otyp == GAUNTLETS_OF_FUMBLING ||
- !rn2(11))) {
- curse(otmp);
- otmp->spe = -rne(3);
- } else if(!rn2(10)) {
- otmp->blessed = rn2(2);
- otmp->spe = rne(3);
- } else blessorcurse(otmp, 10);
- if (artif && !rn2(40))
- otmp = mk_artifact(otmp, (aligntyp)A_NONE);
- /* simulate lacquered armor for samurai */
- if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL &&
- (moves <= 1 || In_quest(&u.uz))) {
+ blessorcurse(otmp, 4);
+ break;
+ case SPBOOK_CLASS:
+ otmp->spestudied = 0;
+ blessorcurse(otmp, 17);
+ break;
+ case ARMOR_CLASS:
+ if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS ||
+ otmp->otyp == LEVITATION_BOOTS ||
+ otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT ||
+ otmp->otyp == GAUNTLETS_OF_FUMBLING ||
+ !rn2(11))) {
+ curse(otmp);
+ otmp->spe = -rne(3);
+ } else if(!rn2(10)) {
+ otmp->blessed = rn2(2);
+ otmp->spe = rne(3);
+ } else blessorcurse(otmp, 10);
+ if (artif && !rn2(40))
+ otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+ /* simulate lacquered armor for samurai */
+ if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL &&
+ (moves <= 1 || In_quest(&u.uz))) {
#ifdef UNIXPC
- /* optimizer bitfield bug */
- otmp->oerodeproof = 1;
- otmp->rknown = 1;
+ /* optimizer bitfield bug */
+ otmp->oerodeproof = 1;
+ otmp->rknown = 1;
#else
- otmp->oerodeproof = otmp->rknown = 1;
+ otmp->oerodeproof = otmp->rknown = 1;
#endif
- }
- break;
- case WAND_CLASS:
- if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else
- otmp->spe = rn1(5,
- (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
- blessorcurse(otmp, 17);
- otmp->recharged = 0; /* used to control recharging */
- break;
- case RING_CLASS:
- if(objects[otmp->otyp].oc_charged) {
- blessorcurse(otmp, 3);
- if(rn2(10)) {
- if(rn2(10) && bcsign(otmp))
- otmp->spe = bcsign(otmp) * rne(3);
- else otmp->spe = rn2(2) ? rne(3) : -rne(3);
- }
- /* make useless +0 rings much less common */
- if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3);
- /* negative rings are usually cursed */
- if (otmp->spe < 0 && rn2(5)) curse(otmp);
- } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION ||
- otmp->otyp == RIN_POLYMORPH ||
- otmp->otyp == RIN_AGGRAVATE_MONSTER ||
- otmp->otyp == RIN_HUNGER || !rn2(9))) {
- curse(otmp);
- }
- break;
- case ROCK_CLASS:
- switch (otmp->otyp) {
- case STATUE:
- /* possibly overridden by mkcorpstat() */
- otmp->corpsenm = rndmonnum();
- if (!verysmall(&mons[otmp->corpsenm]) &&
- rn2(level_difficulty()/2 + 10) > 10)
- (void) add_to_container(otmp,
- mkobj(SPBOOK_CLASS,FALSE));
- }
- break;
- case COIN_CLASS:
- break; /* do nothing */
- default:
- impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
- objects[otmp->otyp].oc_class);
- return (struct obj *)0;
- }
-
- /* some things must get done (corpsenm, timers) even if init = 0 */
- switch (otmp->otyp) {
- case CORPSE:
- if (otmp->corpsenm == NON_PM) {
- otmp->corpsenm = undead_to_corpse(rndmonnum());
- if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE|G_GONE))
- otmp->corpsenm = urole.malenum;
- }
- /*FALLTHRU*/
- case STATUE:
- case FIGURINE:
- if (otmp->corpsenm == NON_PM) otmp->corpsenm = rndmonnum();
- /*FALLTHRU*/
- case EGG:
- /* case TIN: */
- set_corpsenm(otmp, otmp->corpsenm);
- break;
+ }
+ break;
+ case WAND_CLASS:
+ if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else
+ otmp->spe = rn1(5,
+ (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
+ blessorcurse(otmp, 17);
+ otmp->recharged = 0; /* used to control recharging */
+ break;
+ case RING_CLASS:
+ if(objects[otmp->otyp].oc_charged) {
+ blessorcurse(otmp, 3);
+ if(rn2(10)) {
+ if(rn2(10) && bcsign(otmp))
+ otmp->spe = bcsign(otmp) * rne(3);
+ else otmp->spe = rn2(2) ? rne(3) : -rne(3);
+ }
+ /* make useless +0 rings much less common */
+ if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3);
+ /* negative rings are usually cursed */
+ if (otmp->spe < 0 && rn2(5)) curse(otmp);
+ } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION ||
+ otmp->otyp == RIN_POLYMORPH ||
+ otmp->otyp == RIN_AGGRAVATE_MONSTER ||
+ otmp->otyp == RIN_HUNGER || !rn2(9))) {
+ curse(otmp);
+ }
+ break;
+ case ROCK_CLASS:
+ switch (otmp->otyp) {
+ case STATUE:
+ /* possibly overridden by mkcorpstat() */
+ otmp->corpsenm = rndmonnum();
+ if (!verysmall(&mons[otmp->corpsenm]) &&
+ rn2(level_difficulty()/2 + 10) > 10)
+ (void) add_to_container(otmp,
+ mkobj(SPBOOK_CLASS,FALSE));
+ }
+ break;
+ case COIN_CLASS:
+ break; /* do nothing */
+ default:
+ impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
+ objects[otmp->otyp].oc_class);
+ return (struct obj *)0;
+ }
+
+ /* some things must get done (corpsenm, timers) even if init = 0 */
+ switch (otmp->otyp) {
+ case CORPSE:
+ if (otmp->corpsenm == NON_PM) {
+ otmp->corpsenm = undead_to_corpse(rndmonnum());
+ if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE|G_GONE))
+ otmp->corpsenm = urole.malenum;
+ }
+ /*FALLTHRU*/
+ case STATUE:
+ case FIGURINE:
+ if (otmp->corpsenm == NON_PM) otmp->corpsenm = rndmonnum();
+ /*FALLTHRU*/
+ case EGG:
+ /* case TIN: */
+ set_corpsenm(otmp, otmp->corpsenm);
+ break;
+ case SPE_NOVEL:
+ {
+ int novidx = -1;
+ otmp = oname(otmp, noveltitle(&novidx));
+ otmp->novelidx = novidx;
+ }
+ break;
- }
+ }
- /* unique objects may have an associated artifact entry */
- if (objects[otyp].oc_unique && !otmp->oartifact)
- otmp = mk_artifact(otmp, (aligntyp)A_NONE);
- otmp->owt = weight(otmp);
- return(otmp);
+ /* unique objects may have an associated artifact entry */
+ if (objects[otyp].oc_unique && !otmp->oartifact)
+ otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+ otmp->owt = weight(otmp);
+ return(otmp);
}
/*
register struct obj *obj;
unsigned cxn_flags; /* bitmask of CXN_xxx values */
{
- register char *buf;
- register int typ = obj->otyp;
- register struct objclass *ocl = &objects[typ];
- int nn = ocl->oc_name_known, omndx = obj->corpsenm;
- const char *actualn = OBJ_NAME(*ocl);
- const char *dn = OBJ_DESCR(*ocl);
- const char *un = ocl->oc_uname;
+ register char *buf;
+ register int typ = obj->otyp;
+ register struct objclass *ocl = &objects[typ];
+ int nn = ocl->oc_name_known, omndx = obj->corpsenm;
+ const char *actualn = OBJ_NAME(*ocl);
+ const char *dn = OBJ_DESCR(*ocl);
+ const char *un = ocl->oc_uname;
boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
- boolean known, dknown, bknown;
-
- buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
- if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
- actualn = Japanese_item_name(typ);
-
- buf[0] = '\0';
- /*
- * clean up known when it's tied to oc_name_known, eg after AD_DRIN
- * This is only required for unique objects since the article
- * printed for the object is tied to the combination of the two
- * and printing the wrong article gives away information.
- */
- if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
- if (!Blind) obj->dknown = TRUE;
- if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
+ boolean known, dknown, bknown;
- if (iflags.override_ID) {
- known = dknown = bknown = TRUE;
- nn = 1;
- } else {
- known = obj->known;
- dknown = obj->dknown;
- bknown = obj->bknown;
- }
+ buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
+ if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
+ actualn = Japanese_item_name(typ);
- if (obj_is_pname(obj))
- goto nameit;
- switch (obj->oclass) {
- case AMULET_CLASS:
- if (!dknown)
- Strcpy(buf, "amulet");
- else if (typ == AMULET_OF_YENDOR ||
- typ == FAKE_AMULET_OF_YENDOR)
- /* each must be identified individually */
- Strcpy(buf, known ? actualn : dn);
- else if (nn)
- Strcpy(buf, actualn);
- else if (un)
- Sprintf(buf,"amulet called %s", un);
- else
- Sprintf(buf,"%s amulet", dn);
- break;
- case WEAPON_CLASS:
- if (is_poisonable(obj) && obj->opoisoned)
- Strcpy(buf, "poisoned ");
- case VENOM_CLASS:
- case TOOL_CLASS:
- if (typ == LENSES)
- Strcpy(buf, "pair of ");
-
- if (!dknown)
- Strcat(buf, dn ? dn : actualn);
- else if (nn)
- Strcat(buf, actualn);
- else if (un) {
- Strcat(buf, dn ? dn : actualn);
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else
- Strcat(buf, dn ? dn : actualn);
- /* If we use an() here we'd have to remember never to use */
- /* it whenever calling doname() or xname(). */
- if (typ == FIGURINE && omndx != NON_PM)
- Sprintf(eos(buf), " of a%s %s",
- index(vowels, *mons[omndx].mname) ? "n" : "",
- mons[omndx].mname);
- break;
- case ARMOR_CLASS:
- /* depends on order of the dragon scales objects */
- if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
- Sprintf(buf, "set of %s", actualn);
- break;
- }
- if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
-
- if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
- && !dknown) {
- Strcpy(buf, "shield");
- break;
- }
- if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
- Strcpy(buf, "smooth shield");
- break;
- }
+ buf[0] = '\0';
+ /*
+ * clean up known when it's tied to oc_name_known, eg after AD_DRIN
+ * This is only required for unique objects since the article
+ * printed for the object is tied to the combination of the two
+ * and printing the wrong article gives away information.
+ */
+ if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
+ if (!Blind) obj->dknown = TRUE;
+ if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
- if(nn) Strcat(buf, actualn);
- else if(un) {
- if(is_boots(obj))
- Strcat(buf,"boots");
- else if(is_gloves(obj))
- Strcat(buf,"gloves");
- else if(is_cloak(obj))
- Strcpy(buf,"cloak");
- else if(is_helmet(obj))
- Strcpy(buf,"helmet");
- else if(is_shield(obj))
- Strcpy(buf,"shield");
- else
- Strcpy(buf,"armor");
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else Strcat(buf, dn);
- break;
- case FOOD_CLASS:
- if (typ == SLIME_MOLD) {
- register struct fruit *f;
-
- for(f=ffruit; f; f = f->nextf) {
- if(f->fid == obj->spe) {
- Strcpy(buf, f->fname);
- break;
- }
- }
- if (!f) {
- impossible("Bad fruit #%d?", obj->spe);
- Strcpy(buf, "fruit");
- } else if (pluralize) {
- /* ick; already pluralized fruit names
- are allowed--we want to try to avoid
- adding a redundant plural suffix */
- Strcpy(buf, makeplural(makesingular(buf)));
- pluralize = FALSE;
- }
- break;
- }
+ if (iflags.override_ID) {
+ known = dknown = bknown = TRUE;
+ nn = 1;
+ } else {
+ known = obj->known;
+ dknown = obj->dknown;
+ bknown = obj->bknown;
+ }
- Strcpy(buf, actualn);
- if (typ == TIN && known)
- tin_details(obj, omndx, buf);
- break;
- case COIN_CLASS:
- case CHAIN_CLASS:
- Strcpy(buf, actualn);
- break;
- case ROCK_CLASS:
- if (typ == STATUE && omndx != NON_PM)
- Sprintf(buf, "%s%s of %s%s",
- (Role_if(PM_ARCHEOLOGIST) &&
- (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
- actualn,
- type_is_pname(&mons[omndx]) ? "" :
- the_unique_pm(&mons[omndx]) ? "the " :
- index(vowels, *mons[omndx].mname) ? "an " : "a ",
- mons[omndx].mname);
- else Strcpy(buf, actualn);
- break;
- case BALL_CLASS:
- Sprintf(buf, "%sheavy iron ball",
- (obj->owt > ocl->oc_weight) ? "very " : "");
- break;
- case POTION_CLASS:
- if (dknown && obj->odiluted)
- Strcpy(buf, "diluted ");
- if(nn || un || !dknown) {
- Strcat(buf, "potion");
- if(!dknown) break;
- if(nn) {
- Strcat(buf, " of ");
- if (typ == POT_WATER &&
- bknown && (obj->blessed || obj->cursed)) {
- Strcat(buf, obj->blessed ? "holy " : "unholy ");
- }
- Strcat(buf, actualn);
- } else {
- Strcat(buf, " called ");
- Strcat(buf, un);
- }
- } else {
- Strcat(buf, dn);
- Strcat(buf, " potion");
- }
- break;
- case SCROLL_CLASS:
- Strcpy(buf, "scroll");
- if(!dknown) break;
- if(nn) {
- Strcat(buf, " of ");
- Strcat(buf, actualn);
- } else if(un) {
- Strcat(buf, " called ");
- Strcat(buf, un);
- } else if (ocl->oc_magic) {
- Strcat(buf, " labeled ");
- Strcat(buf, dn);
- } else {
- Strcpy(buf, dn);
- Strcat(buf, " scroll");
- }
- break;
- case WAND_CLASS:
- if(!dknown)
- Strcpy(buf, "wand");
- else if(nn)
- Sprintf(buf, "wand of %s", actualn);
- else if(un)
- Sprintf(buf, "wand called %s", un);
- else
- Sprintf(buf, "%s wand", dn);
- break;
- case SPBOOK_CLASS:
- if (typ == SPE_NOVEL) { /* 3.6 tribute */
- if (!dknown) {
- Strcpy(buf, "book");
- } else if (nn) {
- Strcpy(buf, actualn);
- } else if (un) {
- Sprintf(buf, "novel called %s", un);
- } else
- Sprintf(buf, "%s book", dn);
- break;
- } else
- /* end of tribute */
- if (!dknown) {
- Strcpy(buf, "spellbook");
- } else if (nn) {
- if (typ != SPE_BOOK_OF_THE_DEAD)
- Strcpy(buf, "spellbook of ");
- Strcat(buf, actualn);
- } else if (un) {
- Sprintf(buf, "spellbook called %s", un);
- } else
- Sprintf(buf, "%s spellbook", dn);
- break;
- case RING_CLASS:
- if(!dknown)
- Strcpy(buf, "ring");
- else if(nn)
- Sprintf(buf, "ring of %s", actualn);
- else if(un)
- Sprintf(buf, "ring called %s", un);
- else
- Sprintf(buf, "%s ring", dn);
- break;
- case GEM_CLASS:
- {
- const char *rock =
- (ocl->oc_material == MINERAL) ? "stone" : "gem";
- if (!dknown) {
- Strcpy(buf, rock);
- } else if (!nn) {
- if (un) Sprintf(buf,"%s called %s", rock, un);
- else Sprintf(buf, "%s %s", dn, rock);
- } else {
- Strcpy(buf, actualn);
- if (GemStone(typ)) Strcat(buf, " stone");
- }
- break;
- }
- default:
- Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
- }
- if (pluralize) Strcpy(buf, makeplural(buf));
+ if (obj_is_pname(obj))
+ goto nameit;
+ switch (obj->oclass) {
+ case AMULET_CLASS:
+ if (!dknown)
+ Strcpy(buf, "amulet");
+ else if (typ == AMULET_OF_YENDOR ||
+ typ == FAKE_AMULET_OF_YENDOR)
+ /* each must be identified individually */
+ Strcpy(buf, known ? actualn : dn);
+ else if (nn)
+ Strcpy(buf, actualn);
+ else if (un)
+ Sprintf(buf,"amulet called %s", un);
+ else
+ Sprintf(buf,"%s amulet", dn);
+ break;
+ case WEAPON_CLASS:
+ if (is_poisonable(obj) && obj->opoisoned)
+ Strcpy(buf, "poisoned ");
+ case VENOM_CLASS:
+ case TOOL_CLASS:
+ if (typ == LENSES)
+ Strcpy(buf, "pair of ");
+
+ if (!dknown)
+ Strcat(buf, dn ? dn : actualn);
+ else if (nn)
+ Strcat(buf, actualn);
+ else if (un) {
+ Strcat(buf, dn ? dn : actualn);
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else
+ Strcat(buf, dn ? dn : actualn);
+ /* If we use an() here we'd have to remember never to use */
+ /* it whenever calling doname() or xname(). */
+ if (typ == FIGURINE && omndx != NON_PM)
+ Sprintf(eos(buf), " of a%s %s",
+ index(vowels, *mons[omndx].mname) ? "n" : "",
+ mons[omndx].mname);
+ break;
+ case ARMOR_CLASS:
+ /* depends on order of the dragon scales objects */
+ if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
+ Sprintf(buf, "set of %s", actualn);
+ break;
+ }
+ if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
+
+ if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
+ && !dknown) {
+ Strcpy(buf, "shield");
+ break;
+ }
+ if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
+ Strcpy(buf, "smooth shield");
+ break;
+ }
+
+ if(nn) Strcat(buf, actualn);
+ else if(un) {
+ if(is_boots(obj))
+ Strcat(buf,"boots");
+ else if(is_gloves(obj))
+ Strcat(buf,"gloves");
+ else if(is_cloak(obj))
+ Strcpy(buf,"cloak");
+ else if(is_helmet(obj))
+ Strcpy(buf,"helmet");
+ else if(is_shield(obj))
+ Strcpy(buf,"shield");
+ else
+ Strcpy(buf,"armor");
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else Strcat(buf, dn);
+ break;
+ case FOOD_CLASS:
+ if (typ == SLIME_MOLD) {
+ register struct fruit *f;
+
+ for(f=ffruit; f; f = f->nextf) {
+ if(f->fid == obj->spe) {
+ Strcpy(buf, f->fname);
+ break;
+ }
+ }
+ if (!f) {
+ impossible("Bad fruit #%d?", obj->spe);
+ Strcpy(buf, "fruit");
+ } else if (pluralize) {
+ /* ick; already pluralized fruit names
+ are allowed--we want to try to avoid
+ adding a redundant plural suffix */
+ Strcpy(buf, makeplural(makesingular(buf)));
+ pluralize = FALSE;
+ }
+ break;
+ }
+ if (Is_pudding(obj)) {
+ Sprintf(buf, "%s%s",
+ obj->owt < 100 ? "small "
+ : obj->owt > 500 ? "very large "
+ : obj->owt > 300 ? "large "
+ : "", actualn);
+ break;
+ }
+
+ Strcpy(buf, actualn);
+ if (typ == TIN && known)
+ tin_details(obj, omndx, buf);
+ break;
+ case COIN_CLASS:
+ case CHAIN_CLASS:
+ Strcpy(buf, actualn);
+ break;
+ case ROCK_CLASS:
+ if (typ == STATUE && omndx != NON_PM)
+ Sprintf(buf, "%s%s of %s%s",
+ (Role_if(PM_ARCHEOLOGIST) &&
+ (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
+ actualn,
+ type_is_pname(&mons[omndx]) ? "" :
+ the_unique_pm(&mons[omndx]) ? "the " :
+ index(vowels, *mons[omndx].mname) ? "an " : "a ",
+ mons[omndx].mname);
+ else Strcpy(buf, actualn);
+ break;
+ case BALL_CLASS:
+ Sprintf(buf, "%sheavy iron ball",
+ (obj->owt > ocl->oc_weight) ? "very " : "");
+ break;
+ case POTION_CLASS:
+ if (dknown && obj->odiluted)
+ Strcpy(buf, "diluted ");
+ if(nn || un || !dknown) {
+ Strcat(buf, "potion");
+ if(!dknown) break;
+ if(nn) {
+ Strcat(buf, " of ");
+ if (typ == POT_WATER &&
+ bknown && (obj->blessed || obj->cursed)) {
+ Strcat(buf, obj->blessed ? "holy " : "unholy ");
+ }
+ Strcat(buf, actualn);
+ } else {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ }
+ } else {
+ Strcat(buf, dn);
+ Strcat(buf, " potion");
+ }
+ break;
+ case SCROLL_CLASS:
+ Strcpy(buf, "scroll");
+ if(!dknown) break;
+ if(nn) {
+ Strcat(buf, " of ");
+ Strcat(buf, actualn);
+ } else if(un) {
+ Strcat(buf, " called ");
+ Strcat(buf, un);
+ } else if (ocl->oc_magic) {
+ Strcat(buf, " labeled ");
+ Strcat(buf, dn);
+ } else {
+ Strcpy(buf, dn);
+ Strcat(buf, " scroll");
+ }
+ break;
+ case WAND_CLASS:
+ if(!dknown)
+ Strcpy(buf, "wand");
+ else if(nn)
+ Sprintf(buf, "wand of %s", actualn);
+ else if(un)
+ Sprintf(buf, "wand called %s", un);
+ else
+ Sprintf(buf, "%s wand", dn);
+ break;
+ case SPBOOK_CLASS:
- if (!dknown) {
++ if (typ == SPE_NOVEL) { /* 3.6 tribute */
++ if (!dknown)
++ Strcpy(buf, "book");
++ else if (nn)
++ Strcpy(buf, actualn);
++ else if (un)
++ Sprintf(buf, "novel called %s", un);
++ else
++ Sprintf(buf, "%s book", dn);
++ break;
++ /* end of tribute */
++ } else if (!dknown) {
+ Strcpy(buf, "spellbook");
+ } else if (nn) {
+ if (typ != SPE_BOOK_OF_THE_DEAD)
+ Strcpy(buf, "spellbook of ");
+ Strcat(buf, actualn);
+ } else if (un) {
+ Sprintf(buf, "spellbook called %s", un);
+ } else
+ Sprintf(buf, "%s spellbook", dn);
+ break;
+ case RING_CLASS:
+ if(!dknown)
+ Strcpy(buf, "ring");
+ else if(nn)
+ Sprintf(buf, "ring of %s", actualn);
+ else if(un)
+ Sprintf(buf, "ring called %s", un);
+ else
+ Sprintf(buf, "%s ring", dn);
+ break;
+ case GEM_CLASS:
+ {
+ const char *rock =
+ (ocl->oc_material == MINERAL) ? "stone" : "gem";
+ if (!dknown) {
+ Strcpy(buf, rock);
+ } else if (!nn) {
+ if (un) Sprintf(buf,"%s called %s", rock, un);
+ else Sprintf(buf, "%s %s", dn, rock);
+ } else {
+ Strcpy(buf, actualn);
+ if (GemStone(typ)) Strcat(buf, " stone");
+ }
+ break;
+ }
+ default:
+ Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
+ }
+ if (pluralize) Strcpy(buf, makeplural(buf));
if (obj->otyp == T_SHIRT && program_state.gameover) {
char tmpbuf[BUFSZ];
also, spe should always be positive -- some cheaters may try to confuse
atoi()
*/
- if (spe < 0) {
- spesgn = -1; /* cheaters get what they deserve */
- spe = abs(spe);
- }
- if (spe > SCHAR_LIM)
- spe = SCHAR_LIM;
- if (rechrg < 0 || rechrg > 7) rechrg = 7; /* recharge_limit */
-
- /* now we have the actual name, as delivered by xname, say
- green potions called whisky
- scrolls labeled "QWERTY"
- egg
- fortune cookies
- very heavy iron ball named hoei
- wand of wishing
- elven cloak
- */
- if ((p = strstri(bp, " named ")) != 0) {
- *p = 0;
- name = p+7;
- }
- if ((p = strstri(bp, " called ")) != 0) {
- *p = 0;
- un = p+8;
- /* "helmet called telepathy" is not "helmet" (a specific type)
- * "shield called reflection" is not "shield" (a general type)
- */
- for(i = 0; i < SIZE(o_ranges); i++)
- if(!strcmpi(bp, o_ranges[i].name)) {
- oclass = o_ranges[i].oclass;
- goto srch;
- }
- }
- if ((p = strstri(bp, " labeled ")) != 0) {
- *p = 0;
- dn = p+9;
- } else if ((p = strstri(bp, " labelled ")) != 0) {
- *p = 0;
- dn = p+10;
- }
- if ((p = strstri(bp, " of spinach")) != 0) {
- *p = 0;
- contents = SPINACH;
- }
+ if (spe < 0) {
+ spesgn = -1; /* cheaters get what they deserve */
+ spe = abs(spe);
+ }
+ if (spe > SCHAR_LIM)
+ spe = SCHAR_LIM;
+ if (rechrg < 0 || rechrg > 7) rechrg = 7; /* recharge_limit */
+
+ /* now we have the actual name, as delivered by xname, say
+ green potions called whisky
+ scrolls labeled "QWERTY"
+ egg
+ fortune cookies
+ very heavy iron ball named hoei
+ wand of wishing
+ elven cloak
+ */
+ if ((p = strstri(bp, " named ")) != 0) {
+ *p = 0;
+ name = p+7;
+ }
+ if ((p = strstri(bp, " called ")) != 0) {
+ *p = 0;
+ un = p+8;
+ /* "helmet called telepathy" is not "helmet" (a specific type)
+ * "shield called reflection" is not "shield" (a general type)
+ */
+ for(i = 0; i < SIZE(o_ranges); i++)
+ if(!strcmpi(bp, o_ranges[i].name)) {
+ oclass = o_ranges[i].oclass;
+ goto srch;
+ }
+ }
+ if ((p = strstri(bp, " labeled ")) != 0) {
+ *p = 0;
+ dn = p+9;
+ } else if ((p = strstri(bp, " labelled ")) != 0) {
+ *p = 0;
+ dn = p+10;
+ }
+ if ((p = strstri(bp, " of spinach")) != 0) {
+ *p = 0;
+ contents = SPINACH;
+ }
- /*
- Skip over "pair of ", "pairs of", "set of" and "sets of".
-
- Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
- English either way. See makeplural() for more on pair/pairs.
-
- We should only double count if the object in question is not
- refered to as a "pair of". E.g. We should double if the player
- types "pair of spears", but not if the player types "pair of
- lenses". Luckily (?) all objects that are refered to as pairs
- -- boots, gloves, and lenses -- are also not mergable, so cnt is
- ignored anyway.
- */
- if(!strncmpi(bp, "pair of ",8)) {
- bp += 8;
- cnt *= 2;
- } else if(cnt > 1 && !strncmpi(bp, "pairs of ",9)) {
- bp += 9;
- cnt *= 2;
- } else if (!strncmpi(bp, "set of ",7)) {
- bp += 7;
- } else if (!strncmpi(bp, "sets of ",8)) {
- bp += 8;
- }
+ /*
+ Skip over "pair of ", "pairs of", "set of" and "sets of".
+
+ Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
+ English either way. See makeplural() for more on pair/pairs.
+
+ We should only double count if the object in question is not
+ refered to as a "pair of". E.g. We should double if the player
+ types "pair of spears", but not if the player types "pair of
+ lenses". Luckily (?) all objects that are refered to as pairs
+ -- boots, gloves, and lenses -- are also not mergable, so cnt is
+ ignored anyway.
+ */
+ if(!strncmpi(bp, "pair of ",8)) {
+ bp += 8;
+ cnt *= 2;
+ } else if(cnt > 1 && !strncmpi(bp, "pairs of ",9)) {
+ bp += 9;
+ cnt *= 2;
+ } else if (!strncmpi(bp, "set of ",7)) {
+ bp += 7;
+ } else if (!strncmpi(bp, "sets of ",8)) {
+ bp += 8;
+ }
- /*
- * Find corpse type using "of" (figurine of an orc, tin of orc meat)
- * Don't check if it's a wand or spellbook.
- * (avoid "wand/finger of death" confusion).
- */
- if (!strstri(bp, "wand ")
- && !strstri(bp, "spellbook ")
- && !strstri(bp, "finger ")) {
- if (((p = strstri(bp, "tin of ")) != 0) &&
- (tmp = tin_variety_txt(p+7, &tinv)) &&
- (mntmp = name_to_mon(p+7+tmp)) >= LOW_PM) {
- *(p+3) = 0;
- tvariety = tinv;
- } else if ((p = strstri(bp, " of ")) != 0
- && (mntmp = name_to_mon(p+4)) >= LOW_PM)
- *p = 0;
- }
- /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
- if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
- if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
- if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
- if (strncmpi(bp, "master key", 10)) /* not the "master" rank */
- if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
- if (mntmp < LOW_PM && strlen(bp) > 2 &&
- (mntmp = name_to_mon(bp)) >= LOW_PM) {
- int mntmptoo, mntmplen; /* double check for rank title */
- char *obp = bp;
- mntmptoo = title_to_mon(bp, (int *)0, &mntmplen);
- bp += mntmp != mntmptoo ? (int)strlen(mons[mntmp].mname) : mntmplen;
- if (*bp == ' ') bp++;
- else if (!strncmpi(bp, "s ", 2)) bp += 2;
- else if (!strncmpi(bp, "es ", 3)) bp += 3;
- else if (!*bp && !actualn && !dn && !un && !oclass) {
- /* no referent; they don't really mean a monster type */
- bp = obp;
- mntmp = NON_PM;
- }
- }
+ /* intercept pudding globs here; they're a valid wish target,
+ * but we need them to not get treated like a corpse.
+ *
+ * also don't let player wish for multiple globs.
+ */
+ if ((p = strstri(bp, "glob of ")) != 0
+ || (p = strstri(bp, "globs of ")) != 0) {
+ int globoffset = (*(p+4) == 's') ? 9 : 8;
+ if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
+ && mntmp <= PM_BLACK_PUDDING) {
+ mntmp = NON_PM; /* lie to ourselves */
+ cnt = 0; /* force only one */
+ }
+ } else {
+ /*
+ * Find corpse type using "of" (figurine of an orc, tin of orc meat)
+ * Don't check if it's a wand or spellbook.
+ * (avoid "wand/finger of death" confusion).
+ */
+ if (!strstri(bp, "wand ")
+ && !strstri(bp, "spellbook ")
+ && !strstri(bp, "finger ")) {
+ if (((p = strstri(bp, "tin of ")) != 0) &&
+ (tmp = tin_variety_txt(p + 7, &tinv)) &&
+ (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) {
+ *(p + 3) = 0;
+ tvariety = tinv;
+ } else if ((p = strstri(bp, " of ")) != 0
+ && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
+ *p = 0;
+ }
+ }
+ /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
+ if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
+ if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
+ if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
+ if (strncmpi(bp, "master key", 10)) /* not the "master" rank */
+ if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
+ if (mntmp < LOW_PM && strlen(bp) > 2 &&
+ (mntmp = name_to_mon(bp)) >= LOW_PM) {
+ int mntmptoo, mntmplen; /* double check for rank title */
+ char *obp = bp;
+ mntmptoo = title_to_mon(bp, (int *)0, &mntmplen);
+ bp += mntmp != mntmptoo ? (int)strlen(mons[mntmp].mname) : mntmplen;
+ if (*bp == ' ') bp++;
+ else if (!strncmpi(bp, "s ", 2)) bp += 2;
+ else if (!strncmpi(bp, "es ", 3)) bp += 3;
+ else if (!*bp && !actualn && !dn && !un && !oclass) {
+ /* no referent; they don't really mean a monster type */
+ bp = obp;
+ mntmp = NON_PM;
+ }
+ }
- /* first change to singular if necessary */
- if (*bp) {
- char *sng = makesingular(bp);
- if (strcmp(bp, sng)) {
- if (cnt == 1) cnt = 2;
- Strcpy(bp, sng);
- }
- }
+ /* first change to singular if necessary */
+ if (*bp) {
+ char *sng = makesingular(bp);
+ if (strcmp(bp, sng)) {
+ if (cnt == 1) cnt = 2;
+ Strcpy(bp, sng);
+ }
+ }
- /* Alternate spellings (pick-ax, silver sabre, &c) */
+ /* Alternate spellings (pick-ax, silver sabre, &c) */
{
- struct alt_spellings *as = spellings;
-
- while (as->sp) {
- if (fuzzymatch(bp, as->sp, " -", TRUE)) {
- typ = as->ob;
- goto typfnd;
- }
- as++;
- }
- /* can't use spellings list for this one due to shuffling */
- if (!strncmpi(bp, "grey spell", 10))
- *(bp + 2) = 'a';
-
- if ((p = strstri(bp, "armour")) != 0) {
- /* skip past "armo", then copy remainer beyond "u" */
- p += 4;
- while ((*p = *(p + 1)) != '\0') ++p; /* self terminating */
- }
+ struct alt_spellings *as = spellings;
+
+ while (as->sp) {
+ if (fuzzymatch(bp, as->sp, " -", TRUE)) {
+ typ = as->ob;
+ goto typfnd;
+ }
+ as++;
+ }
+ /* can't use spellings list for this one due to shuffling */
+ if (!strncmpi(bp, "grey spell", 10))
+ *(bp + 2) = 'a';
+
+ if ((p = strstri(bp, "armour")) != 0) {
+ /* skip past "armo", then copy remainer beyond "u" */
+ p += 4;
+ while ((*p = *(p + 1)) != '\0') ++p; /* self terminating */
+ }
}
- /* dragon scales - assumes order of dragons */
- if(!strcmpi(bp, "scales") &&
- mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) {
- typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
- mntmp = NON_PM; /* no monster */
- goto typfnd;
- }
+ /* dragon scales - assumes order of dragons */
+ if(!strcmpi(bp, "scales") &&
+ mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) {
+ typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
+ mntmp = NON_PM; /* no monster */
+ goto typfnd;
+ }
- p = eos(bp);
- if(!BSTRCMPI(bp, p-10, "holy water")) {
- typ = POT_WATER;
- if ((p-bp) >= 12 && *(p-12) == 'u')
- iscursed = 1; /* unholy water */
- else blessed = 1;
- goto typfnd;
- }
- if(unlabeled && !BSTRCMPI(bp, p-6, "scroll")) {
- typ = SCR_BLANK_PAPER;
- goto typfnd;
- }
- if(unlabeled && !BSTRCMPI(bp, p-9, "spellbook")) {
- typ = SPE_BLANK_PAPER;
- goto typfnd;
- }
- /*
- * NOTE: Gold pieces are handled as objects nowadays, and therefore
- * this section should probably be reconsidered as well as the entire
- * gold/money concept. Maybe we want to add other monetary units as
- * well in the future. (TH)
- */
- if(!BSTRCMPI(bp, p-10, "gold piece") || !BSTRCMPI(bp, p-7, "zorkmid") ||
- !strcmpi(bp, "gold") || !strcmpi(bp, "money") ||
- !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
- if (cnt > 5000 && !wizard) cnt = 5000;
- else if (cnt < 1) cnt = 1;
- otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
- otmp->quan = (long) cnt;
- otmp->owt = weight(otmp);
- context.botl = 1;
- return otmp;
- }
+ p = eos(bp);
+ if(!BSTRCMPI(bp, p-10, "holy water")) {
+ typ = POT_WATER;
+ if ((p-bp) >= 12 && *(p-12) == 'u')
+ iscursed = 1; /* unholy water */
+ else blessed = 1;
+ goto typfnd;
+ }
+ if(unlabeled && !BSTRCMPI(bp, p-6, "scroll")) {
+ typ = SCR_BLANK_PAPER;
+ goto typfnd;
+ }
+ if(unlabeled && !BSTRCMPI(bp, p-9, "spellbook")) {
+ typ = SPE_BLANK_PAPER;
+ goto typfnd;
+ }
+ /*
+ * NOTE: Gold pieces are handled as objects nowadays, and therefore
+ * this section should probably be reconsidered as well as the entire
+ * gold/money concept. Maybe we want to add other monetary units as
+ * well in the future. (TH)
+ */
+ if(!BSTRCMPI(bp, p-10, "gold piece") || !BSTRCMPI(bp, p-7, "zorkmid") ||
+ !strcmpi(bp, "gold") || !strcmpi(bp, "money") ||
+ !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
+ if (cnt > 5000 && !wizard) cnt = 5000;
+ else if (cnt < 1) cnt = 1;
+ otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
+ otmp->quan = (long) cnt;
+ otmp->owt = weight(otmp);
+ context.botl = 1;
+ return otmp;
+ }
- /* check for single character object class code ("/" for wand, &c) */
- if (strlen(bp) == 1 &&
- (i = def_char_to_objclass(*bp)) < MAXOCLASSES &&
- i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
- oclass = i;
- goto any;
- }
+ /* check for single character object class code ("/" for wand, &c) */
+ if (strlen(bp) == 1 &&
+ (i = def_char_to_objclass(*bp)) < MAXOCLASSES &&
+ i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
+ oclass = i;
+ goto any;
+ }
- /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
- /* false hits on, e.g., rings for "ring mail". */
- if(strncmpi(bp, "enchant ", 8) &&
- strncmpi(bp, "destroy ", 8) &&
- strncmpi(bp, "detect food", 11) &&
- strncmpi(bp, "food detection", 14) &&
- strncmpi(bp, "ring mail", 9) &&
- strncmpi(bp, "studded leather armor", 21) &&
- strncmpi(bp, "leather armor", 13) &&
- strncmpi(bp, "tooled horn", 11) &&
- strncmpi(bp, "food ration", 11) &&
- strncmpi(bp, "meat ring", 9)
- )
- for (i = 0; i < (int)(sizeof wrpsym); i++) {
- register int j = strlen(wrp[i]);
- if(!strncmpi(bp, wrp[i], j)){
- oclass = wrpsym[i];
- if(oclass != AMULET_CLASS) {
- bp += j;
- if(!strncmpi(bp, " of ", 4)) actualn = bp+4;
- /* else if(*bp) ?? */
- } else
- actualn = bp;
- goto srch;
- }
- if(!BSTRCMPI(bp, p-j, wrp[i])){
- oclass = wrpsym[i];
- p -= j;
- *p = 0;
- if(p > bp && p[-1] == ' ') p[-1] = 0;
- actualn = dn = bp;
- goto srch;
- }
- }
+ /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */
+ /* false hits on, e.g., rings for "ring mail". */
+ if(strncmpi(bp, "enchant ", 8) &&
+ strncmpi(bp, "destroy ", 8) &&
+ strncmpi(bp, "detect food", 11) &&
+ strncmpi(bp, "food detection", 14) &&
+ strncmpi(bp, "ring mail", 9) &&
+ strncmpi(bp, "studded leather armor", 21) &&
+ strncmpi(bp, "leather armor", 13) &&
+ strncmpi(bp, "tooled horn", 11) &&
+ strncmpi(bp, "food ration", 11) &&
+ strncmpi(bp, "meat ring", 9)
+ )
+ for (i = 0; i < (int)(sizeof wrpsym); i++) {
+ register int j = strlen(wrp[i]);
+ if(!strncmpi(bp, wrp[i], j)){
+ oclass = wrpsym[i];
+ if(oclass != AMULET_CLASS) {
+ bp += j;
+ if(!strncmpi(bp, " of ", 4)) actualn = bp+4;
+ /* else if(*bp) ?? */
+ } else
+ actualn = bp;
+ goto srch;
+ }
+ if(!BSTRCMPI(bp, p-j, wrp[i])){
+ oclass = wrpsym[i];
+ p -= j;
+ *p = 0;
+ if(p > bp && p[-1] == ' ') p[-1] = 0;
+ actualn = dn = bp;
+ goto srch;
+ }
+ }
- /* Wishing in wizard mode can create traps and furniture.
- * Part I: distinguish between trap and object for the two
- * types of traps which have corresponding objects: bear trap
- * and land mine. "beartrap" (object) and "bear trap" (trap)
- * have a difference in spelling which we used to exploit by
- * adding a special case in wishymatch(), but "land mine" is
- * spelled the same either way so needs different handing.
- * Since we need something else for land mine, we've dropped
- * the bear trap hack so that both are handled exactly the
- * same. To get an armed trap instead of a disarmed object,
- * the player can prefix either the object name or the trap
- * name with "trapped " (which ordinarily applies to chests
- * and tins), or append something--anything at all except for
- * " object", but " trap" is suggested--to either the trap
- * name or the object name.
- */
- if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
- boolean beartrap = (lowc(*bp) == 'b');
- char *zp = bp + 4; /* skip "bear"/"land" */
-
- if (*zp == ' ') ++zp; /* embedded space is optional */
- if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
- zp += 4;
- if (trapped == 2 || !strcmpi(zp, " object")) {
- /* "untrapped <foo>" or "<foo> object" */
- typ = beartrap ? BEARTRAP : LAND_MINE;
- goto typfnd;
- } else if (trapped == 1 || *zp != '\0') {
- /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
- int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
-
- /* use canonical trap spelling, skip object matching */
- Strcpy(bp, defsyms[idx].explanation);
- goto wiztrap;
- }
- /* [no prefix or suffix; we're going to end up matching
- the object name and getting a disarmed trap object] */
- }
- }
+ /* Wishing in wizard mode can create traps and furniture.
+ * Part I: distinguish between trap and object for the two
+ * types of traps which have corresponding objects: bear trap
+ * and land mine. "beartrap" (object) and "bear trap" (trap)
+ * have a difference in spelling which we used to exploit by
+ * adding a special case in wishymatch(), but "land mine" is
+ * spelled the same either way so needs different handing.
+ * Since we need something else for land mine, we've dropped
+ * the bear trap hack so that both are handled exactly the
+ * same. To get an armed trap instead of a disarmed object,
+ * the player can prefix either the object name or the trap
+ * name with "trapped " (which ordinarily applies to chests
+ * and tins), or append something--anything at all except for
+ * " object", but " trap" is suggested--to either the trap
+ * name or the object name.
+ */
+ if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
+ boolean beartrap = (lowc(*bp) == 'b');
+ char *zp = bp + 4; /* skip "bear"/"land" */
+
+ if (*zp == ' ') ++zp; /* embedded space is optional */
+ if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
+ zp += 4;
+ if (trapped == 2 || !strcmpi(zp, " object")) {
+ /* "untrapped <foo>" or "<foo> object" */
+ typ = beartrap ? BEARTRAP : LAND_MINE;
+ goto typfnd;
+ } else if (trapped == 1 || *zp != '\0') {
+ /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
+ int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
+
+ /* use canonical trap spelling, skip object matching */
+ Strcpy(bp, defsyms[idx].explanation);
+ goto wiztrap;
+ }
+ /* [no prefix or suffix; we're going to end up matching
+ the object name and getting a disarmed trap object] */
+ }
+ }
retry:
- /* "grey stone" check must be before general "stone" */
- for (i = 0; i < SIZE(o_ranges); i++)
- if(!strcmpi(bp, o_ranges[i].name)) {
- typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
- goto typfnd;
- }
-
- if (!BSTRCMPI(bp, p-6, " stone")) {
- p[-6] = 0;
- oclass = GEM_CLASS;
- dn = actualn = bp;
- goto srch;
- } else if (!strcmpi(bp, "looking glass")) {
- ; /* avoid false hit on "* glass" */
- } else if (!BSTRCMPI(bp, p-6, " glass") || !strcmpi(bp, "glass")) {
- register char *g = bp;
- if (strstri(g, "broken")) return (struct obj *)0;
- if (!strncmpi(g, "worthless ", 10)) g += 10;
- if (!strncmpi(g, "piece of ", 9)) g += 9;
- if (!strncmpi(g, "colored ", 8)) g += 8;
- else if (!strncmpi(g, "coloured ", 9)) g += 9;
- if (!strcmpi(g, "glass")) { /* choose random color */
- /* 9 different kinds */
- typ = LAST_GEM + rnd(9);
- if (objects[typ].oc_class == GEM_CLASS) goto typfnd;
- else typ = 0; /* somebody changed objects[]? punt */
- } else { /* try to construct canonical form */
- char tbuf[BUFSZ];
- Strcpy(tbuf, "worthless piece of ");
- Strcat(tbuf, g); /* assume it starts with the color */
- Strcpy(bp, tbuf);
- }
- }
+ /* "grey stone" check must be before general "stone" */
+ for (i = 0; i < SIZE(o_ranges); i++)
+ if(!strcmpi(bp, o_ranges[i].name)) {
+ typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
+ goto typfnd;
+ }
+
+ if (!BSTRCMPI(bp, p-6, " stone")) {
+ p[-6] = 0;
+ oclass = GEM_CLASS;
+ dn = actualn = bp;
+ goto srch;
+ } else if (!strcmpi(bp, "looking glass")) {
+ ; /* avoid false hit on "* glass" */
+ } else if (!BSTRCMPI(bp, p-6, " glass") || !strcmpi(bp, "glass")) {
+ register char *g = bp;
+ if (strstri(g, "broken")) return (struct obj *)0;
+ if (!strncmpi(g, "worthless ", 10)) g += 10;
+ if (!strncmpi(g, "piece of ", 9)) g += 9;
+ if (!strncmpi(g, "colored ", 8)) g += 8;
+ else if (!strncmpi(g, "coloured ", 9)) g += 9;
+ if (!strcmpi(g, "glass")) { /* choose random color */
+ /* 9 different kinds */
+ typ = LAST_GEM + rnd(9);
+ if (objects[typ].oc_class == GEM_CLASS) goto typfnd;
+ else typ = 0; /* somebody changed objects[]? punt */
+ } else { /* try to construct canonical form */
+ char tbuf[BUFSZ];
+ Strcpy(tbuf, "worthless piece of ");
+ Strcat(tbuf, g); /* assume it starts with the color */
+ Strcpy(bp, tbuf);
+ }
+ }
- actualn = bp;
- if (!dn) dn = actualn; /* ex. "skull cap" */
+ actualn = bp;
+ if (!dn) dn = actualn; /* ex. "skull cap" */
srch:
- /* check real names of gems first */
- if(!oclass && actualn) {
- for(i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
- register const char *zn;
-
- if((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
- typ = i;
- goto typfnd;
- }
- }
- }
- i = oclass ? bases[(int)oclass] : 1;
- while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){
- register const char *zn;
-
- if (actualn && (zn = OBJ_NAME(objects[i])) != 0 &&
- wishymatch(actualn, zn, TRUE)) {
- typ = i;
- goto typfnd;
- }
- if (dn && (zn = OBJ_DESCR(objects[i])) != 0 &&
- wishymatch(dn, zn, FALSE)) {
- /* don't match extra descriptions (w/o real name) */
- if (!OBJ_NAME(objects[i])) return (struct obj *)0;
- typ = i;
- goto typfnd;
- }
- if (un && (zn = objects[i].oc_uname) != 0 &&
- wishymatch(un, zn, FALSE)) {
- typ = i;
- goto typfnd;
- }
- i++;
- }
- if (actualn) {
- struct Jitem *j = Japanese_items;
- while(j->item) {
- if (actualn && !strcmpi(actualn, j->name)) {
- typ = j->item;
- goto typfnd;
- }
- j++;
- }
- }
- /* if we've stripped off "armor" and failed to match anything
- in objects[], append "mail" and try again to catch misnamed
- requests like "plate armor" and "yellow dragon scale armor" */
- if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
- /* modifying bp's string is ok; we're about to resort
- to random armor if this also fails to match anything */
- Strcat(bp, " mail");
- goto retry;
- }
- if (!strcmpi(bp, "spinach")) {
- contents = SPINACH;
- typ = TIN;
- goto typfnd;
- }
- /* Note: not strcmpi. 2 fruits, one capital, one not, are possible.
- Also not strncmp. We used to ignore trailing text with it, but
- that resulted in "grapefruit" matching "grape" if the latter came
- earlier than the former in the fruit list. */
- {
- char *fp;
- int l, cntf;
- int blessedf, iscursedf, uncursedf, halfeatenf;
-
- blessedf = iscursedf = uncursedf = halfeatenf = 0;
- cntf = 0;
-
- fp = fruitbuf;
- for(;;) {
- if (!fp || !*fp) break;
- if (!strncmpi(fp, "an ", l=3) ||
- !strncmpi(fp, "a ", l=2)) {
- cntf = 1;
- } else if (!cntf && digit(*fp)) {
- cntf = atoi(fp);
- while(digit(*fp)) fp++;
- while(*fp == ' ') fp++;
- l = 0;
- } else if (!strncmpi(fp, "blessed ", l=8)) {
- blessedf = 1;
- } else if (!strncmpi(fp, "cursed ", l=7)) {
- iscursedf = 1;
- } else if (!strncmpi(fp, "uncursed ", l=9)) {
- uncursedf = 1;
- } else if (!strncmpi(fp, "partly eaten ", l=13) ||
- !strncmpi(fp, "partially eaten ", l=16)) {
- halfeatenf = 1;
- } else break;
- fp += l;
- }
-
- for(f=ffruit; f; f = f->nextf) {
- /* match type: 0=none, 1=exact, 2=singular, 3=plural */
- int ftyp = 0;
-
- if (!strcmp(fp, f->fname)) ftyp = 1;
- else if (!strcmp(fp, makesingular(f->fname))) ftyp = 2;
- else if (!strcmp(fp, makeplural(f->fname))) ftyp = 3;
- if (ftyp) {
- typ = SLIME_MOLD;
- blessed = blessedf;
- iscursed = iscursedf;
- uncursed = uncursedf;
- halfeaten = halfeatenf;
- /* adjust count if user explicitly asked for
- singular amount (can't happen unless fruit
- has been given an already pluralized name)
- or for plural amount */
- if (ftyp == 2 && !cntf) cntf = 1;
- else if (ftyp == 3 && !cntf) cntf = 2;
- cnt = cntf;
- ftype = f->fid;
- goto typfnd;
- }
- }
- }
+ /* check real names of gems first */
+ if(!oclass && actualn) {
+ for(i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
+ register const char *zn;
+
+ if((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
+ typ = i;
+ goto typfnd;
+ }
+ }
+ }
+ i = oclass ? bases[(int)oclass] : 1;
+ while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){
+ register const char *zn;
+
+ if (actualn && (zn = OBJ_NAME(objects[i])) != 0 &&
+ wishymatch(actualn, zn, TRUE)) {
+ typ = i;
+ goto typfnd;
+ }
+ if (dn && (zn = OBJ_DESCR(objects[i])) != 0 &&
+ wishymatch(dn, zn, FALSE)) {
+ /* don't match extra descriptions (w/o real name) */
+ if (!OBJ_NAME(objects[i])) return (struct obj *)0;
+ typ = i;
+ goto typfnd;
+ }
+ if (un && (zn = objects[i].oc_uname) != 0 &&
+ wishymatch(un, zn, FALSE)) {
+ typ = i;
+ goto typfnd;
+ }
+ i++;
+ }
+ if (actualn) {
+ struct Jitem *j = Japanese_items;
+ while(j->item) {
+ if (actualn && !strcmpi(actualn, j->name)) {
+ typ = j->item;
+ goto typfnd;
+ }
+ j++;
+ }
+ }
+ /* if we've stripped off "armor" and failed to match anything
+ in objects[], append "mail" and try again to catch misnamed
+ requests like "plate armor" and "yellow dragon scale armor" */
+ if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
+ /* modifying bp's string is ok; we're about to resort
+ to random armor if this also fails to match anything */
+ Strcat(bp, " mail");
+ goto retry;
+ }
+ if (!strcmpi(bp, "spinach")) {
+ contents = SPINACH;
+ typ = TIN;
+ goto typfnd;
+ }
+ /* Note: not strcmpi. 2 fruits, one capital, one not, are possible.
+ Also not strncmp. We used to ignore trailing text with it, but
+ that resulted in "grapefruit" matching "grape" if the latter came
+ earlier than the former in the fruit list. */
+ {
+ char *fp;
+ int l, cntf;
+ int blessedf, iscursedf, uncursedf, halfeatenf;
+
+ blessedf = iscursedf = uncursedf = halfeatenf = 0;
+ cntf = 0;
+
+ fp = fruitbuf;
+ for(;;) {
+ if (!fp || !*fp) break;
+ if (!strncmpi(fp, "an ", l=3) ||
+ !strncmpi(fp, "a ", l=2)) {
+ cntf = 1;
+ } else if (!cntf && digit(*fp)) {
+ cntf = atoi(fp);
+ while(digit(*fp)) fp++;
+ while(*fp == ' ') fp++;
+ l = 0;
+ } else if (!strncmpi(fp, "blessed ", l=8)) {
+ blessedf = 1;
+ } else if (!strncmpi(fp, "cursed ", l=7)) {
+ iscursedf = 1;
+ } else if (!strncmpi(fp, "uncursed ", l=9)) {
+ uncursedf = 1;
+ } else if (!strncmpi(fp, "partly eaten ", l=13) ||
+ !strncmpi(fp, "partially eaten ", l=16)) {
+ halfeatenf = 1;
+ } else break;
+ fp += l;
+ }
+
+ for(f=ffruit; f; f = f->nextf) {
+ /* match type: 0=none, 1=exact, 2=singular, 3=plural */
+ int ftyp = 0;
+
+ if (!strcmp(fp, f->fname)) ftyp = 1;
+ else if (!strcmp(fp, makesingular(f->fname))) ftyp = 2;
+ else if (!strcmp(fp, makeplural(f->fname))) ftyp = 3;
+ if (ftyp) {
+ typ = SLIME_MOLD;
+ blessed = blessedf;
+ iscursed = iscursedf;
+ uncursed = uncursedf;
+ halfeaten = halfeatenf;
+ /* adjust count if user explicitly asked for
+ singular amount (can't happen unless fruit
+ has been given an already pluralized name)
+ or for plural amount */
+ if (ftyp == 2 && !cntf) cntf = 1;
+ else if (ftyp == 3 && !cntf) cntf = 2;
+ cnt = cntf;
+ ftype = f->fid;
+ goto typfnd;
+ }
+ }
+ }
- if(!oclass && actualn) {
- short objtyp;
+ if(!oclass && actualn) {
+ short objtyp;
- /* Perhaps it's an artifact specified by name, not type */
- name = artifact_name(actualn, &objtyp);
- if(name) {
- typ = objtyp;
- goto typfnd;
- }
- }
- /* Let wizards wish for traps and furniture.
- * Must come after objects check so wizards can still wish for
- * trap objects like beartraps.
- * Disallow such topology tweaks for WIZKIT startup wishes.
- */
+ /* Perhaps it's an artifact specified by name, not type */
+ name = artifact_name(actualn, &objtyp);
+ if(name) {
+ typ = objtyp;
+ goto typfnd;
+ }
+ }
+ /* Let wizards wish for traps and furniture.
+ * Must come after objects check so wizards can still wish for
+ * trap objects like beartraps.
+ * Disallow such topology tweaks for WIZKIT startup wishes.
+ */
wiztrap:
- if (wizard && !program_state.wizkit_wishing) {
- struct rm *lev;
- int trap, x = u.ux, y = u.uy;
-
- for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
- struct trap *t;
- const char *tname;
-
- tname = defsyms[trap_to_defsym(trap)].explanation;
- if (strncmpi(tname, bp, strlen(tname))) continue;
- /* found it; avoid stupid mistakes */
- if ((trap == TRAPDOOR || trap == HOLE) &&
- !Can_fall_thru(&u.uz)) trap = ROCKTRAP;
- if ((t = maketrap(x, y, trap)) != 0) {
- trap = t->ttyp;
- tname = defsyms[trap_to_defsym(trap)].explanation;
- pline("%s%s.", An(tname),
- (trap != MAGIC_PORTAL) ? "" : " to nowhere");
- } else
- pline("Creation of %s failed.", an(tname));
- return(&zeroobj);
- }
-
- /* furniture and terrain */
- lev = &levl[x][y];
- p = eos(bp);
- if (!BSTRCMPI(bp, p-8, "fountain")) {
- lev->typ = FOUNTAIN;
- level.flags.nfountains++;
- if(!strncmpi(bp, "magic ", 6)) lev->blessedftn = 1;
- pline("A %sfountain.", lev->blessedftn ? "magic " : "");
- newsym(x, y);
- return(&zeroobj);
- }
- if (!BSTRCMPI(bp, p-6, "throne")) {
- lev->typ = THRONE;
- pline("A throne.");
- newsym(x, y);
- return(&zeroobj);
- }
- if (!BSTRCMPI(bp, p-4, "sink")) {
- lev->typ = SINK;
- level.flags.nsinks++;
- pline("A sink.");
- newsym(x, y);
- return &zeroobj;
- }
- /* ("water" matches "potion of water" rather than terrain) */
- if (!BSTRCMPI(bp, p-4, "pool") || !BSTRCMPI(bp, p-4, "moat")) {
- lev->typ = !BSTRCMPI(bp, p-4, "pool") ? POOL : MOAT;
- del_engr_at(x, y);
- pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
- /* Must manually make kelp! */
- water_damage_chain(level.objects[x][y], TRUE);
- newsym(x, y);
- return &zeroobj;
- }
- if (!BSTRCMPI(bp, p-4, "lava")) { /* also matches "molten lava" */
- lev->typ = LAVAPOOL;
- del_engr_at(x, y);
- pline("A pool of molten lava.");
- if (!(Levitation || Flying)) (void) lava_effects();
- newsym(x, y);
- return &zeroobj;
- }
-
- if (!BSTRCMPI(bp, p-5, "altar")) {
- aligntyp al;
-
- lev->typ = ALTAR;
- if(!strncmpi(bp, "chaotic ", 8))
- al = A_CHAOTIC;
- else if(!strncmpi(bp, "neutral ", 8))
- al = A_NEUTRAL;
- else if(!strncmpi(bp, "lawful ", 7))
- al = A_LAWFUL;
- else if(!strncmpi(bp, "unaligned ", 10))
- al = A_NONE;
- else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
- al = (!rn2(6)) ? A_NONE : rn2((int)A_LAWFUL+2) - 1;
- lev->altarmask = Align2amask(al);
- pline("%s altar.", An(align_str(al)));
- newsym(x, y);
- return(&zeroobj);
- }
-
- if (!BSTRCMPI(bp, p-5, "grave") ||
- !BSTRCMPI(bp, p-9, "headstone")) {
- make_grave(x, y, (char *)0);
- pline("%s.", IS_GRAVE(lev->typ) ? "A grave" :
- "Can't place a grave here");
- newsym(x, y);
- return(&zeroobj);
- }
-
- if (!BSTRCMPI(bp, p-4, "tree")) {
- lev->typ = TREE;
- pline("A tree.");
- newsym(x, y);
- block_point(x, y);
- return &zeroobj;
- }
-
- if (!BSTRCMPI(bp, p-4, "bars")) {
- lev->typ = IRONBARS;
- pline("Iron bars.");
- newsym(x, y);
- return &zeroobj;
- }
- }
+ if (wizard && !program_state.wizkit_wishing) {
+ struct rm *lev;
+ int trap, x = u.ux, y = u.uy;
+
+ for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
+ struct trap *t;
+ const char *tname;
+
+ tname = defsyms[trap_to_defsym(trap)].explanation;
+ if (strncmpi(tname, bp, strlen(tname))) continue;
+ /* found it; avoid stupid mistakes */
+ if ((trap == TRAPDOOR || trap == HOLE) &&
+ !Can_fall_thru(&u.uz)) trap = ROCKTRAP;
+ if ((t = maketrap(x, y, trap)) != 0) {
+ trap = t->ttyp;
+ tname = defsyms[trap_to_defsym(trap)].explanation;
+ pline("%s%s.", An(tname),
+ (trap != MAGIC_PORTAL) ? "" : " to nowhere");
+ } else
+ pline("Creation of %s failed.", an(tname));
+ return(&zeroobj);
+ }
+
+ /* furniture and terrain */
+ lev = &levl[x][y];
+ p = eos(bp);
+ if (!BSTRCMPI(bp, p-8, "fountain")) {
+ lev->typ = FOUNTAIN;
+ level.flags.nfountains++;
+ if(!strncmpi(bp, "magic ", 6)) lev->blessedftn = 1;
+ pline("A %sfountain.", lev->blessedftn ? "magic " : "");
+ newsym(x, y);
+ return(&zeroobj);
+ }
+ if (!BSTRCMPI(bp, p-6, "throne")) {
+ lev->typ = THRONE;
+ pline("A throne.");
+ newsym(x, y);
+ return(&zeroobj);
+ }
+ if (!BSTRCMPI(bp, p-4, "sink")) {
+ lev->typ = SINK;
+ level.flags.nsinks++;
+ pline("A sink.");
+ newsym(x, y);
+ return &zeroobj;
+ }
+ /* ("water" matches "potion of water" rather than terrain) */
+ if (!BSTRCMPI(bp, p-4, "pool") || !BSTRCMPI(bp, p-4, "moat")) {
+ lev->typ = !BSTRCMPI(bp, p-4, "pool") ? POOL : MOAT;
+ del_engr_at(x, y);
+ pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
+ /* Must manually make kelp! */
+ water_damage_chain(level.objects[x][y], TRUE);
+ newsym(x, y);
+ return &zeroobj;
+ }
+ if (!BSTRCMPI(bp, p-4, "lava")) { /* also matches "molten lava" */
+ lev->typ = LAVAPOOL;
+ del_engr_at(x, y);
+ pline("A pool of molten lava.");
+ if (!(Levitation || Flying)) (void) lava_effects();
+ newsym(x, y);
+ return &zeroobj;
+ }
+
+ if (!BSTRCMPI(bp, p-5, "altar")) {
+ aligntyp al;
+
+ lev->typ = ALTAR;
+ if(!strncmpi(bp, "chaotic ", 8))
+ al = A_CHAOTIC;
+ else if(!strncmpi(bp, "neutral ", 8))
+ al = A_NEUTRAL;
+ else if(!strncmpi(bp, "lawful ", 7))
+ al = A_LAWFUL;
+ else if(!strncmpi(bp, "unaligned ", 10))
+ al = A_NONE;
+ else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
+ al = (!rn2(6)) ? A_NONE : rn2((int)A_LAWFUL+2) - 1;
+ lev->altarmask = Align2amask(al);
+ pline("%s altar.", An(align_str(al)));
+ newsym(x, y);
+ return(&zeroobj);
+ }
+
+ if (!BSTRCMPI(bp, p-5, "grave") ||
+ !BSTRCMPI(bp, p-9, "headstone")) {
+ make_grave(x, y, (char *)0);
+ pline("%s.", IS_GRAVE(lev->typ) ? "A grave" :
+ "Can't place a grave here");
+ newsym(x, y);
+ return(&zeroobj);
+ }
+
+ if (!BSTRCMPI(bp, p-4, "tree")) {
+ lev->typ = TREE;
+ pline("A tree.");
+ newsym(x, y);
+ block_point(x, y);
+ return &zeroobj;
+ }
+
+ if (!BSTRCMPI(bp, p-4, "bars")) {
+ lev->typ = IRONBARS;
+ pline("Iron bars.");
+ newsym(x, y);
+ return &zeroobj;
+ }
+ }
- if(!oclass) return((struct obj *)0);
+ if(!oclass) return((struct obj *)0);
any:
- if(!oclass) oclass = wrpsym[rn2((int)sizeof(wrpsym))];
+ if(!oclass) oclass = wrpsym[rn2((int)sizeof(wrpsym))];
typfnd:
- if (typ) oclass = objects[typ].oc_class;
-
- /* handle some objects that are only allowed in wizard mode */
- if (typ && !wizard) {
- switch (typ) {
- case AMULET_OF_YENDOR:
- typ = FAKE_AMULET_OF_YENDOR;
- break;
- case CANDELABRUM_OF_INVOCATION:
- typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
- break;
- case BELL_OF_OPENING:
- typ = BELL;
- break;
- case SPE_BOOK_OF_THE_DEAD:
- typ = SPE_BLANK_PAPER;
- break;
- case MAGIC_LAMP:
- typ = OIL_LAMP;
- break;
- default:
- /* catch any other non-wishable objects (venom) */
- if (objects[typ].oc_nowish) return ((struct obj *)0);
- break;
- }
- }
+ if (typ) oclass = objects[typ].oc_class;
+
+ /* handle some objects that are only allowed in wizard mode */
+ if (typ && !wizard) {
+ switch (typ) {
+ case AMULET_OF_YENDOR:
+ typ = FAKE_AMULET_OF_YENDOR;
+ break;
+ case CANDELABRUM_OF_INVOCATION:
+ typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
+ break;
+ case BELL_OF_OPENING:
+ typ = BELL;
+ break;
+ case SPE_BOOK_OF_THE_DEAD:
+ typ = SPE_BLANK_PAPER;
+ break;
+ case MAGIC_LAMP:
+ typ = OIL_LAMP;
+ break;
+ default:
+ /* catch any other non-wishable objects (venom) */
+ if (objects[typ].oc_nowish) return ((struct obj *)0);
+ break;
+ }
+ }
- /*
- * Create the object, then fine-tune it.
- */
- otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
- typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
-
- if (islit &&
- (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN ||
- Is_candle(otmp) || typ == POT_OIL)) {
- place_object(otmp, u.ux, u.uy); /* make it viable light source */
- begin_burn(otmp, FALSE);
- obj_extract_self(otmp); /* now release it for caller's use */
- }
+ if (typ && wizard) {
+ if (typ == SPE_NOVEL) {
+ if (name && !lookup_novel(name, (int *)0)) {
+ pline("There's no novel by that name.");
+ return ((struct obj *)0);
+ }
+ }
+ }
+
+ /*
+ * Create the object, then fine-tune it.
+ */
+ otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
+ typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
+
+ if (islit &&
+ (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN ||
+ Is_candle(otmp) || typ == POT_OIL)) {
+ place_object(otmp, u.ux, u.uy); /* make it viable light source */
+ begin_burn(otmp, FALSE);
+ obj_extract_self(otmp); /* now release it for caller's use */
+ }
- /* if player specified a reasonable count, maybe honor it */
- if (cnt > 0 && objects[typ].oc_merge &&
- (wizard || cnt < rnd(6) ||
- (cnt <= 7 && Is_candle(otmp)) ||
- (cnt <= 20 &&
- ((oclass == WEAPON_CLASS && is_ammo(otmp))
- || typ == ROCK || is_missile(otmp)))))
- otmp->quan = (long) cnt;
-
- if (oclass == VENOM_CLASS) otmp->spe = 1;
-
- if (spesgn == 0) {
- spe = otmp->spe;
- } else if (wizard) {
- ; /* no alteration to spe */
- } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS ||
- is_weptool(otmp) ||
- (oclass==RING_CLASS && objects[typ].oc_charged)) {
- if(spe > rnd(5) && spe > otmp->spe) spe = 0;
- if(spe > 2 && Luck < 0) spesgn = -1;
- } else {
- if (oclass == WAND_CLASS) {
- if (spe > 1 && spesgn == -1) spe = 1;
- } else {
- if (spe > 0 && spesgn == -1) spe = 0;
- }
- if (spe > otmp->spe) spe = otmp->spe;
- }
+ /* if player specified a reasonable count, maybe honor it */
+ if (cnt > 0 && objects[typ].oc_merge &&
+ (wizard || cnt < rnd(6) ||
+ (cnt <= 7 && Is_candle(otmp)) ||
+ (cnt <= 20 &&
+ ((oclass == WEAPON_CLASS && is_ammo(otmp))
+ || typ == ROCK || is_missile(otmp)))))
+ otmp->quan = (long) cnt;
+
+ if (oclass == VENOM_CLASS) otmp->spe = 1;
+
+ if (spesgn == 0) {
+ spe = otmp->spe;
+ } else if (wizard) {
+ ; /* no alteration to spe */
+ } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS ||
+ is_weptool(otmp) ||
+ (oclass==RING_CLASS && objects[typ].oc_charged)) {
+ if(spe > rnd(5) && spe > otmp->spe) spe = 0;
+ if(spe > 2 && Luck < 0) spesgn = -1;
+ } else {
+ if (oclass == WAND_CLASS) {
+ if (spe > 1 && spesgn == -1) spe = 1;
+ } else {
+ if (spe > 0 && spesgn == -1) spe = 0;
+ }
+ if (spe > otmp->spe) spe = otmp->spe;
+ }
- if (spesgn == -1) spe = -spe;
-
- /* set otmp->spe. This may, or may not, use spe... */
- switch (typ) {
- case TIN: if (contents==EMPTY) {
- otmp->corpsenm = NON_PM;
- otmp->spe = 0;
- } else if (contents==SPINACH) {
- otmp->corpsenm = NON_PM;
- otmp->spe = 1;
- }
- break;
- case SLIME_MOLD: otmp->spe = ftype;
- /* Fall through */
- case SKELETON_KEY: case CHEST: case LARGE_BOX:
- case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
- /* otmp->cobj already done in mksobj() */
- break;
+ if (spesgn == -1) spe = -spe;
+
+ /* set otmp->spe. This may, or may not, use spe... */
+ switch (typ) {
+ case TIN: if (contents==EMPTY) {
+ otmp->corpsenm = NON_PM;
+ otmp->spe = 0;
+ } else if (contents==SPINACH) {
+ otmp->corpsenm = NON_PM;
+ otmp->spe = 1;
+ }
+ break;
+ case SLIME_MOLD: otmp->spe = ftype;
+ /* Fall through */
+ case SKELETON_KEY: case CHEST: case LARGE_BOX:
+ case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
+ /* otmp->cobj already done in mksobj() */
+ break;
#ifdef MAIL
- case SCR_MAIL: otmp->spe = 1; break;
+ case SCR_MAIL: otmp->spe = 1; break;
#endif
- case WAN_WISHING:
- if (!wizard) {
- otmp->spe = (rn2(10) ? -1 : 0);
- break;
- }
- /* fall through, if wizard */
- default: otmp->spe = spe;
- }
+ case WAN_WISHING:
+ if (!wizard) {
+ otmp->spe = (rn2(10) ? -1 : 0);
+ break;
+ }
+ /* fall through, if wizard */
+ default: otmp->spe = spe;
+ }
- /* set otmp->corpsenm or dragon scale [mail] */
- if (mntmp >= LOW_PM) {
- if (mntmp == PM_LONG_WORM_TAIL) mntmp = PM_LONG_WORM;
-
- switch (typ) {
- case TIN:
- otmp->spe = 0; /* No spinach */
- if (dead_species(mntmp, FALSE)) {
- otmp->corpsenm = NON_PM; /* it's empty */
- } else if (!(mons[mntmp].geno & G_UNIQ) &&
- !(mvitals[mntmp].mvflags & G_NOCORPSE) &&
- mons[mntmp].cnutrit != 0) {
- otmp->corpsenm = mntmp;
- }
- break;
- case CORPSE:
- if (!(mons[mntmp].geno & G_UNIQ) &&
- !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
- if (mons[mntmp].msound == MS_GUARDIAN)
- mntmp = genus(mntmp,1);
- set_corpsenm(otmp, mntmp);
- }
- break;
- case FIGURINE:
- if (!(mons[mntmp].geno & G_UNIQ)
- && !is_human(&mons[mntmp])
+ /* set otmp->corpsenm or dragon scale [mail] */
+ if (mntmp >= LOW_PM) {
+ if (mntmp == PM_LONG_WORM_TAIL) mntmp = PM_LONG_WORM;
+
+ switch (typ) {
+ case TIN:
+ otmp->spe = 0; /* No spinach */
+ if (dead_species(mntmp, FALSE)) {
+ otmp->corpsenm = NON_PM; /* it's empty */
+ } else if (!(mons[mntmp].geno & G_UNIQ) &&
+ !(mvitals[mntmp].mvflags & G_NOCORPSE) &&
+ mons[mntmp].cnutrit != 0) {
+ otmp->corpsenm = mntmp;
+ }
+ break;
+ case CORPSE:
+ if (!(mons[mntmp].geno & G_UNIQ) &&
+ !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
+ if (mons[mntmp].msound == MS_GUARDIAN)
+ mntmp = genus(mntmp,1);
+ set_corpsenm(otmp, mntmp);
+ }
+ break;
+ case FIGURINE:
+ if (!(mons[mntmp].geno & G_UNIQ)
+ && !is_human(&mons[mntmp])
#ifdef MAIL
- && mntmp != PM_MAIL_DAEMON
+ && mntmp != PM_MAIL_DAEMON
#endif
- )
- otmp->corpsenm = mntmp;
- break;
- case EGG:
- mntmp = can_be_hatched(mntmp);
- /* this also sets hatch timer if appropriate */
- set_corpsenm(otmp, mntmp);
- break;
- case STATUE: otmp->corpsenm = mntmp;
- if (Has_contents(otmp) && verysmall(&mons[mntmp]))
- delete_contents(otmp); /* no spellbook */
- otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
- break;
- case SCALE_MAIL:
- /* Dragon mail - depends on the order of objects */
- /* & dragons. */
- if (mntmp >= PM_GRAY_DRAGON &&
- mntmp <= PM_YELLOW_DRAGON)
- otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
- mntmp - PM_GRAY_DRAGON;
- break;
- }
- }
-
- /* set blessed/cursed -- setting the fields directly is safe
- * since weight() is called below and addinv() will take care
- * of luck */
- if (iscursed) {
- curse(otmp);
- } else if (uncursed) {
- otmp->blessed = 0;
- otmp->cursed = (Luck < 0 && !wizard);
- } else if (blessed) {
- otmp->blessed = (Luck >= 0 || wizard);
- otmp->cursed = (Luck < 0 && !wizard);
- } else if (spesgn < 0) {
- curse(otmp);
- }
+ )
+ otmp->corpsenm = mntmp;
+ break;
+ case EGG:
+ mntmp = can_be_hatched(mntmp);
+ /* this also sets hatch timer if appropriate */
+ set_corpsenm(otmp, mntmp);
+ break;
+ case STATUE: otmp->corpsenm = mntmp;
+ if (Has_contents(otmp) && verysmall(&mons[mntmp]))
+ delete_contents(otmp); /* no spellbook */
+ otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
+ break;
+ case SCALE_MAIL:
+ /* Dragon mail - depends on the order of objects */
+ /* & dragons. */
+ if (mntmp >= PM_GRAY_DRAGON &&
+ mntmp <= PM_YELLOW_DRAGON)
+ otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
+ mntmp - PM_GRAY_DRAGON;
+ break;
+ }
+ }
- /* set eroded */
- if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
- if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
- otmp->oeroded = eroded;
- if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
- otmp->oeroded2 = eroded2;
+ /* set blessed/cursed -- setting the fields directly is safe
+ * since weight() is called below and addinv() will take care
+ * of luck */
+ if (iscursed) {
+ curse(otmp);
+ } else if (uncursed) {
+ otmp->blessed = 0;
+ otmp->cursed = (Luck < 0 && !wizard);
+ } else if (blessed) {
+ otmp->blessed = (Luck >= 0 || wizard);
+ otmp->cursed = (Luck < 0 && !wizard);
+ } else if (spesgn < 0) {
+ curse(otmp);
+ }
- /* set erodeproof */
- if (erodeproof && !eroded && !eroded2)
- otmp->oerodeproof = (Luck >= 0 || wizard);
- }
+ /* set eroded */
+ if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
+ if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
+ otmp->oeroded = eroded;
+ if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
+ otmp->oeroded2 = eroded2;
- /* set otmp->recharged */
- if (oclass == WAND_CLASS) {
- /* prevent wishing abuse */
- if (otmp->otyp == WAN_WISHING && !wizard) rechrg = 1;
- otmp->recharged = (unsigned)rechrg;
- }
+ /* set erodeproof */
+ if (erodeproof && !eroded && !eroded2)
+ otmp->oerodeproof = (Luck >= 0 || wizard);
+ }
- /* set poisoned */
- if (ispoisoned) {
- if (is_poisonable(otmp))
- otmp->opoisoned = (Luck >= 0);
- else if (oclass == FOOD_CLASS)
- /* try to taint by making it as old as possible */
- otmp->age = 1L;
- }
- /* and [un]trapped */
- if (trapped) {
- if (Is_box(otmp) || typ == TIN)
- otmp->otrapped = (trapped == 1);
- }
+ /* set otmp->recharged */
+ if (oclass == WAND_CLASS) {
+ /* prevent wishing abuse */
+ if (otmp->otyp == WAN_WISHING && !wizard) rechrg = 1;
+ otmp->recharged = (unsigned)rechrg;
+ }
- if (isgreased) otmp->greased = 1;
+ /* set poisoned */
+ if (ispoisoned) {
+ if (is_poisonable(otmp))
+ otmp->opoisoned = (Luck >= 0);
+ else if (oclass == FOOD_CLASS)
+ /* try to taint by making it as old as possible */
+ otmp->age = 1L;
+ }
+ /* and [un]trapped */
+ if (trapped) {
+ if (Is_box(otmp) || typ == TIN)
+ otmp->otrapped = (trapped == 1);
+ }
- if (isdiluted && otmp->oclass == POTION_CLASS &&
- otmp->otyp != POT_WATER)
- otmp->odiluted = 1;
+ if (isgreased) otmp->greased = 1;
- /* set tin variety */
- if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
- set_tin_variety(otmp, tvariety);
+ if (isdiluted && otmp->oclass == POTION_CLASS &&
+ otmp->otyp != POT_WATER)
+ otmp->odiluted = 1;
- if (name) {
- const char *aname;
- short objtyp;
+ /* set tin variety */
+ if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
+ set_tin_variety(otmp, tvariety);
- /* an artifact name might need capitalization fixing */
- aname = artifact_name(name, &objtyp);
- if (aname && objtyp == otmp->otyp) name = aname;
+ if (name) {
+ const char *aname;
+ short objtyp;
- /* 3.6.0 tribute - fix up novel */
- if (otmp->otyp == SPE_NOVEL) {
- int novidx = 0;
- const char *novelname;
+ /* an artifact name might need capitalization fixing */
+ aname = artifact_name(name, &objtyp);
+ if (aname && objtyp == otmp->otyp) name = aname;
- novelname = lookup_novel(name, &novidx);
- if (novelname) {
- otmp->novelidx = novidx;
- name = novelname;
- }
- }
++ /* 3.6.0 tribute - fix up novel */
++ if (otmp->otyp == SPE_NOVEL) {
++ int novidx = 0;
++ const char *novelname;
+
- otmp = oname(otmp, name);
- if (otmp->oartifact) {
- otmp->quan = 1L;
- u.uconduct.wisharti++;
- }
++ novelname = lookup_novel(name, &novidx);
++ if (novelname) {
++ otmp->novelidx = novidx;
++ name = novelname;
++ }
+ }
+
- /* more wishing abuse: don't allow wishing for certain artifacts */
- /* and make them pay; charge them for the wish anyway! */
- if ((is_quest_artifact(otmp) ||
- (otmp->oartifact && rn2(nartifact_exist()) > 1)) &&
- !wizard) {
- artifact_exists(otmp, safe_oname(otmp), FALSE);
- obfree(otmp, (struct obj *) 0);
- otmp = &zeroobj;
- pline("For a moment, you feel %s in your %s, but it disappears!",
- something,
- makeplural(body_part(HAND)));
- }
+ otmp = oname(otmp, name);
+ if (otmp->oartifact) {
+ otmp->quan = 1L;
+ u.uconduct.wisharti++; /* KMH, conduct */
+ }
+ }
- if (halfeaten && otmp->oclass == FOOD_CLASS) {
- if (otmp->otyp == CORPSE)
- otmp->oeaten = mons[otmp->corpsenm].cnutrit;
- else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
- /* (do this adjustment before setting up object's weight) */
- consume_oeaten(otmp, 1);
- }
- otmp->owt = weight(otmp);
- if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
+ /* more wishing abuse: don't allow wishing for certain artifacts */
+ /* and make them pay; charge them for the wish anyway! */
+ if ((is_quest_artifact(otmp) ||
+ (otmp->oartifact && rn2(nartifact_exist()) > 1)) &&
+ !wizard) {
+ artifact_exists(otmp, safe_oname(otmp), FALSE);
+ obfree(otmp, (struct obj *) 0);
+ otmp = &zeroobj;
+ pline("For a moment, you feel %s in your %s, but it disappears!",
+ something,
+ makeplural(body_part(HAND)));
+ }
+
+ if (halfeaten && otmp->oclass == FOOD_CLASS) {
+ if (otmp->otyp == CORPSE)
+ otmp->oeaten = mons[otmp->corpsenm].cnutrit;
+ else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
+ /* (do this adjustment before setting up object's weight) */
+ consume_oeaten(otmp, 1);
+ }
+ otmp->owt = weight(otmp);
+ if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
- return(otmp);
+ return(otmp);
}
int