crystal ball enhancements
Allow crystal ball to search for furniture (stairs and ladders,
altar, throne, sink, fountain) as well as for a class or objects
or of monsters or all traps. Giving any of '<','>','_','\','#',
or '{' will find all of those rather than just the individual type
specified. Because of the default character conflict, '_' can no
longer be used to find chains; looking for altars is more useful.
The chance of getting the cursed effect due to failing a saving
throw against intelligence when the ball isn't actually cursed has
been reduced. If it is the hero's own quest artifact, it will
happen if rnd(8) is greater than Int, so Int of 8 or more will
never yield that effect. Otherwise if it is blessed, rnd(16) is
used so 16 or better Int means it can't act like it is cursed.
When uncursed and not hero's quest artifact, the old rnd(20) > Int
test is still used.
Crystal balls now start with 3..7 charges rather than 1..5, and
blessed charging sets the amount to 7 charges rather than 6 and
also blesses the ball. Recharing with uncursed scroll of charging
is slightly better (adds 1..2 charges instead of always just 1,
caps the amount at 7 rather than 5) and uncurses the ball. Cursed
scroll strips off all charges even if the ball is blessed and also
curses the ball so is harsher than before.
Crystal balls now cancel to -1 instead of 0, like wands, and using
one effect will destroy it, like zapping cancelled wands.
Also a minor tweak to the initial charges for can of grease (5..25
instead of 1..25) and horn of plenty and bag of tricks (both now
3..20 instead of 1..20).
This commit is contained in:
114
src/zap.c
114
src/zap.c
@@ -1031,63 +1031,77 @@ void
|
||||
cancel_item(obj)
|
||||
register struct obj *obj;
|
||||
{
|
||||
boolean u_ring = (obj == uleft || obj == uright);
|
||||
int otyp = obj->otyp;
|
||||
|
||||
switch (otyp) {
|
||||
case RIN_GAIN_STRENGTH:
|
||||
if ((obj->owornmask & W_RING) && u_ring) {
|
||||
ABON(A_STR) -= obj->spe;
|
||||
g.context.botl = 1;
|
||||
if (carried(obj)) {
|
||||
/* handle items being worn by hero */
|
||||
switch (otyp) {
|
||||
case RIN_GAIN_STRENGTH:
|
||||
if ((obj->owornmask & W_RING) != 0L) {
|
||||
ABON(A_STR) -= obj->spe;
|
||||
g.context.botl = TRUE;
|
||||
}
|
||||
break;
|
||||
case RIN_GAIN_CONSTITUTION:
|
||||
if ((obj->owornmask & W_RING) != 0L) {
|
||||
ABON(A_CON) -= obj->spe;
|
||||
g.context.botl = TRUE;
|
||||
}
|
||||
break;
|
||||
case RIN_ADORNMENT:
|
||||
if ((obj->owornmask & W_RING) != 0L) {
|
||||
ABON(A_CHA) -= obj->spe;
|
||||
g.context.botl = TRUE;
|
||||
}
|
||||
break;
|
||||
case RIN_INCREASE_ACCURACY:
|
||||
if ((obj->owornmask & W_RING) != 0L)
|
||||
u.uhitinc -= obj->spe;
|
||||
break;
|
||||
case RIN_INCREASE_DAMAGE:
|
||||
if ((obj->owornmask & W_RING) != 0L)
|
||||
u.udaminc -= obj->spe;
|
||||
break;
|
||||
case RIN_PROTECTION:
|
||||
if ((obj->owornmask & W_RING) != 0L)
|
||||
g.context.botl = TRUE;
|
||||
break;
|
||||
case GAUNTLETS_OF_DEXTERITY:
|
||||
if ((obj->owornmask & W_ARMG) != 0L) {
|
||||
ABON(A_DEX) -= obj->spe;
|
||||
g.context.botl = TRUE;
|
||||
}
|
||||
break;
|
||||
case HELM_OF_BRILLIANCE:
|
||||
if ((obj->owornmask & W_ARMH) != 0L) {
|
||||
ABON(A_INT) -= obj->spe;
|
||||
ABON(A_WIS) -= obj->spe;
|
||||
g.context.botl = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ((obj->owornmask & W_ARMOR) != 0L) /* AC */
|
||||
g.context.botl = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RIN_GAIN_CONSTITUTION:
|
||||
if ((obj->owornmask & W_RING) && u_ring) {
|
||||
ABON(A_CON) -= obj->spe;
|
||||
g.context.botl = 1;
|
||||
}
|
||||
break;
|
||||
case RIN_ADORNMENT:
|
||||
if ((obj->owornmask & W_RING) && u_ring) {
|
||||
ABON(A_CHA) -= obj->spe;
|
||||
g.context.botl = 1;
|
||||
}
|
||||
break;
|
||||
case RIN_INCREASE_ACCURACY:
|
||||
if ((obj->owornmask & W_RING) && u_ring)
|
||||
u.uhitinc -= obj->spe;
|
||||
break;
|
||||
case RIN_INCREASE_DAMAGE:
|
||||
if ((obj->owornmask & W_RING) && u_ring)
|
||||
u.udaminc -= obj->spe;
|
||||
break;
|
||||
case GAUNTLETS_OF_DEXTERITY:
|
||||
if ((obj->owornmask & W_ARMG) && (obj == uarmg)) {
|
||||
ABON(A_DEX) -= obj->spe;
|
||||
g.context.botl = 1;
|
||||
}
|
||||
break;
|
||||
case HELM_OF_BRILLIANCE:
|
||||
if ((obj->owornmask & W_ARMH) && (obj == uarmh)) {
|
||||
ABON(A_INT) -= obj->spe;
|
||||
ABON(A_WIS) -= obj->spe;
|
||||
g.context.botl = 1;
|
||||
}
|
||||
break;
|
||||
/* case RIN_PROTECTION: not needed */
|
||||
}
|
||||
/* cancelled item might not be in hero's possession but
|
||||
cancellation is presumed to be instigated by hero */
|
||||
if (objects[otyp].oc_magic
|
||||
|| (obj->spe && (obj->oclass == ARMOR_CLASS
|
||||
|| obj->oclass == WEAPON_CLASS || is_weptool(obj)))
|
||||
|| otyp == POT_ACID
|
||||
|| otyp == POT_SICKNESS
|
||||
|| (otyp == POT_WATER && (obj->blessed || obj->cursed))) {
|
||||
if (obj->spe != ((obj->oclass == WAND_CLASS) ? -1 : 0)
|
||||
int cancelled_spe = (obj->oclass == WAND_CLASS
|
||||
|| obj->otyp == CRYSTAL_BALL) ? -1 : 0;
|
||||
|
||||
if (obj->spe != cancelled_spe
|
||||
&& otyp != WAN_CANCELLATION /* can't cancel cancellation */
|
||||
&& otyp != MAGIC_LAMP /* cancelling doesn't remove djinni */
|
||||
&& otyp != CANDELABRUM_OF_INVOCATION) {
|
||||
costly_alteration(obj, COST_CANCEL);
|
||||
obj->spe = (obj->oclass == WAND_CLASS) ? -1 : 0;
|
||||
obj->spe = cancelled_spe;
|
||||
}
|
||||
switch (obj->oclass) {
|
||||
case SCROLL_CLASS:
|
||||
@@ -1103,10 +1117,8 @@ register struct obj *obj;
|
||||
}
|
||||
break;
|
||||
case POTION_CLASS:
|
||||
costly_alteration(obj,
|
||||
(otyp != POT_WATER)
|
||||
? COST_CANCEL
|
||||
: obj->cursed ? COST_UNCURS : COST_UNBLSS);
|
||||
costly_alteration(obj, (otyp != POT_WATER) ? COST_CANCEL
|
||||
: obj->cursed ? COST_UNCURS : COST_UNBLSS);
|
||||
if (otyp == POT_SICKNESS || otyp == POT_SEE_INVISIBLE) {
|
||||
/* sickness is "biologically contaminated" fruit juice;
|
||||
cancel it and it just becomes fruit juice...
|
||||
@@ -2759,10 +2771,10 @@ register struct monst *mdef;
|
||||
register struct obj *obj;
|
||||
boolean youattack, allow_cancel_kill, self_cancel;
|
||||
{
|
||||
static const char
|
||||
writing_vanishes[] = "Some writing vanishes from %s head!",
|
||||
your[] = "your"; /* should be extern */
|
||||
boolean youdefend = (mdef == &g.youmonst);
|
||||
static const char writing_vanishes[] =
|
||||
"Some writing vanishes from %s head!";
|
||||
static const char your[] = "your"; /* should be extern */
|
||||
|
||||
if (youdefend ? (!youattack && Antimagic)
|
||||
: resist(mdef, obj->oclass, 0, NOTELL))
|
||||
@@ -2774,9 +2786,11 @@ boolean youattack, allow_cancel_kill, self_cancel;
|
||||
for (otmp = (youdefend ? g.invent : mdef->minvent); otmp;
|
||||
otmp = otmp->nobj)
|
||||
cancel_item(otmp);
|
||||
|
||||
if (youdefend) {
|
||||
g.context.botl = 1; /* potential AC change */
|
||||
find_ac();
|
||||
/* update_inventory(); -- handled by caller */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user