From: Pasi Kallinen Date: Wed, 15 Apr 2020 19:40:11 +0000 (+0300) Subject: Nerf unicorn horn X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=43d331c4ebe7bcd30a7cab7d4228957e283584c2;p=nethack Nerf unicorn horn Unicorn horns are just too good. Nerf it in similar way several other variants have done: don't let it restore attribute loss. This makes potion of restore ability more valuable, and the int loss from the (nerfed) mind flayers matter more. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 366cab99a..29028cf5a 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -135,6 +135,7 @@ male hero poly'd into nymph chooses charm vs seduce message based on being target and noticable if " finishes taking off his suit" is given hostile monsters with launcher and ammo try to stay away from melee range allow displacing peaceful creatures +unicorn horns don't restore attribute loss anymore Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 9383638d5..5d3106d32 100644 --- a/include/extern.h +++ b/include/extern.h @@ -48,7 +48,7 @@ E boolean FDECL(um_dist, (XCHAR_P, XCHAR_P, XCHAR_P)); E boolean FDECL(snuff_candle, (struct obj *)); E boolean FDECL(snuff_lit, (struct obj *)); E boolean FDECL(catch_lit, (struct obj *)); -E void FDECL(use_unicorn_horn, (struct obj *)); +E void FDECL(use_unicorn_horn, (struct obj **)); E boolean FDECL(tinnable, (struct obj *)); E void NDECL(reset_trapset); E void FDECL(fig_transform, (ANY_P *, long)); @@ -994,6 +994,7 @@ E void FDECL(strbuf_empty, (strbuf_t *)); E void FDECL(strbuf_nl_to_crlf, (strbuf_t *)); E char *FDECL(nonconst, (const char *, char *)); E int FDECL(swapbits, (int, int, int)); +E void FDECL(shuffle_int_array, (int *, int)); /* ### insight.c ### */ diff --git a/src/apply.c b/src/apply.c index 43a4b14bb..57671fa7b 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1931,14 +1931,13 @@ struct obj *obj; } void -use_unicorn_horn(obj) -struct obj *obj; +use_unicorn_horn(optr) +struct obj **optr; { #define PROP_COUNT 7 /* number of properties we're dealing with */ -#define ATTR_COUNT (A_MAX * 3) /* number of attribute points we might fix */ - int idx, val, val_limit, trouble_count, unfixable_trbl, did_prop, - did_attr; - int trouble_list[PROP_COUNT + ATTR_COUNT]; + int idx, val, val_limit, trouble_count, unfixable_trbl, did_prop; + int trouble_list[PROP_COUNT]; + struct obj *obj = (optr ? *optr : (struct obj *) 0); if (obj && obj->cursed) { long lcount = (long) rn1(90, 10); @@ -1962,7 +1961,10 @@ struct obj *obj; make_stunned((HStun & TIMEOUT) + lcount, TRUE); break; case 4: - (void) adjattrib(rn2(A_MAX), -1, FALSE); + if (Vomiting) + vomit(); + else + make_vomiting(14L, FALSE); break; case 5: (void) make_hallucinated((HHallucination & TIMEOUT) + lcount, @@ -1980,13 +1982,10 @@ struct obj *obj; /* * Entries in the trouble list use a very simple encoding scheme. */ -#define prop2trbl(X) ((X) + A_MAX) -#define attr2trbl(Y) (Y) -#define prop_trouble(X) trouble_list[trouble_count++] = prop2trbl(X) -#define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y) +#define prop_trouble(X) trouble_list[trouble_count++] = (X) #define TimedTrouble(P) (((P) && !((P) & ~TIMEOUT)) ? ((P) & TIMEOUT) : 0L) - trouble_count = unfixable_trbl = did_prop = did_attr = 0; + trouble_count = unfixable_trbl = did_prop = 0; /* collect property troubles */ if (TimedTrouble(Sick)) @@ -2006,44 +2005,11 @@ struct obj *obj; if (TimedTrouble(HDeaf)) prop_trouble(DEAF); - unfixable_trbl = unfixable_trouble_count(TRUE); - - /* collect attribute troubles */ - for (idx = 0; idx < A_MAX; idx++) { - if (ABASE(idx) >= AMAX(idx)) - continue; - val_limit = AMAX(idx); - /* this used to adjust 'val_limit' for A_STR when u.uhs was - WEAK or worse, but that's handled via ATEMP(A_STR) now */ - if (Fixed_abil) { - /* potion/spell of restore ability override sustain ability - intrinsic but unicorn horn usage doesn't */ - unfixable_trbl += val_limit - ABASE(idx); - continue; - } - /* don't recover more than 3 points worth of any attribute */ - if (val_limit > ABASE(idx) + 3) - val_limit = ABASE(idx) + 3; - - for (val = ABASE(idx); val < val_limit; val++) - attr_trouble(idx); - /* keep track of unfixed trouble, for message adjustment below */ - unfixable_trbl += (AMAX(idx) - val_limit); - } - if (trouble_count == 0) { pline1(nothing_happens); return; - } else if (trouble_count > 1) { /* shuffle */ - int i, j, k; - - for (i = trouble_count - 1; i > 0; i--) - if ((j = rn2(i + 1)) != i) { - k = trouble_list[j]; - trouble_list[j] = trouble_list[i]; - trouble_list[i] = k; - } - } + } else if (trouble_count > 1) + shuffle_int_array(trouble_list, trouble_count); /* * Chances for number of troubles to be fixed @@ -2060,60 +2026,47 @@ struct obj *obj; idx = trouble_list[val]; switch (idx) { - case prop2trbl(SICK): + case SICK: make_sick(0L, (char *) 0, TRUE, SICK_ALL); did_prop++; break; - case prop2trbl(BLINDED): + case BLINDED: make_blinded((long) u.ucreamed, TRUE); did_prop++; break; - case prop2trbl(HALLUC): + case HALLUC: (void) make_hallucinated(0L, TRUE, 0L); did_prop++; break; - case prop2trbl(VOMITING): + case VOMITING: make_vomiting(0L, TRUE); did_prop++; break; - case prop2trbl(CONFUSION): + case CONFUSION: make_confused(0L, TRUE); did_prop++; break; - case prop2trbl(STUNNED): + case STUNNED: make_stunned(0L, TRUE); did_prop++; break; - case prop2trbl(DEAF): + case DEAF: make_deaf(0L, TRUE); did_prop++; break; default: - if (idx >= 0 && idx < A_MAX) { - ABASE(idx) += 1; - did_attr++; - } else - panic("use_unicorn_horn: bad trouble? (%d)", idx); + impossible("use_unicorn_horn: bad trouble? (%d)", idx); break; } } - if (did_attr || did_prop) + if (did_prop) g.context.botl = TRUE; - if (did_attr) - pline("This makes you feel %s!", - (did_prop + did_attr) == (trouble_count + unfixable_trbl) - ? "great" - : "better"); - else if (!did_prop) + else pline("Nothing seems to happen."); #undef PROP_COUNT -#undef ATTR_COUNT -#undef prop2trbl -#undef attr2trbl #undef prop_trouble -#undef attr_trouble #undef TimedTrouble } @@ -3809,7 +3762,7 @@ doapply() use_figurine(&obj); break; case UNICORN_HORN: - use_unicorn_horn(obj); + use_unicorn_horn(&obj); break; case WOODEN_FLUTE: case MAGIC_FLUTE: diff --git a/src/cmd.c b/src/cmd.c index 48b5c958b..8b2b2c9d4 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -721,7 +721,7 @@ domonability(VOID_ARGS) } else There("is no fountain here."); } else if (is_unicorn(g.youmonst.data)) { - use_unicorn_horn((struct obj *) 0); + use_unicorn_horn((struct obj **) 0); return 1; } else if (g.youmonst.data->msound == MS_SHRIEK) { You("shriek."); diff --git a/src/hacklib.c b/src/hacklib.c index 89905d194..60f1dfd76 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -73,7 +73,7 @@ void strbuf_nl_to_crlf (strbuf_t *) char * nonconst (const char *, char *) int swapbits (int, int, int) -UNUSED void shuffle_int_array (int *, int) + void shuffle_int_array (int *, int) =*/ #ifdef LINT #define Static /* pacify lint */ @@ -1302,9 +1302,8 @@ int val, bita, bitb; return (val ^ ((tmp << bita) | (tmp << bitb))); } -#if 0 /* randomize the given list of numbers 0 <= i < count */ -static void +void shuffle_int_array(indices, count) int *indices; int count; @@ -1319,6 +1318,5 @@ int count; indices[iswap] = temp; } } -#endif /*hacklib.c*/