Merge branch 'master' into win32-x64-working

Conflicts:
	src/do_name.c
	src/trap.c
	src/zap.c
	win/X11/winmenu.c
This commit is contained in:
nhmall
2015-04-12 10:35:00 -04:00
25 changed files with 1084 additions and 144 deletions

View File

@@ -489,6 +489,8 @@ newgame()
context.stethoscope_move = -1L;
context.warnlevel = 1;
context.next_attrib_check = 600L; /* arbitrary first setting */
context.tribute.enabled = TRUE; /* turn on 3.6 tributes */
context.tribute.tributesz = sizeof(struct tribute_info);
for (i = 0; i < NUMMONS; i++)
mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 do_name.c $NHDT-Date: 1426558927 2015/03/17 02:22:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.53 $ */
/* NetHack 3.5 do_name.c $NHDT-Date: 1428196077 2015/04/05 01:07:57 $ $NHDT-Branch: nhmall-booktribute $:$NHDT-Revision: 1.64 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -474,6 +474,12 @@ register struct obj *obj;
const char *aname;
short objtyp;
/* Do this now because there's no point in even asking for a name */
if (obj->otyp == SPE_NOVEL) {
pline("%s already has a published name.", Ysimple_name2(obj));
return;
}
Sprintf(qbuf, "What do you want to name %s ",
is_plural(obj) ? "these" : "this");
(void)safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
@@ -1152,4 +1158,55 @@ char *buf;
return buf;
}
/* make sure "The Colour of Magic" remains the first entry in here */
static const char * const sir_Terry_novels[] = {
"The Colour of Magic", "The Light Fantastic", "Equal Rites",
"Mort", "Sourcery", "Wyrd Sisters", "Pyramids", "Guards! Guards!",
"Eric", "Moving Pictures", "Reaper Man", "Witches Abroad",
"Small Gods", "Lords and Ladies", "Men at Arms", "Soul Music",
"Interesting Times", "Maskerade", "Feet of Clay", "Hogfather",
"Jingo", "The Last Continent", "Carpe Jugulum", "The Fifth Elephant",
"The Truth", "Thief of Time", "The Last Hero",
"The Amazing Maurice and his Educated Rodents", "Night Watch",
"The Wee Free Men", "Monstrous Regiment", "A Hat Full of Sky",
"Going Postal", "Thud!", "Wintersmith", "Making Money",
"Unseen Academicals", "I Shall Wear Midnight", "Snuff",
"Raising Steam", "The Shepherd's Crown"
};
const char *
noveltitle(novidx)
int *novidx;
{
int j, k = SIZE(sir_Terry_novels)-1;
j = rn2(k);
if (novidx) {
if (*novidx == -1) *novidx = j;
else if ((*novidx >= 0) && (*novidx <= k)) j = *novidx;
}
return sir_Terry_novels[j];
}
const char *
lookup_novel(lookname, idx)
const char *lookname;
int *idx;
{
int k;
/* Take American or U.K. spelling of this one */
if (strcmpi(lookname, "The Color of Magic") == 0)
lookname = sir_Terry_novels[0];
for (k = 0; k < SIZE(sir_Terry_novels); ++k) {
if (strcmpi(lookname, sir_Terry_novels[k]) == 0) {
if (idx) *idx = k;
return sir_Terry_novels[k];
}
}
return (const char *)0;
}
/*do_name.c*/

View File

