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

View File

@@ -146,9 +146,9 @@
*
* Respectively return a random monster, object, or trap number.
*/
#define random_monster() rn2(NUMMONS)
#define random_object() rn1(NUM_OBJECTS - 1, 1)
#define random_trap() rn1(TRAPNUM - 1, 1)
#define random_monster(rng) rng(NUMMONS)
#define random_object(rng) (rng(NUM_OBJECTS - 1) + 1)
#define random_trap(rng) (rng(TRAPNUM - 1) + 1)
/*
* what_obj()
@@ -156,11 +156,23 @@
* what_trap()
*
* 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_mon(mon) (Hallucination ? random_monster() : mon)
#define what_trap(trp) (Hallucination ? random_trap() : trp)
#define what_obj(obj, rng) (Hallucination ? random_object(rng) : obj)
#define what_mon(mon, rng) (Hallucination ? random_monster(rng) : mon)
#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()
@@ -196,9 +208,10 @@
* Display the hero. It is assumed that all checks necessary to determine
* _if_ the hero can be seen have already been done.
*/
#define maybe_display_usteed(otherwise_self) \
((u.usteed && mon_visible(u.usteed)) ? ridden_mon_to_glyph(u.usteed) \
: (otherwise_self))
#define maybe_display_usteed(otherwise_self) \
((u.usteed && mon_visible(u.usteed)) \
? ridden_mon_to_glyph(u.usteed, rn2_on_display_rng) \
: (otherwise_self))
#define display_self() \
show_glyph(u.ux, u.uy, \
@@ -282,27 +295,27 @@
#define GLYPH_INVISIBLE GLYPH_INVIS_OFF
#define warning_to_glyph(mwarnlev) ((mwarnlev) + GLYPH_WARNING_OFF)
#define mon_to_glyph(mon) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_MON_OFF)
#define detected_mon_to_glyph(mon) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_DETECT_OFF)
#define ridden_mon_to_glyph(mon) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_RIDDEN_OFF)
#define pet_to_glyph(mon) \
((int) what_mon(monsndx((mon)->data)) + GLYPH_PET_OFF)
#define mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data), rng) + GLYPH_MON_OFF)
#define detected_mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data), rng) + GLYPH_DETECT_OFF)
#define ridden_mon_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data), rng) + GLYPH_RIDDEN_OFF)
#define pet_to_glyph(mon, rng) \
((int) what_mon(monsndx((mon)->data), rng) + GLYPH_PET_OFF)
/* This has the unfortunate side effect of needing a global variable */
/* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */
#define random_obj_to_glyph() \
((otg_temp = random_object()) == CORPSE \
? random_monster() + GLYPH_BODY_OFF \
#define random_obj_to_glyph(rng) \
((otg_temp = random_object(rng)) == CORPSE \
? random_monster(rng) + GLYPH_BODY_OFF \
: otg_temp + GLYPH_OBJ_OFF)
#define obj_to_glyph(obj) \
#define obj_to_glyph(obj, rng) \
(((obj)->otyp == STATUE) \
? statue_to_glyph(obj) \
? statue_to_glyph(obj, rng) \
: Hallucination \
? random_obj_to_glyph() \
? random_obj_to_glyph(rng) \
: ((obj)->otyp == CORPSE) \
? (int) (obj)->corpsenm + GLYPH_BODY_OFF \
: (int) (obj)->otyp + GLYPH_OBJ_OFF)
@@ -310,16 +323,16 @@
/* MRKR: Statues now have glyphs corresponding to the monster they */
/* represent and look like monsters when you are hallucinating. */
#define statue_to_glyph(obj) \
(Hallucination ? random_monster() + GLYPH_MON_OFF \
#define statue_to_glyph(obj, rng) \
(Hallucination ? random_monster(rng) + GLYPH_MON_OFF \
: (int) (obj)->corpsenm + GLYPH_STATUE_OFF)
#define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF)
#define explosion_to_glyph(expltype, idx) \
((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
#define trap_to_glyph(trap) \
cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp)))
#define trap_to_glyph(trap, rng) \
cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp, rng)))
/* Not affected by hallucination. Gives a generic body for CORPSE */
/* MRKR: ...and the generic statue */

View File

@@ -2104,6 +2104,7 @@ E void FDECL(genl_outrip, (winid, int, time_t));
/* ### rnd.c ### */
E int FDECL(rn2, (int));
E int FDECL(rn2_on_display_rng, (int));
E int FDECL(rnl, (int));
E int FDECL(rnd, (int));
E int FDECL(d, (int, int));
@@ -2148,7 +2149,7 @@ E const char *NDECL(Goodbye);
/* ### rumors.c ### */
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(outoracle, (BOOLEAN_P, BOOLEAN_P));
E void FDECL(save_oracles, (int, int));