Don't advance the main RNG during hallucination

This is based on the multiple-RNGs code fron NetHack4, but using
only the parts relevant to the display RNG (and with substantial
changes, both because of post-3.4.3 changes, and because Nethack4's
display code is based on Slash'EM's rather than NetHack's).
This commit is contained in:
Alex Smith
2019-01-28 04:45:26 +00:00
parent 1083971228
commit ce5184c3da
21 changed files with 150 additions and 93 deletions
+41 -28
View File
@@ -146,9 +146,9 @@
* *
* Respectively return a random monster, object, or trap number. * Respectively return a random monster, object, or trap number.
*/ */
#define random_monster() rn2(NUMMONS) #define random_monster(rng) rng(NUMMONS)
#define random_object() rn1(NUM_OBJECTS - 1, 1) #define random_object(rng) (rng(NUM_OBJECTS - 1) + 1)
#define random_trap() rn1(TRAPNUM - 1, 1) #define random_trap(rng) (rng(TRAPNUM - 1) + 1)
/* /*
* what_obj() * what_obj()
@@ -156,11 +156,23 @@
* what_trap() * what_trap()
* *
* If hallucinating, choose a random object/monster, otherwise, use the one * If hallucinating, choose a random object/monster, otherwise, use the one
* given. * given. Use the given rng to handle hallucination.
*/ */
#define what_obj(obj) (Hallucination ? random_object() : obj) #define what_obj(obj, rng) (Hallucination ? random_object(rng) : obj)
#define what_mon(mon) (Hallucination ? random_monster() : mon) #define what_mon(mon, rng) (Hallucination ? random_monster(rng) : mon)
#define what_trap(trp) (Hallucination ? random_trap() : trp) #define what_trap(trp, rng) (Hallucination ? random_trap(rng) : trp)
/*
* newsym_rn2
*
* An appropriate random number generator for use with newsym(), when
* randomness is needed there. This is currently hardcoded as
* rn2_on_display_rng, but is futureproofed for cases where we might
* want to prevent display-random objects entering the character's
* memory (this isn't important at present but may be if we need
* reproducible gameplay for some reason).
*/
#define newsym_rn2 rn2_on_display_rng
/* /*
* covers_objects() * covers_objects()
@@ -196,9 +208,10 @@
* Display the hero. It is assumed that all checks necessary to determine * Display the hero. It is assumed that all checks necessary to determine
* _if_ the hero can be seen have already been done. * _if_ the hero can be seen have already been done.
*/ */
#define maybe_display_usteed(otherwise_self) \ #define maybe_display_usteed(otherwise_self) \
((u.usteed && mon_visible(u.usteed)) ? ridden_mon_to_glyph(u.usteed) \ ((u.usteed && mon_visible(u.usteed)) \
: (otherwise_self)) ? ridden_mon_to_glyph(u.usteed, rn2_on_display_rng) \
: (otherwise_self))
#define display_self() \ #define display_self() \
show_glyph(u.ux, u.uy, \ show_glyph(u.ux, u.uy, \
@@ -282,27 +295,27 @@
#define GLYPH_INVISIBLE GLYPH_INVIS_OFF #define GLYPH_INVISIBLE GLYPH_INVIS_OFF
#define warning_to_glyph(mwarnlev) ((mwarnlev) + GLYPH_WARNING_OFF) #define warning_to_glyph(mwarnlev) ((mwarnlev) + GLYPH_WARNING_OFF)
#define mon_to_glyph(mon) \ #define mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_MON_OFF) ((int) what_mon(monsndx((mon)->data), rng) + GLYPH_MON_OFF)
#define detected_mon_to_glyph(mon) \ #define detected_mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_DETECT_OFF) ((int) what_mon(monsndx((mon)->data), rng) + GLYPH_DETECT_OFF)
#define ridden_mon_to_glyph(mon) \ #define ridden_mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_RIDDEN_OFF) ((int) what_mon(monsndx((mon)->data), rng) + GLYPH_RIDDEN_OFF)
#define pet_to_glyph(mon) \ #define pet_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_PET_OFF) ((int) what_mon(monsndx((mon)->data), rng) + GLYPH_PET_OFF)
/* This has the unfortunate side effect of needing a global variable */ /* This has the unfortunate side effect of needing a global variable */
/* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */ /* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */
#define random_obj_to_glyph() \ #define random_obj_to_glyph(rng) \
((otg_temp = random_object()) == CORPSE \ ((otg_temp = random_object(rng)) == CORPSE \
? random_monster() + GLYPH_BODY_OFF \ ? random_monster(rng) + GLYPH_BODY_OFF \
: otg_temp + GLYPH_OBJ_OFF) : otg_temp + GLYPH_OBJ_OFF)
#define obj_to_glyph(obj) \ #define obj_to_glyph(obj, rng) \
(((obj)->otyp == STATUE) \ (((obj)->otyp == STATUE) \
? statue_to_glyph(obj) \ ? statue_to_glyph(obj, rng) \
: Hallucination \ : Hallucination \
? random_obj_to_glyph() \ ? random_obj_to_glyph(rng) \
: ((obj)->otyp == CORPSE) \ : ((obj)->otyp == CORPSE) \
? (int) (obj)->corpsenm + GLYPH_BODY_OFF \ ? (int) (obj)->corpsenm + GLYPH_BODY_OFF \
: (int) (obj)->otyp + GLYPH_OBJ_OFF) : (int) (obj)->otyp + GLYPH_OBJ_OFF)
@@ -310,16 +323,16 @@
/* MRKR: Statues now have glyphs corresponding to the monster they */ /* MRKR: Statues now have glyphs corresponding to the monster they */
/* represent and look like monsters when you are hallucinating. */ /* represent and look like monsters when you are hallucinating. */
#define statue_to_glyph(obj) \ #define statue_to_glyph(obj, rng) \
(Hallucination ? random_monster() + GLYPH_MON_OFF \ (Hallucination ? random_monster(rng) + GLYPH_MON_OFF \
: (int) (obj)->corpsenm + GLYPH_STATUE_OFF) : (int) (obj)->corpsenm + GLYPH_STATUE_OFF)
#define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF) #define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF)
#define explosion_to_glyph(expltype, idx) \ #define explosion_to_glyph(expltype, idx) \
((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF) ((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
#define trap_to_glyph(trap) \ #define trap_to_glyph(trap, rng) \
cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp))) cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp, rng)))
/* Not affected by hallucination. Gives a generic body for CORPSE */ /* Not affected by hallucination. Gives a generic body for CORPSE */
/* MRKR: ...and the generic statue */ /* MRKR: ...and the generic statue */
+2 -1
View File
@@ -2104,6 +2104,7 @@ E void FDECL(genl_outrip, (winid, int, time_t));
/* ### rnd.c ### */ /* ### rnd.c ### */
E int FDECL(rn2, (int)); E int FDECL(rn2, (int));
E int FDECL(rn2_on_display_rng, (int));
E int FDECL(rnl, (int)); E int FDECL(rnl, (int));
E int FDECL(rnd, (int)); E int FDECL(rnd, (int));
E int FDECL(d, (int, int)); E int FDECL(d, (int, int));
@@ -2148,7 +2149,7 @@ E const char *NDECL(Goodbye);
/* ### rumors.c ### */ /* ### rumors.c ### */
E char *FDECL(getrumor, (int, char *, BOOLEAN_P)); E char *FDECL(getrumor, (int, char *, BOOLEAN_P));
E char *FDECL(get_rnd_text, (const char *, char *)); E char *FDECL(get_rnd_text, (const char *, char *, int FDECL((*), (int))));
E void FDECL(outrumor, (int, int)); E void FDECL(outrumor, (int, int));
E void FDECL(outoracle, (BOOLEAN_P, BOOLEAN_P)); E void FDECL(outoracle, (BOOLEAN_P, BOOLEAN_P));
E void FDECL(save_oracles, (int, int)); E void FDECL(save_oracles, (int, int));
+7 -6
View File
@@ -241,7 +241,7 @@ int rx, ry, *resp;
int visglyph, corpseglyph; int visglyph, corpseglyph;
visglyph = glyph_at(rx, ry); visglyph = glyph_at(rx, ry);
corpseglyph = obj_to_glyph(corpse); corpseglyph = obj_to_glyph(corpse, rn2);
if (Blind && (visglyph != corpseglyph)) if (Blind && (visglyph != corpseglyph))
map_object(corpse, TRUE); map_object(corpse, TRUE);
@@ -2501,7 +2501,7 @@ struct obj *otmp;
ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP; ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP;
if (otmp == trapinfo.tobj && u.ux == trapinfo.tx && u.uy == trapinfo.ty) { if (otmp == trapinfo.tobj && u.ux == trapinfo.tx && u.uy == trapinfo.ty) {
You("resume setting %s%s.", shk_your(buf, otmp), You("resume setting %s%s.", shk_your(buf, otmp),
defsyms[trap_to_defsym(what_trap(ttyp))].explanation); defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation);
set_occupation(set_trap, occutext, 0); set_occupation(set_trap, occutext, 0);
return; return;
} }
@@ -2526,7 +2526,8 @@ struct obj *otmp;
chance = (rnl(10) > 5); chance = (rnl(10) > 5);
You("aren't very skilled at reaching from %s.", mon_nam(u.usteed)); You("aren't very skilled at reaching from %s.", mon_nam(u.usteed));
Sprintf(buf, "Continue your attempt to set %s?", Sprintf(buf, "Continue your attempt to set %s?",
the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation)); the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))]
.explanation));
if (yn(buf) == 'y') { if (yn(buf) == 'y') {
if (chance) { if (chance) {
switch (ttyp) { switch (ttyp) {
@@ -2537,7 +2538,7 @@ struct obj *otmp;
case BEAR_TRAP: /* drop it without arming it */ case BEAR_TRAP: /* drop it without arming it */
reset_trapset(); reset_trapset();
You("drop %s!", You("drop %s!",
the(defsyms[trap_to_defsym(what_trap(ttyp))] the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))]
.explanation)); .explanation));
dropx(otmp); dropx(otmp);
return; return;
@@ -2549,7 +2550,7 @@ struct obj *otmp;
} }
} }
You("begin setting %s%s.", shk_your(buf, otmp), You("begin setting %s%s.", shk_your(buf, otmp),
defsyms[trap_to_defsym(what_trap(ttyp))].explanation); defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation);
set_occupation(set_trap, occutext, 0); set_occupation(set_trap, occutext, 0);
return; return;
} }
@@ -2582,7 +2583,7 @@ set_trap()
} }
if (!trapinfo.force_bungle) if (!trapinfo.force_bungle)
You("finish arming %s.", You("finish arming %s.",
the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation)); the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation));
if (((otmp->cursed || Fumbling) && (rnl(10) > 5)) if (((otmp->cursed || Fumbling) && (rnl(10) > 5))
|| trapinfo.force_bungle) || trapinfo.force_bungle)
dotrap(ttmp, dotrap(ttmp,
+15 -7
View File
@@ -78,10 +78,12 @@ struct monst *mtmp;
boolean showtail; boolean showtail;
{ {
if (def_monsyms[(int) mtmp->data->mlet].sym == ' ') if (def_monsyms[(int) mtmp->data->mlet].sym == ' ')
show_glyph(mtmp->mx, mtmp->my, detected_mon_to_glyph(mtmp));
else
show_glyph(mtmp->mx, mtmp->my, show_glyph(mtmp->mx, mtmp->my,
mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp)); detected_mon_to_glyph(mtmp, newsym_rn2));
else
show_glyph(mtmp->mx, mtmp->my, mtmp->mtame
? pet_to_glyph(mtmp, newsym_rn2)
: mon_to_glyph(mtmp, newsym_rn2));
if (showtail && mtmp->data == &mons[PM_LONG_WORM]) if (showtail && mtmp->data == &mons[PM_LONG_WORM])
detect_wsegs(mtmp, 0); detect_wsegs(mtmp, 0);
@@ -1591,14 +1593,20 @@ void
find_trap(trap) find_trap(trap)
struct trap *trap; struct trap *trap;
{ {
int tt = what_trap(trap->ttyp); int tt = what_trap(trap->ttyp, rn2);
boolean cleared = FALSE; boolean cleared = FALSE;
trap->tseen = 1; trap->tseen = 1;
exercise(A_WIS, TRUE); exercise(A_WIS, TRUE);
feel_newsym(trap->tx, trap->ty); feel_newsym(trap->tx, trap->ty);
if (levl[trap->tx][trap->ty].glyph != trap_to_glyph(trap)) { /* The "Hallucination ||" is to preserve 3.6.1 behaviour, but this
behaviour might need a rework in the hallucination case
(e.g. to not prompt if any trap glyph appears on the
square). */
if (Hallucination ||
levl[trap->tx][trap->ty].glyph !=
trap_to_glyph(trap, rn2_on_display_rng)) {
/* There's too much clutter to see your find otherwise */ /* There's too much clutter to see your find otherwise */
cls(); cls();
map_trap(trap, 1); map_trap(trap, 1);
@@ -1832,7 +1840,7 @@ int default_glyph, which_subset;
an object, replacing any object or trap at its spot) */ an object, replacing any object or trap at its spot) */
glyph = !swallowed ? glyph_at(x, y) : levl_glyph; glyph = !swallowed ? glyph_at(x, y) : levl_glyph;
if (keep_mons && x == u.ux && y == u.uy && swallowed) if (keep_mons && x == u.ux && y == u.uy && swallowed)
glyph = mon_to_glyph(u.ustuck); glyph = mon_to_glyph(u.ustuck, rn2_on_display_rng);
else if (((glyph_is_monster(glyph) else if (((glyph_is_monster(glyph)
|| glyph_is_warning(glyph)) && !keep_mons) || glyph_is_warning(glyph)) && !keep_mons)
|| glyph_is_swallow(glyph)) || glyph_is_swallow(glyph))
@@ -1841,7 +1849,7 @@ int default_glyph, which_subset;
|| glyph_is_invisible(glyph)) || glyph_is_invisible(glyph))
&& keep_traps && !covers_traps(x, y)) { && keep_traps && !covers_traps(x, y)) {
if ((t = t_at(x, y)) != 0 && t->tseen) if ((t = t_at(x, y)) != 0 && t->tseen)
glyph = trap_to_glyph(t); glyph = trap_to_glyph(t, rn2_on_display_rng);
} }
if ((glyph_is_object(glyph) && !keep_objs) if ((glyph_is_object(glyph) && !keep_objs)
|| (glyph_is_trap(glyph) && !keep_traps) || (glyph_is_trap(glyph) && !keep_traps)
+18 -13
View File
@@ -222,7 +222,7 @@ register struct trap *trap;
register int show; register int show;
{ {
register int x = trap->tx, y = trap->ty; register int x = trap->tx, y = trap->ty;
register int glyph = trap_to_glyph(trap); register int glyph = trap_to_glyph(trap, newsym_rn2);
if (level.flags.hero_memory) if (level.flags.hero_memory)
levl[x][y].glyph = glyph; levl[x][y].glyph = glyph;
@@ -242,14 +242,14 @@ register struct obj *obj;
register int show; register int show;
{ {
register int x = obj->ox, y = obj->oy; register int x = obj->ox, y = obj->oy;
register int glyph = obj_to_glyph(obj); register int glyph = obj_to_glyph(obj, newsym_rn2);
if (level.flags.hero_memory) { if (level.flags.hero_memory) {
/* MRKR: While hallucinating, statues are seen as random monsters */ /* MRKR: While hallucinating, statues are seen as random monsters */
/* but remembered as random objects. */ /* but remembered as random objects. */
if (Hallucination && obj->otyp == STATUE) { if (Hallucination && obj->otyp == STATUE) {
levl[x][y].glyph = random_obj_to_glyph(); levl[x][y].glyph = random_obj_to_glyph(newsym_rn2);
} else { } else {
levl[x][y].glyph = glyph; levl[x][y].glyph = glyph;
} }
@@ -394,7 +394,7 @@ xchar worm_tail; /* mon is actually a worm tail */
(int) mon->m_ap_type); (int) mon->m_ap_type);
/*FALLTHRU*/ /*FALLTHRU*/
case M_AP_NOTHING: case M_AP_NOTHING:
show_glyph(x, y, mon_to_glyph(mon)); show_glyph(x, y, mon_to_glyph(mon, newsym_rn2));
break; break;
case M_AP_FURNITURE: { case M_AP_FURNITURE: {
@@ -434,7 +434,8 @@ xchar worm_tail; /* mon is actually a worm tail */
case M_AP_MONSTER: case M_AP_MONSTER:
show_glyph(x, y, show_glyph(x, y,
monnum_to_glyph(what_mon((int) mon->mappearance))); monnum_to_glyph(what_mon((int) mon->mappearance,
rn2_on_display_rng)));
break; break;
} }
} }
@@ -456,17 +457,19 @@ xchar worm_tail; /* mon is actually a worm tail */
if (worm_tail) if (worm_tail)
num = petnum_to_glyph(PM_LONG_WORM_TAIL); num = petnum_to_glyph(PM_LONG_WORM_TAIL);
else else
num = pet_to_glyph(mon); num = pet_to_glyph(mon, rn2_on_display_rng);
} else if (sightflags == DETECTED) { } else if (sightflags == DETECTED) {
if (worm_tail) if (worm_tail)
num = detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)); num = detected_monnum_to_glyph(
what_mon(PM_LONG_WORM_TAIL, rn2_on_display_rng));
else else
num = detected_mon_to_glyph(mon); num = detected_mon_to_glyph(mon, rn2_on_display_rng);
} else { } else {
if (worm_tail) if (worm_tail)
num = monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)); num = monnum_to_glyph(
what_mon(PM_LONG_WORM_TAIL, rn2_on_display_rng));
else else
num = mon_to_glyph(mon); num = mon_to_glyph(mon, rn2_on_display_rng);
} }
show_glyph(x, y, num); show_glyph(x, y, num);
} }
@@ -489,10 +492,11 @@ register struct monst *mon;
int glyph; int glyph;
if (mon_warning(mon)) { if (mon_warning(mon)) {
int wl = Hallucination ? rn1(WARNCOUNT - 1, 1) : warning_of(mon); int wl = Hallucination ?
rn2_on_display_rng(WARNCOUNT - 1) + 1 : warning_of(mon);
glyph = warning_to_glyph(wl); glyph = warning_to_glyph(wl);
} else if (MATCH_WARN_OF_MON(mon)) { } else if (MATCH_WARN_OF_MON(mon)) {
glyph = mon_to_glyph(mon); glyph = mon_to_glyph(mon, rn2_on_display_rng);
} else { } else {
impossible("display_warning did not match warning type?"); impossible("display_warning did not match warning type?");
return; return;
@@ -1751,7 +1755,8 @@ int loc;
impossible("swallow_to_glyph: bad swallow location"); impossible("swallow_to_glyph: bad swallow location");
loc = S_sw_br; loc = S_sw_br;
} }
return ((int) (what_mon(mnum) << 3) | (loc - S_sw_tl)) + GLYPH_SWALLOW_OFF; return ((int) (what_mon(mnum, rn2_on_display_rng) << 3) |
(loc - S_sw_tl)) + GLYPH_SWALLOW_OFF;
} }
/* /*
+12 -7
View File
@@ -1538,8 +1538,12 @@ namefloorobj()
unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f) unames[0] = ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
? urole.name.f ? urole.name.f
: urole.name.m; : urole.name.m;
/* random rank title for hero's role */ /* random rank title for hero's role
unames[1] = rank_of(rnd(30), Role_switch, flags.female);
note: the 30 is hardcoded in xlev_to_rank, so should be
hardcoded here too */
unames[1] = rank_of(rn2_on_display_rng(30) + 1,
Role_switch, flags.female);
/* random fake monster */ /* random fake monster */
unames[2] = bogusmon(tmpbuf, (char *) 0); unames[2] = bogusmon(tmpbuf, (char *) 0);
/* increased chance for fake monster */ /* increased chance for fake monster */
@@ -1550,7 +1554,7 @@ namefloorobj()
unames[5] = "Wibbly Wobbly"; unames[5] = "Wibbly Wobbly";
pline("%s %s to call you \"%s.\"", pline("%s %s to call you \"%s.\"",
The(buf), use_plural ? "decide" : "decides", The(buf), use_plural ? "decide" : "decides",
unames[rn2(SIZE(unames))]); unames[rn2_on_display_rng(SIZE(unames))]);
} else if (!objtyp_is_callable(obj->otyp)) { } else if (!objtyp_is_callable(obj->otyp)) {
pline("%s %s can't be assigned a type name.", pline("%s %s can't be assigned a type name.",
use_plural ? "Those" : "That", buf); use_plural ? "Those" : "That", buf);
@@ -1930,7 +1934,7 @@ char *buf, *code;
{ {
char *mname = buf; char *mname = buf;
get_rnd_text(BOGUSMONFILE, buf); get_rnd_text(BOGUSMONFILE, buf, rn2_on_display_rng);
/* strip prefix if present */ /* strip prefix if present */
if (!letter(*mname)) { if (!letter(*mname)) {
if (code) if (code)
@@ -1957,7 +1961,7 @@ char *code;
*code = '\0'; *code = '\0';
do { do {
name = rn1(SPECIAL_PM + BOGUSMONSIZE - LOW_PM, LOW_PM); name = rn2_on_display_rng(SPECIAL_PM + BOGUSMONSIZE - LOW_PM) + LOW_PM;
} while (name < SPECIAL_PM } while (name < SPECIAL_PM
&& (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN))); && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
@@ -2013,8 +2017,9 @@ const char *
hcolor(colorpref) hcolor(colorpref)
const char *colorpref; const char *colorpref;
{ {
return (Hallucination || !colorpref) ? hcolors[rn2(SIZE(hcolors))] return (Hallucination || !colorpref)
: colorpref; ? hcolors[rn2_on_display_rng(SIZE(hcolors))]
: colorpref;
} }
/* return a random real color unless hallucinating */ /* return a random real color unless hallucinating */
+3 -3
View File
@@ -1076,7 +1076,7 @@ struct obj *obj;
if ((u.dx || u.dy) && (bhitpos.x != u.ux || bhitpos.y != u.uy)) { if ((u.dx || u.dy) && (bhitpos.x != u.ux || bhitpos.y != u.uy)) {
int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy; int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy;
tmp_at(DISP_FLASH, obj_to_glyph(obj)); tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
while (isok(x,y) && (x != u.ux || y != u.uy)) { while (isok(x,y) && (x != u.ux || y != u.uy)) {
tmp_at(x, y); tmp_at(x, y);
delay_output(); delay_output();
@@ -1145,7 +1145,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
bhitpos.x = mon->mx; bhitpos.x = mon->mx;
bhitpos.y = mon->my; bhitpos.y = mon->my;
if (tethered_weapon) if (tethered_weapon)
tmp_at(DISP_TETHER, obj_to_glyph(obj)); tmp_at(DISP_TETHER, obj_to_glyph(obj, rn2_on_display_rng));
} else if (u.dz) { } else if (u.dz) {
if (u.dz < 0 if (u.dz < 0
/* Mjollnir must we wielded to be thrown--caller verifies this; /* Mjollnir must we wielded to be thrown--caller verifies this;
@@ -1374,7 +1374,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
} }
if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) { if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && breaktest(obj)) {
tmp_at(DISP_FLASH, obj_to_glyph(obj)); tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
tmp_at(bhitpos.x, bhitpos.y); tmp_at(bhitpos.x, bhitpos.y);
delay_output(); delay_output();
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
+2 -2
View File
@@ -18,7 +18,7 @@ char *outbuf;
/* a random engraving may come from the "rumors" file, /* a random engraving may come from the "rumors" file,
or from the "engrave" file (formerly in an array here) */ or from the "engrave" file (formerly in an array here) */
if (!rn2(4) || !(rumor = getrumor(0, outbuf, TRUE)) || !*rumor) if (!rn2(4) || !(rumor = getrumor(0, outbuf, TRUE)) || !*rumor)
(void) get_rnd_text(ENGRAVEFILE, outbuf); (void) get_rnd_text(ENGRAVEFILE, outbuf, rn2);
wipeout_text(outbuf, (int) (strlen(outbuf) / 4), 0); wipeout_text(outbuf, (int) (strlen(outbuf) / 4), 0);
return outbuf; return outbuf;
@@ -1294,7 +1294,7 @@ const char *str;
/* Engrave the headstone */ /* Engrave the headstone */
del_engr_at(x, y); del_engr_at(x, y);
if (!str) if (!str)
str = get_rnd_text(EPITAPHFILE, buf); str = get_rnd_text(EPITAPHFILE, buf, rn2);
make_engr_at(x, y, str, 0L, HEADSTONE); make_engr_at(x, y, str, 0L, HEADSTONE);
return; return;
} }
+2 -2
View File
@@ -1466,7 +1466,7 @@ domove_core()
if (context.run >= 2) { if (context.run >= 2) {
if (iflags.mention_walls) { if (iflags.mention_walls) {
if (trap && trap->tseen) { if (trap && trap->tseen) {
int tt = what_trap(trap->ttyp); int tt = what_trap(trap->ttyp, rn2_on_display_rng);
You("stop in front of %s.", You("stop in front of %s.",
an(defsyms[trap_to_defsym(tt)].explanation)); an(defsyms[trap_to_defsym(tt)].explanation));
@@ -2709,7 +2709,7 @@ lookaround()
goto bcorr; /* if you must */ goto bcorr; /* if you must */
if (x == u.ux + u.dx && y == u.uy + u.dy) { if (x == u.ux + u.dx && y == u.uy + u.dy) {
if (iflags.mention_walls) { if (iflags.mention_walls) {
int tt = what_trap(trap->ttyp); int tt = what_trap(trap->ttyp, rn2_on_display_rng);
You("stop in front of %s.", You("stop in front of %s.",
an(defsyms[trap_to_defsym(tt)].explanation)); an(defsyms[trap_to_defsym(tt)].explanation));
} }
+4 -3
View File
@@ -2691,8 +2691,8 @@ long *out_cnt;
any.a_obj = otmp; any.a_obj = otmp;
else else
any.a_char = ilet; any.a_char = ilet;
add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, ATR_NONE, add_menu(win, obj_to_glyph(otmp, rn2_on_display_rng), &any, ilet,
doname(otmp), MENU_UNSELECTED); 0, ATR_NONE, doname(otmp), MENU_UNSELECTED);
} }
} }
if (flags.sortpack) { if (flags.sortpack) {
@@ -2805,7 +2805,8 @@ char avoidlet;
classcount++; classcount++;
} }
any.a_char = ilet; any.a_char = ilet;
add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, ATR_NONE, add_menu(win, obj_to_glyph(otmp, rn2_on_display_rng),
&any, ilet, 0, ATR_NONE,
doname(otmp), MENU_UNSELECTED); doname(otmp), MENU_UNSELECTED);
} }
} }
+1 -1
View File
@@ -532,7 +532,7 @@ struct obj *obj; /* missile (or stack providing it) */
* be careful not to use either one after it's been freed. * be careful not to use either one after it's been freed.
*/ */
if (sym) if (sym)
tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
while (range-- > 0) { /* Actually the loop is always exited by break */ while (range-- > 0) { /* Actually the loop is always exited by break */
bhitpos.x += dx; bhitpos.x += dx;
bhitpos.y += dy; bhitpos.y += dy;
+1 -1
View File
@@ -1976,7 +1976,7 @@ struct monst *mtmp;
#ifdef CLIPPING #ifdef CLIPPING
cliparound(mtmp->mx, mtmp->my); cliparound(mtmp->mx, mtmp->my);
#endif #endif
show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp, rn2));
display_self(); display_self();
You_feel("aggravated at %s.", noit_mon_nam(mtmp)); You_feel("aggravated at %s.", noit_mon_nam(mtmp));
display_nhwindow(WIN_MAP, TRUE); display_nhwindow(WIN_MAP, TRUE);
+4 -3
View File
@@ -381,7 +381,8 @@ char *buf, *monbuf;
buf[0] = monbuf[0] = '\0'; buf[0] = monbuf[0] = '\0';
glyph = glyph_at(x, y); glyph = glyph_at(x, y);
if (u.ux == x && u.uy == y && canspotself() if (u.ux == x && u.uy == y && canspotself()
&& !(iflags.save_uswallow && glyph == mon_to_glyph(u.ustuck)) && !(iflags.save_uswallow &&
glyph == mon_to_glyph(u.ustuck, rn2_on_display_rng))
&& (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) { && (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
/* fill in buf[] */ /* fill in buf[] */
(void) self_lookat(buf); (void) self_lookat(buf);
@@ -435,7 +436,7 @@ char *buf, *monbuf;
} else if (glyph_is_object(glyph)) { } else if (glyph_is_object(glyph)) {
look_at_object(buf, x, y, glyph); /* fill in buf[] */ look_at_object(buf, x, y, glyph); /* fill in buf[] */
} else if (glyph_is_trap(glyph)) { } else if (glyph_is_trap(glyph)) {
int tnum = what_trap(glyph_to_trap(glyph)); int tnum = what_trap(glyph_to_trap(glyph), rn2_on_display_rng);
/* Trap detection displays a bear trap at locations having /* Trap detection displays a bear trap at locations having
* a trapped door or trapped container or both. * a trapped door or trapped container or both.
@@ -1487,7 +1488,7 @@ doidtrap()
if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP) if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP)
break; break;
} }
tt = what_trap(tt); tt = what_trap(tt, rn2_on_display_rng);
pline("That is %s%s%s.", pline("That is %s%s%s.",
an(defsyms[trap_to_defsym(tt)].explanation), an(defsyms[trap_to_defsym(tt)].explanation),
!trap->madeby_u !trap->madeby_u
+2 -2
View File
@@ -914,7 +914,7 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */
} }
any.a_obj = curr; any.a_obj = curr;
add_menu(win, obj_to_glyph(curr), &any, add_menu(win, obj_to_glyph(curr, rn2_on_display_rng), &any,
(qflags & USE_INVLET) ? curr->invlet (qflags & USE_INVLET) ? curr->invlet
: (first && curr->oclass == COIN_CLASS) ? '$' : 0, : (first && curr->oclass == COIN_CLASS) ? '$' : 0,
def_oc_syms[(int) objects[curr->otyp].oc_class].sym, def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
@@ -939,7 +939,7 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */
fake_hero_object = zeroobj; fake_hero_object = zeroobj;
fake_hero_object.quan = 1L; /* not strictly necessary... */ fake_hero_object.quan = 1L; /* not strictly necessary... */
any.a_obj = &fake_hero_object; any.a_obj = &fake_hero_object;
add_menu(win, mon_to_glyph(&youmonst), &any, add_menu(win, mon_to_glyph(&youmonst, rn2_on_display_rng), &any,
/* fake inventory letter, no group accelerator */ /* fake inventory letter, no group accelerator */
CONTAINED_SYM, 0, ATR_NONE, an(self_lookat(buf)), CONTAINED_SYM, 0, ATR_NONE, an(self_lookat(buf)),
MENU_UNSELECTED); MENU_UNSELECTED);
+9 -4
View File
@@ -2095,13 +2095,18 @@ aligntyp alignment;
if (!Hallucination) if (!Hallucination)
return align_gname(alignment); return align_gname(alignment);
/* Count the roles, so that we can pick one at random. */
int rolecount = 0;
while (roles[rolecount].filecode)
rolecount++;
/* The priest may not have initialized god names. If this is the /* The priest may not have initialized god names. If this is the
* case, and we roll priest, we need to try again. */ case, and we roll priest, we need to try again. */
do do
which = randrole(); which = rn2_on_display_rng(rolecount);
while (!roles[which].lgod); while (!roles[which].lgod);
switch (rn2(9)) { switch (rn2_on_display_rng(9)) {
case 0: case 0:
case 1: case 1:
gnam = roles[which].lgod; gnam = roles[which].lgod;
@@ -2116,7 +2121,7 @@ aligntyp alignment;
break; break;
case 6: case 6:
case 7: case 7:
gnam = hallu_gods[rn2(sizeof hallu_gods / sizeof *hallu_gods)]; gnam = hallu_gods[rn2_on_display_rng(SIZE(hallu_gods))];
break; break;
case 8: case 8:
gnam = Moloch; gnam = Moloch;
+14
View File
@@ -34,6 +34,20 @@ register int x;
#endif #endif
} }
/* 0 <= rn2(x) < x, but on a different sequence from the "main" rn2;
used in cases where the answer doesn't affect gameplay and we don't
want to give users easy control over the main RNG sequence. This is
an intentionally low-quality RNG to discourage its use for anything
gameplay-affecting; please use a better RNG in that case. */
int
rn2_on_display_rng(x)
register int x;
{
static unsigned seed = 1;
seed *= 2739110765;
return (int)((seed >> 16) % (unsigned)x);
}
/* 0 <= rnl(x) < x; sometimes subtracting Luck; /* 0 <= rnl(x) < x; sometimes subtracting Luck;
good luck approaches 0, bad luck approaches (x-1) */ good luck approaches 0, bad luck approaches (x-1) */
int int
+5 -3
View File
@@ -280,11 +280,13 @@ rumor_check()
} }
} }
/* Gets a random line of text from file 'fname', and returns it. */ /* Gets a random line of text from file 'fname', and returns it.
rng is the random number generator to use, and should act like rn2 does. */
char * char *
get_rnd_text(fname, buf) get_rnd_text(fname, buf, rng)
const char *fname; const char *fname;
char *buf; char *buf;
int FDECL((*rng), (int));
{ {
dlb *fh; dlb *fh;
@@ -305,7 +307,7 @@ char *buf;
(void) dlb_fseek(fh, 0L, SEEK_END); (void) dlb_fseek(fh, 0L, SEEK_END);
endtxt = dlb_ftell(fh); endtxt = dlb_ftell(fh);
sizetxt = endtxt - starttxt; sizetxt = endtxt - starttxt;
tidbit = Rand() % sizetxt; tidbit = rng(sizetxt);
(void) dlb_fseek(fh, starttxt + tidbit, SEEK_SET); (void) dlb_fseek(fh, starttxt + tidbit, SEEK_SET);
(void) dlb_fgets(line, sizeof line, fh); (void) dlb_fgets(line, sizeof line, fh);
+1 -1
View File
@@ -1814,7 +1814,7 @@ int style;
delaycnt = 1; delaycnt = 1;
if (!cansee(bhitpos.x, bhitpos.y)) if (!cansee(bhitpos.x, bhitpos.y))
curs_on_u(); curs_on_u();
tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
tmp_at(bhitpos.x, bhitpos.y); tmp_at(bhitpos.x, bhitpos.y);
} }
/* Mark a spot to place object in bones files to prevent /* Mark a spot to place object in bones files to prevent
+1 -1
View File
@@ -2023,7 +2023,7 @@ struct monst *mdef;
{ {
if (!Invisible) { if (!Invisible) {
map_location(u.ux, u.uy, TRUE); map_location(u.ux, u.uy, TRUE);
tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst)); tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst, rn2_on_display_rng));
tmp_at(mdef->mx, mdef->my); tmp_at(mdef->mx, mdef->my);
} }
You("engulf %s!", mon_nam(mdef)); You("engulf %s!", mon_nam(mdef));
+4 -3
View File
@@ -457,13 +457,14 @@ boolean use_detection_glyph;
struct wseg *curr = wtails[worm->wormno]; struct wseg *curr = wtails[worm->wormno];
/* if (!mtmp->wormno) return; bullet proofing */ /* if (!mtmp->wormno) return; bullet proofing */
int what_tail = what_mon(PM_LONG_WORM_TAIL, newsym_rn2);
while (curr != wheads[worm->wormno]) { while (curr != wheads[worm->wormno]) {
num = use_detection_glyph num = use_detection_glyph
? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)) ? detected_monnum_to_glyph(what_tail)
: (worm->mtame : (worm->mtame
? petnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)) ? petnum_to_glyph(what_tail)
: monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))); : monnum_to_glyph(what_tail));
show_glyph(curr->wx, curr->wy, num); show_glyph(curr->wx, curr->wy, num);
curr = curr->nseg; curr = curr->nseg;
} }
+2 -2
View File
@@ -3200,9 +3200,9 @@ struct obj **pobj; /* object tossed/used, set to NULL
} else if (weapon == THROWN_TETHERED_WEAPON && obj) { } else if (weapon == THROWN_TETHERED_WEAPON && obj) {
tethered_weapon = TRUE; tethered_weapon = TRUE;
weapon = THROWN_WEAPON; /* simplify if's that follow below */ weapon = THROWN_WEAPON; /* simplify if's that follow below */
tmp_at(DISP_TETHER, obj_to_glyph(obj)); tmp_at(DISP_TETHER, obj_to_glyph(obj, rn2_on_display_rng));
} else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) } else if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM)
tmp_at(DISP_FLASH, obj_to_glyph(obj)); tmp_at(DISP_FLASH, obj_to_glyph(obj, rn2_on_display_rng));
while (range-- > 0) { while (range-- > 0) {
int x, y; int x, y;