@@ -3329,4 +3329,152 @@ const char *filename;
}
#endif /*DEBUG*/
/* ---------- BEGIN TRIBUTE ----------- */
/* 3.6 tribute code */
#define SECTIONSCOPE 1
#define TITLESCOPE 2
#define PASSAGESCOPE 3
void
read_tribute(tribsection, tribtitle, tribpassage)
const char *tribsection, *tribtitle;
int tribpassage;
{
dlb *fp;
char *endp;
char line[BUFSZ];
int scopes[4] = {0, SECTIONSCOPE, TITLESCOPE, PASSAGESCOPE};
int scope = 0, section = 0, passage = 0, book = 0;
int linect = 0, passagecnt = 0, targetpassage = 0, textcnt = 0;
char *sectionnm = "", *booknm = "";
const char *badtranslation = "an incomprehensible foreign translation";
boolean matchedsection = FALSE, matchedtitle = FALSE;
winid tribwin = WIN_ERR;
/* check for mandatories */
if (!tribsection || !tribtitle) {
pline("It's %s of \"%s\"!",
badtranslation, tribtitle);
return;
}
debugpline3("read_tribute %s, %s, %d.", tribsection, tribtitle, tribpassage);
fp = dlb_fopen(TRIBUTEFILE, "r");
if (!fp) {
/* this is actually an error - cannot open tribute file! */
pline("You feel too overwhelmed to continue!");
return;
}
/*
* Syntax (not case-sensitive):
* %section books
*
* In the books section:
* %title booktitle(n)
* where booktitle=book title
* (n)= total number of passages present for this title
* %passage n
* where n=sequential passage number
*
* %e ends the passage/book/section
* If in a passage, it marks the end of that passage.
* If in a book, it marks the end of that book.
* If in a section, it marks the end of that section.
*
* %section death
*/
while (dlb_fgets(line, sizeof line, fp) != 0) {
linect++;
if ((endp = index(line, '\n')) != 0) *endp = 0;
switch (line[0]) {
case '%':
if (!strncmpi(&line[1], "section ", sizeof("section ")-1)) {
char *st = &line[9]; /* 9 from "%section " */
scope = SECTIONSCOPE;
if (!strcmpi(st, tribsection))
matchedsection = TRUE;
else
matchedsection = FALSE;
} else if (!strncmpi(&line[1], "title ", sizeof("title ")-1)) {
char *st = &line[7]; /* 7 from "%title " */
char *p1, *p2;
if ((p1 = index(st, '(')) != 0) {
*p1++ = '\0';
(void)mungspaces(st);
if ((p2 = index(p1, ')')) != 0) {
*p2 = '\0';
passagecnt = atoi(p1);
/* sanity check here caps #passages at 50 */
if ((passagecnt > 0) && (passagecnt < 50)) {
scope = TITLESCOPE;
if (matchedsection && !strcmpi(st, tribtitle)) {
matchedtitle = TRUE;
if (!tribpassage) {
targetpassage = rnd(passagecnt);
} else {
if (tribpassage <= passagecnt)
targetpassage = tribpassage;
else
targetpassage = 0;
}
} else {
matchedtitle = FALSE;
}
}
}
}
} else if (!strncmpi(&line[1], "passage ", sizeof("passage ")-1)) {
int passagenum = 0;
char *st = &line[9]; /* 9 from "%passage " */
while(*st == ' ' || *st == '\t') st++;
if (*st && digit(*st) && (strlen(st) < 3))
passagenum = atoi(st);
if (passagenum && (passagenum <= passagecnt)) {
scope = PASSAGESCOPE;
if (matchedtitle && (passagenum == targetpassage))
tribwin = create_nhwindow(NHW_MENU);
}
} else if (!strncmpi(&line[1], "e ", sizeof("e ")-1)) {
if (matchedtitle && (scope == PASSAGESCOPE) && tribwin != WIN_ERR)
goto cleanup;
if (scope == TITLESCOPE) matchedtitle = FALSE;
if (scope == SECTIONSCOPE) matchedsection = FALSE;
if (scope) --scope;
} else {
debugpline1("tribute file error: bad %% command, line %d.",
linect);
}
break;
case '#':
/* comment only, next! */
break;
default:
if (matchedtitle && (scope == PASSAGESCOPE) && tribwin != WIN_ERR)
putstr(tribwin, 0, line);
}
}
cleanup:
(void) dlb_fclose(fp);
if (tribwin != WIN_ERR) {
if (matchedtitle && (scope == PASSAGESCOPE))
display_nhwindow(tribwin, FALSE);
destroy_nhwindow(tribwin);
tribwin = WIN_ERR;
u.uconduct.literate++;
} else {
pline("It seems to be %s of \"%s\"!",
badtranslation, tribtitle);
}
return;
}
/* ---------- END TRIBUTE ----------- */
/*files.c*/

View File

@@ -869,6 +869,13 @@ boolean artif;
/* 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 */

View File

@@ -1626,8 +1626,8 @@ register struct monst *mtmp;
}
if(mtmp->iswiz) wizdead();
if(mtmp->data->msound == MS_NEMESIS) nemdead();
if(mtmp->data == &mons[PM_MEDUSA])
u.uachieve.killed_medusa = 1;
if(mtmp->data == &mons[PM_MEDUSA])
u.uachieve.killed_medusa = 1;
if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
unmap_object(mtmp->mx, mtmp->my);
m_detach(mtmp, mptr);

View File

