X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fread.c;h=943eec8a9ba1b3ad765db64821ea7087df0b9662;hb=096152cd7d9acc1d7efcc0b6fa8028bab1ff3200;hp=2881b1907392543888607ffaa4fa598ff24d2c01;hpb=d3b604a1ecccab7279648bd8d75569764c126439;p=jnethack%2Fsource.git diff --git a/src/read.c b/src/read.c index 2881b19..943eec8 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1515802375 2018/01/13 00:12:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.150 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1546465285 2019/01/02 21:41:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.164 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -24,19 +24,23 @@ static NEARDATA const char readable[] = { ALL_CLASSES, SCROLL_CLASS, static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; STATIC_DCL boolean FDECL(learnscrolltyp, (SHORT_P)); -STATIC_DCL char * FDECL(erode_obj_text, (struct obj *, char *)); -STATIC_DCL void NDECL(do_class_genocide); +STATIC_DCL char *FDECL(erode_obj_text, (struct obj *, char *)); +STATIC_DCL char *FDECL(apron_text, (struct obj *, char *buf)); STATIC_DCL void FDECL(stripspe, (struct obj *)); STATIC_DCL void FDECL(p_glow1, (struct obj *)); STATIC_DCL void FDECL(p_glow2, (struct obj *, const char *)); -STATIC_DCL void FDECL(randomize, (int *, int)); STATIC_DCL void FDECL(forget_single_object, (int)); +#if 0 /* not used */ +STATIC_DCL void FDECL(forget_objclass, (int)); +#endif +STATIC_DCL void FDECL(randomize, (int *, int)); STATIC_DCL void FDECL(forget, (int)); STATIC_DCL int FDECL(maybe_tame, (struct monst *, struct obj *)); -STATIC_DCL boolean FDECL(is_valid_stinking_cloud_pos, (int, int, BOOLEAN_P)); -STATIC_DCL void FDECL(display_stinking_cloud_positions, (int)); STATIC_DCL boolean FDECL(get_valid_stinking_cloud_pos, (int, int)); +STATIC_DCL boolean FDECL(is_valid_stinking_cloud_pos, (int, int, BOOLEAN_P)); +STATIC_PTR void FDECL(display_stinking_cloud_positions, (int)); STATIC_PTR void FDECL(set_lit, (int, int, genericptr)); +STATIC_DCL void NDECL(do_class_genocide); STATIC_OVL boolean learnscrolltyp(scrolltyp) @@ -61,7 +65,7 @@ struct obj *sobj; (void) learnscrolltyp(sobj->otyp); } -char * +STATIC_OVL char * erode_obj_text(otmp, buf) struct obj *otmp; char *buf; @@ -250,7 +254,7 @@ char *buf; return erode_obj_text(tshirt, buf); } -char * +STATIC_OVL char * apron_text(apron, buf) struct obj *apron; char *buf; @@ -503,6 +507,7 @@ doread() return 0; } else if (Blind && (scroll->otyp != SPE_BOOK_OF_THE_DEAD)) { const char *what = 0; + if (scroll->oclass == SPBOOK_CLASS) /*JP what = "mystic runes"; @@ -1200,7 +1205,7 @@ int x,y; || distu(x, y) >= 32)); } -boolean +STATIC_OVL boolean is_valid_stinking_cloud_pos(x, y, showmsg) int x, y; boolean showmsg; @@ -1216,7 +1221,7 @@ boolean showmsg; return TRUE; } -void +STATIC_PTR void display_stinking_cloud_positions(state) int state; { @@ -2089,7 +2094,8 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ pline("Where do you want to center the explosion?"); */ pline("‚Ç‚±‚𔚔­‚Ì’†S‚É‚µ‚Ü‚·‚©H"); - getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos); + getpos_sethilite(display_stinking_cloud_positions, + get_valid_stinking_cloud_pos); /*JP (void) getpos(&cc, TRUE, "the desired position"); */ @@ -2188,7 +2194,8 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ #endif cc.x = u.ux; cc.y = u.uy; - getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos); + getpos_sethilite(display_stinking_cloud_positions, + get_valid_stinking_cloud_pos); /*JP if (getpos(&cc, TRUE, "the desired position") < 0) { */ @@ -2205,6 +2212,11 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ default: impossible("What weird effect is this? (%u)", otyp); } + /* if sobj is gone, we've already called useup() above and the + update_inventory() that it performs might have come too soon + (before charging an item, for instance) */ + if (!sobj) + update_inventory(); return sobj ? 0 : 1; } @@ -2335,7 +2347,7 @@ boolean confused, byu; } } mtmp->mhp -= mdmg; - if (mtmp->mhp <= 0) { + if (DEADMONSTER(mtmp)) { if (byu) { killed(mtmp); } else { @@ -3029,8 +3041,8 @@ struct obj *sobj; uball->spe = 1; /* special ball (see save) */ /* - * Place ball & chain if not swallowed. If swallowed, the ball & - * chain variables will be set at the next call to placebc(). + * Place ball & chain if not swallowed. If swallowed, the ball & chain + * variables will be set at the next call to placebc(). */ if (!u.uswallow) { placebc(); @@ -3083,6 +3095,185 @@ struct obj *from_obj; return FALSE; } +struct _create_particular_data { + int which; + int fem; + char monclass; + boolean randmonst; + boolean maketame, makepeaceful, makehostile; + boolean sleeping, saddled, invisible; +}; + +boolean +create_particular_parse(str, d) +char *str; +struct _create_particular_data *d; +{ + char *bufp = str; + char *tmpp; + + d->monclass = MAXMCLASSES; + d->which = urole.malenum; /* an arbitrary index into mons[] */ + d->fem = -1; /* gender not specified */ + d->randmonst = FALSE; + d->maketame = d->makepeaceful = d->makehostile = FALSE; + d->sleeping = d->saddled = d->invisible = FALSE; + + if ((tmpp = strstri(bufp, "saddled ")) != 0) { + d->saddled = TRUE; + (void) memset(tmpp, ' ', sizeof "saddled " - 1); + } + if ((tmpp = strstri(bufp, "sleeping ")) != 0) { + d->sleeping = TRUE; + (void) memset(tmpp, ' ', sizeof "sleeping " - 1); + } + if ((tmpp = strstri(bufp, "invisible ")) != 0) { + d->invisible = TRUE; + (void) memset(tmpp, ' ', sizeof "invisible " - 1); + } + /* check "female" before "male" to avoid false hit mid-word */ + if ((tmpp = strstri(bufp, "female ")) != 0) { + d->fem = 1; + (void) memset(tmpp, ' ', sizeof "female " - 1); + } + if ((tmpp = strstri(bufp, "male ")) != 0) { + d->fem = 0; + (void) memset(tmpp, ' ', sizeof "male " - 1); + } + bufp = mungspaces(bufp); /* after potential memset(' ') */ + /* allow the initial disposition to be specified */ +#if 0 /*JP*/ + if (!strncmpi(bufp, "tame ", 5)) { + bufp += 5; +#else + if (!strncmpi(bufp, "Žè‚È‚¸‚¯‚ç‚ꂽ", 14)) { + bufp += 14; +#endif + d->maketame = TRUE; +#if 0 /*JP*/ + } else if (!strncmpi(bufp, "peaceful ", 9)) { + bufp += 9; +#else + } else if (!strncmpi(bufp, "—FD“I‚È", 8)) { + bufp += 8; +#endif + d->makepeaceful = TRUE; +#if 0 /*JP*/ + } else if (!strncmpi(bufp, "hostile ", 8)) { + bufp += 8; +#else + } else if (!strncmpi(bufp, "“G‘ΓI‚È", 8)) { + bufp += 8; +#endif + d->makehostile = TRUE; + } + /* decide whether a valid monster was chosen */ +/*JP + if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) { +*/ + if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "ƒ‰ƒ“ƒ_ƒ€"))) { + d->randmonst = TRUE; + return TRUE; + } + d->which = name_to_mon(bufp); + if (d->which >= LOW_PM) + return TRUE; /* got one */ + d->monclass = name_to_monclass(bufp, &d->which); + + if (d->which >= LOW_PM) { + d->monclass = MAXMCLASSES; /* matters below */ + return TRUE; + } else if (d->monclass == S_invisible) { /* not an actual monster class */ + d->which = PM_STALKER; + d->monclass = MAXMCLASSES; + return TRUE; + } else if (d->monclass == S_WORM_TAIL) { /* empty monster class */ + d->which = PM_LONG_WORM; + d->monclass = MAXMCLASSES; + return TRUE; + } else if (d->monclass > 0) { + d->which = urole.malenum; /* reset from NON_PM */ + return TRUE; + } + return FALSE; +} + +boolean +create_particular_creation(d) +struct _create_particular_data *d; +{ + struct permonst *whichpm = NULL; + int i, firstchoice = NON_PM; + struct monst *mtmp; + boolean madeany = FALSE; + + if (!d->randmonst) { + firstchoice = d->which; + if (cant_revive(&d->which, FALSE, (struct obj *) 0) + && firstchoice != PM_LONG_WORM_TAIL) { + /* wizard mode can override handling of special monsters */ + char buf[BUFSZ]; + +#if 0 /*JP*/ + Sprintf(buf, "Creating %s instead; force %s?", + mons[d->which].mname, mons[firstchoice].mname); +#else + Sprintf(buf, "‘ã‚í‚è‚É%s‚ªì‚ç‚ê‚Ü‚·G%s‚É‚·‚éH", + mons[d->which].mname, mons[firstchoice].mname); +#endif + if (yn(buf) == 'y') + d->which = firstchoice; + } + whichpm = &mons[d->which]; + } + for (i = 0; i <= multi; i++) { + if (d->monclass != MAXMCLASSES) + whichpm = mkclass(d->monclass, 0); + else if (d->randmonst) + whichpm = rndmonst(); + mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS); + if (!mtmp) { + /* quit trying if creation failed and is going to repeat */ + if (d->monclass == MAXMCLASSES && !d->randmonst) + break; + /* otherwise try again */ + continue; + } + /* 'is_FOO()' ought to be called 'always_FOO()' */ + if (d->fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data)) + mtmp->female = d->fem; /* ignored for is_neuter() */ + if (d->maketame) { + (void) tamedog(mtmp, (struct obj *) 0); + } else if (d->makepeaceful || d->makehostile) { + mtmp->mtame = 0; /* sanity precaution */ + mtmp->mpeaceful = d->makepeaceful ? 1 : 0; + set_malign(mtmp); + } + if (d->saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) { + struct obj *otmp = mksobj(SADDLE, TRUE, FALSE); + + put_saddle_on_mon(otmp, mtmp); + } + if (d->invisible) { + int mx = mtmp->mx, my = mtmp->my; + mon_set_minvis(mtmp); + if (does_block(mx, my, &levl[mx][my])) + block_point(mx, my); + else + unblock_point(mx, my); + } + if (d->sleeping) + mtmp->msleeping = 1; + madeany = TRUE; + /* in case we got a doppelganger instead of what was asked + for, make it start out looking like what was asked for */ + if (mtmp->cham != NON_PM && firstchoice != NON_PM + && mtmp->cham != firstchoice) + (void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE); + } + return madeany; +} + /* * Make a new monster with the type controlled by the user. * @@ -3098,23 +3289,11 @@ struct obj *from_obj; boolean create_particular() { - char buf[BUFSZ] = DUMMY, *bufp, monclass; - char *tmpp; - int which, tryct, i, firstchoice = NON_PM; - struct permonst *whichpm = NULL; - struct monst *mtmp; - boolean madeany = FALSE, randmonst = FALSE, - maketame, makepeaceful, makehostile, saddled, invisible, - sleeping; - int fem; + char buf[BUFSZ] = DUMMY, *bufp; + int tryct = 5; + struct _create_particular_data d; - tryct = 5; do { - monclass = MAXMCLASSES; - which = urole.malenum; /* an arbitrary index into mons[] */ - maketame = makepeaceful = makehostile = FALSE; - sleeping = saddled = invisible = FALSE; - fem = -1; /* gender not specified */ /*JP getlin("Create what kind of monster? [type the name or symbol]", buf); */ @@ -3122,73 +3301,10 @@ create_particular() bufp = mungspaces(buf); if (*bufp == '\033') return FALSE; - if ((tmpp = strstri(bufp, "saddled ")) != 0) { - saddled = TRUE; - (void) memset(tmpp, ' ', sizeof "saddled " - 1); - } - if ((tmpp = strstri(bufp, "sleeping ")) != 0) { - sleeping = TRUE; - (void) memset(tmpp, ' ', sizeof "sleeping " - 1); - } - if ((tmpp = strstri(bufp, "invisible ")) != 0) { - invisible = TRUE; - (void) memset(tmpp, ' ', sizeof "invisible " - 1); - } - /* check "female" before "male" to avoid false hit mid-word */ - if ((tmpp = strstri(bufp, "female ")) != 0) { - fem = 1; - (void) memset(tmpp, ' ', sizeof "female " - 1); - } - if ((tmpp = strstri(bufp, "male ")) != 0) { - fem = 0; - (void) memset(tmpp, ' ', sizeof "male " - 1); - } - bufp = mungspaces(bufp); /* after potential memset(' ') */ - /* allow the initial disposition to be specified */ -#if 0 /*JP*/ - if (!strncmpi(bufp, "tame ", 5)) { - bufp += 5; -#else - if (!strncmpi(bufp, "Žè‚È‚¸‚¯‚ç‚ꂽ", 14)) { - bufp += 14; -#endif - maketame = TRUE; -#if 0 /*JP*/ - } else if (!strncmpi(bufp, "peaceful ", 9)) { - bufp += 9; -#else - } else if (!strncmpi(bufp, "—FD“I‚È", 8)) { - bufp += 8; -#endif - makepeaceful = TRUE; -#if 0 /*JP*/ - } else if (!strncmpi(bufp, "hostile ", 8)) { - bufp += 8; -#else - } else if (!strncmpi(bufp, "“G‘ΓI‚È", 8)) { - bufp += 8; -#endif - makehostile = TRUE; - } - /* decide whether a valid monster was chosen */ -/*JP - if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) { -*/ - if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "ƒ‰ƒ“ƒ_ƒ€"))) { - randmonst = TRUE; - break; - } - which = name_to_mon(bufp); - if (which >= LOW_PM) - break; /* got one */ - monclass = name_to_monclass(bufp, &which); - if (which >= LOW_PM) { - monclass = MAXMCLASSES; /* matters below */ - break; - } else if (monclass > 0) { - which = urole.malenum; /* reset from NON_PM */ + + if (create_particular_parse(bufp, &d)) break; - } + /* no good; try again... */ /*JP pline("I've never heard of such monsters."); @@ -3196,66 +3312,12 @@ create_particular() pline("‚»‚̂悤‚ȉö•¨‚Í•·‚¢‚½‚±‚Æ‚ª‚È‚¢D"); } while (--tryct > 0); - if (!tryct) { + if (!tryct) pline1(thats_enough_tries); - } else { - if (!randmonst) { - firstchoice = which; - if (cant_revive(&which, FALSE, (struct obj *) 0)) { - /* wizard mode can override handling of special monsters */ -#if 0 /*JP*/ - Sprintf(buf, "Creating %s instead; force %s?", - mons[which].mname, mons[firstchoice].mname); -#else - Sprintf(buf, "‘ã‚í‚è‚É%s‚ªì‚ç‚ê‚Ü‚·G%s‚É‚·‚éH", - mons[which].mname, mons[firstchoice].mname); -#endif - if (yn(buf) == 'y') - which = firstchoice; - } - whichpm = &mons[which]; - } - for (i = 0; i <= multi; i++) { - if (monclass != MAXMCLASSES) - whichpm = mkclass(monclass, 0); - else if (randmonst) - whichpm = rndmonst(); - mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS); - if (!mtmp) { - /* quit trying if creation failed and is going to repeat */ - if (monclass == MAXMCLASSES && !randmonst) - break; - /* otherwise try again */ - continue; - } - /* 'is_FOO()' ought to be called 'always_FOO()' */ - if (fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data)) - mtmp->female = fem; /* ignored for is_neuter() */ - if (maketame) { - (void) tamedog(mtmp, (struct obj *) 0); - } else if (makepeaceful || makehostile) { - mtmp->mtame = 0; /* sanity precaution */ - mtmp->mpeaceful = makepeaceful ? 1 : 0; - set_malign(mtmp); - } - if (saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) { - struct obj *otmp = mksobj(SADDLE, TRUE, FALSE); + else + return create_particular_creation(&d); - put_saddle_on_mon(otmp, mtmp); - } - if (invisible) - mon_set_minvis(mtmp); - if (sleeping) - mtmp->msleeping = 1; - madeany = TRUE; - /* in case we got a doppelganger instead of what was asked - for, make it start out looking like what was asked for */ - if (mtmp->cham != NON_PM && firstchoice != NON_PM - && mtmp->cham != firstchoice) - (void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE); - } - } - return madeany; + return FALSE; } /*read.c*/