more context (trunk only)
- reading spellbooks - taking off
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#ifndef CONTEXT_H
|
||||
#define CONTEXT_H
|
||||
|
||||
#define CONTEXTVERBSZ 30
|
||||
|
||||
/*
|
||||
* The context structure houses things that the game tracks
|
||||
* or adjusts during the game, to preserve game state or context.
|
||||
@@ -31,6 +33,20 @@ struct tin_info {
|
||||
int usedtime, reqtime;
|
||||
};
|
||||
|
||||
struct book_info {
|
||||
struct obj *book; /* last/current book being xscribed */
|
||||
unsigned o_id; /* o_id of book in save file */
|
||||
schar delay; /* moves left for this spell */
|
||||
};
|
||||
|
||||
struct takeoff_info {
|
||||
long mask;
|
||||
long what;
|
||||
int delay;
|
||||
boolean cancelled_don;
|
||||
char disrobing[CONTEXTVERBSZ+1];
|
||||
};
|
||||
|
||||
struct victual_info {
|
||||
struct obj *piece; /* the thing being eaten, or last thing that
|
||||
* was partially eaten, unless that thing was
|
||||
@@ -73,6 +89,8 @@ struct context_info {
|
||||
struct dig_info digging;
|
||||
struct victual_info victual;
|
||||
struct tin_info tin;
|
||||
struct book_info spbook;
|
||||
struct takeoff_info takeoff;
|
||||
};
|
||||
|
||||
extern NEARDATA struct context_info context;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 4
|
||||
#define EDITLEVEL 5
|
||||
|
||||
#define COPYRIGHT_BANNER_A \
|
||||
"NetHack, Copyright 1985-2003"
|
||||
|
||||
202
src/do_wear.c
202
src/do_wear.c
@@ -4,12 +4,6 @@
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
STATIC_OVL NEARDATA long takeoff_mask = 0L;
|
||||
static NEARDATA long taking_off = 0L;
|
||||
|
||||
static NEARDATA int todelay;
|
||||
static boolean cancelled_don = FALSE;
|
||||
|
||||
static NEARDATA const char see_yourself[] = "see yourself";
|
||||
static NEARDATA const char unknown_type[] = "Unknown type of %s (%d)";
|
||||
static NEARDATA const char c_armor[] = "armor",
|
||||
@@ -141,7 +135,7 @@ Boots_off()
|
||||
setworn((struct obj *)0, W_ARMF);
|
||||
switch (otyp) {
|
||||
case SPEED_BOOTS:
|
||||
if (!Very_fast && !cancelled_don) {
|
||||
if (!Very_fast && !context.takeoff.cancelled_don) {
|
||||
makeknown(otyp);
|
||||
You_feel("yourself slow down%s.",
|
||||
Fast ? " a bit" : "");
|
||||
@@ -149,14 +143,14 @@ Boots_off()
|
||||
break;
|
||||
case WATER_WALKING_BOOTS:
|
||||
if (is_pool(u.ux,u.uy) && !Levitation && !Flying &&
|
||||
!is_clinger(youmonst.data) && !cancelled_don) {
|
||||
!is_clinger(youmonst.data) && !context.takeoff.cancelled_don) {
|
||||
makeknown(otyp);
|
||||
/* make boots known in case you survive the drowning */
|
||||
spoteffects(TRUE);
|
||||
}
|
||||
break;
|
||||
case ELVEN_BOOTS:
|
||||
if (!oldprop && !HStealth && !BStealth && !cancelled_don) {
|
||||
if (!oldprop && !HStealth && !BStealth && !context.takeoff.cancelled_don) {
|
||||
makeknown(otyp);
|
||||
You("sure are noisy.");
|
||||
}
|
||||
@@ -166,7 +160,7 @@ Boots_off()
|
||||
HFumbling = EFumbling = 0;
|
||||
break;
|
||||
case LEVITATION_BOOTS:
|
||||
if (!oldprop && !HLevitation && !cancelled_don) {
|
||||
if (!oldprop && !HLevitation && !context.takeoff.cancelled_don) {
|
||||
(void) float_down(0L, 0L);
|
||||
makeknown(otyp);
|
||||
}
|
||||
@@ -179,7 +173,7 @@ Boots_off()
|
||||
break;
|
||||
default: impossible(unknown_type, c_boots, otyp);
|
||||
}
|
||||
cancelled_don = FALSE;
|
||||
context.takeoff.cancelled_don = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -351,7 +345,7 @@ Helmet_off()
|
||||
context.botl = 1;
|
||||
break;
|
||||
case CORNUTHAUM:
|
||||
if (!cancelled_don) {
|
||||
if (!context.takeoff.cancelled_don) {
|
||||
ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1);
|
||||
context.botl = 1;
|
||||
}
|
||||
@@ -362,7 +356,7 @@ Helmet_off()
|
||||
see_monsters();
|
||||
return 0;
|
||||
case HELM_OF_BRILLIANCE:
|
||||
if (!cancelled_don) adj_abon(uarmh, -uarmh->spe);
|
||||
if (!context.takeoff.cancelled_don) adj_abon(uarmh, -uarmh->spe);
|
||||
break;
|
||||
case HELM_OF_OPPOSITE_ALIGNMENT:
|
||||
u.ualign.type = u.ualignbase[A_CURRENT];
|
||||
@@ -372,7 +366,7 @@ Helmet_off()
|
||||
default: impossible(unknown_type, c_helmet, uarmh->otyp);
|
||||
}
|
||||
setworn((struct obj *)0, W_ARMH);
|
||||
cancelled_don = FALSE;
|
||||
context.takeoff.cancelled_don = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -420,12 +414,12 @@ Gloves_off()
|
||||
context.botl = 1; /* taken care of in attrib.c */
|
||||
break;
|
||||
case GAUNTLETS_OF_DEXTERITY:
|
||||
if (!cancelled_don) adj_abon(uarmg, -uarmg->spe);
|
||||
if (!context.takeoff.cancelled_don) adj_abon(uarmg, -uarmg->spe);
|
||||
break;
|
||||
default: impossible(unknown_type, c_gloves, uarmg->otyp);
|
||||
}
|
||||
setworn((struct obj *)0, W_ARMG);
|
||||
cancelled_don = FALSE;
|
||||
context.takeoff.cancelled_don = FALSE;
|
||||
(void) encumber_msg(); /* immediate feedback for GoP */
|
||||
|
||||
/* Prevent wielding cockatrice when not wearing gloves */
|
||||
@@ -510,7 +504,7 @@ int
|
||||
Armor_off()
|
||||
{
|
||||
setworn((struct obj *)0, W_ARM);
|
||||
cancelled_don = FALSE;
|
||||
context.takeoff.cancelled_don = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -521,7 +515,7 @@ int
|
||||
Armor_gone()
|
||||
{
|
||||
setnotworn(uarm);
|
||||
cancelled_don = FALSE;
|
||||
context.takeoff.cancelled_don = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -947,7 +941,7 @@ cancel_don()
|
||||
* wasting time on it (and don't dereference it when donning would
|
||||
* otherwise finish)
|
||||
*/
|
||||
cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on ||
|
||||
context.takeoff.cancelled_don = (afternmv == Boots_on || afternmv == Helmet_on ||
|
||||
afternmv == Gloves_on || afternmv == Armor_on);
|
||||
afternmv = 0;
|
||||
nomovemsg = (char *)0;
|
||||
@@ -1011,10 +1005,10 @@ dotakeoff()
|
||||
return 0;
|
||||
}
|
||||
|
||||
reset_remarm(); /* clear takeoff_mask and taking_off */
|
||||
reset_remarm(); /* clear context.takeoff.mask and context.takeoff.what */
|
||||
(void) select_off(otmp);
|
||||
if (!takeoff_mask) return 0;
|
||||
reset_remarm(); /* armoroff() doesn't use takeoff_mask */
|
||||
if (!context.takeoff.mask) return 0;
|
||||
reset_remarm(); /* armoroff() doesn't use context.takeoff.mask */
|
||||
|
||||
(void) armoroff(otmp);
|
||||
return(1);
|
||||
@@ -1050,9 +1044,9 @@ doremring()
|
||||
return(0);
|
||||
}
|
||||
|
||||
reset_remarm(); /* clear takeoff_mask and taking_off */
|
||||
reset_remarm(); /* clear context.takeoff.mask and context.takeoff.what */
|
||||
(void) select_off(otmp);
|
||||
if (!takeoff_mask) return 0;
|
||||
if (!context.takeoff.mask) return 0;
|
||||
reset_remarm(); /* not used by Ring_/Amulet_/Blindf_off() */
|
||||
|
||||
if (otmp == uright || otmp == uleft) {
|
||||
@@ -1139,7 +1133,7 @@ register struct obj *otmp;
|
||||
else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
|
||||
off_msg(otmp);
|
||||
}
|
||||
takeoff_mask = taking_off = 0L;
|
||||
context.takeoff.mask = context.takeoff.what = 0L;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -1371,7 +1365,7 @@ dowear()
|
||||
/* if(is_shield(otmp)) (void) Shield_on(); */
|
||||
on_msg(otmp);
|
||||
}
|
||||
takeoff_mask = taking_off = 0L;
|
||||
context.takeoff.mask = context.takeoff.what = 0L;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -1754,22 +1748,22 @@ register struct obj *otmp;
|
||||
if (cursed(otmp)) return 0;
|
||||
}
|
||||
|
||||
if(otmp == uarm) takeoff_mask |= WORN_ARMOR;
|
||||
else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK;
|
||||
else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS;
|
||||
else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES;
|
||||
else if(otmp == uarmh) takeoff_mask |= WORN_HELMET;
|
||||
else if(otmp == uarms) takeoff_mask |= WORN_SHIELD;
|
||||
if(otmp == uarm) context.takeoff.mask |= WORN_ARMOR;
|
||||
else if(otmp == uarmc) context.takeoff.mask |= WORN_CLOAK;
|
||||
else if(otmp == uarmf) context.takeoff.mask |= WORN_BOOTS;
|
||||
else if(otmp == uarmg) context.takeoff.mask |= WORN_GLOVES;
|
||||
else if(otmp == uarmh) context.takeoff.mask |= WORN_HELMET;
|
||||
else if(otmp == uarms) context.takeoff.mask |= WORN_SHIELD;
|
||||
#ifdef TOURIST
|
||||
else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
|
||||
else if(otmp == uarmu) context.takeoff.mask |= WORN_SHIRT;
|
||||
#endif
|
||||
else if(otmp == uleft) takeoff_mask |= LEFT_RING;
|
||||
else if(otmp == uright) takeoff_mask |= RIGHT_RING;
|
||||
else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
|
||||
else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
|
||||
else if(otmp == uwep) takeoff_mask |= W_WEP;
|
||||
else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP;
|
||||
else if(otmp == uquiver) takeoff_mask |= W_QUIVER;
|
||||
else if(otmp == uleft) context.takeoff.mask |= LEFT_RING;
|
||||
else if(otmp == uright) context.takeoff.mask |= RIGHT_RING;
|
||||
else if(otmp == uamul) context.takeoff.mask |= WORN_AMUL;
|
||||
else if(otmp == ublindf) context.takeoff.mask |= WORN_BLINDF;
|
||||
else if(otmp == uwep) context.takeoff.mask |= W_WEP;
|
||||
else if(otmp == uswapwep) context.takeoff.mask |= W_SWAPWEP;
|
||||
else if(otmp == uquiver) context.takeoff.mask |= W_QUIVER;
|
||||
|
||||
else impossible("select_off: %s???", doname(otmp));
|
||||
|
||||
@@ -1781,61 +1775,59 @@ do_takeoff()
|
||||
{
|
||||
register struct obj *otmp = (struct obj *)0;
|
||||
|
||||
if (taking_off == W_WEP) {
|
||||
if (context.takeoff.what == W_WEP) {
|
||||
if(!cursed(uwep)) {
|
||||
setuwep((struct obj *) 0);
|
||||
You("are empty %s.", body_part(HANDED));
|
||||
u.twoweap = FALSE;
|
||||
}
|
||||
} else if (taking_off == W_SWAPWEP) {
|
||||
} else if (context.takeoff.what == W_SWAPWEP) {
|
||||
setuswapwep((struct obj *) 0);
|
||||
You("no longer have a second weapon readied.");
|
||||
u.twoweap = FALSE;
|
||||
} else if (taking_off == W_QUIVER) {
|
||||
} else if (context.takeoff.what == W_QUIVER) {
|
||||
setuqwep((struct obj *) 0);
|
||||
You("no longer have ammunition readied.");
|
||||
} else if (taking_off == WORN_ARMOR) {
|
||||
} else if (context.takeoff.what == WORN_ARMOR) {
|
||||
otmp = uarm;
|
||||
if(!cursed(otmp)) (void) Armor_off();
|
||||
} else if (taking_off == WORN_CLOAK) {
|
||||
} else if (context.takeoff.what == WORN_CLOAK) {
|
||||
otmp = uarmc;
|
||||
if(!cursed(otmp)) (void) Cloak_off();
|
||||
} else if (taking_off == WORN_BOOTS) {
|
||||
} else if (context.takeoff.what == WORN_BOOTS) {
|
||||
otmp = uarmf;
|
||||
if(!cursed(otmp)) (void) Boots_off();
|
||||
} else if (taking_off == WORN_GLOVES) {
|
||||
} else if (context.takeoff.what == WORN_GLOVES) {
|
||||
otmp = uarmg;
|
||||
if(!cursed(otmp)) (void) Gloves_off();
|
||||
} else if (taking_off == WORN_HELMET) {
|
||||
} else if (context.takeoff.what == WORN_HELMET) {
|
||||
otmp = uarmh;
|
||||
if(!cursed(otmp)) (void) Helmet_off();
|
||||
} else if (taking_off == WORN_SHIELD) {
|
||||
} else if (context.takeoff.what == WORN_SHIELD) {
|
||||
otmp = uarms;
|
||||
if(!cursed(otmp)) (void) Shield_off();
|
||||
#ifdef TOURIST
|
||||
} else if (taking_off == WORN_SHIRT) {
|
||||
} else if (context.takeoff.what == WORN_SHIRT) {
|
||||
otmp = uarmu;
|
||||
if(!cursed(otmp))
|
||||
setworn((struct obj *)0, uarmu->owornmask & W_ARMOR);
|
||||
#endif
|
||||
} else if (taking_off == WORN_AMUL) {
|
||||
} else if (context.takeoff.what == WORN_AMUL) {
|
||||
otmp = uamul;
|
||||
if(!cursed(otmp)) Amulet_off();
|
||||
} else if (taking_off == LEFT_RING) {
|
||||
} else if (context.takeoff.what == LEFT_RING) {
|
||||
otmp = uleft;
|
||||
if(!cursed(otmp)) Ring_off(uleft);
|
||||
} else if (taking_off == RIGHT_RING) {
|
||||
} else if (context.takeoff.what == RIGHT_RING) {
|
||||
otmp = uright;
|
||||
if(!cursed(otmp)) Ring_off(uright);
|
||||
} else if (taking_off == WORN_BLINDF) {
|
||||
} else if (context.takeoff.what == WORN_BLINDF) {
|
||||
if (!cursed(ublindf)) Blindf_off(ublindf);
|
||||
} else impossible("do_takeoff: taking off %lx", taking_off);
|
||||
} else impossible("do_takeoff: taking off %lx", context.takeoff.what);
|
||||
|
||||
return(otmp);
|
||||
}
|
||||
|
||||
static const char *disrobing = "";
|
||||
|
||||
STATIC_PTR
|
||||
int
|
||||
take_off()
|
||||
@@ -1843,89 +1835,91 @@ take_off()
|
||||
register int i;
|
||||
register struct obj *otmp;
|
||||
|
||||
if (taking_off) {
|
||||
if (todelay > 0) {
|
||||
todelay--;
|
||||
if (context.takeoff.what) {
|
||||
if (context.takeoff.delay > 0) {
|
||||
context.takeoff.delay--;
|
||||
return(1); /* still busy */
|
||||
} else {
|
||||
if ((otmp = do_takeoff())) off_msg(otmp);
|
||||
}
|
||||
takeoff_mask &= ~taking_off;
|
||||
taking_off = 0L;
|
||||
context.takeoff.mask &= ~context.takeoff.what;
|
||||
context.takeoff.what = 0L;
|
||||
}
|
||||
|
||||
for(i = 0; takeoff_order[i]; i++)
|
||||
if(takeoff_mask & takeoff_order[i]) {
|
||||
taking_off = takeoff_order[i];
|
||||
if(context.takeoff.mask & takeoff_order[i]) {
|
||||
context.takeoff.what = takeoff_order[i];
|
||||
break;
|
||||
}
|
||||
|
||||
otmp = (struct obj *) 0;
|
||||
todelay = 0;
|
||||
context.takeoff.delay = 0;
|
||||
|
||||
if (taking_off == 0L) {
|
||||
You("finish %s.", disrobing);
|
||||
if (context.takeoff.what == 0L) {
|
||||
You("finish %s.", context.takeoff.disrobing);
|
||||
return 0;
|
||||
} else if (taking_off == W_WEP) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == W_SWAPWEP) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == W_QUIVER) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == WORN_ARMOR) {
|
||||
} else if (context.takeoff.what == W_WEP) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == W_SWAPWEP) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == W_QUIVER) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == WORN_ARMOR) {
|
||||
otmp = uarm;
|
||||
/* If a cloak is being worn, add the time to take it off and put
|
||||
* it back on again. Kludge alert! since that time is 0 for all
|
||||
* known cloaks, add 1 so that it actually matters...
|
||||
*/
|
||||
if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
|
||||
} else if (taking_off == WORN_CLOAK) {
|
||||
if (uarmc) context.takeoff.delay += 2 * objects[uarmc->otyp].oc_delay + 1;
|
||||
} else if (context.takeoff.what == WORN_CLOAK) {
|
||||
otmp = uarmc;
|
||||
} else if (taking_off == WORN_BOOTS) {
|
||||
} else if (context.takeoff.what == WORN_BOOTS) {
|
||||
otmp = uarmf;
|
||||
} else if (taking_off == WORN_GLOVES) {
|
||||
} else if (context.takeoff.what == WORN_GLOVES) {
|
||||
otmp = uarmg;
|
||||
} else if (taking_off == WORN_HELMET) {
|
||||
} else if (context.takeoff.what == WORN_HELMET) {
|
||||
otmp = uarmh;
|
||||
} else if (taking_off == WORN_SHIELD) {
|
||||
} else if (context.takeoff.what == WORN_SHIELD) {
|
||||
otmp = uarms;
|
||||
#ifdef TOURIST
|
||||
} else if (taking_off == WORN_SHIRT) {
|
||||
} else if (context.takeoff.what == WORN_SHIRT) {
|
||||
otmp = uarmu;
|
||||
/* add the time to take off and put back on armor and/or cloak */
|
||||
if (uarm) todelay += 2 * objects[uarm->otyp].oc_delay;
|
||||
if (uarmc) todelay += 2 * objects[uarmc->otyp].oc_delay + 1;
|
||||
if (uarm) context.takeoff.delay += 2 * objects[uarm->otyp].oc_delay;
|
||||
if (uarmc) context.takeoff.delay += 2 * objects[uarmc->otyp].oc_delay + 1;
|
||||
#endif
|
||||
} else if (taking_off == WORN_AMUL) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == LEFT_RING) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == RIGHT_RING) {
|
||||
todelay = 1;
|
||||
} else if (taking_off == WORN_BLINDF) {
|
||||
todelay = 2;
|
||||
} else if (context.takeoff.what == WORN_AMUL) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == LEFT_RING) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == RIGHT_RING) {
|
||||
context.takeoff.delay = 1;
|
||||
} else if (context.takeoff.what == WORN_BLINDF) {
|
||||
context.takeoff.delay = 2;
|
||||
} else {
|
||||
impossible("take_off: taking off %lx", taking_off);
|
||||
impossible("take_off: taking off %lx", context.takeoff.what);
|
||||
return 0; /* force done */
|
||||
}
|
||||
|
||||
if (otmp) todelay += objects[otmp->otyp].oc_delay;
|
||||
if (otmp) context.takeoff.delay += objects[otmp->otyp].oc_delay;
|
||||
|
||||
/* Since setting the occupation now starts the counter next move, that
|
||||
* would always produce a delay 1 too big per item unless we subtract
|
||||
* 1 here to account for it.
|
||||
*/
|
||||
if (todelay>0) todelay--;
|
||||
if (context.takeoff.delay>0) context.takeoff.delay--;
|
||||
|
||||
set_occupation(take_off, disrobing, 0);
|
||||
set_occupation(take_off,
|
||||
(context.takeoff.disrobing[0]) ?
|
||||
context.takeoff.disrobing : (char *)0, 0);
|
||||
return(1); /* get busy */
|
||||
}
|
||||
|
||||
void
|
||||
reset_remarm()
|
||||
{
|
||||
taking_off = takeoff_mask = 0L;
|
||||
disrobing = nul;
|
||||
context.takeoff.what = context.takeoff.mask = 0L;
|
||||
context.takeoff.disrobing[0] = '\0';
|
||||
}
|
||||
|
||||
/* the 'A' command */
|
||||
@@ -1934,9 +1928,9 @@ doddoremarm()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (taking_off || takeoff_mask) {
|
||||
You("continue %s.", disrobing);
|
||||
set_occupation(take_off, disrobing, 0);
|
||||
if (context.takeoff.what || context.takeoff.mask) {
|
||||
You("continue %s.", context.takeoff.disrobing);
|
||||
set_occupation(take_off, context.takeoff.disrobing, 0);
|
||||
(void) take_off();
|
||||
return 0;
|
||||
} else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf &&
|
||||
@@ -1950,13 +1944,13 @@ doddoremarm()
|
||||
(result = ggetobj("take off", select_off, 0, FALSE, (unsigned *)0)) < -1)
|
||||
result = menu_remarm(result);
|
||||
|
||||
if (takeoff_mask) {
|
||||
if (context.takeoff.mask) {
|
||||
/* default activity for armor and/or accessories,
|
||||
possibly combined with weapons */
|
||||
disrobing = "disrobing";
|
||||
(void)strncpy(context.takeoff.disrobing, "disrobing", CONTEXTVERBSZ);
|
||||
/* specific activity when handling weapons only */
|
||||
if (!(takeoff_mask & ~(W_WEP|W_SWAPWEP|W_QUIVER)))
|
||||
disrobing = "disarming";
|
||||
if (!(context.takeoff.mask & ~(W_WEP|W_SWAPWEP|W_QUIVER)))
|
||||
(void)strncpy(context.takeoff.disrobing, "disarming", CONTEXTVERBSZ);
|
||||
(void) take_off();
|
||||
}
|
||||
/* The time to perform the command is already completely accounted for
|
||||
|
||||
@@ -351,6 +351,8 @@ do_reset_eat()
|
||||
if (context.victual.piece) {
|
||||
context.victual.o_id = 0;
|
||||
context.victual.piece = touchfood(context.victual.piece);
|
||||
if (context.victual.piece)
|
||||
context.victual.o_id = context.victual.piece->o_id;
|
||||
recalc_wt();
|
||||
}
|
||||
context.victual.fullwarn = context.victual.eating = context.victual.doreset = FALSE;
|
||||
@@ -1147,7 +1149,8 @@ no_opener:
|
||||
context.tin.reqtime = tmp;
|
||||
context.tin.usedtime = 0;
|
||||
context.tin.tin = otmp;
|
||||
if (otmp) context.tin.o_id = otmp->o_id;
|
||||
if (context.tin.tin)
|
||||
context.tin.o_id = context.tin.tin->o_id;
|
||||
set_occupation(opentin, "opening the tin", 0);
|
||||
return;
|
||||
}
|
||||
@@ -1955,6 +1958,7 @@ doeat() /* generic "eat" command funtion (see cmd.c) */
|
||||
* they shouldn't be able to choke now.
|
||||
*/
|
||||
if (u.uhs != SATIATED) context.victual.canchoke = FALSE;
|
||||
context.victual.o_id = 0;
|
||||
context.victual.piece = touchfood(otmp);
|
||||
if (context.victual.piece)
|
||||
context.victual.o_id = context.victual.piece->o_id;
|
||||
@@ -1974,6 +1978,7 @@ doeat() /* generic "eat" command funtion (see cmd.c) */
|
||||
/* KMH, conduct */
|
||||
u.uconduct.food++;
|
||||
|
||||
context.victual.o_id = 0;
|
||||
context.victual.piece = otmp = touchfood(otmp);
|
||||
if (context.victual.piece)
|
||||
context.victual.o_id = context.victual.piece->o_id;
|
||||
|
||||
@@ -235,10 +235,12 @@ boolean ghostly, frozen;
|
||||
if (otmp->bypass) otmp->bypass = 0;
|
||||
if (!ghostly) {
|
||||
/* fix the pointers */
|
||||
if (context.victual.o_id == otmp->o_id)
|
||||
if (otmp->o_id == context.victual.o_id)
|
||||
context.victual.piece = otmp;
|
||||
if (context.tin.o_id == otmp->o_id)
|
||||
if (otmp->o_id == context.tin.o_id)
|
||||
context.tin.tin = otmp;
|
||||
if (otmp->o_id == context.spbook.o_id)
|
||||
context.spbook.book = otmp;
|
||||
}
|
||||
otmp2 = otmp;
|
||||
}
|
||||
|
||||
19
src/save.c
19
src/save.c
@@ -877,17 +877,34 @@ register struct obj *otmp;
|
||||
saveobjchn(fd,otmp->cobj,mode);
|
||||
if (release_data(mode)) {
|
||||
/* if (otmp->oclass == FOOD_CLASS) food_disappears(otmp); */
|
||||
/*
|
||||
* If these are on the floor, the discarding could
|
||||
* be because of a game save, or we could just be changing levels.
|
||||
* Always invalidate the pointer, but ensure that we have
|
||||
* the o_id in order to restore the pointer on reload.
|
||||
*/
|
||||
if (otmp == context.victual.piece) {
|
||||
/* Store the o_id of the victual if mismatched */
|
||||
if (context.victual.o_id != otmp->o_id)
|
||||
context.victual.o_id = otmp->o_id;
|
||||
/* invalidate the pointer; on reload it will get restored */
|
||||
context.victual.piece = (struct obj *)0;
|
||||
}
|
||||
if (otmp == context.tin.tin) {
|
||||
/* Store the o_id of your tin */
|
||||
if (context.tin.o_id != otmp->o_id)
|
||||
context.tin.o_id = otmp->o_id;
|
||||
/* invalidate the pointer; on reload it will get restored */
|
||||
context.tin.tin = (struct obj *)0;
|
||||
}
|
||||
/* if (otmp->oclass == SPBOOK_CLASS) book_disappears(otmp); */
|
||||
if (otmp == context.spbook.book) {
|
||||
/* Store the o_id of your spellbook */
|
||||
if (context.spbook.o_id != otmp->o_id)
|
||||
context.spbook.o_id = otmp->o_id;
|
||||
/* invalidate the pointer; on reload it will get restored */
|
||||
context.spbook.book = (struct obj *)0;
|
||||
}
|
||||
if (otmp->oclass == SPBOOK_CLASS) book_disappears(otmp);
|
||||
otmp->where = OBJ_FREE; /* set to free so dealloc will work */
|
||||
otmp->timed = 0; /* not timed any more */
|
||||
otmp->lamplit = 0; /* caller handled lights */
|
||||
|
||||
84
src/spell.c
84
src/spell.c
@@ -4,9 +4,6 @@
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
static NEARDATA schar delay; /* moves left for this spell */
|
||||
static NEARDATA struct obj *book; /* last/current book being xscribed */
|
||||
|
||||
/* spellmenu arguments; 0 thru n-1 used as spl_book[] index when swapping */
|
||||
#define SPELLMENU_CAST (-2)
|
||||
#define SPELLMENU_VIEW (-1)
|
||||
@@ -194,7 +191,7 @@ struct obj *spellbook;
|
||||
gone = TRUE;
|
||||
} else {
|
||||
You("find yourself reading the %s line over and over again.",
|
||||
spellbook == book ? "next" : "first");
|
||||
spellbook == context.spbook.book ? "next" : "first");
|
||||
}
|
||||
return gone;
|
||||
}
|
||||
@@ -321,22 +318,23 @@ learn()
|
||||
boolean costly = TRUE;
|
||||
|
||||
/* JDS: lenses give 50% faster reading; 33% smaller read time */
|
||||
if (delay && ublindf && ublindf->otyp == LENSES && rn2(2)) delay++;
|
||||
if (context.spbook.delay && ublindf && ublindf->otyp == LENSES && rn2(2)) context.spbook.delay++;
|
||||
if (Confusion) { /* became confused while learning */
|
||||
(void) confused_book(book);
|
||||
book = 0; /* no longer studying */
|
||||
nomul(delay); /* remaining delay is uninterrupted */
|
||||
delay = 0;
|
||||
(void) confused_book(context.spbook.book);
|
||||
context.spbook.book = 0; /* no longer studying */
|
||||
context.spbook.o_id = 0;
|
||||
nomul(context.spbook.delay); /* remaining delay is uninterrupted */
|
||||
context.spbook.delay = 0;
|
||||
return(0);
|
||||
}
|
||||
if (delay) { /* not if (delay++), so at end delay == 0 */
|
||||
delay++;
|
||||
if (context.spbook.delay) { /* not if (context.spbook.delay++), so at end delay == 0 */
|
||||
context.spbook.delay++;
|
||||
return(1); /* still busy */
|
||||
}
|
||||
exercise(A_WIS, TRUE); /* you're studying. */
|
||||
booktype = book->otyp;
|
||||
booktype = context.spbook.book->otyp;
|
||||
if(booktype == SPE_BOOK_OF_THE_DEAD) {
|
||||
deadbook(book);
|
||||
deadbook(context.spbook.book);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -345,13 +343,13 @@ learn()
|
||||
OBJ_NAME(objects[booktype]));
|
||||
for (i = 0; i < MAXSPELL; i++) {
|
||||
if (spellid(i) == booktype) {
|
||||
if (book->spestudied > MAX_SPELL_STUDY) {
|
||||
if (context.spbook.book->spestudied > MAX_SPELL_STUDY) {
|
||||
pline("This spellbook is too faint to be read any more.");
|
||||
book->otyp = booktype = SPE_BLANK_PAPER;
|
||||
context.spbook.book->otyp = booktype = SPE_BLANK_PAPER;
|
||||
} else if (spellknow(i) <= 1000) {
|
||||
Your("knowledge of %s is keener.", splname);
|
||||
incrnknow(i);
|
||||
book->spestudied++;
|
||||
context.spbook.book->spestudied++;
|
||||
exercise(A_WIS,TRUE); /* extra study */
|
||||
} else { /* 1000 < spellknow(i) <= MAX_SPELL_STUDY */
|
||||
You("know %s quite well already.", splname);
|
||||
@@ -365,7 +363,7 @@ learn()
|
||||
spl_book[i].sp_id = booktype;
|
||||
spl_book[i].sp_lev = objects[booktype].oc_level;
|
||||
incrnknow(i);
|
||||
book->spestudied++;
|
||||
context.spbook.book->spestudied++;
|
||||
You(i > 0 ? "add %s to your repertoire." : "learn %s.",
|
||||
splname);
|
||||
makeknown((int)booktype);
|
||||
@@ -374,15 +372,17 @@ learn()
|
||||
}
|
||||
if (i == MAXSPELL) impossible("Too many spells memorized!");
|
||||
|
||||
if (book->cursed) { /* maybe a demon cursed it */
|
||||
if (cursed_book(book)) {
|
||||
useup(book);
|
||||
book = 0;
|
||||
if (context.spbook.book->cursed) { /* maybe a demon cursed it */
|
||||
if (cursed_book(context.spbook.book)) {
|
||||
useup(context.spbook.book);
|
||||
context.spbook.book = 0;
|
||||
context.spbook.o_id = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (costly) check_unpaid(book);
|
||||
book = 0;
|
||||
if (costly) check_unpaid(context.spbook.book);
|
||||
context.spbook.book = 0;
|
||||
context.spbook.o_id = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -394,9 +394,9 @@ register struct obj *spellbook;
|
||||
register boolean confused = (Confusion != 0);
|
||||
boolean too_hard = FALSE;
|
||||
|
||||
if (delay && !confused && spellbook == book &&
|
||||
if (context.spbook.delay && !confused && spellbook == context.spbook.book &&
|
||||
/* handle the sequence: start reading, get interrupted,
|
||||
have book become erased somehow, resume reading it */
|
||||
have context.spbook.book become erased somehow, resume reading it */
|
||||
booktype != SPE_BLANK_PAPER) {
|
||||
You("continue your efforts to memorize the spell.");
|
||||
} else {
|
||||
@@ -409,20 +409,20 @@ register struct obj *spellbook;
|
||||
switch (objects[booktype].oc_level) {
|
||||
case 1:
|
||||
case 2:
|
||||
delay = -objects[booktype].oc_delay;
|
||||
context.spbook.delay = -objects[booktype].oc_delay;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
delay = -(objects[booktype].oc_level - 1) *
|
||||
context.spbook.delay = -(objects[booktype].oc_level - 1) *
|
||||
objects[booktype].oc_delay;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
delay = -objects[booktype].oc_level *
|
||||
context.spbook.delay = -objects[booktype].oc_level *
|
||||
objects[booktype].oc_delay;
|
||||
break;
|
||||
case 7:
|
||||
delay = -8 * objects[booktype].oc_delay;
|
||||
context.spbook.delay = -8 * objects[booktype].oc_delay;
|
||||
break;
|
||||
default:
|
||||
impossible("Unknown spellbook level %d, book %d;",
|
||||
@@ -463,8 +463,8 @@ register struct obj *spellbook;
|
||||
if (too_hard) {
|
||||
boolean gone = cursed_book(spellbook);
|
||||
|
||||
nomul(delay); /* study time */
|
||||
delay = 0;
|
||||
nomul(context.spbook.delay); /* study time */
|
||||
context.spbook.delay = 0;
|
||||
if(gone || !rn2(3)) {
|
||||
if (!gone) pline_The("spellbook crumbles to dust!");
|
||||
if (!objects[spellbook->otyp].oc_name_known &&
|
||||
@@ -478,8 +478,8 @@ register struct obj *spellbook;
|
||||
if (!confused_book(spellbook)) {
|
||||
spellbook->in_use = FALSE;
|
||||
}
|
||||
nomul(delay);
|
||||
delay = 0;
|
||||
nomul(context.spbook.delay);
|
||||
context.spbook.delay = 0;
|
||||
return(1);
|
||||
}
|
||||
spellbook->in_use = FALSE;
|
||||
@@ -489,7 +489,9 @@ register struct obj *spellbook;
|
||||
"memorize");
|
||||
}
|
||||
|
||||
book = spellbook;
|
||||
context.spbook.book = spellbook;
|
||||
if (context.spbook.book)
|
||||
context.spbook.o_id = context.spbook.book->o_id;
|
||||
set_occupation(learn, "studying", 0);
|
||||
return(1);
|
||||
}
|
||||
@@ -500,7 +502,10 @@ void
|
||||
book_disappears(obj)
|
||||
struct obj *obj;
|
||||
{
|
||||
if (obj == book) book = (struct obj *)0;
|
||||
if (obj == context.spbook.book) {
|
||||
context.spbook.book = (struct obj *)0;
|
||||
context.spbook.o_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* renaming an object usually results in it having a different address;
|
||||
@@ -510,7 +515,11 @@ void
|
||||
book_substitution(old_obj, new_obj)
|
||||
struct obj *old_obj, *new_obj;
|
||||
{
|
||||
if (old_obj == book) book = new_obj;
|
||||
if (old_obj == context.spbook.book) {
|
||||
context.spbook.book = new_obj;
|
||||
if (context.spbook.book)
|
||||
context.spbook.o_id = context.spbook.book->o_id;
|
||||
}
|
||||
}
|
||||
|
||||
/* called from moveloop() */
|
||||
@@ -1005,7 +1014,8 @@ losespells()
|
||||
boolean confused = (Confusion != 0);
|
||||
int n, nzap, i;
|
||||
|
||||
book = 0;
|
||||
context.spbook.book = 0;
|
||||
context.spbook.o_id = 0;
|
||||
for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++)
|
||||
continue;
|
||||
if (n) {
|
||||
|
||||
Reference in New Issue
Block a user