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.
This commit is contained in:
Pasi Kallinen
2020-04-15 22:40:11 +03:00
parent a768507ebd
commit 43d331c4eb
5 changed files with 30 additions and 77 deletions

View File

@@ -135,6 +135,7 @@ male hero poly'd into nymph chooses charm vs seduce message based on being
target and noticable if "<mon> finishes taking off his suit" is given target and noticable if "<mon> finishes taking off his suit" is given
hostile monsters with launcher and ammo try to stay away from melee range hostile monsters with launcher and ammo try to stay away from melee range
allow displacing peaceful creatures 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 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -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_candle, (struct obj *));
E boolean FDECL(snuff_lit, (struct obj *)); E boolean FDECL(snuff_lit, (struct obj *));
E boolean FDECL(catch_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 boolean FDECL(tinnable, (struct obj *));
E void NDECL(reset_trapset); E void NDECL(reset_trapset);
E void FDECL(fig_transform, (ANY_P *, long)); 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 void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
E char *FDECL(nonconst, (const char *, char *)); E char *FDECL(nonconst, (const char *, char *));
E int FDECL(swapbits, (int, int, int)); E int FDECL(swapbits, (int, int, int));
E void FDECL(shuffle_int_array, (int *, int));
/* ### insight.c ### */ /* ### insight.c ### */

View File

@@ -1931,14 +1931,13 @@ struct obj *obj;
} }
void void
use_unicorn_horn(obj) use_unicorn_horn(optr)
struct obj *obj; struct obj **optr;
{ {
#define PROP_COUNT 7 /* number of properties we're dealing with */ #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;
int idx, val, val_limit, trouble_count, unfixable_trbl, did_prop, int trouble_list[PROP_COUNT];
did_attr; struct obj *obj = (optr ? *optr : (struct obj *) 0);
int trouble_list[PROP_COUNT + ATTR_COUNT];
if (obj && obj->cursed) { if (obj && obj->cursed) {
long lcount = (long) rn1(90, 10); long lcount = (long) rn1(90, 10);
@@ -1962,7 +1961,10 @@ struct obj *obj;
make_stunned((HStun & TIMEOUT) + lcount, TRUE); make_stunned((HStun & TIMEOUT) + lcount, TRUE);
break; break;
case 4: case 4:
(void) adjattrib(rn2(A_MAX), -1, FALSE); if (Vomiting)
vomit();
else
make_vomiting(14L, FALSE);
break; break;
case 5: case 5:
(void) make_hallucinated((HHallucination & TIMEOUT) + lcount, (void) make_hallucinated((HHallucination & TIMEOUT) + lcount,
@@ -1980,13 +1982,10 @@ struct obj *obj;
/* /*
* Entries in the trouble list use a very simple encoding scheme. * Entries in the trouble list use a very simple encoding scheme.
*/ */
#define prop2trbl(X) ((X) + A_MAX) #define prop_trouble(X) trouble_list[trouble_count++] = (X)
#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 TimedTrouble(P) (((P) && !((P) & ~TIMEOUT)) ? ((P) & TIMEOUT) : 0L) #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 */ /* collect property troubles */
if (TimedTrouble(Sick)) if (TimedTrouble(Sick))
@@ -2006,44 +2005,11 @@ struct obj *obj;
if (TimedTrouble(HDeaf)) if (TimedTrouble(HDeaf))
prop_trouble(DEAF); 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) { if (trouble_count == 0) {
pline1(nothing_happens); pline1(nothing_happens);
return; return;
} else if (trouble_count > 1) { /* shuffle */ } else if (trouble_count > 1)
int i, j, k; shuffle_int_array(trouble_list, trouble_count);
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;
}
}
/* /*
* Chances for number of troubles to be fixed * Chances for number of troubles to be fixed
@@ -2060,60 +2026,47 @@ struct obj *obj;
idx = trouble_list[val]; idx = trouble_list[val];
switch (idx) { switch (idx) {
case prop2trbl(SICK): case SICK:
make_sick(0L, (char *) 0, TRUE, SICK_ALL); make_sick(0L, (char *) 0, TRUE, SICK_ALL);
did_prop++; did_prop++;
break; break;
case prop2trbl(BLINDED): case BLINDED:
make_blinded((long) u.ucreamed, TRUE); make_blinded((long) u.ucreamed, TRUE);
did_prop++; did_prop++;
break; break;
case prop2trbl(HALLUC): case HALLUC:
(void) make_hallucinated(0L, TRUE, 0L); (void) make_hallucinated(0L, TRUE, 0L);
did_prop++; did_prop++;
break; break;
case prop2trbl(VOMITING): case VOMITING:
make_vomiting(0L, TRUE); make_vomiting(0L, TRUE);
did_prop++; did_prop++;
break; break;
case prop2trbl(CONFUSION): case CONFUSION:
make_confused(0L, TRUE); make_confused(0L, TRUE);
did_prop++; did_prop++;
break; break;
case prop2trbl(STUNNED): case STUNNED:
make_stunned(0L, TRUE); make_stunned(0L, TRUE);
did_prop++; did_prop++;
break; break;
case prop2trbl(DEAF): case DEAF:
make_deaf(0L, TRUE); make_deaf(0L, TRUE);
did_prop++; did_prop++;
break; break;
default: default:
if (idx >= 0 && idx < A_MAX) { impossible("use_unicorn_horn: bad trouble? (%d)", idx);
ABASE(idx) += 1;
did_attr++;
} else
panic("use_unicorn_horn: bad trouble? (%d)", idx);
break; break;
} }
} }
if (did_attr || did_prop) if (did_prop)
g.context.botl = TRUE; g.context.botl = TRUE;
if (did_attr) else
pline("This makes you feel %s!",
(did_prop + did_attr) == (trouble_count + unfixable_trbl)
? "great"
: "better");
else if (!did_prop)
pline("Nothing seems to happen."); pline("Nothing seems to happen.");
#undef PROP_COUNT #undef PROP_COUNT
#undef ATTR_COUNT
#undef prop2trbl
#undef attr2trbl
#undef prop_trouble #undef prop_trouble
#undef attr_trouble
#undef TimedTrouble #undef TimedTrouble
} }
@@ -3809,7 +3762,7 @@ doapply()
use_figurine(&obj); use_figurine(&obj);
break; break;
case UNICORN_HORN: case UNICORN_HORN:
use_unicorn_horn(obj); use_unicorn_horn(&obj);
break; break;
case WOODEN_FLUTE: case WOODEN_FLUTE:
case MAGIC_FLUTE: case MAGIC_FLUTE:

View File

@@ -721,7 +721,7 @@ domonability(VOID_ARGS)
} else } else
There("is no fountain here."); There("is no fountain here.");
} else if (is_unicorn(g.youmonst.data)) { } else if (is_unicorn(g.youmonst.data)) {
use_unicorn_horn((struct obj *) 0); use_unicorn_horn((struct obj **) 0);
return 1; return 1;
} else if (g.youmonst.data->msound == MS_SHRIEK) { } else if (g.youmonst.data->msound == MS_SHRIEK) {
You("shriek."); You("shriek.");

View File

@@ -73,7 +73,7 @@
void strbuf_nl_to_crlf (strbuf_t *) void strbuf_nl_to_crlf (strbuf_t *)
char * nonconst (const char *, char *) char * nonconst (const char *, char *)
int swapbits (int, int, int) int swapbits (int, int, int)
UNUSED void shuffle_int_array (int *, int) void shuffle_int_array (int *, int)
=*/ =*/
#ifdef LINT #ifdef LINT
#define Static /* pacify lint */ #define Static /* pacify lint */
@@ -1302,9 +1302,8 @@ int val, bita, bitb;
return (val ^ ((tmp << bita) | (tmp << bitb))); return (val ^ ((tmp << bita) | (tmp << bitb)));
} }
#if 0
/* randomize the given list of numbers 0 <= i < count */ /* randomize the given list of numbers 0 <= i < count */
static void void
shuffle_int_array(indices, count) shuffle_int_array(indices, count)
int *indices; int *indices;
int count; int count;
@@ -1319,6 +1318,5 @@ int count;
indices[iswap] = temp; indices[iswap] = temp;
} }
} }
#endif
/*hacklib.c*/ /*hacklib.c*/