Ejemplo n.º 1
0
/* He is digging in the shop. */
void
shopdig(int fall)
{
    if(!fall) {
	if(u.utraptype == TT_PIT)
	    pline("\"Be careful, sir, or you might fall through the floor.\"");
	else
	    pline("\"Please, do not damage the floor here.\"");
    } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) {
	struct obj *obj, *obj2;

	pline("%s grabs your backpack!", shkname(shopkeeper));
	for(obj = invent; obj; obj = obj2) {
		obj2 = obj->nobj;
		if(obj->owornmask) continue;
		freeinv(obj);
		obj->nobj = shopkeeper->minvent;
		shopkeeper->minvent = obj;
		if(obj->unpaid)
			subfrombill(obj);
	}
    }
}
Ejemplo n.º 2
0
/* He is digging in the shop. */
void shopdig(Boolean fall)
{
  if (!fall) {
    if (you.utraptype == TT_PIT)
      message("\"Be careful, sir, or you might fall through the floor.\"");
    else
      message("\"Please, do not damage the floor here.\"");
  } else if (dist(shopkeeper->mx, shopkeeper->my) < 3) {
    obj_t *obj, *obj2;

    StrPrintF(ScratchBuffer, "%s grabs your backpack!", shkname(shopkeeper));
    message(ScratchBuffer);
    for (obj = invent ; obj ; obj = obj2) {
      obj2 = obj->nobj;
      if (obj->owornmask) continue;
      unlink_inv(obj); //freeinv(obj);
      obj->nobj = shopkeeper->minvent;
      shopkeeper->minvent = obj;
      if (obj->bitflags & O_IS_UNPAID)
	subfrombill(obj);
    }
  }
}
Ejemplo n.º 3
0
int
dopay(void)
{
	long ltmp;
	struct bill_x *bp;
	struct monst *shkp;
	int pass, tmp;

	multi = 0;
	inshop();
	for (shkp = fmon; shkp; shkp = shkp->nmon)
		if (shkp->isshk && dist(shkp->mx, shkp->my) < 3)
			break;
	if (!shkp && u.uinshop &&
	    inroom(shopkeeper->mx, shopkeeper->my) == ESHK(shopkeeper)->shoproom)
		shkp = shopkeeper;

	if (!shkp) {
		pline("There is nobody here to receive your payment.");
		return (0);
	}
	ltmp = ESHK(shkp)->robbed;
	if (shkp != shopkeeper && NOTANGRY(shkp)) {
		if (!ltmp)
			pline("You do not owe %s anything.", monnam(shkp));
		else if (!u.ugold)
			pline("You have no money.");
		else {
			long ugold = u.ugold;

			if (u.ugold > ltmp) {
				pline("You give %s the %ld gold pieces he asked for.",
				    monnam(shkp), ltmp);
				pay(ltmp, shkp);
			} else {
				pline("You give %s all your gold.", monnam(shkp));
				pay(u.ugold, shkp);
			}
			if (ugold < ltmp / 2)
				pline("Unfortunately, he doesn't look satisfied.");
			else {
				ESHK(shkp)->robbed = 0;
				ESHK(shkp)->following = 0;
				if (ESHK(shkp)->shoplevel != dlevel) {
					/* For convenience's sake, let him disappear */
					shkp->minvent = 0;	/* %% */
					shkp->mgold = 0;
					mondead(shkp);
				}
			}
		}
		return (1);
	}

	if (!ESHK(shkp)->billct) {
		pline("You do not owe %s anything.", monnam(shkp));
		if (!u.ugold) {
			pline("Moreover, you have no money.");
			return (1);
		}
		if (ESHK(shkp)->robbed) {
#define	min(a, b)	((a < b) ? a : b)
			pline("But since his shop has been robbed recently,");
			pline("you %srepay %s's expenses.",
			    (u.ugold < ESHK(shkp)->robbed) ? "partially " : "",
			    monnam(shkp));
			pay(min(u.ugold, ESHK(shkp)->robbed), shkp);
			ESHK(shkp)->robbed = 0;
			return (1);
		}
		if (ANGRY(shkp)) {
			pline("But in order to appease %s,",
			      amonnam(shkp, "angry"));
			if (u.ugold >= 1000) {
				ltmp = 1000;
				pline(" you give him 1000 gold pieces.");
			} else {
				ltmp = u.ugold;
				pline(" you give him all your money.");
			}
			pay(ltmp, shkp);
			if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
			    || rn2(3)) {
				pline("%s calms down.", Monnam(shkp));
				NOTANGRY(shkp) = 1;
			} else
				pline("%s is as angry as ever.", Monnam(shkp));
		}
		return (1);
	}
	if (shkp != shopkeeper) {
		impossible("dopay: not to shopkeeper?");
		if (shopkeeper)
			setpaid();
		return (0);
	}
	for (pass = 0; pass <= 1; pass++) {
		tmp = 0;
		while (tmp < ESHK(shopkeeper)->billct) {
			bp = &bill[tmp];
			if (!pass && !bp->useup) {
				tmp++;
				continue;
			}
			if (!dopayobj(bp))
				return (1);
			bill[tmp] = bill[--ESHK(shopkeeper)->billct];
		}
	}
	pline("Thank you for shopping in %s's %s store!",
	      shkname(shopkeeper),
	      shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
	NOTANGRY(shopkeeper) = 1;
	return (1);
}
Ejemplo n.º 4
0
int
inshop(void)
{
	int roomno = inroom(u.ux, u.uy);

	/* Did we just leave a shop? */
	if (u.uinshop &&
	    (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
		if (shopkeeper) {
			if (ESHK(shopkeeper)->billct) {
				if (inroom(shopkeeper->mx, shopkeeper->my)
				    == u.uinshop - 1)	/* ab@unido */
					pline("Somehow you escaped the shop without paying!");
				addupbill();
				pline("You stole for a total worth of %ld zorkmids.",
				    total);
				ESHK(shopkeeper)->robbed += total;
				setpaid();
				if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
				    == (rn2(3) == 0))
					ESHK(shopkeeper)->following = 1;
			}
			shopkeeper = NULL;
			shlevel = 0;
		}
		u.uinshop = 0;
	}

	/* Did we just enter a zoo of some kind? */
	if (roomno >= 0) {
		int rt = rooms[roomno].rtype;
		struct monst *mtmp;
		if (rt == ZOO)
			pline("Welcome to David's treasure zoo!");
		else if (rt == SWAMP)
			pline("It looks rather muddy down here.");
		else if (rt == MORGUE) {
			if (midnight())
				pline("Go away! Go away!");
			else
				pline("You get an uncanny feeling ...");
		} else
			rt = 0;
		if (rt != 0) {
			rooms[roomno].rtype = 0;
			for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
				if (rt != ZOO || !rn2(3))
					mtmp->msleep = 0;
		}
	}

	/* Did we just enter a shop? */
	if (roomno >= 0 && rooms[roomno].rtype >= 8) {
		if (shlevel != dlevel || !shopkeeper
		    || ESHK(shopkeeper)->shoproom != roomno)
			findshk(roomno);
		if (!shopkeeper) {
			rooms[roomno].rtype = 0;
			u.uinshop = 0;
		} else if (!u.uinshop) {
			if (!ESHK(shopkeeper)->visitct ||
			    strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {
				/* He seems to be new here */
				ESHK(shopkeeper)->visitct = 0;
				ESHK(shopkeeper)->following = 0;
				strncpy(ESHK(shopkeeper)->customer, plname, PL_NSIZ);
				NOTANGRY(shopkeeper) = 1;
			}
			if (!ESHK(shopkeeper)->following) {
				boolean box, pick;

				pline("Hello %s! Welcome%s to %s's %s shop!",
				      plname,
				      ESHK(shopkeeper)->visitct++ ? " again" : "",
				      shkname(shopkeeper),
				      shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
				box = carrying(ICE_BOX);
				pick = carrying(PICK_AXE);
				if (box || pick) {
					if (dochug(shopkeeper)) {
						u.uinshop = 0;	/* he died moving */
						return (0);
					}
					pline("Will you please leave your %s outside?",
					    (box && pick) ? "box and pick-axe" :
					    box ? "box" : "pick-axe");
				}
			}
			u.uinshop = roomno + 1;
		}
	}
	return (u.uinshop);
}
Ejemplo n.º 5
0
// What does the return value indicate??
Boolean dopay()
{
  Long ltmp;
  bill_t *bp;
  monst_t *shkp;
  Short pass, tmp;

  multi = 0;
  inshop();
  for (shkp = fmon ; shkp ; shkp = shkp->nmon)
    if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3)
      break;
  if (!shkp && you.uinshop &&
      inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom)
    shkp = shopkeeper;

  if (!shkp) {
    message("There is nobody here to receive your payment.");
    return false;
  }
  ltmp = ESHK(shkp)->robbed;
  if (shkp != shopkeeper && NOTANGRY(shkp)) {
    if (!ltmp) {
      StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp));
      message(ScratchBuffer);
    } else
      if (!you.ugold) {
	message("You have no money.");
      } else {
	Long ugold = you.ugold;

	if (you.ugold > ltmp) {
	  StrPrintF(ScratchBuffer,
		    "You give %s the %ld gold pieces he asked for.",
		    monnam(shkp), ltmp);
	  message(ScratchBuffer);
	  pay(ltmp, shkp);
	} else {
	  StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp));
	  message(ScratchBuffer);
	  pay(you.ugold, shkp);
	}
	if (ugold < ltmp/2) {
	  message("Unfortunately, he doesn't look satisfied.");
	} else {
	  ESHK(shkp)->robbed = 0;
	  ESHK(shkp)->following = false;
	  if (ESHK(shkp)->shoplevel != dlevel) {
	    /* For convenience's sake, let him disappear */
	    shkp->minvent = NULL;	/* %% */ // xxx leak?
	    shkp->mgold = 0;
	    mondead(shkp);
	  }
	}
      }
    return true;
  }
		
  if (!ESHK(shkp)->billct) {
    StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp));
    message(ScratchBuffer);
    if (!you.ugold) {
      message("Moreover, you have no money.");
      return true;
    }
    if (ESHK(shkp)->robbed) {
      message("But since his shop has been robbed recently,");
      StrPrintF(ScratchBuffer, "you%srepay %s's expenses.",
		(you.ugold < ESHK(shkp)->robbed) ? " partially " : " ",
		monnam(shkp));
      message(ScratchBuffer);
      pay(min(you.ugold, ESHK(shkp)->robbed), shkp);
      ESHK(shkp)->robbed = 0;
      return true;
    }
    if (ANGRY(shkp)) {
      StrPrintF(ScratchBuffer, "But in order to appease %s,",
		amonnam(shkp, "angry"));
      message(ScratchBuffer);
      if (you.ugold >= 1000) {
	ltmp = 1000;
	message(" you give him 1000 gold pieces.");
      } else {
	ltmp = you.ugold;
	message(" you give him all your money.");
      }
      pay(ltmp, shkp);
      if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)
	  || rund(3)){
	StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp));
	message(ScratchBuffer);
	shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
      } else {
	StrPrintF(ScratchBuffer, "%s is as angry as ever.",
		  Monnam(shkp));
	message(ScratchBuffer);
      }
    }
    return true;
  }
  if (shkp != shopkeeper) {
    message("BUG: dopay: not to shopkeeper?");
    if (shopkeeper) setpaid();
    return false;
  }
  for (pass = 0 ; pass <= 1 ; pass++) {
    tmp = 0;
    while (tmp < ESHK(shopkeeper)->billct) {
      bp = &bill[tmp];
      if (!pass && !bp->useup) {
	tmp++;
	continue;
      }
      if (!dopayobj(bp)) return true;
      bill[tmp] = bill[--ESHK(shopkeeper)->billct];
    }
  }
  StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!",
	    shkname(shopkeeper),
	    shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
  shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
  return true;
}
Ejemplo n.º 6
0
UInt inshop()
{
  Short roomno = inroom(you.ux,you.uy);

  /* Did we just leave a shop? */
  if (you.uinshop &&
      (you.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
    if (shopkeeper) {
      if (ESHK(shopkeeper)->billct) {
	if (inroom(shopkeeper->mx, shopkeeper->my) 
	    == you.uinshop - 1)	/* ab@unido */
	  message("Somehow you escaped the shop without paying!");
	addupbill();
	StrPrintF(ScratchBuffer,"You stole for a total worth of %ld zorkmids.",
		  total);
	message(ScratchBuffer);
	ESHK(shopkeeper)->robbed += total;
	setpaid();
	if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
	    == (rund(3) == 0))
	  ESHK(shopkeeper)->following = true;
      }
      shopkeeper = NULL;
      shlevel = 0;
    }
    you.uinshop = 0;
  }

  /* Did we just enter a zoo of some kind? */
  if (roomno >= 0) {
    Short rt = rooms[roomno].rtype;
    monst_t *mtmp;
    if (rt == ZOO) {
      message("Welcome to David's treasure zoo!");
    } else
      if (rt == SWAMP) {
	message("It looks rather muddy down here.");
      } else
	if (rt == MORGUE) {
	  if (midnight())
	    message("Go away! Go away!");
	  else
	    message("You get an uncanny feeling ...");
	} else
	  rt = 0;
    if (rt != 0) {
      rooms[roomno].rtype = 0;
      for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
	if (rt != ZOO || !rund(3))
	  mtmp->bitflags &= ~M_IS_ASLEEP;
    }
  }

  /* Did we just enter a shop? */
  if (roomno >= 0 && rooms[roomno].rtype >= 8) {
    if (shlevel != dlevel || !shopkeeper
	|| ESHK(shopkeeper)->shoproom != roomno)
      findshk(roomno);
    if (!shopkeeper) {
      rooms[roomno].rtype = 0;
      you.uinshop = 0;
    } else if (!you.uinshop) {
      if (!ESHK(shopkeeper)->visitct ||
	  StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {

	/* He seems to be new here */
	ESHK(shopkeeper)->visitct = 0;
	ESHK(shopkeeper)->following = false;
	StrNCopy(ESHK(shopkeeper)->customer, plname, PL_NSIZ);
	shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1;
      }
      if (!ESHK(shopkeeper)->following) {
	Boolean box, pick;

	StrPrintF(ScratchBuffer, "Hello %s! Welcome%sto %s's %s shop!",
		  plname,
		  ESHK(shopkeeper)->visitct++ ? " again " : " ",
		  shkname(shopkeeper),
		  shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] );
	message(ScratchBuffer);
	box = carrying(ICE_BOX);
	pick = carrying(PICK_AXE);
	if (box || pick) {
	  if (do_chug(shopkeeper)) {
	    you.uinshop = 0;	/* he died moving */
	    return 0;
	  }
	  StrPrintF(ScratchBuffer, "Will you please leave your %s outside?",
		    (box && pick) ? "box and pick-axe" :
		    box ? "box" : "pick-axe");
	  message(ScratchBuffer);
	}
      }
      you.uinshop = roomno + 1; // (0 is "not in shop")
    }
  }
  return you.uinshop;
}
Ejemplo n.º 7
0
static int ready_weapon(struct obj *wep)
{
	/* Separated function so swapping works easily */
	int res = 0;

	if (!wep) {
	    /* No weapon */
	    if (uwep) {
		pline("You are empty %s.", body_part(HANDED));
		setuwep(NULL);
		res++;
	    } else
		pline("You are already empty %s.", body_part(HANDED));
	} else if (!uarmg && !Stone_resistance && wep->otyp == CORPSE
				&& touch_petrifies(&mons[wep->corpsenm])) {
	    /* Prevent wielding cockatrice when not wearing gloves --KAA */
	    char kbuf[BUFSZ];

	    pline("You wield the %s corpse in your bare %s.",
		mons[wep->corpsenm].mname, makeplural(body_part(HAND)));
	    sprintf(kbuf, "%s corpse", an(mons[wep->corpsenm].mname));
	    instapetrify(kbuf);
	} else if (uarms && bimanual(wep))
	    pline("You cannot wield a two-handed %s while wearing a shield.",
		is_sword(wep) ? "sword" :
		    wep->otyp == BATTLE_AXE ? "axe" : "weapon");
	else if (wep->oartifact && !touch_artifact(wep, &youmonst)) {
	    res++;	/* takes a turn even though it doesn't get wielded */
	} else {
	    /* Weapon WILL be wielded after this point */
	    res++;
	    if (will_weld(wep)) {
		const char *tmp = xname(wep), *thestr = "The ";
		if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4))
		    tmp = thestr;
		else tmp = "";
		pline("%s%s %s to your %s!", tmp, aobjnam(wep, "weld"),
			(wep->quan == 1L) ? "itself" : "themselves", /* a3 */
			bimanual(wep) ?
				(const char *)makeplural(body_part(HAND))
				: body_part(HAND));
		wep->bknown = TRUE;
	    } else {
		/* The message must be printed before setuwep (since
		 * you might die and be revived from changing weapons),
		 * and the message must be before the death message and
		 * Lifesaved rewielding.  Yet we want the message to
		 * say "weapon in hand", thus this kludge.
		 */
		long dummy = wep->owornmask;
		wep->owornmask |= W_WEP;
		prinv(NULL, wep, 0L);
		wep->owornmask = dummy;
	    }
	    setuwep(wep);

	    /* KMH -- Talking artifacts are finally implemented */
	    arti_speak(wep);

	    if (artifact_light(wep) && !wep->lamplit) {
		begin_burn(wep, FALSE);
		if (!Blind)
		    pline("%s to glow brilliantly!", Tobjnam(wep, "begin"));
	    }

	    if (wep->unpaid) {
		struct monst *this_shkp;

		if ((this_shkp = shop_keeper(level, inside_shop(level, u.ux, u.uy))) !=
		    NULL) {
		    pline("%s says \"You be careful with my %s!\"",
			  shkname(this_shkp),
			  xname(wep));
		}
	    }
	}
	return res;
}
Ejemplo n.º 8
0
/* Bug: if the monster is a priest or shopkeeper, not every one of these
 * options works, since those are special cases.
 */
