adopt github pull request #286 - rndmonst()
Eliminate the cache that was supporting rndmonst() and pick a random monster in a single pass through mons[] via "weighted reservoir sampling", a term I'm not familiar with. It had a couple of bugs: if the first monster examined happened to be given a weighting of 0, rn2() would divide by 0. I didn't try to figure out how to trigger that. But the second one was easy to trigger: if all eligible monsters were extinct or genocided, it would issue a warning even though the situation isn't impossible. Aside from fixing those, the rest is mostly as-is. I included a bit of formatting in decl.c, moved some declarations to not require C99, and changed a couple of macros to not hide and duplicate a call to level_difficulty(). Fixes #286
This commit is contained in:
@@ -886,18 +886,19 @@ struct instance_globals {
|
||||
boolean chosen_symset_end;
|
||||
int symset_which_set;
|
||||
/* SAVESIZE, BONESSIZE, LOCKNAMESIZE are defined in "fnamesiz.h" */
|
||||
char SAVEF[SAVESIZE]; /* holds relative path of save file from playground */
|
||||
char SAVEF[SAVESIZE]; /* relative path of save file from playground */
|
||||
#ifdef MICRO
|
||||
char SAVEP[SAVESIZE]; /* holds path of directory for save file */
|
||||
#endif
|
||||
char bones[BONESSIZE];
|
||||
char lock[LOCKNAMESIZE];
|
||||
|
||||
|
||||
/* hack.c */
|
||||
anything tmp_anything;
|
||||
int wc; /* current weight_cap(); valid after call to inv_weight() */
|
||||
|
||||
/* insight.c */
|
||||
|
||||
/* invent.c */
|
||||
int lastinvnr; /* 0 ... 51 (never saved&restored) */
|
||||
unsigned sortlootmode; /* set by sortloot() for use by sortloot_cmp();
|
||||
@@ -905,7 +906,7 @@ struct instance_globals {
|
||||
char *invbuf;
|
||||
unsigned invbufsiz;
|
||||
/* for perm_invent when operating on a partial inventory display, so that
|
||||
the persistent one doesn't get shrunk during filtering for item selection
|
||||
persistent one doesn't get shrunk during filtering for item selection
|
||||
then regrown to full inventory, possibly being resized in the process */
|
||||
winid cached_pickinv_win;
|
||||
/* query objlist callback: return TRUE if obj type matches "this_type" */
|
||||
@@ -916,15 +917,10 @@ struct instance_globals {
|
||||
/* light.c */
|
||||
light_source *light_base;
|
||||
|
||||
|
||||
/* lock.c */
|
||||
struct xlock_s xlock;
|
||||
|
||||
/* makemon.c */
|
||||
struct {
|
||||
int choice_count;
|
||||
char mchoices[SPECIAL_PM]; /* value range is 0..127 */
|
||||
} rndmonst_state;
|
||||
|
||||
/* mhitm.c */
|
||||
boolean vis;
|
||||
|
||||
@@ -1216,7 +1216,6 @@ E void FDECL(dealloc_mextra, (struct monst *));
|
||||
E struct monst *FDECL(makemon, (struct permonst *, int, int, int));
|
||||
E boolean FDECL(create_critters, (int, struct permonst *, BOOLEAN_P));
|
||||
E struct permonst *NDECL(rndmonst);
|
||||
E void FDECL(reset_rndmonst, (int));
|
||||
E struct permonst *FDECL(mkclass, (CHAR_P, int));
|
||||
E struct permonst *FDECL(mkclass_aligned, (CHAR_P, int, ALIGNTYP_P));
|
||||
E int FDECL(mkclass_poly, (int));
|
||||
|
||||
@@ -201,4 +201,13 @@ struct monst {
|
||||
#define is_obj_mappear(mon,otyp) (M_AP_TYPE(mon) == M_AP_OBJECT \
|
||||
&& (mon)->mappearance == (otyp))
|
||||
|
||||
/* Get the maximum difficulty monsters that can currently be generated,
|
||||
given the current level difficulty and the hero's level. */
|
||||
#define monmax_difficulty(levdif) (((levdif) + u.ulevel) / 2)
|
||||
#define monmin_difficulty(levdif) ((levdif) / 6)
|
||||
|
||||
/* Macros for whether a type of monster is too strong for a specific level. */
|
||||
#define montoostrong(monindx, lev) (mons[monindx].difficulty > lev)
|
||||
#define montooweak(monindx, lev) (mons[monindx].difficulty < lev)
|
||||
|
||||
#endif /* MONST_H */
|
||||
|
||||
Reference in New Issue
Block a user