diff --git a/include/extern.h b/include/extern.h index c5b0b0af9..3a7041556 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1194,6 +1194,7 @@ extern int near_capacity(void); extern int calc_capacity(int); extern int max_capacity(void); extern boolean check_capacity(const char *); +extern void dump_weights(void); extern int inv_cnt(boolean); /* sometimes money_cnt(gi.invent) which can be null */ extern long money_cnt(struct obj *) NO_NNARGS; diff --git a/include/hack.h b/include/hack.h index f2f8d979a..d356d64c5 100644 --- a/include/hack.h +++ b/include/hack.h @@ -440,6 +440,7 @@ enum earlyarg { #endif , ARG_DUMPGLYPHIDS , ARG_DUMPMONGEN + , ARG_DUMPWEIGHTS #ifdef WIN32 , ARG_WINDOWS #endif diff --git a/include/objects.h b/include/objects.h index 784b66c36..93866d1a5 100644 --- a/include/objects.h +++ b/include/objects.h @@ -1501,7 +1501,7 @@ COIN("gold piece", 1000, GOLD, 1, GOLD_PIECE), OBJECT(OBJ(name, desc), \ BITS(0, 1, 0, 0, 0, 0, 0, 0, 0, \ HARDGEM(mohs), 0, -P_SLING, glass), \ - 0, GEM_CLASS, prob, 0, 1, gval, 3, 3, 0, 0, nutr, color, sn) + 0, GEM_CLASS, prob, 0, wt, gval, 3, 3, 0, 0, nutr, color, sn) #define ROCK(name,desc,kn,prob,wt,gval,sdam,ldam,mgc,nutr,mohs,glass,colr,sn) \ OBJECT(OBJ(name, desc), \ BITS(kn, 1, 0, 0, mgc, 0, 0, 0, 0, \ diff --git a/src/allmain.c b/src/allmain.c index f65ce13b2..f3fe1decd 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -938,6 +938,7 @@ static const struct early_opt earlyopts[] = { #endif { ARG_DUMPGLYPHIDS, "dumpglyphids", 12, FALSE }, { ARG_DUMPMONGEN, "dumpmongen", 10, FALSE }, + { ARG_DUMPWEIGHTS, "dumpweights", 11, FALSE }, #ifdef WIN32 { ARG_WINDOWS, "windows", 4, TRUE }, #endif @@ -1042,6 +1043,9 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) case ARG_DUMPMONGEN: dump_mongen(); return 2; + case ARG_DUMPWEIGHTS: + dump_weights(); + return 2; #ifdef CRASHREPORT case ARG_BIDSHOW: crashreport_bidshow(); diff --git a/src/hack.c b/src/hack.c index 8f4a21fc9..6d282e896 100644 --- a/src/hack.c +++ b/src/hack.c @@ -49,6 +49,7 @@ staticfn void move_update(boolean); staticfn int pickup_checks(void); staticfn void maybe_wail(void); staticfn boolean water_turbulence(coordxy *, coordxy *); +staticfn int QSORTCALLBACK cmp_weights(const void *, const void *); #define IS_SHOP(x) (svr.rooms[x].rtype >= SHOPBASE) @@ -4293,6 +4294,106 @@ check_capacity(const char *str) return 0; } +struct weight_table_entry { + unsigned wtyp; /* 1 = monst, 2 = obj */ + const char *nm; + int wt, idx; + boolean unique; +}; + +static struct weight_table_entry *weightlist; + +void +dump_weights(void) +{ + int i, cnt = 0, nmwidth = 49, mcount = NUMMONS, ocount = NUM_OBJECTS; + char nmbuf[BUFSZ], nmbufbase[BUFSZ]; + struct obj o = cg.zeroobj; + + weightlist = (struct weight_table_entry *) alloc(sizeof(struct weight_table_entry) + * (mcount + ocount)); + decl_globals_init(); + init_objects(); + o.quan = 1; + o.known = o.dknown == 1; + for (i = 0; i < mcount; ++i) { + if (i != PM_LONG_WORM_TAIL) { + weightlist[cnt].idx = i; + weightlist[cnt].wtyp = 1; + weightlist[cnt].nm = dupstr(mons[i].pmnames[NEUTRAL]); + weightlist[cnt].wt = (int) mons[i].cwt; + weightlist[cnt].unique = ((mons[i].geno & G_UNIQ) != 0); + cnt++; + } + } + for (i = 0; i < ocount; ++i) { + int wt = (int) objects[i].oc_weight; + if (wt && i != SLIME_MOLD && obj_descr[i].oc_name) { + weightlist[cnt].idx = i; + o.otyp = i; + o.oclass = objects[i].oc_class; + weightlist[cnt].wtyp = 2; + weightlist[cnt].nm = dupstr(obj_descr[i].oc_name); + weightlist[cnt].wt = wt; + weightlist[cnt].unique = (objects[i].oc_unique != 0); + cnt++; + } + } + qsort((genericptr_t) weightlist, cnt, + sizeof (struct weight_table_entry), cmp_weights); + raw_printf("int all_weights[] = {"); + for (i = 0; i < cnt; ++i) { + if (weightlist[i].wtyp == 1) { + boolean cm = CapitalMon(weightlist[i].nm); + + Snprintf(nmbuf, sizeof nmbuf, "%s%s", "the body of ", + (cm) ? the(weightlist[i].nm) + : weightlist[i].unique ? weightlist[i].nm + : an(weightlist[i].nm)); + } else { + Snprintf(nmbufbase, sizeof nmbufbase, "%s%s", + objects[weightlist[i].idx].oc_class == POTION_CLASS + ? "potion of " + : objects[weightlist[i].idx].oc_class == WAND_CLASS + ? "wand of " + : objects[weightlist[i].idx].oc_class == SCROLL_CLASS + ? "scroll of " + : objects[weightlist[i].idx].oc_class == SPBOOK_CLASS + ? "spellbook of " + : "", + weightlist[i].nm); + Snprintf(nmbuf, sizeof nmbuf, "%s", + (weightlist[i].unique) ? the(nmbufbase) : an(nmbufbase)); + } + raw_printf(" %7u%s /* %*s */", weightlist[i].wt, + (i == cnt - 1) ? " " : ",", -nmwidth, nmbuf); + if (weightlist[i].nm) + free((genericptr_t) weightlist[i].nm), weightlist[i].nm = 0; + } + raw_print("};"); + raw_print(""); + free((genericptr_t) weightlist); + freedynamicdata(); +} + +staticfn int QSORTCALLBACK +cmp_weights(const void *p1, const void *p2) +{ + struct weight_table_entry *i1 = (struct weight_table_entry *) p1, + *i2 = (struct weight_table_entry *) p2; + int x1 = i1->wt << 17, x2 = i2->wt << 17, + t1 = ((i1->wtyp == 1) ? 0 : 1) << 16, + t2 = ((i2->wtyp == 1) ? 0 : 1) << 16; + + x1 |= t1 | ((i1->nm != 0) ? i1->nm[0] : 0) << 8; + x2 |= t2 | ((i2->nm != 0) ? i2->nm[0] : 0) << 8; + + x1 |= ((i1->nm != 0) ? i1->nm[1] : 0); + x2 |= ((i2->nm != 0) ? i2->nm[1] : 0); + + return (x1 - x2); +} + int inv_cnt(boolean incl_gold) { diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 154c7e15b..6e943d685 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -662,6 +662,9 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p) } else if (argcheck(argc, argv, ARG_DUMPMONGEN) == 2) { opt_terminate(); /*NOTREACHED*/ + } else if (argcheck(argc, argv, ARG_DUMPWEIGHTS) == 2) { + opt_terminate(); + /*NOTREACHED*/ } else { #ifdef CHDIR oldargc = argc; diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index c622a707e..45282b446 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -487,6 +487,9 @@ early_options(int argc, char *argv[]) if (argcheck(argc, argv, ARG_DUMPMONGEN) == 2) { nethack_exit(EXIT_SUCCESS); } + if (argcheck(argc, argv, ARG_DUMPWEIGHTS) == 2) { + nethack_exit(EXIT_SUCCESS); + } if (argcheck(argc, argv, ARG_DEBUG) == 1) { argc--; argv++;