char *x_monnam(const struct monst *mtmp,
	       int article, /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
	                     * ARTICLE_YOUR: "your" on pets, "the" on everything
			     * else
			     * If the monster would be referred to as "it" or if the monster has a name
			     * _and_ there is no adjective, "invisible", "saddled", etc., override this
			     * and always use no article.
			     */
	       const char *adjective,
	       int suppress, /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
	                      * EXACT_NAME: combination of all the above
			      */
	       boolean called)
{
	static char buf[BUFSZ];

	const struct permonst *mdat = mtmp->data;
	boolean do_hallu, do_invis, do_it, do_saddle;
	boolean name_at_start, has_adjectives;
	char *bp;

	if (program_state.gameover)
	    suppress |= SUPPRESS_HALLUCINATION;
	if (article == ARTICLE_YOUR && !mtmp->mtame)
	    article = ARTICLE_THE;

	do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
	do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
	do_it = !canspotmon(mtmp) && 
	    article != ARTICLE_YOUR &&
	    !program_state.gameover &&
	    mtmp != u.usteed &&
	    !(u.uswallow && mtmp == u.ustuck) &&
	    !(suppress & SUPPRESS_IT);
	do_saddle = !(suppress & SUPPRESS_SADDLE);

	buf[0] = 0;

	/* unseen monsters, etc.  Use "it" */
	if (do_it) {
	    strcpy(buf, "it");
	    return buf;
	}

	/* priests and minions: don't even use this function */
	if (mtmp->ispriest || mtmp->isminion) {
	    struct monst *priestmon = newmonst(mtmp->mxtyp, mtmp->mnamelth);
	    char priestnambuf[BUFSZ];
	    char *name;
	    long save_prop = EHalluc_resistance;
	    memcpy(priestmon, mtmp, sizeof(struct monst) + mtmp->mxlth + mtmp->mnamelth);

	    /* when true name is wanted, explicitly block Hallucination */
	    if (!do_hallu) EHalluc_resistance = 1L;
	    if (!do_invis) priestmon->minvis = 0;
	    name = priestname(priestmon, priestnambuf);
	    EHalluc_resistance = save_prop;
	    if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
		name += 4;
	    strcpy(buf, name);
	    free(priestmon);
	    return buf;
	}

	/* Shopkeepers: use shopkeeper name.  For normal shopkeepers, just
	 * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
	 * shopkeeper" or "Asidonhopo the blue dragon".  If hallucinating,
	 * none of this applies.
	 */
	if (mtmp->isshk && !do_hallu) {
	    if (adjective && article == ARTICLE_THE) {
		/* pathological case: "the angry Asidonhopo the blue dragon"
		   sounds silly */
		strcpy(buf, "the ");
		strcat(strcat(buf, adjective), " ");
		strcat(buf, shkname(mtmp));
		return buf;
	    }
	    strcat(buf, shkname(mtmp));
	    if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
		return buf;
	    strcat(buf, " the ");
	    if (do_invis)
		strcat(buf, "invisible ");
	    strcat(buf, mdat->mname);
	    return buf;
	}

	/* Put the adjectives in the buffer */
	if (adjective)
	    strcat(strcat(buf, adjective), " ");
	if (do_invis)
	    strcat(buf, "invisible ");

	if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) &&
	    !Blind && !Hallucination)
	    strcat(buf, "saddled ");

	if (buf[0] != 0)
	    has_adjectives = TRUE;
	else
	    has_adjectives = FALSE;

	/* Put the actual monster name or type into the buffer now */
	/* Be sure to remember whether the buffer starts with a name */
	if (do_hallu) {
	    strcat(buf, rndmonnam());
	    name_at_start = FALSE;
	} else if (mtmp->mnamelth) {
	    char *name = NAME(mtmp);

	    if (mdat == &mons[PM_GHOST]) {
		sprintf(eos(buf), "%s ghost", s_suffix(name));
		name_at_start = TRUE;
	    } else if (called) {
		sprintf(eos(buf), "%s called %s", mdat->mname, name);
		name_at_start = (boolean)type_is_pname(mdat);
	    } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
		/* <name> the <adjective> <invisible> <saddled> <rank> */
		char pbuf[BUFSZ];

		strcpy(pbuf, name);
		pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
		if (has_adjectives)
		    strcat(pbuf, buf);
		strcat(pbuf, bp + 5);	/* append the rest of the name */
		strcpy(buf, pbuf);
		article = ARTICLE_NONE;
		name_at_start = TRUE;
	    } else {
		strcat(buf, name);
		name_at_start = TRUE;
	    }
	} else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
	    char pbuf[BUFSZ];
	    strcpy(pbuf, rank_of((int)mtmp->m_lev,
				 monsndx(mdat), (boolean)mtmp->female));
	    strcat(buf, lcase(pbuf));
	    name_at_start = FALSE;
	} else {
	    strcat(buf, mdat->mname);
	    name_at_start = (boolean)type_is_pname(mdat);
	}

	if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
	    if (mdat == &mons[PM_WIZARD_OF_YENDOR])
		article = ARTICLE_THE;
	    else
		article = ARTICLE_NONE;
	} else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
	    article = ARTICLE_THE;
	}

	{
	    char buf2[BUFSZ];

	    switch(article) {
		case ARTICLE_YOUR:
		    strcpy(buf2, "your ");
		    strcat(buf2, buf);
		    strcpy(buf, buf2);
		    return buf;
		case ARTICLE_THE:
		    strcpy(buf2, "the ");
		    strcat(buf2, buf);
		    strcpy(buf, buf2);
		    return buf;
		case ARTICLE_A:
		    return an(buf);
		case ARTICLE_NONE:
		default:
		    return buf;
	    }
	}
}