*** empty log message ***
This commit is contained in:
994
src/do_name.c
Normal file
994
src/do_name.c
Normal file
@@ -0,0 +1,994 @@
|
||||
/* SCCS Id: @(#)do_name.c 3.3 2000/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
#ifdef OVLB
|
||||
|
||||
STATIC_DCL void FDECL(do_oname, (struct obj *));
|
||||
static void FDECL(getpos_help, (BOOLEAN_P,const char *));
|
||||
|
||||
extern const char what_is_an_unknown_object[]; /* from pager.c */
|
||||
|
||||
/* the response for '?' help request in getpos() */
|
||||
static void
|
||||
getpos_help(force, goal)
|
||||
boolean force;
|
||||
const char *goal;
|
||||
{
|
||||
char sbuf[BUFSZ];
|
||||
boolean doing_what_is;
|
||||
winid tmpwin = create_nhwindow(NHW_MENU);
|
||||
|
||||
Sprintf(sbuf, "Use [%s] to move the cursor to %s.",
|
||||
iflags.num_pad ? "2468" : "hjkl", goal);
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
|
||||
putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
|
||||
/* disgusting hack; the alternate selection characters work for any
|
||||
getpos call, but they only matter for dowhatis (and doquickwhatis) */
|
||||
doing_what_is = (goal == what_is_an_unknown_object);
|
||||
Sprintf(sbuf, "Type a .%s when you are at the right place.",
|
||||
doing_what_is ? " or , or ; or :" : "");
|
||||
putstr(tmpwin, 0, sbuf);
|
||||
if (!force)
|
||||
putstr(tmpwin, 0, "Type Space or Escape when you're done.");
|
||||
putstr(tmpwin, 0, "");
|
||||
display_nhwindow(tmpwin, TRUE);
|
||||
destroy_nhwindow(tmpwin);
|
||||
}
|
||||
|
||||
int
|
||||
getpos(cc, force, goal)
|
||||
coord *cc;
|
||||
boolean force;
|
||||
const char *goal;
|
||||
{
|
||||
int result = 0;
|
||||
int cx, cy, i, c;
|
||||
int sidx, tx, ty;
|
||||
boolean msg_given = TRUE; /* clear message window by default */
|
||||
static const char *pick_chars = ".,;:";
|
||||
const char *cp;
|
||||
const char *sdp;
|
||||
if(iflags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */
|
||||
|
||||
if (flags.verbose) {
|
||||
pline("(For instructions type a ?)");
|
||||
msg_given = TRUE;
|
||||
}
|
||||
cx = cc->x;
|
||||
cy = cc->y;
|
||||
#ifdef CLIPPING
|
||||
cliparound(cx, cy);
|
||||
#endif
|
||||
curs(WIN_MAP, cx,cy);
|
||||
flush_screen(0);
|
||||
#ifdef MAC
|
||||
lock_mouse_cursor(TRUE);
|
||||
#endif
|
||||
for (;;) {
|
||||
c = nh_poskey(&tx, &ty, &sidx);
|
||||
if (c == '\033') {
|
||||
cx = cy = -10;
|
||||
msg_given = TRUE; /* force clear */
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if(c == 0) {
|
||||
if (!isok(tx, ty)) continue;
|
||||
/* a mouse click event, just assign and return */
|
||||
cx = tx;
|
||||
cy = ty;
|
||||
break;
|
||||
}
|
||||
if ((cp = index(pick_chars, c)) != 0) {
|
||||
/* '.' => 0, ',' => 1, ';' => 2, ':' => 3 */
|
||||
result = cp - pick_chars;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
int dx, dy;
|
||||
|
||||
if (sdp[i] == c) {
|
||||
/* a normal movement letter or digit */
|
||||
dx = xdir[i];
|
||||
dy = ydir[i];
|
||||
} else if (sdir[i] == lowc((char)c)) {
|
||||
/* a shifted movement letter */
|
||||
dx = 8 * xdir[i];
|
||||
dy = 8 * ydir[i];
|
||||
} else
|
||||
continue;
|
||||
|
||||
/* truncate at map edge; diagonal moves complicate this... */
|
||||
if (cx + dx < 1) {
|
||||
dy -= sgn(dy) * (1 - (cx + dx));
|
||||
dx = 1 - cx; /* so that (cx+dx == 1) */
|
||||
} else if (cx + dx > COLNO-1) {
|
||||
dy += sgn(dy) * ((COLNO-1) - (cx + dx));
|
||||
dx = (COLNO-1) - cx;
|
||||
}
|
||||
if (cy + dy < 0) {
|
||||
dx -= sgn(dx) * (0 - (cy + dy));
|
||||
dy = 0 - cy; /* so that (cy+dy == 0) */
|
||||
} else if (cy + dy > ROWNO-1) {
|
||||
dx += sgn(dx) * ((ROWNO-1) - (cy + dy));
|
||||
dy = (ROWNO-1) - cy;
|
||||
}
|
||||
cx += dx;
|
||||
cy += dy;
|
||||
goto nxtc;
|
||||
}
|
||||
|
||||
if(c == '?'){
|
||||
getpos_help(force, goal);
|
||||
} else {
|
||||
if (!index(quitchars, c)) {
|
||||
char matching[MAXPCHARS];
|
||||
int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
|
||||
(void)memset((genericptr_t)matching, 0, sizeof matching);
|
||||
for (sidx = 1; sidx < MAXPCHARS; sidx++)
|
||||
if (c == defsyms[sidx].sym || c == (int)showsyms[sidx])
|
||||
matching[sidx] = (char) ++k;
|
||||
if (k) {
|
||||
for (pass = 0; pass <= 1; pass++) {
|
||||
/* pass 0: just past current pos to lower right;
|
||||
pass 1: upper left corner to current pos */
|
||||
lo_y = (pass == 0) ? cy : 0;
|
||||
hi_y = (pass == 0) ? ROWNO - 1 : cy;
|
||||
for (ty = lo_y; ty <= hi_y; ty++) {
|
||||
lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
|
||||
hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
|
||||
for (tx = lo_x; tx <= hi_x; tx++) {
|
||||
k = levl[tx][ty].glyph;
|
||||
if (glyph_is_cmap(k) &&
|
||||
matching[glyph_to_cmap(k)]) {
|
||||
cx = tx, cy = ty;
|
||||
if (msg_given) {
|
||||
clear_nhwindow(WIN_MESSAGE);
|
||||
msg_given = FALSE;
|
||||
}
|
||||
goto nxtc;
|
||||
}
|
||||
} /* column */
|
||||
} /* row */
|
||||
} /* pass */
|
||||
pline("Can't find dungeon feature '%c'", c);
|
||||
msg_given = TRUE;
|
||||
goto nxtc;
|
||||
} else {
|
||||
pline("Unknown direction: '%s' (%s).",
|
||||
visctrl((char)c),
|
||||
!force ? "aborted" :
|
||||
iflags.num_pad ? "use 2468 or ." : "use hjkl or .");
|
||||
msg_given = TRUE;
|
||||
} /* k => matching */
|
||||
} /* !quitchars */
|
||||
if (force) goto nxtc;
|
||||
pline("Done.");
|
||||
msg_given = FALSE; /* suppress clear */
|
||||
cx = -1;
|
||||
cy = 0;
|
||||
result = 0; /* not -1 */
|
||||
break;
|
||||
}
|
||||
nxtc: ;
|
||||
#ifdef CLIPPING
|
||||
cliparound(cx, cy);
|
||||
#endif
|
||||
curs(WIN_MAP,cx,cy);
|
||||
flush_screen(0);
|
||||
}
|
||||
#ifdef MAC
|
||||
lock_mouse_cursor(FALSE);
|
||||
#endif
|
||||
if (msg_given) clear_nhwindow(WIN_MESSAGE);
|
||||
cc->x = cx;
|
||||
cc->y = cy;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct monst *
|
||||
christen_monst(mtmp, name)
|
||||
struct monst *mtmp;
|
||||
const char *name;
|
||||
{
|
||||
int lth;
|
||||
struct monst *mtmp2;
|
||||
char buf[PL_PSIZ];
|
||||
|
||||
/* dogname & catname are PL_PSIZ arrays; object names have same limit */
|
||||
lth = *name ? (int)(strlen(name) + 1) : 0;
|
||||
if(lth > PL_PSIZ){
|
||||
lth = PL_PSIZ;
|
||||
name = strncpy(buf, name, PL_PSIZ - 1);
|
||||
buf[PL_PSIZ - 1] = '\0';
|
||||
}
|
||||
if (lth == mtmp->mnamelth) {
|
||||
/* don't need to allocate a new monst struct */
|
||||
if (lth) Strcpy(NAME(mtmp), name);
|
||||
return mtmp;
|
||||
}
|
||||
mtmp2 = newmonst(mtmp->mxlth + lth);
|
||||
*mtmp2 = *mtmp;
|
||||
(void) memcpy((genericptr_t)mtmp2->mextra,
|
||||
(genericptr_t)mtmp->mextra, mtmp->mxlth);
|
||||
mtmp2->mnamelth = lth;
|
||||
if (lth) Strcpy(NAME(mtmp2), name);
|
||||
replmon(mtmp,mtmp2);
|
||||
return(mtmp2);
|
||||
}
|
||||
|
||||
int
|
||||
do_mname()
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
coord cc;
|
||||
register int cx,cy;
|
||||
register struct monst *mtmp;
|
||||
char qbuf[QBUFSZ];
|
||||
|
||||
if (Hallucination) {
|
||||
You("would never recognize it anyway.");
|
||||
return 0;
|
||||
}
|
||||
cc.x = u.ux;
|
||||
cc.y = u.uy;
|
||||
if (getpos(&cc, FALSE, "the monster you want to name") < 0 ||
|
||||
(cx = cc.x) < 0)
|
||||
return 0;
|
||||
cy = cc.y;
|
||||
|
||||
if (cx == u.ux && cy == u.uy) {
|
||||
#ifdef STEED
|
||||
if (u.usteed && canspotmon(u.usteed))
|
||||
mtmp = u.usteed;
|
||||
else {
|
||||
#endif
|
||||
pline("This %s creature is called %s and cannot be renamed.",
|
||||
ACURR(A_CHA) > 14 ?
|
||||
(flags.female ? "beautiful" : "handsome") :
|
||||
"ugly",
|
||||
plname);
|
||||
return(0);
|
||||
#ifdef STEED
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
mtmp = m_at(cx, cy);
|
||||
|
||||
if (!mtmp || (!sensemon(mtmp) &&
|
||||
(!(cansee(cx,cy) || see_with_infrared(mtmp)) || mtmp->mundetected
|
||||
|| mtmp->m_ap_type == M_AP_FURNITURE
|
||||
|| mtmp->m_ap_type == M_AP_OBJECT
|
||||
|| (mtmp->minvis && !See_invisible)))) {
|
||||
pline("I see no monster there.");
|
||||
return(0);
|
||||
}
|
||||
/* special case similar to the one in lookat() */
|
||||
if (mtmp->data != &mons[PM_HIGH_PRIEST])
|
||||
Strcpy(buf, x_monnam(mtmp, ARTICLE_THE, (char *)0, 0, TRUE));
|
||||
else
|
||||
Sprintf(buf, "the high priest%s", mtmp->female ? "ess" : "");
|
||||
Sprintf(qbuf, "What do you want to call %s?", buf);
|
||||
getlin(qbuf,buf);
|
||||
if(!*buf || *buf == '\033') return(0);
|
||||
/* strip leading and trailing spaces; unnames monster if all spaces */
|
||||
(void)mungspaces(buf);
|
||||
|
||||
if (mtmp->iswiz || type_is_pname(mtmp->data))
|
||||
pline("%s doesn't like being called names!", Monnam(mtmp));
|
||||
else (void) christen_monst(mtmp, buf);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine changes the address of obj. Be careful not to call it
|
||||
* when there might be pointers around in unknown places. For now: only
|
||||
* when obj is in the inventory.
|
||||
*/
|
||||
STATIC_OVL
|
||||
void
|
||||
do_oname(obj)
|
||||
register struct obj *obj;
|
||||
{
|
||||
char buf[BUFSZ], qbuf[QBUFSZ];
|
||||
const char *aname;
|
||||
short objtyp;
|
||||
|
||||
Sprintf(qbuf, "What do you want to name %s %s?",
|
||||
(obj->quan > 1L) ? "these" : "this", xname(obj));
|
||||
getlin(qbuf, buf);
|
||||
if(!*buf || *buf == '\033') return;
|
||||
/* strip leading and trailing spaces; unnames item if all spaces */
|
||||
(void)mungspaces(buf);
|
||||
|
||||
/* relax restrictions over proper capitalization for artifacts */
|
||||
if ((aname = artifact_name(buf, &objtyp)) != 0 && objtyp == obj->otyp)
|
||||
Strcpy(buf, aname);
|
||||
|
||||
if (obj->oartifact) {
|
||||
pline_The("artifact seems to resist the attempt.");
|
||||
return;
|
||||
} else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
|
||||
int n = rn2((int)strlen(buf));
|
||||
register char c1, c2;
|
||||
|
||||
c1 = lowc(buf[n]);
|
||||
do c2 = 'a' + rn2('z'-'a'); while (c1 == c2);
|
||||
buf[n] = (buf[n] == c1) ? c2 : highc(c2); /* keep same case */
|
||||
pline("While engraving your %s slips.", body_part(HAND));
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
You("engrave: \"%s\".",buf);
|
||||
}
|
||||
obj = oname(obj, buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new and possibly larger storage space for an obj.
|
||||
*/
|
||||
struct obj *
|
||||
realloc_obj(obj, oextra_size, oextra_src, oname_size, name)
|
||||
struct obj *obj;
|
||||
int oextra_size; /* storage to allocate for oextra */
|
||||
genericptr_t oextra_src;
|
||||
int oname_size; /* size of name string + 1 (null terminator) */
|
||||
const char *name;
|
||||
{
|
||||
struct obj *otmp;
|
||||
|
||||
otmp = newobj(oextra_size + oname_size);
|
||||
*otmp = *obj; /* the cobj pointer is copied to otmp */
|
||||
if (oextra_size) {
|
||||
if (oextra_src)
|
||||
(void) memcpy((genericptr_t)otmp->oextra, oextra_src,
|
||||
oextra_size);
|
||||
} else {
|
||||
otmp->oattached = OATTACHED_NOTHING;
|
||||
}
|
||||
otmp->oxlth = oextra_size;
|
||||
|
||||
otmp->onamelth = oname_size;
|
||||
otmp->timed = 0; /* not timed, yet */
|
||||
otmp->lamplit = 0; /* ditto */
|
||||
/* __GNUC__ note: if the assignment of otmp->onamelth immediately
|
||||
precedes this `if' statement, a gcc bug will miscompile the
|
||||
test on vax (`insv' instruction used to store bitfield does
|
||||
not set condition codes, but optimizer behaves as if it did).
|
||||
gcc-2.7.2.1 finally fixed this. */
|
||||
if (oname_size) {
|
||||
if (name)
|
||||
Strcpy(ONAME(otmp), name);
|
||||
}
|
||||
|
||||
if (obj->owornmask) {
|
||||
setworn((struct obj *)0, obj->owornmask);
|
||||
setworn(otmp, otmp->owornmask);
|
||||
}
|
||||
|
||||
/* replace obj with otmp */
|
||||
replace_object(obj, otmp);
|
||||
|
||||
/* fix ocontainer pointers */
|
||||
if (Has_contents(obj)) {
|
||||
struct obj *inside;
|
||||
|
||||
for(inside = obj->cobj; inside; inside = inside->nobj)
|
||||
inside->ocontainer = otmp;
|
||||
}
|
||||
|
||||
/* move timers and light sources from obj to otmp */
|
||||
if (obj->timed) obj_move_timers(obj, otmp);
|
||||
if (obj->lamplit) obj_move_light_source(obj, otmp);
|
||||
|
||||
/* objects possibly being manipulated by multi-turn occupations
|
||||
which have been interrupted but might be subsequently resumed */
|
||||
if (obj->oclass == FOOD_CLASS)
|
||||
food_substitution(obj, otmp); /* eat food or open tin */
|
||||
else if (obj->oclass == SPBOOK_CLASS)
|
||||
book_substitution(obj, otmp); /* read spellbook */
|
||||
|
||||
/* obfree(obj, otmp); now unnecessary: no pointers on bill */
|
||||
dealloc_obj(obj); /* let us hope nobody else saved a pointer */
|
||||
return otmp;
|
||||
}
|
||||
|
||||
struct obj *
|
||||
oname(obj, name)
|
||||
struct obj *obj;
|
||||
const char *name;
|
||||
{
|
||||
int lth;
|
||||
char buf[PL_PSIZ];
|
||||
|
||||
lth = *name ? (int)(strlen(name) + 1) : 0;
|
||||
if (lth > PL_PSIZ) {
|
||||
lth = PL_PSIZ;
|
||||
name = strncpy(buf, name, PL_PSIZ - 1);
|
||||
buf[PL_PSIZ - 1] = '\0';
|
||||
}
|
||||
/* If named artifact exists in the game, do not create another.
|
||||
* Also trying to create an artifact shouldn't de-artifact
|
||||
* it (e.g. Excalibur from prayer). In this case the object
|
||||
* will retain its current name. */
|
||||
if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
|
||||
return obj;
|
||||
|
||||
if (lth == obj->onamelth) {
|
||||
/* no need to replace entire object */
|
||||
if (lth) Strcpy(ONAME(obj), name);
|
||||
} else {
|
||||
obj = realloc_obj(obj, obj->oxlth,
|
||||
(genericptr_t)obj->oextra, lth, name);
|
||||
}
|
||||
if (lth) artifact_exists(obj, name, TRUE);
|
||||
if (obj->oartifact && obj == uswapwep) untwoweapon();
|
||||
if (carried(obj)) update_inventory();
|
||||
return obj;
|
||||
}
|
||||
|
||||
static NEARDATA const char callable[] = {
|
||||
SCROLL_CLASS, POTION_CLASS, WAND_CLASS, RING_CLASS, AMULET_CLASS,
|
||||
GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0 };
|
||||
|
||||
int
|
||||
ddocall()
|
||||
{
|
||||
register struct obj *obj;
|
||||
#ifdef REDO
|
||||
char ch;
|
||||
#endif
|
||||
char allowall[2];
|
||||
|
||||
switch(
|
||||
#ifdef REDO
|
||||
ch =
|
||||
#endif
|
||||
ynq("Name an individual object?")) {
|
||||
case 'q':
|
||||
break;
|
||||
case 'y':
|
||||
#ifdef REDO
|
||||
savech(ch);
|
||||
#endif
|
||||
allowall[0] = ALL_CLASSES; allowall[1] = '\0';
|
||||
obj = getobj(allowall, "name");
|
||||
if(obj) do_oname(obj);
|
||||
break;
|
||||
default :
|
||||
#ifdef REDO
|
||||
savech(ch);
|
||||
#endif
|
||||
obj = getobj(callable, "call");
|
||||
if (obj) {
|
||||
if (!obj->dknown) {
|
||||
You("would never recognize another one.");
|
||||
return 0;
|
||||
}
|
||||
docall(obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
docall(obj)
|
||||
register struct obj *obj;
|
||||
{
|
||||
char buf[BUFSZ], qbuf[QBUFSZ];
|
||||
struct obj otemp;
|
||||
register char **str1;
|
||||
|
||||
if (!obj->dknown) return; /* probably blind */
|
||||
otemp = *obj;
|
||||
otemp.quan = 1L;
|
||||
otemp.onamelth = 0;
|
||||
otemp.oxlth = 0;
|
||||
if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.corpsenm)
|
||||
/* kludge, meaning it's sink water */
|
||||
Sprintf(qbuf,"Call a stream of %s fluid:",
|
||||
OBJ_DESCR(objects[otemp.otyp]));
|
||||
else
|
||||
Sprintf(qbuf, "Call %s:", an(xname(&otemp)));
|
||||
getlin(qbuf, buf);
|
||||
if(!*buf || *buf == '\033')
|
||||
return;
|
||||
|
||||
/* clear old name */
|
||||
str1 = &(objects[obj->otyp].oc_uname);
|
||||
if(*str1) free((genericptr_t)*str1);
|
||||
|
||||
/* strip leading and trailing spaces; uncalls item if all spaces */
|
||||
(void)mungspaces(buf);
|
||||
if (!*buf) {
|
||||
if (*str1) { /* had name, so possibly remove from disco[] */
|
||||
/* strip name first, for the update_inventory() call
|
||||
from undiscover_object() */
|
||||
*str1 = (char *)0;
|
||||
undiscover_object(obj->otyp);
|
||||
}
|
||||
} else {
|
||||
*str1 = strcpy((char *) alloc((unsigned)strlen(buf)+1), buf);
|
||||
discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*OVLB*/
|
||||
#ifdef OVL0
|
||||
|
||||
static const char *ghostnames[] = {
|
||||
/* these names should have length < PL_NSIZ */
|
||||
/* Capitalize the names for aesthetics -dgk */
|
||||
"Adri", "Andries", "Andreas", "Bert", "David", "Dirk", "Emile",
|
||||
"Frans", "Fred", "Greg", "Hether", "Jay", "John", "Jon", "Karnov",
|
||||
"Kay", "Kenny", "Kevin", "Maud", "Michiel", "Mike", "Peter", "Robert",
|
||||
"Ron", "Tom", "Wilmar", "Nick Danger", "Phoenix", "Jiro", "Mizue",
|
||||
"Stephan", "Lance Braccus", "Shadowhawk"
|
||||
};
|
||||
|
||||
/* ghost names formerly set by x_monnam(), now by makemon() instead */
|
||||
const char *
|
||||
rndghostname()
|
||||
{
|
||||
return rn2(7) ? ghostnames[rn2(SIZE(ghostnames))] : (const char *)plname;
|
||||
}
|
||||
|
||||
/* Monster naming functions:
|
||||
* x_monnam is the generic monster-naming function.
|
||||
* seen unseen detected named
|
||||
* mon_nam: the newt it the invisible orc Fido
|
||||
* noit_mon_nam:the newt (as if detected) the invisible orc Fido
|
||||
* l_monnam: newt it invisible orc dog called fido
|
||||
* Monnam: The newt It The invisible orc Fido
|
||||
* noit_Monnam: The newt (as if detected) The invisible orc Fido
|
||||
* Adjmonnam: The poor newt It The poor invisible orc The poor Fido
|
||||
* Amonnam: A newt It An invisible orc Fido
|
||||
* a_monnam: a newt it an invisible orc Fido
|
||||
* m_monnam: newt xan orc Fido
|
||||
* y_monnam: your newt your xan your invisible orc Fido
|
||||
*/
|
||||
|
||||
/* Bug: if the monster is a priest or shopkeeper, not every one of these
|
||||
* options works, since those are special cases.
|
||||
*/
|
||||
char *
|
||||
x_monnam(mtmp, article, adjective, suppress, called)
|
||||
register 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;
|
||||
{
|
||||
#ifdef LINT /* static char buf[BUFSZ]; */
|
||||
char buf[BUFSZ];
|
||||
#else
|
||||
static char buf[BUFSZ];
|
||||
#endif
|
||||
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 &&
|
||||
#ifdef STEED
|
||||
mtmp != u.usteed &&
|
||||
#endif
|
||||
!(u.uswallow && mtmp == u.ustuck) &&
|
||||
!(suppress & SUPPRESS_IT);
|
||||
do_saddle = !(suppress & SUPPRESS_SADDLE);
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
/* priests and minions: don't even use this function */
|
||||
if (mtmp->ispriest || mtmp->isminion) {
|
||||
char priestnambuf[BUFSZ];
|
||||
char *name;
|
||||
long save_prop = EHalluc_resistance;
|
||||
unsigned save_invis = mtmp->minvis;
|
||||
|
||||
/* when true name is wanted, explicitly block Hallucination */
|
||||
if (!do_hallu) EHalluc_resistance = 1L;
|
||||
if (!do_invis) mtmp->minvis = 0;
|
||||
name = priestname(mtmp, priestnambuf);
|
||||
EHalluc_resistance = save_prop;
|
||||
mtmp->minvis = save_invis;
|
||||
if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
|
||||
name += 4;
|
||||
return strcpy(buf, name);
|
||||
}
|
||||
|
||||
/* unseen monsters, etc. Use "it" */
|
||||
if (do_it) {
|
||||
Strcpy(buf, "it");
|
||||
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 ");
|
||||
#ifdef STEED
|
||||
if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) &&
|
||||
!Blind && !Hallucination)
|
||||
Strcat(buf, "saddled ");
|
||||
#endif
|
||||
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 && !has_adjectives) {
|
||||
if (mdat == &mons[PM_WIZARD_OF_YENDOR])
|
||||
article = ARTICLE_THE;
|
||||
else
|
||||
article = ARTICLE_NONE;
|
||||
} else if (mons[monsndx(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OVL0 */
|
||||
#ifdef OVLB
|
||||
|
||||
char *
|
||||
l_monnam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
return(x_monnam(mtmp, ARTICLE_NONE, (char *)0,
|
||||
mtmp->mnamelth ? SUPPRESS_SADDLE : 0, TRUE));
|
||||
}
|
||||
|
||||
#endif /* OVLB */
|
||||
#ifdef OVL0
|
||||
|
||||
char *
|
||||
mon_nam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
return(x_monnam(mtmp, ARTICLE_THE, (char *)0,
|
||||
mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE));
|
||||
}
|
||||
|
||||
/* print the name as if mon_nam() was called, but assume that the player
|
||||
* can always see the monster--used for probing and for monsters aggravating
|
||||
* the player with a cursed potion of invisibility
|
||||
*/
|
||||
char *
|
||||
noit_mon_nam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
return(x_monnam(mtmp, ARTICLE_THE, (char *)0,
|
||||
mtmp->mnamelth ? (SUPPRESS_SADDLE|SUPPRESS_IT) :
|
||||
SUPPRESS_IT, FALSE));
|
||||
}
|
||||
|
||||
char *
|
||||
Monnam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
register char *bp = mon_nam(mtmp);
|
||||
|
||||
*bp = highc(*bp);
|
||||
return(bp);
|
||||
}
|
||||
|
||||
char *
|
||||
noit_Monnam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
register char *bp = noit_mon_nam(mtmp);
|
||||
|
||||
*bp = highc(*bp);
|
||||
return(bp);
|
||||
}
|
||||
|
||||
/* monster's own name */
|
||||
char *
|
||||
m_monnam(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
return x_monnam(mtmp, ARTICLE_NONE, (char *)0, EXACT_NAME, FALSE);
|
||||
}
|
||||
|
||||
/* pet name: "your little dog" */
|
||||
char *
|
||||
y_monnam(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
return x_monnam(mtmp, ARTICLE_YOUR, (char *)0,
|
||||
mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE);
|
||||
}
|
||||
|
||||
#endif /* OVL0 */
|
||||
#ifdef OVLB
|
||||
|
||||
char *
|
||||
Adjmonnam(mtmp, adj)
|
||||
register struct monst *mtmp;
|
||||
register const char *adj;
|
||||
{
|
||||
register char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
|
||||
mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE);
|
||||
|
||||
*bp = highc(*bp);
|
||||
return(bp);
|
||||
}
|
||||
|
||||
char *
|
||||
a_monnam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
return x_monnam(mtmp, ARTICLE_A, (char *)0,
|
||||
mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
Amonnam(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
register char *bp = a_monnam(mtmp);
|
||||
|
||||
*bp = highc(*bp);
|
||||
return(bp);
|
||||
}
|
||||
|
||||
static const char *bogusmons[] = {
|
||||
"jumbo shrimp", "giant pigmy", "gnu", "killer penguin",
|
||||
"giant cockroach", "giant slug", "maggot", "pterodactyl",
|
||||
"tyrannosaurus rex", "basilisk", "beholder", "nightmare",
|
||||
"efreeti", "marid", "rot grub", "bookworm", "master lichen",
|
||||
"shadow", "hologram", "jester", "attorney", "sleazoid",
|
||||
"killer tomato", "amazon", "robot", "battlemech",
|
||||
"rhinovirus", "harpy", "lion-dog", "rat-ant", "Y2K bug",
|
||||
/* misc. */
|
||||
"grue", "Christmas-tree monster", "luck sucker", "paskald",
|
||||
"brogmoid", "dornbeast", /* Quendor (Zork, &c.) */
|
||||
"Ancient Multi-Hued Dragon", "Evil Iggy",
|
||||
/* Moria */
|
||||
"emu", "kestrel", "xeroc", "venus flytrap",
|
||||
/* Rogue */
|
||||
"creeping coins", /* Wizardry */
|
||||
"hydra", "siren", /* Greek legend */
|
||||
"killer bunny", /* Monty Python */
|
||||
"rodent of unusual size", /* The Princess Bride */
|
||||
"Smokey the bear", /* "Only you can prevent forest fires!" */
|
||||
"Luggage", /* Discworld */
|
||||
"Ent", /* Lord of the Rings */
|
||||
"tangle tree", "nickelpede", "wiggle", /* Xanth */
|
||||
"white rabbit", "snark", /* Lewis Carroll */
|
||||
"pushmi-pullyu", /* Dr. Doolittle */
|
||||
"smurf", /* The Smurfs */
|
||||
"tribble", "Klingon", "Borg", /* Star Trek */
|
||||
"Ewok", /* Star Wars */
|
||||
"Totoro", /* Tonari no Totoro */
|
||||
"ohmu", /* Nausicaa */
|
||||
"youma", /* Sailor Moon */
|
||||
"nyaasu", /* Pokemon (Meowth) */
|
||||
"Godzilla", "King Kong", /* monster movies */
|
||||
"earthquake beast", /* old L of SH */
|
||||
"Invid", /* Robotech */
|
||||
"Terminator", /* The Terminator */
|
||||
"boomer", /* Bubblegum Crisis */
|
||||
"Dalek", /* Dr. Who ("Exterminate!") */
|
||||
"microscopic space fleet", "Ravenous Bugblatter Beast of Traal",
|
||||
/* HGttG */
|
||||
"teenage mutant ninja turtle", /* TMNT */
|
||||
"samurai rabbit", /* Usagi Yojimbo */
|
||||
"aardvark", /* Cerebus */
|
||||
"Audrey II", /* Little Shop of Horrors */
|
||||
"witch doctor", "one-eyed one-horned flying purple people eater",
|
||||
/* 50's rock 'n' roll */
|
||||
"Barney the dinosaur", /* saccharine kiddy TV */
|
||||
"Morgoth", /* Angband */
|
||||
"Vorlon", /* Babylon 5 */
|
||||
"questing beast", /* King Arthur */
|
||||
"Predator", /* Movie */
|
||||
"mother-in-law" /* common pest */
|
||||
};
|
||||
|
||||
|
||||
/* Return a random monster name, for hallucination.
|
||||
* KNOWN BUG: May be a proper name (Godzilla, Barney), may not
|
||||
* (the Terminator, a Dalek). There's no elegant way to deal
|
||||
* with this without radically modifying the calling functions.
|
||||
*/
|
||||
const char *
|
||||
rndmonnam()
|
||||
{
|
||||
int name;
|
||||
|
||||
do {
|
||||
name = rn1(SPECIAL_PM + SIZE(bogusmons) - LOW_PM, LOW_PM);
|
||||
} while (name < SPECIAL_PM &&
|
||||
(type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
|
||||
|
||||
if (name >= SPECIAL_PM) return bogusmons[name - SPECIAL_PM];
|
||||
return mons[name].mname;
|
||||
}
|
||||
|
||||
#ifdef REINCARNATION
|
||||
const char *
|
||||
roguename() /* Name of a Rogue player */
|
||||
{
|
||||
char *i, *opts;
|
||||
|
||||
if ((opts = nh_getenv("ROGUEOPTS")) != 0) {
|
||||
for (i = opts; *i; i++)
|
||||
if (!strncmp("name=",i,5)) {
|
||||
char *j;
|
||||
if ((j = index(i+5,',')) != 0)
|
||||
*j = (char)0;
|
||||
return i+5;
|
||||
}
|
||||
}
|
||||
return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
|
||||
: "Glenn Wichman";
|
||||
}
|
||||
#endif /* REINCARNATION */
|
||||
#endif /* OVLB */
|
||||
|
||||
#ifdef OVL2
|
||||
|
||||
static NEARDATA const char *hcolors[] = {
|
||||
"ultraviolet", "infrared", "bluish-orange",
|
||||
"reddish-green", "dark white", "light black", "sky blue-pink",
|
||||
"salty", "sweet", "sour", "bitter",
|
||||
"striped", "spiral", "swirly", "plaid", "checkered", "argyle",
|
||||
"paisley", "blotchy", "guernsey-spotted", "polka-dotted",
|
||||
"square", "round", "triangular",
|
||||
"cabernet", "sangria", "fuchsia", "wisteria",
|
||||
"lemon-lime", "strawberry-banana", "peppermint",
|
||||
"romantic", "incandescent"
|
||||
};
|
||||
|
||||
const char *
|
||||
hcolor(colorpref)
|
||||
const char *colorpref;
|
||||
{
|
||||
return (Hallucination || !colorpref) ?
|
||||
hcolors[rn2(SIZE(hcolors))] : colorpref;
|
||||
}
|
||||
|
||||
/* Aliases for road-runner nemesis
|
||||
* See also http://www.geocities.com/EnchantedForest/1141/latin.html
|
||||
*/
|
||||
static const char *coynames[] = {
|
||||
"Carnivorous Vulgaris","Road-Runnerus Digestus",
|
||||
"Eatibus Anythingus" ,"Famishus-Famishus",
|
||||
"Eatibus Almost Anythingus","Eatius Birdius",
|
||||
"Famishius Fantasticus","Eternalii Famishiis",
|
||||
"Famishus Vulgarus","Famishius Vulgaris Ingeniusi",
|
||||
"Eatius-Slobbius","Hardheadipus Oedipus",
|
||||
"Carnivorous Slobbius","Hard-Headipus Ravenus",
|
||||
"Evereadii Eatibus","Apetitius Giganticus",
|
||||
"Hungrii Flea-Bagius","Overconfidentii Vulgaris",
|
||||
"Caninus Nervous Rex","Grotesques Appetitus",
|
||||
"Nemesis Riduclii","Canis latrans"
|
||||
};
|
||||
|
||||
char *coyotename(mtmp, buf)
|
||||
struct monst *mtmp;
|
||||
char *buf;
|
||||
{
|
||||
if (mtmp && buf) {
|
||||
Sprintf(buf, "%s - %s",
|
||||
x_monnam(mtmp, ARTICLE_NONE, (char *)0, 0, TRUE),
|
||||
mtmp->mcan ? coynames[SIZE(coynames)-1] : coynames[rn2(SIZE(coynames)-1)]);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
#endif /* OVL2 */
|
||||
|
||||
/*do_name.c*/
|
||||
Reference in New Issue
Block a user