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
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

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_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 ### */

View File

@@ -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:

View File

@@ -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.");

View File

@@ -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*/