@@ -827,6 +827,9 @@ SPELL("freeze sphere", "hardcover", P_MATTER_SPELL, 20, 2, 1, 1, NODIR, CLR
#endif
/* blank spellbook must come last because it retains its description */
SPELL("blank paper", "plain", P_NONE, 18, 0, 0, 0, 0, HI_PAPER),
/* tribute book for 3.6 */
OBJECT(OBJ("novel", "paperback"), BITS(0,0,1,0,0,0,0,1,0,0,0,P_NONE,HI_PAPER), 0,
SPBOOK_CLASS, 0, 0, 0, 1, 0, 0, 0, 1, 20, CLR_BRIGHT_BLUE),
/* a special, one of a kind, spellbook */
OBJECT(OBJ("Book of the Dead", "papyrus"), BITS(0,0,1,0,1,0,1,1,0,0,0,P_NONE,PAPER), 0,
SPBOOK_CLASS, 0, 0,20, 10000, 0, 0, 0, 7, 20, HI_PAPER),

View File

@@ -465,7 +465,18 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
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)
@@ -3044,6 +3055,15 @@ typfnd:
}
}
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.
*/
@@ -3236,6 +3256,18 @@ typfnd:
aname = artifact_name(name, &objtyp);
if (aname && objtyp == otmp->otyp) name = aname;
/* 3.6.0 tribute - fix up novel */
if (otmp->otyp == SPE_NOVEL) {
int novidx = 0;
const char *novelname;
novelname = lookup_novel(name, &novidx);
if (novelname) {
otmp->novelidx = novidx;
name = novelname;
}
}
otmp = oname(otmp, name);
if (otmp->oartifact) {
otmp->quan = 1L;

View File

@@ -320,9 +320,11 @@ doread()
#endif
/* Actions required to win the game aren't counted towards conduct */
/* Novel conduct is handled in read_tribute so exclude it too*/
if (scroll->otyp != SPE_BOOK_OF_THE_DEAD &&
scroll->otyp != SPE_BLANK_PAPER &&
scroll->otyp != SCR_BLANK_PAPER)
scroll->otyp != SCR_BLANK_PAPER &&
scroll->otyp != SPE_NOVEL)
u.uconduct.literate++;
if(scroll->oclass == SPBOOK_CLASS) {

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 shknam.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */
/* NetHack 3.5 shknam.c $NHDT-Date: 1428207608 2015/04/05 04:20:08 $ $NHDT-Branch: nhmall-booktribute $:$NHDT-Revision: 1.32 $ */
/* NetHack 3.5 shknam.c $Date: 2011/04/15 01:55:42 $ $Revision: 1.24 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -10,7 +10,7 @@
STATIC_DCL boolean FDECL(veggy_item, (struct obj *obj,int));
STATIC_DCL int NDECL(shkveg);
STATIC_DCL void FDECL(mkveggy_at, (int,int));
STATIC_DCL void FDECL(mkshobj_at, (const struct shclass *,int,int));
STATIC_DCL void FDECL(mkshobj_at, (const struct shclass *,int,int,BOOLEAN_P));
STATIC_DCL void FDECL(nameshk, (struct monst *,const char * const *));
STATIC_DCL int FDECL(shkinit, (const struct shclass *,struct mkroom *));
@@ -357,15 +357,24 @@ int sx, sy;
}
STATIC_OVL void
mkshobj_at(shp, sx, sy)
mkshobj_at(shp, sx, sy, mkspecl)
/* make an object of the appropriate type for a shop square */
const struct shclass *shp;
int sx, sy;
boolean mkspecl;
{
struct monst *mtmp;
int atype;
struct permonst *ptr;
/* 3.6.0 tribute */
if (mkspecl && (!strcmp(shp->name, "rare books") ||
!strcmp(shp->name, "second-hand bookstore"))) {
struct obj *novel=mksobj_at(SPE_NOVEL, sx, sy, FALSE, FALSE);
if (novel) context.tribute.bookstock = TRUE;
return;
}
if (rn2(100) < depth(&u.uz) &&
!MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC,0)) &&
(mtmp = makemon(ptr,sx,sy,NO_MM_FLAGS)) != 0) {
@@ -572,7 +581,8 @@ register struct mkroom *sroom;
* shop-style placement (all squares except a row nearest the first
* door get objects).
*/
register int sx, sy, sh;
int sx, sy, sh;
int stockcount = 0, specialspot = 0;
char buf[BUFSZ];
int rmno = (int)((sroom - rooms) + ROOMOFFSET);
const struct shclass *shp = &shtypes[shp_indx];
@@ -608,6 +618,29 @@ register struct mkroom *sroom;
make_engr_at(m, n, buf, 0L, DUST);
}
if (context.tribute.enabled && !context.tribute.bookstock) {
/*
* Out of the number of spots where we're actually
* going to put stuff, randomly single out one in particular.
*/
for (sx = sroom->lx; sx <= sroom->hx; sx++)
for (sy = sroom->ly; sy <= sroom->hy; sy++) {
if (sroom->irregular) {
if (levl[sx][sy].edge || (int)levl[sx][sy].roomno != rmno ||
distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)
continue;
}
else if ((sx == sroom->lx && doors[sh].x == sx - 1) ||
(sx == sroom->hx && doors[sh].x == sx + 1) ||
(sy == sroom->ly && doors[sh].y == sy - 1) ||
(sy == sroom->hy && doors[sh].y == sy + 1)) continue;
stockcount++;
}
specialspot = rnd(stockcount);
stockcount = 0;
}
for(sx = sroom->lx; sx <= sroom->hx; sx++)
for(sy = sroom->ly; sy <= sroom->hy; sy++) {
if(sroom->irregular) {
@@ -618,7 +651,8 @@ register struct mkroom *sroom;
(sx == sroom->hx && doors[sh].x == sx+1) ||
(sy == sroom->ly && doors[sh].y == sy-1) ||
(sy == sroom->hy && doors[sh].y == sy+1)) continue;
mkshobj_at(shp, sx, sy);
stockcount++;
mkshobj_at(shp, sx, sy, ((stockcount) && (stockcount == specialspot)));
}
/*

View File

@@ -411,8 +411,8 @@ int
study_book(spellbook)
register struct obj *spellbook;
{
register int booktype = spellbook->otyp;
register boolean confused = (Confusion != 0);
int booktype = spellbook->otyp;
boolean confused = (Confusion != 0);
boolean too_hard = FALSE;
/* attempting to read dull book may make hero fall asleep */
@@ -440,7 +440,8 @@ register struct obj *spellbook;
/* handle the sequence: start reading, get interrupted,
have context.spbook.book become erased somehow, resume reading it */
booktype != SPE_BLANK_PAPER) {
You("continue your efforts to memorize the spell.");
You("continue your efforts to %s.", (booktype == SPE_NOVEL) ?
"read the novel" : "memorize the spell");
} else {
/* KMH -- Simplified this code */
if (booktype == SPE_BLANK_PAPER) {
@@ -448,6 +449,16 @@ register struct obj *spellbook;
makeknown(booktype);
return(1);
}
/* 3.6.0 tribute */
if (booktype == SPE_NOVEL) {
/* Obtain current Terry Pratchett book
title for the current game. */
const char *tribtitle = noveltitle(&spellbook->novelidx);
read_tribute("books", tribtitle, 0);
return(1);
}
switch (objects[booktype].oc_level) {
case 1:
case 2:

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 trap.c $NHDT-Date: 1427934551 2015/04/02 00:29:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.223 $ */
/* NetHack 3.5 trap.c $NHDT-Date: 1428207616 2015/04/05 04:20:16 $ $NHDT-Branch: nhmall-booktribute $:$NHDT-Revision: 1.224 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3205,6 +3205,10 @@ boolean force;
pline("Steam rises from %s.", the(xname(obj)));
return 0;
}
if (obj->otyp == SPE_NOVEL) {
obj->novelidx = 0;
free_oname(obj);
}
obj->otyp = SPE_BLANK_PAPER;
obj->dknown = 0;
if (carried(obj))

View File

@@ -1,4 +1,4 @@
/* NetHack 3.5 zap.c $NHDT-Date: 1427782839 2015/03/31 06:20:39 $ $NHDT-Branch: master $:$NHDT-Revision: 1.200 $ */
/* NetHack 3.5 zap.c $NHDT-Date: 1428207622 2015/04/05 04:20:22 $ $NHDT-Branch: nhmall-booktribute $:$NHDT-Revision: 1.215 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -955,7 +955,9 @@ register struct obj *obj;
obj->spe = 0;
break;
case SPBOOK_CLASS:
if (otyp != SPE_CANCELLATION && otyp != SPE_BOOK_OF_THE_DEAD) {
if (otyp != SPE_CANCELLATION &&
otyp != SPE_NOVEL &&
otyp != SPE_BOOK_OF_THE_DEAD) {
costly_alteration(obj, COST_CANCEL);
obj->otyp = SPE_BLANK_PAPER;
}