From 07de17d747d5e4e0ad31e020e098fa6094a21764 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Jun 2024 12:57:31 -0700 Subject: [PATCH 001/121] obj->where == OBJ_DELETED The list of possible object locations used when formatting obj->where wasn't updated when the objs_deleted list was introduced. If object sanity checking ever tried to report it for something, it would have been described as "unknown[9]" rather than as the intended "deleted". --- include/obj.h | 4 +++- src/mkobj.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/obj.h b/include/obj.h index 08d11dcf8..b1e95091b 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 obj.h $NHDT-Date: 1633802062 2021/10/09 17:54:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.94 $ */ +/* NetHack 3.7 obj.h $NHDT-Date: 1718999845 2024/06/21 19:57:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -82,6 +82,8 @@ struct obj { #define OBJ_ONBILL 7 /* object on shk bill */ #define OBJ_LUAFREE 8 /* object has been dealloc'd, but is ref'd by lua */ #define OBJ_DELETED 9 /* object is marked for deletion by dobjsfree() */ + /* note: OBJ_xxx values are used in obj_state_names[] in mkobj.c + so adding, removing, or renumbering these needs to change that too */ #define NOBJ_STATES 10 xint16 timed; /* # of fuses (timers) attached to this obj */ diff --git a/src/mkobj.c b/src/mkobj.c index d289dd0fe..4b73775c1 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1715109575 2024/05/07 19:19:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1718999849 2024/06/21 19:57:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3185,7 +3185,7 @@ nomerge_exception(struct obj *obj) static const char *const obj_state_names[NOBJ_STATES] = { "free", "floor", "contained", "invent", "minvent", "migrating", "buried", "onbill", - "luafree" + "luafree", "deleted", }; staticfn const char * From d5d646a9e9952e732854477d1278c91cd02fab27 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Jun 2024 13:32:21 -0700 Subject: [PATCH 002/121] ancient comment typo/thinko Change "it gets size gets reduced" to "its size gets reduced". This was present in 3.4.3, doubtless even ealier. --- src/mkobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkobj.c b/src/mkobj.c index 4b73775c1..4b2b51894 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -447,7 +447,7 @@ copy_oextra(struct obj *obj2, struct obj *obj1) } /* - * Split obj so that it gets size gets reduced by num. The quantity num is + * Split stack so that its size gets reduced by num. The quantity num is * put in the object structure delivered by this call. The returned object * has its wornmask cleared and is positioned just following the original * in the nobj chain (and nexthere chain when on the floor). From bf1e3d3e561f22b051cb8cc9a5a1a0dd6d0e6e96 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Jun 2024 14:26:48 -0700 Subject: [PATCH 003/121] more obj->where == OBJ_DELETED --- src/mkobj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mkobj.c b/src/mkobj.c index 4b2b51894..93f762c26 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2459,7 +2459,8 @@ discard_minvent(struct monst *mtmp, boolean uncreate_artifacts) /* * Free obj from whatever list it is on in preparation for deleting it - * or moving it elsewhere; obj->where will end up set to OBJ_FREE. + * or moving it elsewhere; obj->where will end up set to OBJ_FREE unless + * it is already OBJ_LUAFREE or OBJ_DELETED. * Doesn't handle unwearing of objects in hero's or monsters' inventories. * * Object positions: @@ -2472,6 +2473,7 @@ discard_minvent(struct monst *mtmp, boolean uncreate_artifacts) * OBJ_BURIED level.buriedobjs chain * OBJ_ONBILL on gb.billobjs chain * OBJ_LUAFREE obj is dealloc'd from core, but still used by lua + * OBJ_DELETED obj has been deleted from play but not yet deallocated */ void obj_extract_self(struct obj *obj) From 54138bbbe3837c304530e7c14de88975d0471dad Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Jun 2024 15:32:46 -0700 Subject: [PATCH 004/121] 'Ix' fix This took me a while to track down. I noticed it while drinking unpaid potions but didn't expect the issue to be potion-specific. Affects paying shop bill in addition to examining [former] inventory. Start with a stack of 3 unpaid potions. Iu a - 3 potions of healing (unpaid) Ix no used up items Drink one. qa Iu a - 2 potions of healing (unpaid) Ix x - potion of healing So, far everything's normal. Note that 'x' is an arbitrary letter used for expended items when shown in inventory style rather than an inventory letter or menu choice. Drink another. qa Iu a - a potion of healing (unpaid) Ix x - potion of healing x - potion of healing Drink the last one. qa Iu no unpaid items Ix x - potion of healing x - potion of healing x - potion of healing In 3.4.3, these last two Ix cases would have had single lines of 'x - 2 potions of healing' and 'x - 3 potions of healing', respectively. After this fix, they will again--unless potion stack 'a' was wielded, readied as alt-weapon, or quivered. --- doc/fixes3-7-0.txt | 4 ++++ src/potion.c | 36 +++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 23782811f..f8a776ba8 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1422,6 +1422,10 @@ if hero is on scroll of scare monster or Elbereth, werecreature switching from "n ESC c" wasn't treated as "n M-c" because reading the 'n' changed program_state.input_state from commandInp to otherInp, preventing special ESC handling; not an issue when number_pad was Off +a 3.6 fix to avoid a potential "object lost" panic when drinking potions had + unintended side-effect of making used up potions on shop's bill become + separate bill entries all with count 1 despite having come from same + unpaid stack; affected Ix inventory listing and itemized shop billing Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/potion.c b/src/potion.c index d97f274a9..5274e904d 100644 --- a/src/potion.c +++ b/src/potion.c @@ -570,19 +570,29 @@ dodrink(void) if (!otmp) return ECMD_CANCEL; - /* quan > 1 used to be left to useup(), but we need to force - the current potion to be unworn, and don't want to do - that for the entire stack when starting with more than 1. - [Drinking a wielded potion of polymorph can trigger a shape - change which causes hero's weapon to be dropped. In 3.4.x, - that led to an "object lost" panic since subsequent useup() - was no longer dealing with an inventory item. Unwearing - the current potion is intended to keep it in inventory.] */ - if (otmp->quan > 1L) { - otmp = splitobj(otmp, 1L); - otmp->owornmask = 0L; /* rest of original stuck unaffected */ - } else if (otmp->owornmask) { - remove_worn_item(otmp, FALSE); + /* + * 3.6: quan > 1 used to be left to useup(), but we need to + * force the current potion to be unworn, and don't want to do + * that for the entire stack when starting with more than 1. + * [Drinking a wielded potion of polymorph can trigger a shape + * change which causes hero's weapon to be dropped. In 3.4.x, + * that led to an "object lost" panic since subsequent useup() + * was no longer dealing with an inventory item. Unwearing + * the current potion is intended to keep it in inventory.] + * + * 3.7: switch back to relying on useup() unless the object is + * actually worn. Otherwise drinking a stack of unpaid potions + * one by one in a shop makes each one a separate used-up item + * for 'Ix' invent display and for itemized shop billing instead + * of having a single stack with quantity greater than 1. + */ + if (otmp->owornmask) { + if (otmp->quan > 1L) { + otmp = splitobj(otmp, 1L); + otmp->owornmask = 0L; /* rest of original stack is unaffected */ + } else { + remove_worn_item(otmp, FALSE); + } } otmp->in_use = TRUE; /* you've opened the stopper */ From 238d501ccee9f636429df8b051ef6d5ec02d6750 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 21 Jun 2024 22:52:13 +0300 Subject: [PATCH 005/121] win/curses: Check input range in menu selection fallthrough curletter is screened to be in valid range in all other switch/case branches except in the default case, which is fallthrough. Add check for valid range in here also, otherwise array might be addressed with invalid offset. This should fix the following, found with UBSAN and #debugfuzzer: ../win/curses/cursdial.c:1558:49: runtime error: index -154 out of bounds for type 'char [256]' 0x5f3857eff140 in menu_get_selections ../win/curses/cursdial.c:1558 0x5f3857ef78c8 in curses_display_nhmenu ../win/curses/cursdial.c:801 0x5f3857edd390 in curses_select_menu ../win/curses/cursmain.c:768 --- win/curses/cursdial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index f93707463..021d89e15 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1555,7 +1555,8 @@ menu_get_selections(WINDOW *win, nhmenu *menu, int how) } /*FALLTHRU*/ default: - if (isdigit(curletter) && !selectors[curletter] + if (curletter > 0 && curletter < 256 + && isdigit(curletter) && !selectors[curletter] && !groupaccels[curletter]) { count = curses_get_count(curletter); /* after count, we know some non-digit is already pending */ From 70d0bc25f852ef0d2e8507471568188c10a6fe09 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sun, 23 Jun 2024 13:04:28 -0400 Subject: [PATCH 006/121] fetch-lua bits Add a local copy of the lua source file. Re-organize the sh code to avoid duplication and add (a little) clarity. --- sys/unix/Makefile.top | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 957bfe81e..af547ccf5 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -322,6 +322,7 @@ dofiles-nodlb: LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp +LUA_URL_NHD :=www.nethack.org/download/thirdparty fetch-lua-mirror: LUA_URL :=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @@ -331,36 +332,33 @@ fetch-lua: fetch-Lua @true fetch-Lua: - @( mkdir -p lib && cd lib && \ - n=0; \ + @( \ + shac1=`command -v shasum`; \ + shac2=`command -v sha256sum`; \ + if [ ! -z $$shac1 ]; then \ + shac="$$shac1 -a 256"; elif [ ! -z $$shac2 ]; then \ + shac=$$shac2; else echo "CAUTION: no way to check integrity"; \ + fi; \ + set -- DUMMY $(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD); \ + luafile=lua-$(LUA_VERSION).tar.gz; \ export curlstatus=1; \ - while [ $${n} -lt 2 ]; do \ + mkdir -p lib && cd lib && \ + while [ $$# -gt 0 ]; do \ + shift; \ if [ $$curlstatus -ne 0 ]; then \ - if [ $${n} -eq 0 ]; then \ - luaurl=https://$(LUA_URL)/lua-$(LUA_VERSION).tar.gz; \ - fi; \ - if [ $${n} -eq 1 ]; then \ - luaurl=https://$(LUA_URL_MIRROR)/lua-$(LUA_VERSION).tar.gz; \ - fi; \ + luaurl=https://$$1/$$luafile; \ echo trying $$luaurl; \ - shac1=`command -v shasum`; \ - shac2=`command -v sha256sum`; \ - if [ ! -z $$shac1 ]; then \ - shac="$$shac1 -a 256"; elif [ ! -z $$shac2 ]; then \ - shac=$$shac2; else echo "CAUTION: no way to check integrity"; \ - fi; \ curl -R -O $$luaurl; \ - export curlstatus=$$?; \ + curlstatus=$$?; \ if [ $$curlstatus -eq 0 ]; then \ if [ ! -z "$$shac" ]; then \ echo Checking integrity with $$shac; \ - $$shac -w -c ../submodules/CHKSUMS < lua-$(LUA_VERSION).tar.gz; \ + $$shac -w -c ../submodules/CHKSUMS < $$luafile; \ fi; \ - tar zxf lua-$(LUA_VERSION).tar.gz && \ - rm -f lua-$(LUA_VERSION).tar.gz; \ + tar zxf $$luafile && \ + rm -f $$luafile; \ fi; \ fi; \ - n=`expr $$n + 1`; \ done; \ true ) From 2674a9904db83cdae509ef46383ab2d2485ff36d Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 27 Jun 2024 14:13:39 -0700 Subject: [PATCH 007/121] github issue #1249 - menu pay of contained items Issue reported by ars3niy: unpaid containers containing one or more other unpaid items appear on the menu for 'p' along with separate menu entries for those other items. Buying the container buys the contents too, then if any of the contents were also picked in the menu, an attempt will be made to pay for them separately. Since they are no longer on the bill by that point, that triggers an impossible warning. This fixes that by paying for the container but not its contents. (Temporarily, until more extensive changes get implemented.) Then those contents will still be on the bill. It they've been chosen in the 'p' menu, paying for them will work as expected. This also fixes the pay menu for the case where the bill contains any instances of a partly used up portion of some stack and also the unpaid intact portion of the same stack. With itemized billing, you are allowed to buy the used up portion separately, then maybe drop the unpaid portion. (If you try to pay for the intact portion, the shk won't accept the payment and will tell you to pay for the used up portion first.) With the recently added menu for billing, they were lumped together as a single item and you had to pay for their whole stack. And it fixes a much older bug dealing with the cheapest item on the shop bill. If you don't have enough to pay for that, the rest of buying gets skipped. But stacks that had used up and intact portions were lumping those together instead of separately checking the two portions for possibly being the cheapest, so it was possible to have enough gold to pay for one portion but be told that you couldn't affort to pay for anything. If it was the intact portion, you wouldn't be able to buy it anyway, but if the cheapest item was used up portion, being told you didn't have enough gold was wrong. This commit does not fix the longstanding bug that itemized billing reveals the contents of containers which haven't been opened. It was intended to do so but I've run out of steam. (There is groundwork for that, where buying a container would include payment for its unpaid contents without revealing what those are, and they couldn't be purchased separately unless they get taken out of the container. Uncommenting '#define CONTAINED_BUYING' will enable it, with updated pay menu handling but without being able to pay for non-empty containers.) Fixes #1249 --- include/extern.h | 1 + src/objnam.c | 37 +-- src/shk.c | 644 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 501 insertions(+), 181 deletions(-) diff --git a/include/extern.h b/include/extern.h index 5391be599..7da52c591 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2153,6 +2153,7 @@ extern char *Tobjnam(struct obj *, const char *) NONNULL NONNULLARG1; extern char *otense(struct obj *, const char *) NONNULL NONNULLARG12; extern char *vtense(const char *, const char *) NONNULL NONNULLARG2; extern char *Doname2(struct obj *) NONNULL NONNULLARG1; +extern char *paydoname(struct obj *) NONNULL NONNULLARG1; extern char *yname(struct obj *) NONNULL NONNULLARG1; extern char *Yname2(struct obj *) NONNULL NONNULLARG1; extern char *ysimple_name(struct obj *) NONNULL NONNULLARG1; diff --git a/src/objnam.c b/src/objnam.c index 7713a5dad..96fd36e81 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -2273,28 +2273,37 @@ Doname2(struct obj *obj) return s; } -#if 0 /* stalled-out work in progress */ -/* Doname2() for itemized buying of 'obj' from a shop */ +/* doname() for itemized buying of 'obj' from a shop */ char * -payDoname(struct obj *obj) +paydoname(struct obj *obj) { static const char and_contents[] = " and its contents"; - char *p = doname(obj); + char *p; - if (Is_container(obj) && !obj->cknown) { - if (obj->unpaid) { - if ((int) strlen(p) + sizeof and_contents - 1 < BUFSZ - PREFIX) - Strcat(p, and_contents); - *p = highc(*p); - } else { - p = strprepend(p, "Contents of "); + /* suppress invent-style price; caller will add billing-style price */ + iflags.suppress_price++; + p = doname_base(obj, 0U); + iflags.suppress_price--; + + if (Has_contents(obj)) { + if (!strncmp(p, "a ", 2)) + p += 2; + else if (!strncmp(p, "an ", 3)) + p += 3; + p = strprepend(p, obj->unpaid ? "an unpaid " : "your "); + + if (!obj->cknown) { + if (obj->unpaid) { + if ((int) strlen(p) + sizeof and_contents - 1 + < BUFSZ - PREFIX) + Strcat(p, and_contents); + } else { + p = strprepend(p, "contents of "); + } } - } else { - *p = highc(*p); } return p; } -#endif /*0*/ /* returns "[your ]xname(obj)" or "Foobar's xname(obj)" or "the xname(obj)" */ char * diff --git a/src/shk.c b/src/shk.c index c78f045e6..ec52bb633 100644 --- a/src/shk.c +++ b/src/shk.c @@ -5,12 +5,40 @@ #include "hack.h" +/* CONTAINED_BUYING: for itemized billing (including default menu for + 'p'), unpaid items in containers are concealed from itemized billing; + there's a single price for the container and all its contents; + player must pay all-or-nothing for such, and all used up items have + to already be paid for */ +/*#define CONTAINED_BUYING*/ /**** not fully implemented yet ****/ + #define PAY_SOME 2 #define PAY_BUY 1 #define PAY_CANT 0 /* too poor */ #define PAY_SKIP (-1) #define PAY_BROKE (-2) +enum billitem_status { + FullyUsedUp = 1, /* completely used up; obj->where==OBJ_ONBILL */ + PartlyUsedUp = 2, /* partly used up; obj->where==OBJ_INVENT or similar */ + PartlyIntact = 3, /* intact portion of partly used up item */ + FullyIntact = 4, /* normal unpaid item */ + BillContainer = 5, /* container holding unpaid item(s) */ +}; +/* this is similar to sortloot; the shop bill gets converted into a array of + struct sortbill_item so that sorting and traversal don't need to access + the original bill or even the shk; the array gets sorted by usedup vs + unpaid and by cost within each of those two categories */ +struct sortbill_item { + struct obj *obj; + long cost; + long quan; + int bidx; + int8 usedup; /* small but signed */ + boolean queuedpay; +}; +typedef struct sortbill_item Bill; + staticfn void makekops(coord *); staticfn void call_kops(struct monst *, boolean); staticfn void kops_gone(boolean); @@ -44,10 +72,17 @@ staticfn long get_cost(struct obj *, struct monst *); staticfn long set_cost(struct obj *, struct monst *); staticfn const char *shk_embellish(struct obj *, long); staticfn long cost_per_charge(struct monst *, struct obj *, boolean); -staticfn long cheapest_item(struct monst *); -staticfn int menu_pick_pay_items(struct monst *); + +staticfn int QSORTCALLBACK sortbill_cmp(const genericptr, const genericptr) + NONNULLPTRS; +staticfn long cheapest_item(int, Bill *) NONNULLPTRS; +staticfn int make_itemized_bill(struct monst *shkp, Bill **ibill) NONNULLPTRS; +staticfn int menu_pick_pay_items(int, Bill *) NONNULLPTRS; +staticfn boolean pay_billed_items(struct monst *, int, Bill *, boolean, + boolean *) NONNULLPTRS; staticfn int dopayobj(struct monst *, struct bill_x *, struct obj **, int, - boolean); + boolean); +staticfn void reject_purchase(struct monst *, struct obj *, long) NONNULLPTRS; staticfn long stolen_container(struct obj *, struct monst *, long, boolean); staticfn long corpsenm_price_adj(struct obj *); staticfn long getprice(struct obj *, boolean); @@ -1367,70 +1402,242 @@ static const char no_money[] = "Moreover, you%s have no gold.", not_enough_money[] = "Besides, you don't have enough to interest %s."; +/* if one item is used-up and the other isn't, the used-up one comes first; + otherwise, if their costs differ, the more expensive one comes first; + if costs are the same, use internal index as tie-breaker for stable sort */ +staticfn int QSORTCALLBACK +sortbill_cmp(const genericptr vptr1, const genericptr vptr2) +{ + const struct sortbill_item *sbi1 = (struct sortbill_item *) vptr1, + *sbi2 = (struct sortbill_item *) vptr2; + long cost1 = sbi1->cost, cost2 = sbi2->cost; + int bidx1 = sbi1->bidx, bidx2 = sbi2->bidx, + /* sort such that FullyUsedUp and PartlyUsedUp come before + PartlyIntact, FullyIntact, and BillContainer */ + used1 = sbi1->usedup <= PartlyUsedUp, /* 0=>unpaid, 1=>used */ + used2 = sbi2->usedup <= PartlyUsedUp; + + if (used1 != used2) + return (used2 - used1); /* bigger comes before smaller here */ + if (cost1 != cost2) + return (cost2 - cost1); /* bigger comes before smaller here too */ + /* index into eshkp->bill_p[] isn't unique (an item that is partly + used and partly intact will have two ibill[] entries indexing same + bill_p[] element) but duplicates won't reach here (used1 vs used2) */ + return (bidx1 - bidx2); +} + /* delivers the cheapest item on the list */ staticfn long -cheapest_item(struct monst *shkp) +cheapest_item(int ibillct, Bill *ibill) { - int ct = ESHK(shkp)->billct; - struct bill_x *bp = ESHK(shkp)->bill_p; - long gmin = (bp->price * bp->bquan); + int i; + long gmin = ibill[0].cost; - while (ct--) { - if (bp->price * bp->bquan < gmin) - gmin = bp->price * bp->bquan; - bp++; - } + /* + * 3.7: old version didn't determine cheapest item correctly if it + * was either the partly used or partly intact portion of a partially + * used stack. Rather than modify it to use bp_to_obj() in order to + * obtain quanities for every entry on eshkp->bill_p[], switch to + * ibill[] which has already split such items into separate entries. + */ + + for (i = 1; i < ibillct; ++i) + if (ibill[i].cost < gmin) + gmin = ibill[i].cost; return gmin; } +/* for itemized purchasing, create an alternate shop bill that hides + container contents */ +staticfn int /* returns number of entries */ +make_itemized_bill( + struct monst *shkp, + Bill **ibill_p) /* output, a 'sortloot array' */ +{ + static Bill zerosbi; /* Null sortbill item */ + Bill *ibill; + struct bill_x *bp; + struct obj *otmp; + struct eshk *eshkp = ESHK(shkp); + int i, n, ebillct = eshkp->billct; + int8 used; + long quan, cost; + + /* this overallocates unless there happens to be a used-up portion + and an intact potion for every object on the bill; doing it this + way avoids the need to look up every object on the bill an extra + time; (the +1 for a terminator isn't actually needed) */ + n = 2 * ebillct + 1; + ibill = *ibill_p = (Bill *) alloc(n * sizeof *ibill); + for (i = 0; i < n; ++i) + ibill[i] = zerosbi; + + n = 0; /* number of entries in ibill[]; won't necessary match ebillct */ + for (i = 0; i < ebillct; ++i) { + bp = &(eshkp->bill_p[i]); + bp->queuedpay = FALSE; + /* find the object on the bill */ + otmp = bp_to_obj(bp); + if (!otmp) { + impossible("Can't find shop bill entry for #%d", bp->bo_id); + continue; + } + + if (otmp->quan == 0L || otmp->where == OBJ_ONBILL) { + /* item is completely used up; restore quantity from when it + was first unpaid; otmp is on billobjs list where it can + only be seen via Ix and itemized billing while paying shk */ + otmp->quan = bp->bquan; + bp->useup = 1; /* (expected to be set already) */ + } else if (otmp->quan < bp->bquan) { + /* item is partly used up; we will create two entries in the + augmented bill: one for the used up part here, another for + the intact part (which might be inside a container if put in + after using part of a stack; used up part isn't) below */ + ibill[n].obj = otmp; + ibill[n].quan = bp->bquan - otmp->quan; + ibill[n].cost = (long) bp->price * ibill[n].quan; + ibill[n].bidx = i; /* duplicate index into eshkp->bill_p[] */ + ibill[n].usedup = PartlyUsedUp; /* for sorting */ + ++n; /* intact portion will be a separate entry, next */ + } + + if (otmp->where == OBJ_ONBILL) { + /* completely used up */ + quan = bp->bquan; + cost = (long) bp->price * quan; + used = FullyUsedUp; +#ifdef CONTAINED_BUYING + } else if (otmp->where == OBJ_CONTAINED || Has_contents(otmp)) { + int j; + struct obj *item = otmp; + + /* when it's in a container, put the container rather than the + specific object into ibill[]; find outermost container */ + while (otmp->where == OBJ_CONTAINED) + otmp = otmp->ocontainer; + /* this container might already be in ibill[] if it is unpaid + itself or if it holds more than one unpaid item and another + besides this one has already been processed; only include + first instance */ + for (j = 0; j < n; ++j) + if (otmp == ibill[j].obj) { + /* unpaid container might be on bill as FullyIntact */ + ibill[j].usedup = BillContainer; + break; + } + if (j < n) + continue; /* 'i' loop */ + /* include 1 container containing unpaid item(s) */ + quan = 1L; + cost = unpaid_cost(otmp, COST_CONTENTS); + /* an unpaid container without any unpaid contents is classified + as 'FullyIntact'; a container with unpaid contents will be + 'BillContainer' regardless of whether it is unpaid itself */ + used = (otmp == item) ? FullyIntact : BillContainer; +#endif + } else { + /* ordinary unpaid; when partly used, these are values for the + intact portion; might be an empty shop-owned container */ + quan = otmp->quan; + cost = (long) bp->price * quan; + used = (quan < bp->bquan) ? PartlyIntact : FullyIntact; + } + + ibill[n].obj = otmp; + ibill[n].quan = quan; + ibill[n].cost = cost; + ibill[n].bidx = i; + ibill[n].usedup = used; + ++n; + } + ibill[n].bidx = -1; /* end of list; not strictly needed */ + + /* ibill[0..n-1] contains data, ibill[n] has Null obj and -1 bidx */ + qsort((genericptr_t) ibill, n, sizeof *ibill, sortbill_cmp); + return n; +} + /* show items on your bill in a menu, and ask which to pay. returns the number of entries selected. */ staticfn int -menu_pick_pay_items(struct monst *shkp) +menu_pick_pay_items( + int ibillct, /* number of entries in ibill[] */ + Bill *ibill) /* all used up items, if any, precede all intact items */ { - struct eshk *eshkp = ESHK(shkp); + struct obj *otmp; winid win; anything any; menu_item *pick_list = (menu_item *) 0; - int i, j, n, clr = NO_COLOR; - char buf[BUFSZ]; + char *p, buf[BUFSZ]; + boolean save_wizweight; + long amt, largest_amt, save_quan; + int i, j, n, amt_width; any = cg.zeroany; win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - for (n = 0; n < eshkp->billct; n++) { - struct obj *otmp; - struct bill_x *bp = &(eshkp->bill_p[n]); + /* we go through ibill[] twice, first time to control price formatting + during the second */ + largest_amt = 0L; + for (i = 0; i < ibillct; ++i) + if (ibill[i].cost > largest_amt) + largest_amt = ibill[i].cost; + Sprintf(buf, "%ld", largest_amt); + amt_width = (int) strlen(buf); - bp->queuedpay = FALSE; - - /* find the object on one of the lists */ - if ((otmp = bp_to_obj(bp)) != 0) { - /* if completely used up, object quantity is stale; - restoring it to its original value here avoids - making the partly-used-up code more complicated */ - if (bp->useup) - otmp->quan = bp->bquan; - Snprintf(buf, sizeof buf, "%s%s", - bp->useup ? "(used up) " : "", - doname(otmp)); - any.a_int = n + 1; /* +1: avoid 0 */ - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, - MENU_ITEMFLAGS_NONE); - } + /* avoid showing item weights to unclutter billing a bit */ + save_wizweight = iflags.wizweight; + iflags.wizweight = FALSE; + /* show the "used up items" header if there are any used up items on + the bill, no matter whether there are also any intact items; + note: ibill[] has been sorted to hold used-up items first */ + if (ibill[0].usedup <= PartlyUsedUp) { + Sprintf(buf, "Used up item%s:", + (ibillct > 1 && ibill[1].usedup) ? "s" : ""); + add_menu_heading(win, buf); } + for (i = 0; i < ibillct; ++i) { + /* the "unpaid items" header is only shown if the "used up items" + one was shown before the first menu entry */ + if (i > 0 && (ibill[i - 1].usedup <= PartlyUsedUp) + && (ibill[i].usedup >= PartlyIntact)) { + Sprintf(buf, "Unpaid item%s:", (i < ibillct - 1) ? "s" : ""); + add_menu_heading(win, buf); + } + otmp = ibill[i].obj; + save_quan = otmp->quan; + otmp->quan = ibill[i].quan; /* in case it's partly used */ + p = paydoname(otmp); + otmp->quan = save_quan; + amt = ibill[i].cost; + /* this doesn't support hallucinatory currency because shopkeeper + isn't hallucinating; also, that would mess up the alignment */ + Snprintf(buf, sizeof buf, "%*ld Zm, %s", amt_width, amt, p); + any.a_int = i + 1; /* +1: avoid 0 */ + add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, + MENU_ITEMFLAGS_NONE); + } + iflags.wizweight = save_wizweight; end_menu(win, "Pay for which items?"); n = select_menu(win, PICK_ANY, &pick_list); destroy_nhwindow(win); for (j = 0; j < n; ++j) { + /* + * FIXME: + * The menu will accept a subset count for each entry but buying + * doesn't have any support for that. + */ i = pick_list[j].item.a_int - 1; /* -1: reverse +1 above */ - eshkp->bill_p[i].queuedpay = TRUE; + ibill[i].queuedpay = TRUE; } free(pick_list); - return n; + /* for ESC, return 0 instead of usual -1 */ + return max(n, 0); } /* the #pay command */ @@ -1440,9 +1647,10 @@ dopay(void) struct eshk *eshkp; struct monst *shkp; struct monst *nxtm, *resident; + Bill *ibill = (Bill *) NULL; long ltmp; long umoney; - int pass, tmp, sk = 0, seensk = 0, nexttosk = 0; + int sk = 0, seensk = 0, nexttosk = 0; boolean paid = FALSE, stashed_gold = (hidden_gold(TRUE) > 0L); gm.multi = 0; @@ -1560,9 +1768,9 @@ dopay(void) if (shkp != resident && NOTANGRY(shkp)) { umoney = money_cnt(gi.invent); - if (!ltmp) + if (!ltmp) { You("do not owe %s anything.", shkname(shkp)); - else if (!umoney) { + } else if (!umoney) { You("%shave no gold.", stashed_gold ? "seem to " : ""); if (stashed_gold) pline("But you have some gold stashed away."); @@ -1655,8 +1863,9 @@ dopay(void) else Strcat(sbuf, "for gold picked up and the use of merchandise."); - } else + } else { Strcat(sbuf, "for the use of merchandise."); + } pline1(sbuf); if (umoney + eshkp->credit < dtmp) { pline("But you don't%s have enough gold%s.", @@ -1688,114 +1897,15 @@ dopay(void) paid = TRUE; } } + /* now check items on bill */ if (eshkp->billct) { - boolean itemize; - boolean queuedpay = FALSE, via_menu; - int iprompt; + int ibillct = make_itemized_bill(shkp, &ibill); - umoney = money_cnt(gi.invent); - if (!umoney && !eshkp->credit) { - You("%shave no gold or credit%s.", - stashed_gold ? "seem to " : "", paid ? " left" : ""); - return ECMD_OK; - } - if ((umoney + eshkp->credit) < cheapest_item(shkp)) { - You("don't have enough gold to buy%s the item%s you picked.", - eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct)); - if (stashed_gold) - pline("Maybe you have some gold stashed away?"); - return ECMD_OK; - } - - via_menu = (flags.menu_style != MENU_TRADITIONAL); - /* allow 'm p' to request a menu for menustyle:traditional; - for other styles, it will do the opposite; that doesn't make - a whole lot of sense for a 'request-menu' prefix, but otherwise - it would simply be redundant and there wouldn't be any way to - skip the menu when hero owes for multiple items */ - if (iflags.menu_requested) - via_menu = !via_menu; - /* this will loop for a second iteration iff not initially using a - menu and player answers 'm' to custom ynq prompt */ - do { - if (via_menu && eshkp->billct > 1) { - if (!menu_pick_pay_items(shkp)) - return ECMD_OK; - queuedpay = TRUE; - itemize = FALSE; - via_menu = FALSE; /* reset so that we don't loop */ - } else { - /* this isn't quite right; it itemizes without asking if the - single item on bill is partly used up and partly unpaid */ - iprompt = (eshkp->billct < 2) ? 'y' - : yn_function("Itemized billing?", - "ynq m", 'q', TRUE); - itemize = (iprompt == 'y'); - if (iprompt == 'q') - goto thanks; - via_menu = (iprompt == 'm'); - } - } while (via_menu); - - for (pass = 0; pass <= 1; pass++) { - tmp = 0; - while (tmp < eshkp->billct) { - struct obj *otmp; - struct bill_x *bp = &(eshkp->bill_p[tmp]); - - if (queuedpay && !bp->queuedpay) { - tmp++; - continue; - } - - /* find the object on one of the lists */ - if ((otmp = bp_to_obj(bp)) != 0) { - /* if completely used up, object quantity is stale; - restoring it to its original value here avoids - making the partly-used-up code more complicated */ - if (bp->useup) - otmp->quan = bp->bquan; - } else { - impossible("Shopkeeper administration out of order."); - setpaid(shkp); /* be nice to the player */ - return ECMD_TIME; - } - if (pass == bp->useup && otmp->quan == bp->bquan) { - /* pay for used-up items on first pass and others - * on second, so player will be stuck in the store - * less often; things which are partly used up - * are processed on both passes */ - tmp++; - } else { - switch (dopayobj(shkp, bp, &otmp, pass, itemize)) { - case PAY_CANT: - return ECMD_TIME; /*break*/ - case PAY_BROKE: - paid = TRUE; - goto thanks; /*break*/ - case PAY_SKIP: - tmp++; - continue; /*break*/ - case PAY_SOME: - paid = TRUE; - if (itemize) - bot(); - continue; /*break*/ - case PAY_BUY: - paid = TRUE; - break; - } - if (itemize) - bot(); - *bp = eshkp->bill_p[--eshkp->billct]; - } - } - } - thanks: - if (!itemize) - update_inventory(); /* Done in dopayobj() if itemize. */ + if (!pay_billed_items(shkp, ibillct, ibill, stashed_gold, &paid)) + goto pay_done; } + if (!ANGRY(shkp) && paid) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); @@ -1810,7 +1920,177 @@ dopay(void) !eshkp->surcharge ? "!" : "."); } } - return ECMD_TIME; + pay_done: + if (paid) + update_inventory(); + iflags.menu_requested = FALSE; /* reset */ + /* free the sortbill array used for itemized billing */ + if (ibill) { + free((genericptr_t) ibill), ibill = NULL; + nhUse(ibill); + } + return paid ? ECMD_TIME : ECMD_OK; +} + +/* for menustyle=Traditional, choose between paying for everything (by + declining to itemize), asking item-by-item (by accepting itemization), + or switch to selecting via menu (special 'm' answer at "Itemize? [ynq m]" + prompt); for other menustyles, always select via menu; + player can use 'm' prefix before 'p' command to invert those behaviors; + then actually pay for the selected items, item by item for as long as + hero has enough credit+cash */ +staticfn boolean +pay_billed_items( + struct monst *shkp, + int ibillct, + Bill *ibill, + boolean stashed_gold, + boolean *paid_p) +{ + struct bill_x *bp; + struct obj *otmp; + long umoney; + boolean itemize, more_than_one; + boolean queuedpay = FALSE, via_menu; + int indx, bidx, pass, iprompt, j, ebillct; + struct eshk *eshkp = ESHK(shkp); + + umoney = money_cnt(gi.invent); + if (!umoney && !eshkp->credit) { + You("%shave no gold or credit%s.", + stashed_gold ? "seem to " : "", *paid_p ? " left" : ""); + return TRUE; + } + bp = eshkp->bill_p; + otmp = bp_to_obj(bp); + ebillct = eshkp->billct; + more_than_one = (ebillct > 1 || otmp->where == OBJ_CONTAINED + || otmp->quan < bp->bquan); + if ((umoney + eshkp->credit) < cheapest_item(ibillct, ibill)) { + You("don't have enough gold to buy%s the item%s %s.", + more_than_one ? " any of" : "", plur(more_than_one ? 2 : 1), + (ebillct > 1) ? "you've picked" : "on your bill"); + if (stashed_gold) + pline("Maybe you have some gold stashed away?"); + return TRUE; + } + + via_menu = (flags.menu_style != MENU_TRADITIONAL); + /* allow 'm p' to request a menu for menustyle:traditional; + for other styles, it will do the opposite; that doesn't make + a whole lot of sense for a 'request-menu' prefix, but otherwise + it would simply be redundant and there wouldn't be any way to + skip the menu when hero owes for multiple items */ + if (iflags.menu_requested) + via_menu = !via_menu; + /* this will loop for a second iteration iff not initially using a + menu and player answers 'm' at custom ynq prompt */ + do { + if (via_menu && more_than_one) { + if (!menu_pick_pay_items(ibillct, ibill)) + return TRUE; + queuedpay = TRUE; + itemize = FALSE; + via_menu = FALSE; /* reset so that we don't loop */ + } else { + iprompt = !more_than_one ? 'y' + : yn_function("Itemized billing?", "ynq m", 'q', TRUE); + if (iprompt == 'q') + return TRUE; + itemize = (iprompt == 'y'); + via_menu = (iprompt == 'm'); + } + } while (via_menu); + + /* + * 3.7: this used to make two passes through eshkp->bill_p[], + * the first for used up items and the second for unpaid ones. + * Items which were partly used were processed on both passes. + * + * Now it makes one pass through ibill[], which has all used up + * items sorted to the beginning and unpaid ones sorted to the end. + * Partly used items have two entries for same base item, one in + * each section. + */ + for (indx = 0; indx < ibillct; ++indx) { + if (queuedpay && !ibill[indx].queuedpay) + continue; + + /* + * TODO: ******** + * Finish implementing CONTAINED_BUYING. + * If a container holds any unpaid items, it might not be on + * the regular eshkp->bill_p[] bill itself. And possibly only + * some of its contents will be. + * To keep things simpler, disallow purchase of a container that + * holds one or more unpaid items if there are any used up items + * that haven't been paid for yet. This will avoid the complex + * case of using part of a stack, putting the unused portion + * into a container, then declining to buy the used up portion + * before buying the unpaid portion along with the container. + * Partly used/partly intact items must always have their used + * up portion paid for before the shopkeeper will sell the + * intact ones; encountering that mid-container would end up + * being very cumbersome. + */ + + bidx = ibill[indx].bidx; + bp = &eshkp->bill_p[bidx]; + otmp = ibill[indx].obj; + pass = (ibill[indx].usedup <= PartlyUsedUp) ? 0 : 1; + +#ifdef CONTAINED_BUYING + /***TEMP***/ + if (ibill[indx].usedup == BillContainer) { + verbalize("You need to remove any unpaid items from that %s" + " and buy them separately.", simpleonames(otmp)); + return PAY_CANT; + } +#endif + + switch (dopayobj(shkp, bp, &otmp, pass, itemize)) { + case PAY_CANT: + return FALSE; + case PAY_BROKE: + *paid_p = TRUE; + return TRUE; + case PAY_SKIP: + continue; + case PAY_SOME: + *paid_p = TRUE; + if (itemize) + bot(); + continue; + case PAY_BUY: + *paid_p = TRUE; + break; + } + if (itemize) + bot(); + + /* remove from eshkp->bill+p[] unless this was the used up portion + of partly used up item (since removal would take out both; note: + can't buy PartlyIntact until PartlyUsedUp has been paid for) */ + if (ibill[indx].usedup == PartlyUsedUp) { + for (j = 0; j < ibillct; ++j) + if (ibill[j].bidx == bidx && ibill[j].usedup == PartlyIntact) { + bp->bquan = ibill[j].obj->quan; + ibill[j].usedup = FullyIntact; + break; + } + } else { + /* if we get here, something was bought and needs to be removed + from shop bill; move last bill_p[] entry into vacated slot; + also update ibill[] indices for it */ + *bp = eshkp->bill_p[ebillct - 1]; + for (j = 0; j < ibillct; ++j) + if (ibill[j].bidx == ebillct - 1) + ibill[j].bidx = bidx; + ebillct -= 1; + eshkp->billct = ebillct; + } + } + return TRUE; } /* return 2 if used-up portion paid @@ -1835,7 +2115,8 @@ dopayobj( boolean stashed_gold = (hidden_gold(TRUE) > 0L), consumed = (which == 0); - if (!obj->unpaid && !bp->useup) { + if (!obj->unpaid && !bp->useup + && !(Has_contents(obj) && unpaid_cost(obj, COST_CONTENTS))) { impossible("Paid object on bill??"); return PAY_BUY; } @@ -1856,38 +2137,36 @@ dopayobj( /* dealing with ordinary unpaid item */ quan = obj->quan; } + ltmp = (long) bp->price * quan; + obj->quan = quan; /* to be used by doname() */ obj->unpaid = 0; /* ditto */ iflags.suppress_price++; /* affects containers */ - ltmp = bp->price * quan; buy = PAY_BUY; /* flag; if changed then return early */ if (itemize) { char qbuf[BUFSZ], qsfx[BUFSZ]; + /* + * TODO: + * This should also accept 'a' and 'q' to end itemized paying: + * 'a' to buy the rest without asking, 'q' to just stop. + */ + Sprintf(qsfx, " for %ld %s. Pay?", ltmp, currency(ltmp)); (void) safe_qbuf(qbuf, (char *) 0, qsfx, obj, (quan == 1L) ? Doname2 : doname, ansimpleoname, (quan == 1L) ? "that" : "those"); if (y_n(qbuf) == 'n') { buy = PAY_SKIP; /* don't want to buy */ - } else if (quan < bp->bquan && !consumed) { /* partly used goods */ - obj->quan = bp->bquan - save_quan; /* used up amount */ - if (!Deaf && !muteshk(shkp)) { - SetVoice(shkp, 0, 80, 0); - verbalize("%s for the other %s before buying %s.", - ANGRY(shkp) ? "Pay" : "Please pay", - simpleonames(obj), /* short name suffices */ - save_quan > 1L ? "these" : "this one"); - } else { - pline("%s %s%s your bill for the other %s first.", - Shknam(shkp), - ANGRY(shkp) ? "angrily " : "", - nolimbs(shkp->data) ? "motions to" : "points out", - simpleonames(obj)); - } - buy = PAY_SKIP; /* shk won't sell */ } + } /* itemize */ + + if (quan < bp->bquan && !consumed) { /* partly used goods */ + /* shk won't sell the intact portion until the used up portion has + been paid for (once it has been, bp->bquan will match quan) */ + reject_purchase(shkp, obj, bp->bquan); + buy = PAY_SKIP; } if (buy == PAY_BUY && umoney + ESHK(shkp)->credit < ltmp) { You("don't%s have gold%s enough to pay for %s.", @@ -1896,7 +2175,6 @@ dopayobj( thesimpleoname(obj)); buy = itemize ? PAY_SKIP : PAY_CANT; } - if (buy != PAY_BUY) { /* restore unpaid object to original state */ obj->quan = save_quan; @@ -1933,6 +2211,38 @@ dopayobj( return buy; } +/* called if an item on shop bill is partly used up and partly intact and + player tries to buy the intact portion before paying for used up portion + (not actually very effective since player can just drop the unpaid + portion then pick it back up to have it get its own distinct bill entry; + the former partly used up portion becomes a fully used up separate item) */ +staticfn void +reject_purchase( + struct monst *shkp, + struct obj *obj, + long billed_quan) +{ + long intact_quan = obj->quan; + + assert(intact_quan < billed_quan); + /* temporarily change obj to refer to the used up portion */ + obj->quan = billed_quan - intact_quan; + if (!Deaf && !muteshk(shkp)) { + SetVoice(shkp, 0, 80, 0); + verbalize("%s for the other %s before buying %s.", + ANGRY(shkp) ? "Pay" : "Please pay", + simpleonames(obj), /* short name suffices */ + (intact_quan > 1L) ? "these" : "this one"); + } else { + pline("%s %s%s your bill for the other %s first.", + Shknam(shkp), + ANGRY(shkp) ? "angrily " : "", + nolimbs(shkp->data) ? "motions to" : "points out", + simpleonames(obj)); + } + obj->quan = intact_quan; +} + /* routine called after dying (or quitting) */ boolean paybill( @@ -3078,9 +3388,9 @@ splitbill(struct obj *obj, struct obj *otmp) } bp->bquan -= otmp->quan; - if (ESHK(shkp)->billct == BILLSZ) + if (ESHK(shkp)->billct == BILLSZ) { otmp->unpaid = 0; - else { + } else { tmp = bp->price; bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]); bp->bo_id = otmp->o_id; From 17e0385f0e72f15cb78debf1cfe4b7d47f69340f Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 28 Jun 2024 08:31:49 -0700 Subject: [PATCH 008/121] shk.c and priest.c vs 'onefile' --- src/priest.c | 4 ++++ src/shk.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/priest.c b/src/priest.c index 108bf11a4..32ff818e6 100644 --- a/src/priest.c +++ b/src/priest.c @@ -91,6 +91,7 @@ move_special(struct monst *mtmp, boolean in_his_shop, schar appr, } } } +#undef GDIST if (mtmp->ispriest && avoid && nix == omx && niy == omy && onlineu(omx, omy)) { /* might as well move closer as long it's going to stay @@ -901,4 +902,7 @@ restpriest(struct monst *mtmp, boolean ghostly) } } +#undef ALGN_SINNED +#undef ALGN_PIOUS + /*priest.c*/ diff --git a/src/shk.c b/src/shk.c index ec52bb633..abe93d020 100644 --- a/src/shk.c +++ b/src/shk.c @@ -4727,6 +4727,7 @@ shk_move(struct monst *shkp) appr = gtx = gty = 0; } } +#undef GDIST } z = move_special(shkp, inhishop(shkp), appr, uondoor, avoid, omx, omy, @@ -5856,4 +5857,17 @@ use_unpaid_trapobj(struct obj *otmp, coordxy x, coordxy y) } } +#ifdef CONTAINED_BUYING +#undef CONTAINED_BUYING +#endif +#undef PAY_SOME +#undef PAY_BUY +#undef PAY_CANT +#undef PAY_SKIP +#undef PAY_BROKE +#undef NOTANGRY +#undef ANGRY +#undef IS_SHOP +#undef muteshk + /*shk.c*/ From 02ddbf001bf792e32369df406b64a25d1b132612 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 28 Jun 2024 09:04:55 -0700 Subject: [PATCH 009/121] shk.c menu-pay comments --- src/shk.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/shk.c b/src/shk.c index abe93d020..ac43999d4 100644 --- a/src/shk.c +++ b/src/shk.c @@ -5,11 +5,12 @@ #include "hack.h" -/* CONTAINED_BUYING: for itemized billing (including default menu for - 'p'), unpaid items in containers are concealed from itemized billing; - there's a single price for the container and all its contents; - player must pay all-or-nothing for such, and all used up items have - to already be paid for */ +/* CONTAINED_BUYING: for itemized billing (including default menu for 'p'), + unpaid items in containers are concealed whether or not its has been + flagged as contents-known; there's a single price for the container and + all its contents + [TODO: player must pay all-or-nothing for such, and all used up items + have to already be paid for] */ /*#define CONTAINED_BUYING*/ /**** not fully implemented yet ****/ #define PAY_SOME 2 @@ -1453,7 +1454,7 @@ cheapest_item(int ibillct, Bill *ibill) staticfn int /* returns number of entries */ make_itemized_bill( struct monst *shkp, - Bill **ibill_p) /* output, a 'sortloot array' */ + Bill **ibill_p) /* output, augmented bill similar to a 'sortloot array' */ { static Bill zerosbi; /* Null sortbill item */ Bill *ibill; @@ -2068,7 +2069,7 @@ pay_billed_items( if (itemize) bot(); - /* remove from eshkp->bill+p[] unless this was the used up portion + /* remove from eshkp->bill_p[] unless this was the used up portion of partly used up item (since removal would take out both; note: can't buy PartlyIntact until PartlyUsedUp has been paid for) */ if (ibill[indx].usedup == PartlyUsedUp) { From dc9d0e279fa19943fb54a8b85dcf48ea5905ce5e Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 30 Jun 2024 17:33:41 -0700 Subject: [PATCH 010/121] suppress sanity_check for invalid command ESC If sanity_check starts spewing out warnings, don't run it again if player types ESC when the program finally asks for the next command (rather than --More--). Also, some reformatting of the main command table. --- src/cmd.c | 108 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index ae3b325ae..dd1d40fe6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1771,7 +1771,7 @@ struct ext_func_tab extcmdlist[] = { doputon, 0, NULL }, { 'q', "quaff", "quaff (drink) something", dodrink, CMD_M_PREFIX, NULL }, - { '\0', "quit", "exit without saving current game", + { '\0', "quit", "exit without saving current game", done2, IFBURIED | AUTOCOMPLETE | GENERALCMD | NOFUZZERCMD, NULL }, { 'Q', "quiver", "select ammunition for quiver", @@ -1820,7 +1820,8 @@ struct ext_func_tab extcmdlist[] = { doprtool, IFBURIED | CMD_M_PREFIX, NULL }, { WEAPON_SYM, "seeweapon", "show the weapon currently wielded", doprwep, IFBURIED | CMD_M_PREFIX, NULL }, - { '!', "shell", "leave game to enter a sub-shell ('exit' to come back)", + { '!', "shell", + "leave game to enter a sub-shell ('exit' to come back)", dosh_core, (IFBURIED | GENERALCMD | NOFUZZERCMD #ifndef SHELL | CMD_NOT_AVAILABLE @@ -1959,56 +1960,56 @@ struct ext_func_tab extcmdlist[] = { dozap, 0, NULL }, /* movement commands will be bound by reset_commands() */ /* move or attack; accept m/g/G/F prefixes */ - { '\0', "movewest", "move west (screen left)", - do_move_west, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movenorthwest", "move northwest (screen upper left)", - do_move_northwest, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movenorth", "move north (screen up)", - do_move_north, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movenortheast", "move northeast (screen upper right)", - do_move_northeast, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "moveeast", "move east (screen right)", - do_move_east, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movesoutheast", "move southeast (screen lower right)", - do_move_southeast, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movesouth", "move south (screen down)", - do_move_south, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, - { '\0', "movesouthwest", "move southwest (screen lower left)", - do_move_southwest, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movewest", "move west (screen left)", + do_move_west, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movenorthwest", "move northwest (screen upper left)", + do_move_northwest, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movenorth", "move north (screen up)", + do_move_north, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movenortheast", "move northeast (screen upper right)", + do_move_northeast, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "moveeast", "move east (screen right)", + do_move_east, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movesoutheast", "move southeast (screen lower right)", + do_move_southeast, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movesouth", "move south (screen down)", + do_move_south, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, + { '\0', "movesouthwest", "move southwest (screen lower left)", + do_move_southwest, MOVEMENTCMD | CMD_MOVE_PREFIXES, NULL }, /* rush; accept m prefix but not g/G/F */ - { '\0', "rushwest", "rush west (screen left)", - do_rush_west, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushnorthwest", "rush northwest (screen upper left)", - do_rush_northwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushnorth", "rush north (screen up)", - do_rush_north, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushnortheast", "rush northeast (screen upper right)", - do_rush_northeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rusheast", "rush east (screen right)", - do_rush_east, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushsoutheast", "rush southeast (screen lower right)", - do_rush_southeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushsouth", "rush south (screen down)", - do_rush_south, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "rushsouthwest", "rush southwest (screen lower left)", - do_rush_southwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushwest", "rush west (screen left)", + do_rush_west, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushnorthwest", "rush northwest (screen upper left)", + do_rush_northwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushnorth", "rush north (screen up)", + do_rush_north, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushnortheast", "rush northeast (screen upper right)", + do_rush_northeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rusheast", "rush east (screen right)", + do_rush_east, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushsoutheast", "rush southeast (screen lower right)", + do_rush_southeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushsouth", "rush south (screen down)", + do_rush_south, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "rushsouthwest", "rush southwest (screen lower left)", + do_rush_southwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, /* run; accept m prefix but not g/G/F */ - { '\0', "runwest", "run west (screen left)", - do_run_west, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runnorthwest", "run northwest (screen upper left)", - do_run_northwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runnorth", "run north (screen up)", - do_run_north, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runnortheast", "run northeast (screen upper right)", - do_run_northeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runeast", "run east (screen right)", - do_run_east, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runsoutheast", "run southeast (screen lower right)", - do_run_southeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runsouth", "run south (screen down)", - do_run_south, MOVEMENTCMD | CMD_M_PREFIX, NULL }, - { '\0', "runsouthwest", "run southwest (screen lower left)", - do_run_southwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runwest", "run west (screen left)", + do_run_west, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runnorthwest", "run northwest (screen upper left)", + do_run_northwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runnorth", "run north (screen up)", + do_run_north, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runnortheast", "run northeast (screen upper right)", + do_run_northeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runeast", "run east (screen right)", + do_run_east, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runsoutheast", "run southeast (screen lower right)", + do_run_southeast, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runsouth", "run south (screen down)", + do_run_south, MOVEMENTCMD | CMD_M_PREFIX, NULL }, + { '\0', "runsouthwest", "run southwest (screen lower left)", + do_run_southwest, MOVEMENTCMD | CMD_M_PREFIX, NULL }, /* internal commands: only used by game core, not available for user */ { '\0', "clicklook", NULL, doclicklook, INTERNALCMD | MOUSECMD, NULL }, @@ -3316,7 +3317,12 @@ rhack(int key) /* if there's no command, there's nothing to do except reset */ if (!key || key == (char) 0377 || key == gc.Cmd.spkeys[NHKF_ESC]) { - if (!key || key != gc.Cmd.spkeys[NHKF_ESC]) + if (key == gc.Cmd.spkeys[NHKF_ESC]) + /* don't perform next sanity check if player typed ESC for + the current command, similar to handling for CMD_INSANE + flag below (^P and ^R) */ + iflags.sanity_no_check = iflags.sanity_check; + else nhbell(); reset_cmd_vars(TRUE); return; From 14d0e48e73ae575608204cf97f5f75fbaaac97e4 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 1 Jul 2024 00:44:42 -0700 Subject: [PATCH 011/121] less verbose sanity checking If the 'sanity_check' option triggers a warning, don't show the "Program in disorder! (Save and restore might fix this.)" and "Report these messages to ." messages and also don't run the crash report submission. Doesn't affect the fuzzer because it escalates impossible() to panic() before reaching those extra messages. --- include/extern.h | 2 +- include/hack.h | 1 + src/pline.c | 10 ++++++++-- src/wizcmds.c | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7da52c591..a5d0f24e4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -428,7 +428,6 @@ extern void end_of_input(void); #endif extern char readchar(void); extern char readchar_poskey(coordxy *, coordxy *, int *); -extern void sanity_check(void); extern char* key2txt(uchar, char *); extern char yn_function(const char *, const char *, char, boolean); extern char paranoid_ynq(boolean, const char *, boolean); @@ -3743,6 +3742,7 @@ extern void wizcustom_callback(winid win, int glyphnum, char *id); extern int wiz_display_macros(void); extern int wiz_mon_diff(void); #endif +extern void sanity_check(void); /* ### worm.c ### */ diff --git a/include/hack.h b/include/hack.h index b385fc37f..81f97632b 100644 --- a/include/hack.h +++ b/include/hack.h @@ -783,6 +783,7 @@ struct sinfo { int in_parseoptions; /* in parseoptions */ int in_role_selection; /* role/race/&c selection menus in progress */ int in_getlin; /* inside interface getlin routine */ + int in_sanity_check; /* for impossible() during sanity checking */ int config_error_ready; /* config_error_add is ready, available */ int beyond_savefile_load; /* set when past savefile loading */ #ifdef PANICLOG diff --git a/src/pline.c b/src/pline.c index 811d5a2fe..7e22c1a85 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pline.c $NHDT-Date: 1693083243 2023/08/26 20:54:03 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 3.7 pline.c $NHDT-Date: 1719819280 2024/07/01 07:34:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.130 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -594,6 +594,12 @@ impossible(const char *s, ...) pline("%s", pbuf); gp.pline_flags = 0; + if (gp.program_state.in_sanity_check) { + /* skip rest of multi-line feedback */ + gp.program_state.in_impossible = 0; + return; + } + Strcpy(pbuf2, "Program in disorder!"); if (gp.program_state.something_worth_saving) Strcat(pbuf2, " (Saving and reloading may fix this problem.)"); @@ -608,7 +614,7 @@ impossible(const char *s, ...) boolean report = ('y' == yn_function("Report now?", ynchars, 'n', FALSE)); - raw_print(""); // prove to the user the character was accepted + raw_print(""); /* prove to the user the character was accepted */ if (report) { submit_web_report(1, "Impossible", pbuf); } diff --git a/src/wizcmds.c b/src/wizcmds.c index f4f3006f2..6d1585ce9 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1435,6 +1435,7 @@ sanity_check(void) iflags.sanity_no_check = FALSE; return; } + gp.program_state.in_sanity_check++; you_sanity_check(); obj_sanity_check(); timer_sanity_check(); @@ -1443,6 +1444,7 @@ sanity_check(void) bc_sanity_check(); trap_sanity_check(); engraving_sanity_check(); + gp.program_state.in_sanity_check--; } /* qsort() comparison routine for use in list_migrating_mons() */ From 7fa328fda357ea15a81156fc2c06d5d54fda6db9 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 2 Jul 2024 14:52:49 -0700 Subject: [PATCH 012/121] redo itemized shop billing for containers Finish shop changes begun in 2674a9904db83cdae509ef46383ab2d2485ff36d. Fix the longstanding bug where shop paying with itemized buying would reveal container contents if any unpaid items were inside containers, regardless of whether the containers' contents were known yet, even when the container was a locked box/chest or a cursed bag of holding. Paying by menu made that be more noticeable but it has been present ever since itemized paying was introduced. I can't find any old bug reports for it though. I did find an old message of mine that claims it's in bugzilla with a "#Hnnnn" tag. This changes how buying containers and their contained items behaves. It's now an all or nothing operation. Itemized billing will list the container but not contents, and to buy what is inside you need to pay for the whole thing as a single unit. If the container itself is unpaid then its price is part of that item's total cost. If it is hero-owned than it is listed as an item to buy but doesn't increase the cost derived from its unpaid contents. (If you decline to pay, hero will still own the container and still owe for unpaid contents.) --- doc/fixes3-7-0.txt | 5 + src/objnam.c | 26 ++- src/shk.c | 460 ++++++++++++++++++++++++++++++--------------- 3 files changed, 329 insertions(+), 162 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f8a776ba8..b2dbfb4db 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1426,6 +1426,11 @@ a 3.6 fix to avoid a potential "object lost" panic when drinking potions had unintended side-effect of making used up potions on shop's bill become separate bill entries all with count 1 despite having come from same unpaid stack; affected Ix inventory listing and itemized shop billing +buying shop items which include any unpaid ones inside containers would reveal + them even when the containers hadn't been opened (obj->cknown==0); + recent change to pay via menu made the problem become more visible; + shopping has been changed such that buying anything that is inside a + container requires that the whole container be bought as a unit Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/objnam.c b/src/objnam.c index 96fd36e81..c1ed38dfb 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -2279,18 +2279,31 @@ paydoname(struct obj *obj) { static const char and_contents[] = " and its contents"; char *p; + unsigned save_cknown = obj->cknown; + boolean save_wizweight = iflags.wizweight; + if (Has_contents(obj)) + obj->cknown = 0; + /* avoid showing item weights to unclutter billing's pay-menu a bit */ + iflags.wizweight = FALSE; /* suppress invent-style price; caller will add billing-style price */ iflags.suppress_price++; p = doname_base(obj, 0U); iflags.suppress_price--; + iflags.wizweight = save_wizweight; if (Has_contents(obj)) { - if (!strncmp(p, "a ", 2)) - p += 2; - else if (!strncmp(p, "an ", 3)) - p += 3; - p = strprepend(p, obj->unpaid ? "an unpaid " : "your "); + /* buy_container() sets no_charge for a container that has just + been purchased so that when paydoname() is called by + shk_names_obj(), we'll provide "a/an " instead of + "your " */ + if (!obj->no_charge) { + if (!strncmp(p, "a ", 2)) + p += 2; + else if (!strncmp(p, "an ", 3)) + p += 3; + p = strprepend(p, obj->unpaid ? "an unpaid " : "your "); + } if (!obj->cknown) { if (obj->unpaid) { @@ -2298,10 +2311,11 @@ paydoname(struct obj *obj) < BUFSZ - PREFIX) Strcat(p, and_contents); } else { - p = strprepend(p, "contents of "); + p = strprepend(p, "the contents of "); } } } + obj->cknown = save_cknown; return p; } diff --git a/src/shk.c b/src/shk.c index ac43999d4..bf82f1532 100644 --- a/src/shk.c +++ b/src/shk.c @@ -5,15 +5,15 @@ #include "hack.h" -/* CONTAINED_BUYING: for itemized billing (including default menu for 'p'), - unpaid items in containers are concealed whether or not its has been - flagged as contents-known; there's a single price for the container and - all its contents - [TODO: player must pay all-or-nothing for such, and all used up items - have to already be paid for] */ -/*#define CONTAINED_BUYING*/ /**** not fully implemented yet ****/ +/* + * FIXME: + * The normal shop messages are verbal. There are a lot of cases + * where an alternate message is given if the hero is deaf or shk + * is mute (when poly'd), but that is usually visual-based. It is + * possible for hero to pay for items while blind (only if adjacent + * to shk) and the alternate messages fail to account for that. + */ -#define PAY_SOME 2 #define PAY_BUY 1 #define PAY_CANT 0 /* too poor */ #define PAY_SKIP (-1) @@ -24,7 +24,8 @@ enum billitem_status { PartlyUsedUp = 2, /* partly used up; obj->where==OBJ_INVENT or similar */ PartlyIntact = 3, /* intact portion of partly used up item */ FullyIntact = 4, /* normal unpaid item */ - BillContainer = 5, /* container holding unpaid item(s) */ + KnownContainer = 5, /* container->cknown==1, holding unpaid item(s) */ + UndisclosedContainer = 6, /* container->cknown==0 */ }; /* this is similar to sortloot; the shop bill gets converted into a array of struct sortbill_item so that sorting and traversal don't need to access @@ -81,9 +82,14 @@ staticfn int make_itemized_bill(struct monst *shkp, Bill **ibill) NONNULLPTRS; staticfn int menu_pick_pay_items(int, Bill *) NONNULLPTRS; staticfn boolean pay_billed_items(struct monst *, int, Bill *, boolean, boolean *) NONNULLPTRS; -staticfn int dopayobj(struct monst *, struct bill_x *, struct obj **, int, - boolean); +staticfn void update_bill(int, int, Bill *, struct eshk *, struct bill_x *, + struct obj *) NONNULLPTRS; +staticfn int dopayobj(struct monst *, struct bill_x *, struct obj *, int, + boolean, boolean) NONNULLPTRS; +staticfn int buy_container(struct monst *, int, int, Bill *) NONNULLPTRS; staticfn void reject_purchase(struct monst *, struct obj *, long) NONNULLPTRS; +staticfn boolean insufficient_funds(struct monst *, struct obj *, long) + NONNULLPTRS; staticfn long stolen_container(struct obj *, struct monst *, long, boolean); staticfn long corpsenm_price_adj(struct obj *); staticfn long getprice(struct obj *, boolean); @@ -1414,7 +1420,7 @@ sortbill_cmp(const genericptr vptr1, const genericptr vptr2) long cost1 = sbi1->cost, cost2 = sbi2->cost; int bidx1 = sbi1->bidx, bidx2 = sbi2->bidx, /* sort such that FullyUsedUp and PartlyUsedUp come before - PartlyIntact, FullyIntact, and BillContainer */ + PartlyIntact, FullyIntact, KnownContainer, UndisclosedContainer */ used1 = sbi1->usedup <= PartlyUsedUp, /* 0=>unpaid, 1=>used */ used2 = sbi2->usedup <= PartlyUsedUp; @@ -1476,8 +1482,8 @@ make_itemized_bill( n = 0; /* number of entries in ibill[]; won't necessary match ebillct */ for (i = 0; i < ebillct; ++i) { - bp = &(eshkp->bill_p[i]); - bp->queuedpay = FALSE; + bp = &eshkp->bill_p[i]; + bp->queuedpay = FALSE; /* [no longer used] */ /* find the object on the bill */ otmp = bp_to_obj(bp); if (!otmp) { @@ -1498,7 +1504,7 @@ make_itemized_bill( after using part of a stack; used up part isn't) below */ ibill[n].obj = otmp; ibill[n].quan = bp->bquan - otmp->quan; - ibill[n].cost = (long) bp->price * ibill[n].quan; + ibill[n].cost = bp->price * ibill[n].quan; ibill[n].bidx = i; /* duplicate index into eshkp->bill_p[] */ ibill[n].usedup = PartlyUsedUp; /* for sorting */ ++n; /* intact portion will be a separate entry, next */ @@ -1507,42 +1513,50 @@ make_itemized_bill( if (otmp->where == OBJ_ONBILL) { /* completely used up */ quan = bp->bquan; - cost = (long) bp->price * quan; + cost = bp->price * quan; used = FullyUsedUp; -#ifdef CONTAINED_BUYING } else if (otmp->where == OBJ_CONTAINED || Has_contents(otmp)) { int j; struct obj *item = otmp; + boolean cknown = TRUE; /* assume container contents are known */ /* when it's in a container, put the container rather than the specific object into ibill[]; find outermost container */ - while (otmp->where == OBJ_CONTAINED) + while (otmp->where == OBJ_CONTAINED) { otmp = otmp->ocontainer; + if (!otmp->cknown) + cknown = FALSE; + } /* this container might already be in ibill[] if it is unpaid itself or if it holds more than one unpaid item and another besides this one has already been processed; only include first instance */ for (j = 0; j < n; ++j) - if (otmp == ibill[j].obj) { - /* unpaid container might be on bill as FullyIntact */ - ibill[j].usedup = BillContainer; + if (otmp == ibill[j].obj) break; - } - if (j < n) + if (j < n) { + /* when already on bill as FullyIntact, update; the cost + saved in ibill[j] is based on the container even if the + entry was initially created for an item of its contents */ + if (ibill[j].usedup == FullyIntact) + ibill[j].usedup = cknown ? KnownContainer + : UndisclosedContainer; continue; /* 'i' loop */ + } /* include 1 container containing unpaid item(s) */ quan = 1L; cost = unpaid_cost(otmp, COST_CONTENTS); /* an unpaid container without any unpaid contents is classified as 'FullyIntact'; a container with unpaid contents will be - 'BillContainer' regardless of whether it is unpaid itself */ - used = (otmp == item) ? FullyIntact : BillContainer; -#endif + '*Container' regardless of whether it is unpaid itself */ + used = (otmp == item) ? FullyIntact + : cknown ? KnownContainer + : UndisclosedContainer; } else { /* ordinary unpaid; when partly used, these are values for the intact portion; might be an empty shop-owned container */ quan = otmp->quan; - cost = (long) bp->price * quan; + cost = bp->price * quan; used = (quan < bp->bquan) ? PartlyIntact : FullyIntact; } @@ -1556,7 +1570,8 @@ make_itemized_bill( ibill[n].bidx = -1; /* end of list; not strictly needed */ /* ibill[0..n-1] contains data, ibill[n] has Null obj and -1 bidx */ - qsort((genericptr_t) ibill, n, sizeof *ibill, sortbill_cmp); + if (n > 1) + qsort((genericptr_t) ibill, n, sizeof *ibill, sortbill_cmp); return n; } @@ -1572,7 +1587,6 @@ menu_pick_pay_items( anything any; menu_item *pick_list = (menu_item *) 0; char *p, buf[BUFSZ]; - boolean save_wizweight; long amt, largest_amt, save_quan; int i, j, n, amt_width; @@ -1589,22 +1603,19 @@ menu_pick_pay_items( Sprintf(buf, "%ld", largest_amt); amt_width = (int) strlen(buf); - /* avoid showing item weights to unclutter billing a bit */ - save_wizweight = iflags.wizweight; - iflags.wizweight = FALSE; /* show the "used up items" header if there are any used up items on the bill, no matter whether there are also any intact items; note: ibill[] has been sorted to hold used-up items first */ if (ibill[0].usedup <= PartlyUsedUp) { Sprintf(buf, "Used up item%s:", - (ibillct > 1 && ibill[1].usedup) ? "s" : ""); + (ibillct > 1 && ibill[1].usedup <= PartlyUsedUp) ? "s" : ""); add_menu_heading(win, buf); } for (i = 0; i < ibillct; ++i) { /* the "unpaid items" header is only shown if the "used up items" one was shown before the first menu entry */ - if (i > 0 && (ibill[i - 1].usedup <= PartlyUsedUp) - && (ibill[i].usedup >= PartlyIntact)) { + if (i > 0 && ibill[i - 1].usedup <= PartlyUsedUp + && ibill[i].usedup >= PartlyIntact) { Sprintf(buf, "Unpaid item%s:", (i < ibillct - 1) ? "s" : ""); add_menu_heading(win, buf); } @@ -1621,7 +1632,6 @@ menu_pick_pay_items( add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); } - iflags.wizweight = save_wizweight; end_menu(win, "Pay for which items?"); n = select_menu(win, PICK_ANY, &pick_list); @@ -1652,7 +1662,8 @@ dopay(void) long ltmp; long umoney; int sk = 0, seensk = 0, nexttosk = 0; - boolean paid = FALSE, stashed_gold = (hidden_gold(TRUE) > 0L); + boolean paid = FALSE, stashed_gold = (hidden_gold(TRUE) > 0L), + pay_done; gm.multi = 0; @@ -1900,14 +1911,16 @@ dopay(void) } /* now check items on bill */ + pay_done = TRUE; /* assume success */ if (eshkp->billct) { int ibillct = make_itemized_bill(shkp, &ibill); if (!pay_billed_items(shkp, ibillct, ibill, stashed_gold, &paid)) - goto pay_done; + pay_done = FALSE; /* skip thank you message */ } - if (!ANGRY(shkp) && paid) { + /* {mute shk,deaf hero}-aware thank you message */ + if (pay_done && !ANGRY(shkp) && paid) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("Thank you for shopping in %s %s%s", @@ -1921,7 +1934,7 @@ dopay(void) !eshkp->surcharge ? "!" : "."); } } - pay_done: + if (paid) update_inventory(); iflags.menu_requested = FALSE; /* reset */ @@ -1938,22 +1951,22 @@ dopay(void) or switch to selecting via menu (special 'm' answer at "Itemize? [ynq m]" prompt); for other menustyles, always select via menu; player can use 'm' prefix before 'p' command to invert those behaviors; - then actually pay for the selected items, item by item for as long as - hero has enough credit+cash */ + once the method is chosen, actually pay for the selected items, item by + item for as long as hero has enough credit+cash */ staticfn boolean pay_billed_items( struct monst *shkp, int ibillct, Bill *ibill, boolean stashed_gold, - boolean *paid_p) + boolean *paid_p) /* output */ { struct bill_x *bp; struct obj *otmp; long umoney; boolean itemize, more_than_one; boolean queuedpay = FALSE, via_menu; - int indx, bidx, pass, iprompt, j, ebillct; + int buy, indx, bidx, pass, iprompt, ebillct; struct eshk *eshkp = ESHK(shkp); umoney = money_cnt(gi.invent); @@ -1965,8 +1978,10 @@ pay_billed_items( bp = eshkp->bill_p; otmp = bp_to_obj(bp); ebillct = eshkp->billct; - more_than_one = (ebillct > 1 || otmp->where == OBJ_CONTAINED - || otmp->quan < bp->bquan); + more_than_one = (ebillct > 1 || otmp->quan < bp->bquan + /* note: will only get here for for single item, so + we can deduce that it is ibill[0] */ + || ibill[0].usedup == UndisclosedContainer); if ((umoney + eshkp->credit) < cheapest_item(ibillct, ibill)) { You("don't have enough gold to buy%s the item%s %s.", more_than_one ? " any of" : "", plur(more_than_one ? 2 : 1), @@ -1987,7 +2002,7 @@ pay_billed_items( /* this will loop for a second iteration iff not initially using a menu and player answers 'm' at custom ynq prompt */ do { - if (via_menu && more_than_one) { + if (via_menu /*&& more_than_one*/ ) { if (!menu_pick_pay_items(ibillct, ibill)) return TRUE; queuedpay = TRUE; @@ -2017,39 +2032,32 @@ pay_billed_items( if (queuedpay && !ibill[indx].queuedpay) continue; - /* - * TODO: ******** - * Finish implementing CONTAINED_BUYING. - * If a container holds any unpaid items, it might not be on - * the regular eshkp->bill_p[] bill itself. And possibly only - * some of its contents will be. - * To keep things simpler, disallow purchase of a container that - * holds one or more unpaid items if there are any used up items - * that haven't been paid for yet. This will avoid the complex - * case of using part of a stack, putting the unused portion - * into a container, then declining to buy the used up portion - * before buying the unpaid portion along with the container. - * Partly used/partly intact items must always have their used - * up portion paid for before the shopkeeper will sell the - * intact ones; encountering that mid-container would end up - * being very cumbersome. - */ - bidx = ibill[indx].bidx; bp = &eshkp->bill_p[bidx]; otmp = ibill[indx].obj; pass = (ibill[indx].usedup <= PartlyUsedUp) ? 0 : 1; -#ifdef CONTAINED_BUYING - /***TEMP***/ - if (ibill[indx].usedup == BillContainer) { - verbalize("You need to remove any unpaid items from that %s" - " and buy them separately.", simpleonames(otmp)); - return PAY_CANT; - } -#endif + if (ibill[indx].usedup >= KnownContainer) { + /* when successfull, buy_container() will call both + dopayobj() and update_bill(), possibly multiple times */ + int boxbag_result = buy_container(shkp, indx, ibillct, ibill); - switch (dopayobj(shkp, bp, &otmp, pass, itemize)) { + if (boxbag_result == 0) { + buy = PAY_BUY; + } else { /* buy_container() failed... */ + if (boxbag_result == 2) /* ... but didn't explain why */ + verbalize("You need to remove any unpaid items from" + " that %s and buy them separately.", + simpleonames(otmp)); + buy = PAY_CANT; + } + } else { + buy = dopayobj(shkp, bp, otmp, pass, itemize, FALSE); + + if (buy == PAY_BUY) + update_bill(indx, ibillct, ibill, eshkp, bp, otmp); + } + switch (buy) { case PAY_CANT: return FALSE; case PAY_BROKE: @@ -2057,43 +2065,64 @@ pay_billed_items( return TRUE; case PAY_SKIP: continue; - case PAY_SOME: - *paid_p = TRUE; - if (itemize) - bot(); - continue; + /* case PAY_SOME: //no longer used */ case PAY_BUY: *paid_p = TRUE; + if (itemize || queuedpay) { + update_inventory(); + bot(); + } break; } - if (itemize) - bot(); - - /* remove from eshkp->bill_p[] unless this was the used up portion - of partly used up item (since removal would take out both; note: - can't buy PartlyIntact until PartlyUsedUp has been paid for) */ - if (ibill[indx].usedup == PartlyUsedUp) { - for (j = 0; j < ibillct; ++j) - if (ibill[j].bidx == bidx && ibill[j].usedup == PartlyIntact) { - bp->bquan = ibill[j].obj->quan; - ibill[j].usedup = FullyIntact; - break; - } - } else { - /* if we get here, something was bought and needs to be removed - from shop bill; move last bill_p[] entry into vacated slot; - also update ibill[] indices for it */ - *bp = eshkp->bill_p[ebillct - 1]; - for (j = 0; j < ibillct; ++j) - if (ibill[j].bidx == ebillct - 1) - ibill[j].bidx = bidx; - ebillct -= 1; - eshkp->billct = ebillct; - } } return TRUE; } +/* update shk's bill and augmented bill after an item has been purchased */ +staticfn void +update_bill( + int indx, + int ibillct, + Bill *ibill, + struct eshk *eshkp, + struct bill_x *bp, + struct obj *paiditem) +{ + int j, newebillct; + int bidx = ibill[indx].bidx; + + /* remove from eshkp->bill_p[] unless this was the used up portion + of partly used item (since removal would take out both; note: + can't buy PartlyIntact until PartlyUsedUp has been paid for) */ + if (ibill[indx].usedup == PartlyUsedUp) { + /* 'paiditem' points to the partly intact portion still in invent or + inside a container (ibill[indx].obj points to the container) */ + bp->bquan = paiditem->quan; + for (j = 0; j < ibillct; ++j) + if (ibill[j].obj == paiditem && ibill[j].usedup == PartlyIntact) { + ibill[j].usedup = FullyIntact; + break; + } + } else { + /* if we get here, something was bought and needs to be removed + from shop bill; if it was used up, remove it from the billobjs + list and delete it; update shop's bill by moving last bill_p[] + entry into vacated slot; also update ibill[] indices for that */ + paiditem->unpaid = 0; /* set before maybe deallocating */ + if (paiditem->where == OBJ_ONBILL) { + obj_extract_self(paiditem); + dealloc_obj(paiditem); + } + newebillct = eshkp->billct - 1; + *bp = eshkp->bill_p[newebillct]; + for (j = 0; j < ibillct; ++j) + if (ibill[j].bidx == newebillct) + ibill[j].bidx = bidx; + eshkp->billct = newebillct; /* eshkp->billct - 1 */ + } + return; +} + /* return 2 if used-up portion paid * 1 if paid successfully * 0 if not enough money @@ -2104,30 +2133,26 @@ staticfn int dopayobj( struct monst *shkp, struct bill_x *bp, - struct obj **obj_p, + struct obj *obj, int which /* 0 => used-up item, 1 => other (unpaid or lost) */, - boolean itemize) - + boolean itemize, + boolean unseen) { - struct obj *obj = *obj_p; long ltmp, quan, save_quan; - long umoney = money_cnt(gi.invent); int buy; - boolean stashed_gold = (hidden_gold(TRUE) > 0L), - consumed = (which == 0); + boolean consumed = (which == 0); if (!obj->unpaid && !bp->useup && !(Has_contents(obj) && unpaid_cost(obj, COST_CONTENTS))) { impossible("Paid object on bill??"); return PAY_BUY; } - if (itemize && umoney + ESHK(shkp)->credit == 0L) { - You("%shave no gold or credit left.", - stashed_gold ? "seem to " : ""); + if (itemize && insufficient_funds(shkp, obj, 0L)) { return PAY_BROKE; } /* we may need to temporarily adjust the object, if part of the - original quantity has been used up but part remains unpaid */ + original quantity has been used up but part remains unpaid; [note: + this predates 'ibill[]' and feels redundant but still works] */ save_quan = obj->quan; if (consumed) { /* either completely used up (simple), or split needed */ @@ -2138,10 +2163,9 @@ dopayobj( /* dealing with ordinary unpaid item */ quan = obj->quan; } - ltmp = (long) bp->price * quan; + ltmp = bp->price * quan; obj->quan = quan; /* to be used by doname() */ - obj->unpaid = 0; /* ditto */ iflags.suppress_price++; /* affects containers */ buy = PAY_BUY; /* flag; if changed then return early */ @@ -2169,49 +2193,132 @@ dopayobj( reject_purchase(shkp, obj, bp->bquan); buy = PAY_SKIP; } - if (buy == PAY_BUY && umoney + ESHK(shkp)->credit < ltmp) { - You("don't%s have gold%s enough to pay for %s.", - stashed_gold ? " seem to" : "", - (ESHK(shkp)->credit > 0L) ? " or credit" : "", - thesimpleoname(obj)); + if (buy == PAY_BUY && insufficient_funds(shkp, obj, ltmp)) { buy = itemize ? PAY_SKIP : PAY_CANT; } - if (buy != PAY_BUY) { - /* restore unpaid object to original state */ - obj->quan = save_quan; - obj->unpaid = 1; - iflags.suppress_price--; - return buy; + + if (buy == PAY_BUY) { + pay(ltmp, shkp); + if (!unseen) + shk_names_obj(shkp, obj, + consumed + ? "paid for %s at a cost of %ld gold piece%s.%s" + : "bought %s for %ld gold piece%s.%s", + ltmp, ""); } - pay(ltmp, shkp); - shk_names_obj(shkp, obj, - consumed ? "paid for %s at a cost of %ld gold piece%s.%s" - : "bought %s for %ld gold piece%s.%s", - ltmp, ""); + /* restore obj to original state */ obj->quan = save_quan; /* restore original count */ - /* quan => amount just bought, save_quan => remaining unpaid count */ + iflags.suppress_price--; - iflags.suppress_price--; /* before update_inventory() below */ - if (consumed) { - if (quan != bp->bquan) { - /* eliminate used-up portion; remainder is still unpaid */ - bp->bquan = obj->quan; - obj->unpaid = 1; - bp->useup = 0; - buy = PAY_SOME; - } else { /* completely used-up, so get rid of it */ - obj_extract_self(obj); - /* assert( obj == *obj_p ); */ - dealloc_obj(obj); - *obj_p = 0; /* destroy pointer to freed object */ - } - } else if (itemize) { - update_inventory(); /* Done just once in dopay() if !itemize. */ - } return buy; } +/* pay for the unpaid contents of a container without itemizing, + and for the container itself if it is unpaid too; + returns 0==successfully bought; 1==rejected, message given here; + 2=rejected, caller should issue message */ +staticfn int +buy_container( + struct monst *shkp, + int indx, + int ibillct, + Bill *ibill) +{ + unsigned boid, boids[BILLSZ]; + int i, j, buy, buycount = 0, boidsct = 0; + struct eshk *eshkp = ESHK(shkp); + int bidx = ibill[indx].bidx, + ebillct = eshkp->billct; + struct bill_x *bp = &eshkp->bill_p[bidx]; + struct obj *otmp, *otop, + *container = ibill[indx].obj; + unsigned unpaidcontainer = container->unpaid; + long totalcost = ibill[indx].cost; + boolean sightunseen = ibill[indx].usedup == UndisclosedContainer + /* give feedback just for container+contents rather + than for individiual contents even when those + contents are known */ + || ibill[indx].usedup == KnownContainer; + + /* check for no-gold first, then for not-enough-gold; feedback is + different for the two cases */ + if (insufficient_funds(shkp, container, 0L) + || insufficient_funds(shkp, container, totalcost)) + return 1; /* message given by insufficent_funds() */ + + /* check for partly intact portion of a not-yet-paid partly used item */ + for (i = 0; i < ebillct; ++i) { + bp = &eshkp->bill_p[i]; + otmp = bp_to_obj(bp); /* ibill[bidx].obj is the container */ + if (!otmp) { + impossible("Can't find contained item on shop bill (#%d).", + bp->bo_id); + return 2; /* failure; have caller give a generic message */ + } + if (otmp->where != OBJ_CONTAINED && !Has_contents(otmp)) + continue; + /* otmp is contained, but possibly inside a different container */ + for (otop = otmp; otop->where == OBJ_CONTAINED; + otop = otop->ocontainer) + continue; /* where==OBJ_CONTAINED loop */ + if (otop != container) + continue; /* 'i' loop */ + /* now check for partly intact portion of partly used item */ + if (otmp->quan < bp->bquan) { + reject_purchase(shkp, otmp, bp->bquan); + return 1; /* message given by reject_purchase() */ + } + /* record this for the second pass; unless it's the container--that + will be deferred until after the loop so that it will be last */ + if (bp->bo_id != container->o_id) + boids[boidsct++] = bp->bo_id; + } + if (unpaidcontainer) + boids[boidsct++] = container->o_id; + + /* now make the actual purchasing pass; we've collected a set of + o_id values in order to avoid traversing the shk's bill while it + undergoes updates */ + for (j = 0; j < boidsct; ++j) { + boid = boids[j]; + for (i = 0, bp = eshkp->bill_p; i < ebillct; ++i, ++bp) + if (bp->bo_id == boid) + break; + if (i == ebillct) { + impossible("Buying %s contents: item #%u disappeared from bill.", + simpleonames(container), boid); + return 2; + } + otmp = bp_to_obj(bp); + + buy = dopayobj(shkp, bp, otmp, 1, FALSE, sightunseen); + if (buy != PAY_BUY) + impossible("Buying %s contents failed unexpectedly (#%u %d).", + simpleonames(container), otmp->o_id, buy); + update_bill(indx, ibillct, ibill, eshkp, bp, otmp); + ++buycount; + } + if (buycount && sightunseen) { + /* if the container was unpaid, the hero has just purchased it; + normally paydoname()--called by shk_names_obj()--would give + "contents of your " when it's hero-owned but we + want it to reflect container's state before purchase; + since paydoname() isn't called for no_charge items, we use + obj->no_charge as a hack to avoid that phrasing in favor of + "a/an and its contents"; temporarily set + obj->unpaid to reflect the before-purchase state too */ + if (unpaidcontainer) + container->unpaid = container->no_charge = 1; + shk_names_obj(shkp, container, + "bought %s for %ld gold piece%s.%s", + totalcost, ""); + container->unpaid = container->no_charge = 0; + } + + return buycount ? 0 : 2; /* we don't expect buycount to be 0 */ +} + /* called if an item on shop bill is partly used up and partly intact and player tries to buy the intact portion before paying for used up portion (not actually very effective since player can just drop the unpaid @@ -2229,11 +2336,19 @@ reject_purchase( /* temporarily change obj to refer to the used up portion */ obj->quan = billed_quan - intact_quan; if (!Deaf && !muteshk(shkp)) { + char which[BUFSZ]; + + if (obj->where == OBJ_CONTAINED) + Snprintf(which, sizeof which, "the one%s in %s", + plur(intact_quan), thesimpleoname(obj->ocontainer)); + else + Sprintf(which, "%s", (intact_quan > 1L) ? "these" : "this one"); + SetVoice(shkp, 0, 80, 0); verbalize("%s for the other %s before buying %s.", ANGRY(shkp) ? "Pay" : "Please pay", simpleonames(obj), /* short name suffices */ - (intact_quan > 1L) ? "these" : "this one"); + which); } else { pline("%s %s%s your bill for the other %s first.", Shknam(shkp), @@ -2244,6 +2359,36 @@ reject_purchase( obj->quan = intact_quan; } +/* gold+credit checking+feedback common to dopayobj() and buy_container() */ +staticfn boolean +insufficient_funds( + struct monst *shkp, + struct obj *item, + long cost) /* 0: check for no-gold; >0: check for specified amount */ +{ + long stashed_gold; + long umoney = money_cnt(gi.invent), + ecredit = ESHK(shkp)->credit; + + /* dopayobj() checks for no-gold early and not-enough-gold later; + buy_container() checks for both early but uses separate calls to us */ + if (!cost && umoney + ecredit == 0L) { + stashed_gold = hidden_gold(TRUE); + You("%shave no gold or credit left.", + (stashed_gold > 0) ? "seem to " : ""); + return TRUE; + } + if (cost && umoney + ecredit < cost) { + stashed_gold = hidden_gold(TRUE); + You("don't%s have gold%s enough to pay for %s.", + (stashed_gold > 0L) ? " seem to" : "", + (ecredit > 0L) ? " or credit" : "", + paydoname(item)); + return TRUE; + } + return FALSE; +} + /* routine called after dying (or quitting) */ boolean paybill( @@ -2642,6 +2787,13 @@ get_cost( struct obj *obj, struct monst *shkp) /* if angry, impose a surcharge */ { + /* + * FIXME: + * If this obj is already on the shop's bill, use the price which + * has been set there. Otherwise, the amount could be different + * (if billed while undiscovered and now become discovered or + * hero's charisma and/or visible worn gear have changed). + */ long tmp = getprice(obj, FALSE), /* used to perform a single calculation even when multiple adjustments (unID'd, dunce/tourist, charisma) are made */ @@ -3180,7 +3332,7 @@ shk_names_obj( was_unknown |= !objects[obj->otyp].oc_name_known; makeknown(obj->otyp); } - obj_name = doname(obj); + obj_name = paydoname(obj); /* Use an alternate message when extra information is being provided */ if (was_unknown) { Sprintf(fmtbuf, "%%s; you %s", fmt); @@ -5858,10 +6010,6 @@ use_unpaid_trapobj(struct obj *otmp, coordxy x, coordxy y) } } -#ifdef CONTAINED_BUYING -#undef CONTAINED_BUYING -#endif -#undef PAY_SOME #undef PAY_BUY #undef PAY_CANT #undef PAY_SKIP From 10c85d68bb66294140888b261add68e95ce836fa Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 3 Jul 2024 23:28:05 -0700 Subject: [PATCH 013/121] fix #K4172 - selling all into container When using #loot to put items into a shop-owned container on a shop's floor, you are asked "Sell it? [ynaq] (n)" for each item, but the 'a' and 'q' choices only worked as y or n for the current item. By the next one, the preferred answer had been reset to default and ynaq was asked again. Set a flag in use_container() to have in_container() set the sell vs don't sell state for the first item but not for any others. Reset the state at the end of use_container() instead of after each item in in_container(). This bug was present in 3.6.x, also in 3.4.3, and probably earlier. --- doc/fixes3-7-0.txt | 8 +++++++- include/decl.h | 3 ++- src/decl.c | 3 ++- src/pickup.c | 20 ++++++++++++-------- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index b2dbfb4db..ec2ef2923 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1445 $ $NHDT-Date: 1718303201 2024/06/13 18:26:41 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1450 $ $NHDT-Date: 1720074479 2024/07/04 06:27:59 $ General Fixes and Modified Features ----------------------------------- @@ -1431,6 +1431,12 @@ buying shop items which include any unpaid ones inside containers would reveal recent change to pay via menu made the problem become more visible; shopping has been changed such that buying anything that is inside a container requires that the whole container be bought as a unit +using #loot -> 'i'n to put multiple items into a shop-owned container would + ask whether to sell each item to the shop, and was prepared to accept + 'a' to sell the current one plus all the rest beyond it, or to accept + 'q' to not sell the current one or any beyond it, but the sell vs + don't-sell state was being reset for each item so 'a' and 'q' didn't + stick beyond the current one Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index 2b1cff207..ecba32b1f 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1706079834 2024/01/24 07:03:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.355 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1720074483 2024/07/04 06:28:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -937,6 +937,7 @@ struct instance_globals_s { boolean simple_options_help; /* pickup.c */ + boolean sellobj_first; /* True => need sellobj_state(); False => don't */ boolean shop_filter; /* pline.c */ diff --git a/src/decl.c b/src/decl.c index eba205fed..a27e3eed0 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1706079841 2024/01/24 07:04:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.314 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1720074480 2024/07/04 06:28:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.334 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -792,6 +792,7 @@ static const struct instance_globals_s g_init_s = { (struct menucoloring *) 0, /* save_colorings */ FALSE, /* simple_options_help */ /* pickup.c */ + FALSE, /* sellobj_first */ FALSE, /* shop_filter */ /* pline.c */ #ifdef DUMPLOG_CORE diff --git a/src/pickup.c b/src/pickup.c index a215d4ff8..c228d51b7 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pickup.c $NHDT-Date: 1707521383 2024/02/09 23:29:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.370 $ */ +/* NetHack 3.7 pickup.c $NHDT-Date: 1720074481 2024/07/04 06:28:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.374 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2608,12 +2608,14 @@ in_container(struct obj *obj) if (obj->oclass != COIN_CLASS) { /* sellobj() will take an unpaid item off the shop bill */ was_unpaid = obj->unpaid ? TRUE : FALSE; - /* don't sell when putting the item into your own container, - * but handle billing correctly */ - sellobj_state(gc.current_container->no_charge - ? SELL_DONTSELL : SELL_DELIBERATE); + if (gs.sellobj_first) { + /* don't sell when putting the item into your own container, + but handle billing correctly */ + sellobj_state(gc.current_container->no_charge + ? SELL_DONTSELL : SELL_DELIBERATE); + gs.sellobj_first = FALSE; + } sellobj(obj, u.ux, u.uy); - sellobj_state(SELL_NORMAL); } } if (Icebox && !age_is_relative(obj)) { @@ -2645,8 +2647,8 @@ in_container(struct obj *obj) /* if carried, shop goods will be flagged 'unpaid' and obfree() will handle bill issues, but if on floor, we need to put them on bill before deleting them (non-shop items will be flagged 'no_charge') */ - if (floor_container - && costly_spot(gc.current_container->ox, gc.current_container->oy)) { + if (floor_container && costly_spot(gc.current_container->ox, + gc.current_container->oy)) { struct obj save_no_charge; save_no_charge.no_charge = gc.current_container->no_charge; @@ -2943,6 +2945,7 @@ use_container( long loss; ga.abort_looting = FALSE; + gs.sellobj_first = TRUE; /* in_container() should call sellobj_state() */ emptymsg[0] = '\0'; if (!u_handsy()) @@ -3176,6 +3179,7 @@ use_container( update_inventory(); } + sellobj_state(SELL_NORMAL); /* in case in_container() set it */ *objp = gc.current_container; /* might have become null */ if (gc.current_container) gc.current_container = 0; /* avoid hanging on to stale pointer */ From 0e464398142417dc91b9f156d9fd74aaf4563fd9 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Jul 2024 14:19:40 -0700 Subject: [PATCH 014/121] fix add_one_tobill() 'fixme' Not exhaustively tested. --- src/mkobj.c | 4 ++-- src/shk.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/mkobj.c b/src/mkobj.c index 93f762c26..6b0e518d8 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -722,12 +722,12 @@ bill_dummy_object(struct obj *otmp) dummy->timed = 0; copy_oextra(dummy, otmp); if (has_omid(dummy)) - free_omid(dummy); /* only one association with m_id*/ + free_omid(dummy); /* only one association with m_id */ if (Is_candle(dummy)) dummy->lamplit = 0; dummy->owornmask = 0L; /* dummy object is not worn */ addtobill(dummy, FALSE, TRUE, TRUE); - if (cost) + if (cost && dummy->where != OBJ_DELETED) alter_cost(dummy, -cost); /* no_charge is only valid for some locations */ otmp->no_charge = (otmp->where == OBJ_FLOOR diff --git a/src/shk.c b/src/shk.c index bf82f1532..b2380e0f1 100644 --- a/src/shk.c +++ b/src/shk.c @@ -3213,35 +3213,43 @@ unpaid_cost( return amt; } +/* add 'obj' to 'shkp's bill */ staticfn void -add_one_tobill(struct obj *obj, boolean dummy, struct monst *shkp) +add_one_tobill( + struct obj *obj, + boolean dummy, /* True: obj is used up so goes on bill differently */ + struct monst *shkp) { struct eshk *eshkp; struct bill_x *bp; int bct; + boolean unbilled = FALSE; - if (!billable(&shkp, obj, *u.ushops, TRUE)) - return; eshkp = ESHK(shkp); - - if (eshkp->billct == BILLSZ) { - You("got that for free!"); - /* - * FIXME: - * What happens when this is a dummy object? It won't be on any - * object list. - */ - return; - } - /* normally bill_p gets set up whenever you enter the shop, but obj might be going onto the bill because hero just snagged it with a grappling hook from outside without ever having been inside */ if (!eshkp->bill_p) - eshkp->bill_p = &(eshkp->bill[0]); + eshkp->bill_p = &eshkp->bill[0]; + + if (!billable(&shkp, obj, *u.ushops, TRUE)) { + /* shk doesn't want it */ + unbilled = TRUE; + } else if (eshkp->billct == BILLSZ) { + /* shk's bill is completely full */ + You("got that for free!"); + unbilled = TRUE; + } + /* if not on any list (probably from bill_dummy_object() which creates + a new OBJ_FREE object), don't leave unmanaged object hanging around */ + if (unbilled) { + if (obj->where == OBJ_FREE) + dealloc_obj(obj); /* change to obj->where==OBJ_DELETED */ + return; + } bct = eshkp->billct; - bp = &(eshkp->bill_p[bct]); + bp = &eshkp->bill_p[bct]; bp->bo_id = obj->o_id; bp->bquan = obj->quan; if (dummy) { /* a dummy object must be inserted into */ From a33f1edd249c3d3a9865272a68cc31e2d00f9ea7 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Jul 2024 14:27:28 -0700 Subject: [PATCH 015/121] YMonnam(monst) Replace several upstart(y_monnam(mon)) with new YMonnam(mon) to produce "Your little dog" and such. Also change one or two Monnam(mon) to YMonnam(mon) and one pline(...) to pline_mon(mon, ...). --- include/extern.h | 3 ++- src/apply.c | 8 ++++---- src/do_name.c | 22 ++++++++++++++++------ src/hack.c | 33 +++++++++++++++------------------ src/makemon.c | 12 ++++++------ src/steed.c | 6 +++--- src/trap.c | 4 ++-- 7 files changed, 48 insertions(+), 40 deletions(-) diff --git a/include/extern.h b/include/extern.h index a5d0f24e4..58774113f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1718303205 2024/06/13 18:26:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1426 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1720128155 2024/07/04 21:22:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1430 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -649,6 +649,7 @@ extern char *Some_Monnam(struct monst *) NONNULLARG1; extern char *noname_monnam(struct monst *, int) NONNULLARG1; extern char *m_monnam(struct monst *) NONNULLARG1; extern char *y_monnam(struct monst *) NONNULLARG1; +extern char *YMonnam(struct monst *) NONNULLARG1; extern char *Adjmonnam(struct monst *, const char *) NONNULLARG1; extern char *Amonnam(struct monst *) NONNULLARG1; extern char *a_monnam(struct monst *) NONNULLARG1; diff --git a/src/apply.c b/src/apply.c index 7988bbce4..4773d3c86 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1708126533 2024/02/16 23:35:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.437 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1720128162 2024/07/04 21:22:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.449 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -716,7 +716,8 @@ m_unleash(struct monst *mtmp, boolean feedback) if (feedback) { if (canseemon(mtmp)) - pline_mon(mtmp, "%s pulls free of %s leash!", Monnam(mtmp), mhis(mtmp)); + pline_mon(mtmp, "%s pulls free of %s leash!", + Monnam(mtmp), mhis(mtmp)); else Your("leash falls slack."); } @@ -2046,8 +2047,7 @@ jump(int magic) /* 0=Physical, otherwise skill level */ if (!is_valid_jump_pos(cc.x, cc.y, magic, TRUE)) { return ECMD_FAIL; } else if (u.usteed && u_at(cc.x, cc.y)) { - pline("%s isn't capable of jumping in place.", - upstart(y_monnam(u.usteed))); + pline("%s isn't capable of jumping in place.", YMonnam(u.usteed)); return ECMD_FAIL; } else { coord uc; diff --git a/src/do_name.c b/src/do_name.c index c1574618a..01b5d0cf3 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1708126536 2024/02/16 23:35:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1720128164 2024/07/04 21:22:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.319 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1061,7 +1061,7 @@ Monnam(struct monst *mtmp) char *bp = mon_nam(mtmp); *bp = highc(*bp); - return bp; + return bp; } char * @@ -1070,7 +1070,7 @@ noit_Monnam(struct monst *mtmp) char *bp = noit_mon_nam(mtmp); *bp = highc(*bp); - return bp; + return bp; } char * @@ -1079,7 +1079,7 @@ Some_Monnam(struct monst *mtmp) char *bp = some_mon_nam(mtmp); *bp = highc(*bp); - return bp; + return bp; } /* return "a dog" rather than "Fido", honoring hallucination and visibility */ @@ -1113,6 +1113,16 @@ y_monnam(struct monst *mtmp) return x_monnam(mtmp, prefix, (char *) 0, suppression_flag, FALSE); } +/* y_monnam() for start of sentence */ +char * +YMonnam(struct monst *mtmp) +{ + char *bp = y_monnam(mtmp); + + *bp = highc(*bp); + return bp; +} + char * Adjmonnam(struct monst *mtmp, const char *adj) { @@ -1120,7 +1130,7 @@ Adjmonnam(struct monst *mtmp, const char *adj) has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); *bp = highc(*bp); - return bp; + return bp; } char * @@ -1136,7 +1146,7 @@ Amonnam(struct monst *mtmp) char *bp = a_monnam(mtmp); *bp = highc(*bp); - return bp; + return bp; } /* used for monster ID by the '/', ';', and 'C' commands to block remote diff --git a/src/hack.c b/src/hack.c index 1432a06d9..2836500e8 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1715022473 2024/05/06 19:07:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.447 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1720128165 2024/07/04 21:22:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.449 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -389,7 +389,7 @@ moverock(void) case TELEP_TRAP: if (u.usteed) pline("%s pushes %s and suddenly it disappears!", - upstart(y_monnam(u.usteed)), the(xname(otmp))); + YMonnam(u.usteed), the(xname(otmp))); else You("push %s and suddenly it disappears!", the(xname(otmp))); @@ -450,8 +450,7 @@ moverock(void) exercise(A_STR, TRUE); } else { if (givemesg) - pline("%s moves %s.", - upstart(y_monnam(u.usteed)), what); + pline("%s moves %s.", YMonnam(u.usteed), what); } gb.bldrpushtime = gm.moves; } @@ -489,7 +488,7 @@ moverock(void) what = the(xname(otmp)); if (u.usteed) pline("%s tries to move %s, but cannot.", - upstart(y_monnam(u.usteed)), what); + YMonnam(u.usteed), what); else You("try to move %s, but in vain.", what); if (Blind) @@ -1075,7 +1074,7 @@ test_move( } else if (dx && dy && worm_cross(ux, uy, x, y)) { /* consecutive long worm segments are at and */ if (mode == DO_MOVE) - pline("%s is in your way.", Monnam(m_at(ux, y))); + pline("%s is in your way.", YMonnam(m_at(ux, y))); return FALSE; } /* Pick travel path that does not require crossing a trap. @@ -2009,20 +2008,20 @@ domove_swap_with_pet(struct monst *mtmp, coordxy x, coordxy y) didnt_move = TRUE; } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) { /* can't swap places when pet can't move to your spot */ - You("stop. %s can't move diagonally.", upstart(y_monnam(mtmp))); + You("stop. %s can't move diagonally.", YMonnam(mtmp)); didnt_move = TRUE; } else if (u_with_boulder && !(verysmall(mtmp->data) && (!mtmp->minvent || curr_mon_load(mtmp) <= 600))) { /* can't swap places when pet won't fit there with the boulder */ You("stop. %s won't fit into the same spot that you're at.", - upstart(y_monnam(mtmp))); + YMonnam(mtmp)); didnt_move = TRUE; } else if (u.ux0 != x && u.uy0 != y && bad_rock(mtmp->data, x, u.uy0) && bad_rock(mtmp->data, u.ux0, y) && (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) { /* can't swap places when pet won't fit thru the opening */ - You("stop. %s won't fit through.", upstart(y_monnam(mtmp))); + You("stop. %s won't fit through.", YMonnam(mtmp)); didnt_move = TRUE; } else if (mtmp->mpeaceful && mtmp->mtrapped) { /* all mtame are also mpeaceful, so this affects pets too */ @@ -2034,8 +2033,7 @@ domove_swap_with_pet(struct monst *mtmp, coordxy x, coordxy y) feeltrap(trap); /* show on map once mtmp is out of the way */ which = just_an(anbuf, what); /* "a " or "an " */ } - You("stop. %s can't move out of %s%s.", - upstart(y_monnam(mtmp)), which, what); + You("stop. %s can't move out of %s%s.", YMonnam(mtmp), which, what); handle_tip(TIP_UNTRAP_MON); didnt_move = TRUE; } else if (mtmp->mpeaceful @@ -2044,8 +2042,7 @@ domove_swap_with_pet(struct monst *mtmp, coordxy x, coordxy y) || mundisplaceable(mtmp))) { /* displacing peaceful into unsafe or trapped space, or trying to displace quest leader, Oracle, shopkeeper, priest, or vault guard */ - You("stop. %s doesn't want to swap places.", - upstart(y_monnam(mtmp))); + You("stop. %s doesn't want to swap places.", YMonnam(mtmp)); didnt_move = TRUE; } else { mtmp->mtrapped = 0; @@ -2460,7 +2457,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) */ mtmp = u.ustuck; set_ustuck((struct monst *) 0); - You("release %s.", mon_nam(mtmp)); + You("release %s.", y_monnam(mtmp)); } else { /* If holder is asleep or paralyzed: * 37.5% chance of getting away, @@ -2478,7 +2475,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) pull_free: mtmp = u.ustuck; set_ustuck((struct monst *) 0); - You("pull free from %s.", mon_nam(mtmp)); + You("pull free from %s.", y_monnam(mtmp)); break; case 3: if (!u.ustuck->mcanmove) { @@ -2490,7 +2487,7 @@ escape_from_sticky_mon(coordxy x, coordxy y) default: if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf) goto pull_free; - You("cannot escape from %s!", mon_nam(u.ustuck)); + You("cannot escape from %s!", y_monnam(u.ustuck)); nomul(0); return TRUE; } @@ -2733,7 +2730,7 @@ domove_core(void) mtmp->mux = u.ux, mtmp->muy = u.uy; pline("%s swaps places with you...", - !noticed_it ? Something : Monnam(mtmp)); + !noticed_it ? Something : YMonnam(mtmp)); if (!canspotmon(mtmp)) map_invisible(u.ux0, u.uy0); /* monster chose to swap places; hero doesn't get any credit @@ -3673,7 +3670,7 @@ lookaround(void) || (infront && !gc.context.travel)) { if (flags.mention_walls) pline_xy(x, y, "%s blocks your path.", - upstart(a_monnam(mtmp))); + upstart(a_monnam(mtmp))); goto stop; } } diff --git a/src/makemon.c b/src/makemon.c index 2e2662210..249cfc6c7 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makemon.c $NHDT-Date: 1713334814 2024/04/17 06:20:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.245 $ */ +/* NetHack 3.7 makemon.c $NHDT-Date: 1720128166 2024/07/04 21:22:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1999,11 +1999,11 @@ grow_up(struct monst *mtmp, struct monst *victim) slightly less sexist if prepared for it...) */ : (fem && !mtmp->female) ? "female " : "", pmname(ptr, fem)); - pline("%s %s %s.", upstart(y_monnam(mtmp)), - (fem != mtmp->female) ? "changes into" - : humanoid(ptr) ? "becomes" - : "grows up into", - an(buf)); + pline_mon(mtmp, "%s %s %s.", YMonnam(mtmp), + (fem != mtmp->female) ? "changes into" + : humanoid(ptr) ? "becomes" + : "grows up into", + an(buf)); } set_mon_data(mtmp, ptr); if (mtmp->cham == oldtype && is_shapeshifter(ptr)) diff --git a/src/steed.c b/src/steed.c index 7866939f9..0fae5a4ca 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steed.c $NHDT-Date: 1702274036 2023/12/11 05:53:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.115 $ */ +/* NetHack 3.7 steed.c $NHDT-Date: 1720128167 2024/07/04 21:22:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -869,12 +869,12 @@ stucksteed(boolean checkfeeding) if (steed) { /* check whether steed can move */ if (helpless(steed)) { - pline("%s won't move!", upstart(y_monnam(steed))); + pline("%s won't move!", YMonnam(steed)); return TRUE; } /* optionally check whether steed is in the midst of a meal */ if (checkfeeding && steed->meating) { - pline("%s is still eating.", upstart(y_monnam(steed))); + pline("%s is still eating.", YMonnam(steed)); return TRUE; } } diff --git a/src/trap.c b/src/trap.c index 301d686ae..5aaaee0de 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1717884802 2024/06/08 22:13:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.598 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1720128169 2024/07/04 21:22:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.602 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4082,7 +4082,7 @@ climb_pit(void) many times without further user intervention by using a run attempt to keep retrying to escape from the pit) */ if (u.usteed) - Norep("%s is still in a pit.", upstart(y_monnam(u.usteed))); + Norep("%s is still in a pit.", YMonnam(u.usteed)); else Norep((Hallucination && !rn2(5)) ? "You've fallen, and you can't get up." From d4ac146c5f8bf28d5553300e08e5addf13a96405 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 6 Jul 2024 23:12:19 +0300 Subject: [PATCH 016/121] Pets avoid a possible boulder pushing location in Sokoban --- doc/fixes3-7-0.txt | 1 + include/extern.h | 1 + src/dogmove.c | 2 ++ src/monmove.c | 15 +++++++++++++++ 4 files changed, 19 insertions(+) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index ec2ef2923..eef59eac7 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1401,6 +1401,7 @@ gold thrown or kicked at a sleeping monster with the 'greedy' attribute gets neglected to report that target monster was awakened in the process hero movement affects the water bubble movement direction pets and peacefuls avoid a location hero just kicked +pets avoid a possible boulder pushing location in sokoban shopkeepers bill you for using their bear trap or land mine when engraving with a stack of eligible weapons, split one off the stack and dull it rather than dull the whole stack diff --git a/include/extern.h b/include/extern.h index 58774113f..8476b017b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1850,6 +1850,7 @@ extern void m_break_boulder(struct monst *, coordxy, coordxy) NONNULLARG1; extern int dochug(struct monst *) NONNULLARG1; extern boolean m_digweapon_check(struct monst *, coordxy, coordxy) NONNULLARG1; extern boolean m_avoid_kicked_loc(struct monst *, coordxy, coordxy) NONNULLARG1; +extern boolean m_avoid_soko_push_loc(struct monst *, coordxy, coordxy) NONNULLARG1; extern int m_move(struct monst *, int) NONNULLARG1; extern int m_move_aggress(struct monst *, coordxy, coordxy) NONNULLARG1; extern void dissolve_bars(coordxy, coordxy); diff --git a/src/dogmove.c b/src/dogmove.c index 567ab9808..90171c6f8 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1148,6 +1148,8 @@ dog_move( /* avoid a location hero just kicked */ if (m_avoid_kicked_loc(mtmp, nx, ny)) continue; + if (m_avoid_soko_push_loc(mtmp, nx, ny)) + continue; { /* Dog avoids harmful traps, but perhaps it has to pass one diff --git a/src/monmove.c b/src/monmove.c index c461fb46e..18d573f4a 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1240,6 +1240,21 @@ m_avoid_kicked_loc(struct monst *mtmp, coordxy nx, coordxy ny) return FALSE; } +/* monster avoids a location nx, ny, if we're in sokoban, and + there's a boulder between the location and hero */ +boolean +m_avoid_soko_push_loc(struct monst *mtmp, coordxy nx, coordxy ny) +{ + if (Sokoban + && (mtmp->mpeaceful || mtmp->mtame) + && !mtmp->mconf && !mtmp->mstun + && !Conflict + && (dist2(nx, ny, u.ux, u.uy) == 4) + && sobj_at(BOULDER, nx + sgn(u.ux - nx), ny + sgn(u.uy - ny))) + return TRUE; + return FALSE; +} + /* max distmin() distance for monster to look for items */ #define SQSRCHRADIUS 5 From 40716b7b0abb3bbdb4f21b8849f1f2882e244e80 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 6 Jul 2024 17:00:30 -0700 Subject: [PATCH 017/121] fix #K4199 - dereference of null firstmatch pointer Bumping into something (by fuzzer) with mention_walls On crashed when trying to display output generated by do_screen_description(). I wasn't able to reproduce this but didn't spend much time trying. Without a test case I'm only guessing that this fix solves the problem. If there was a monster phazing at the 'wall' location or an object embedded there, the screen description wouldn't be appropriate for trying to describe the terrain. (I don't think that the pass-walls monster csse would reach the affected code but the embedded object case might.) Use the background glyph calculated for the map, which yields the intended "stone" instead of "wall" when outside a not-yet-mapped wall, rather than the displayed glyph. --- src/hack.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/hack.c b/src/hack.c index 2836500e8..886215770 100644 --- a/src/hack.c +++ b/src/hack.c @@ -959,25 +959,24 @@ test_move( return FALSE; } else { if (mode == DO_MOVE) { - if (is_db_wall(x, y)) + if (is_db_wall(x, y)) { pline("That drawbridge is up!"); - /* sokoban restriction stays even after puzzle is solved */ - else if (Passes_walls && !may_passwall(x, y) - && In_sokoban(&u.uz)) + } else if (Passes_walls && !may_passwall(x, y) + && In_sokoban(&u.uz)) { + /* soko restriction stays even after puzzle is solved */ pline_The("Sokoban walls resist your ability."); - else if (flags.mention_walls) { + } else if (flags.mention_walls) { char buf[BUFSZ]; - coord cc; - int sym = 0; - const char *firstmatch = 0; + int glyph = back_to_glyph(x, y), + sym = glyph_is_cmap(glyph) ? glyph_to_cmap(glyph) : -1; - cc.x = x, cc.y = y; - do_screen_description(cc, TRUE, sym, buf, &firstmatch, - NULL); - if (!strcmp(firstmatch, "stone")) - Sprintf(buf, "solid stone"); + if (sym == S_stone) + Strcpy(buf, "solid stone"); + else if (sym >= 0) + Strcpy(buf, an(defsyms[sym].explanation)); else - Sprintf(buf, "%s", an(firstmatch)); + Sprintf(buf, "impossible [background glyph=%d]", + glyph); pline_dir(xytod(dx, dy), "It's %s.", buf); } } From fbda1183d703a5ee499dcd534b9b8312d161b2a6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 7 Jul 2024 10:40:03 -0400 Subject: [PATCH 018/121] comment bit --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 16f92f19a..82d27558c 100644 --- a/src/display.c +++ b/src/display.c @@ -2379,7 +2379,7 @@ swallow_to_glyph(int mnum, int loc) * * Change the given zap direction and beam type into a glyph. Each beam * type has four glyphs, one for each of the symbols below. The order of - * the zap symbols [0-3] as defined in rm.h are: + * the zap symbols [0-3] as defined in defsym.h are: * * | S_vbeam ( 0, 1) or ( 0,-1) * - S_hbeam ( 1, 0) or (-1, 0) From 0447a1f107d516ff042301fd82ca378b48a46db1 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 7 Jul 2024 16:43:55 -0700 Subject: [PATCH 019/121] band-aid for fuzzer crash in doclassdisco() This should prevent the unexplained situation in doclassdisco(the back-tick command) from triggering a crash, but doesn't solve the underlying problem. And the new impossible() will be escalated to panic() by the fuzzer, so will still cause it to die. Still no idea why the class input letter 'c' ended up with value 'I', leading to 'oclass' being MAXOCLASSES and going out of array bounds during during doclassdisco()'s final loop. --- include/decl.h | 2 +- src/o_init.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/decl.h b/include/decl.h index ecba32b1f..db8283ae8 100644 --- a/include/decl.h +++ b/include/decl.h @@ -194,7 +194,7 @@ struct instance_globals_b { #endif /* decl.c */ - int bases[MAXOCLASSES + 1]; + int bases[MAXOCLASSES + 2]; /* make bases[MAXOCLASSES+1] available */ coord bhitpos; /* place where throw or zap hits or stops */ struct obj *billobjs; /* objects not yet paid for */ diff --git a/src/o_init.c b/src/o_init.c index 7ae3840e7..5eb8ec865 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 o_init.c $NHDT-Date: 1701720461 2023/12/04 20:07:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.79 $ */ +/* NetHack 3.7 o_init.c $NHDT-Date: 1720391455 2024/07/07 22:30:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -192,8 +192,12 @@ init_objects(void) /* extra entry allows deriving the range of a class via bases[class] through bases[class+1]-1 for all classes (except for ILLOBJ_CLASS which is separated from WEAPON_CLASS - by generic objects) */ - gb.bases[MAXOCLASSES] = NUM_OBJECTS; + by generic objects); second extra entry is to prevent an + explained crash in doclassdisco(), where the code ended up + attempting to process non-existent class MAXOCLASSES; the + [MAXOCLASSES+1] element gives that non-class 0 objects + when traversing objects[] from bases[X] through bases[X+1]-1 */ + gb.bases[MAXOCLASSES] = gb.bases[MAXOCLASSES + 1] = NUM_OBJECTS; /* hypothetically someone might remove all objects of some class, or be adding a new class and not populated it yet, leaving gaps in bases[]; guarantee that there are no such gaps */ @@ -757,7 +761,8 @@ dodiscovered(void) /* free after Robert Viduya */ if (oclass != prev_class) { if ((alphabyclass || lootsort) && sorted_ct) { /* output previous class */ - disco_output_sorted(tmpwin, sorted_lines, sorted_ct, lootsort); + disco_output_sorted(tmpwin, sorted_lines, sorted_ct, + lootsort); sorted_ct = 0; } if (!alphabetized || alphabyclass) { @@ -884,7 +889,7 @@ doclassdisco(void) i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) if ((dis = gd.disco[i]) != 0 && interesting_to_discover(dis)) { if (!strchr(discosyms, c)) { - Sprintf(eos(discosyms), "%c", c); + (void) strkitten(discosyms, c); if (!traditional) { any.a_int = c; add_menu(tmpwin, &nul_glyphinfo, &any, @@ -981,6 +986,9 @@ doclassdisco(void) break; default: oclass = def_char_to_objclass(c); + /* this should never happen but has been observed via the fuzzer */ + if (oclass == MAXOCLASSES) + impossible("doclassdisco: invalid object class '%s'", visctrl(c)); Sprintf(buf, "Discovered %s in %s", let_to_name(oclass, FALSE, FALSE), (flags.discosort == 'o') ? "order of discovery" : (flags.discosort == 's') ? "'sortloot' order" From 8073c40477f08299d391cf17f5fc27fa91997493 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 7 Jul 2024 17:34:37 -0700 Subject: [PATCH 020/121] redo nowrap_add() Yahoo!'s mailer delivered the report about nowrap_add() to my spam folder, apparently because it thinks that the signature attachments "may contain harmful content". :-( nowrap_add() checks for signed overflow after the fact, so after undefined behavior if that happens. This rewrites nowrap_add() and moves it from end.c to integer.h. I haven't generated any values big enough to exercise it, but the algorithm is straightforward so I'll take it on faith. --- include/integer.h | 7 ++++++- src/botl.c | 23 +++++++++++++---------- src/end.c | 6 +----- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/integer.h b/include/integer.h index 435da8ad3..32a3b3266 100644 --- a/include/integer.h +++ b/include/integer.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 integer.h $NHDT-Date: 1717967331 2024/06/09 21:08:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ @@ -110,4 +110,9 @@ typedef uint64_t uint64; ? (L) * 10L + (D) \ : -1L) +/* add a and b, return max long value if overflow would have occurred; + assumes that both a and b are non-negative; caller should apply + cast(s) to (long) in the arguments if any are needed */ +#define nowrap_add(a,b) ((a) <= (LONG_MAX - (b)) ? ((a) + (b)) : LONG_MAX) + #endif /* INTEGER_H */ diff --git a/src/botl.c b/src/botl.c index c415c554b..6f6234f4a 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.c $NHDT-Date: 1694893342 2023/09/16 19:42:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 3.7 botl.c $NHDT-Date: 1720397739 2024/07/08 00:15:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -423,17 +423,20 @@ long botl_score(void) { long deepest = deepest_lev_reached(FALSE); - long utotal; + long umoney, depthbonus; /* hidden_gold(False): only gold in containers whose contents are known */ - utotal = money_cnt(gi.invent) + hidden_gold(FALSE); - if ((utotal -= u.umoney0) < 0L) - utotal = 0L; - utotal += u.urexp + (50 * (deepest - 1)) - + (deepest > 30 ? 10000 : deepest > 20 ? 1000 * (deepest - 20) : 0); - if (utotal < u.urexp) - utotal = LONG_MAX; /* wrap around */ - return utotal; + umoney = money_cnt(gi.invent) + hidden_gold(FALSE); + /* don't include initial gold; don't impose penalty if its all gone */ + if ((umoney -= u.umoney0) < 0L) + umoney = 0L; + depthbonus = 50 * (deepest - 1) + + (deepest > 30) ? 10000 + : (deepest > 20) ? 1000 * (deepest - 20) + : 0; + /* neither umoney nor depthbonus can grow unusually big (gold due to + weight); u.urexp might */ + return nowrap_add(u.urexp, umoney + depthbonus); } #endif /* SCORE_ON_BOTL */ diff --git a/src/end.c b/src/end.c index 48e017d7c..6287bfc5c 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1711735821 2024/03/29 18:10:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.313 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,10 +15,6 @@ #endif #include "dlb.h" - -/* add b to long a, convert wraparound to max value */ -#define nowrap_add(a, b) (a = ((a + b) < 0 ? LONG_MAX : (a + b))) - #ifndef NO_SIGNAL staticfn void done_intr(int); # if defined(UNIX) || defined(VMS) || defined(__EMX__) From 0598880bb592e17c28848905779ad52f92483e49 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 8 Jul 2024 02:52:40 -0700 Subject: [PATCH 021/121] minor shk.c comment fix --- src/shk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shk.c b/src/shk.c index b2380e0f1..2f999d2a3 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1979,7 +1979,7 @@ pay_billed_items( otmp = bp_to_obj(bp); ebillct = eshkp->billct; more_than_one = (ebillct > 1 || otmp->quan < bp->bquan - /* note: will only get here for for single item, so + /* note: will only get here for a single item, so we can deduce that it is ibill[0] */ || ibill[0].usedup == UndisclosedContainer); if ((umoney + eshkp->credit) < cheapest_item(ibillct, ibill)) { From 49a669a863b5d1f2eca0f7bc628d7436a997de33 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 8 Jul 2024 13:50:26 -0700 Subject: [PATCH 022/121] yn_function() sanity Add the impossible with slightly less detail. With any luck paxed's magic debugger can track down what is happening with the canned response queue. --- src/cmd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cmd.c b/src/cmd.c index dd1d40fe6..e4d68213c 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -5158,6 +5158,18 @@ yn_function( dumplogmsg(dumplog_buf); } #endif + /* should not happen but cq.key has been observed to not obey 'resp'; + do this after dumplog has recorded the potentially bad value */ + if (!res || (resp && !strchr(resp, res))) { + /* this probably needs refinement since caller is expecting something + within 'resp' and ESC won't be (it could be present, but as a flag + for unshown possibilities rather than as acceptable input) */ + int altres = def ? def : '\033'; + + impossible("yn_function() returned '%s'; using '%s' instead", + visctrl(res), visctrl(altres)); + res = altres; + } /* in case we're called via getdir() which sets input_state */ gp.program_state.input_state = otherInp; return res; From e6ccd734e5e292e8185a91f75c175a358dc41b02 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2024 01:55:55 -0700 Subject: [PATCH 023/121] yn_function() again The new impossible() was testing for a NUL response incorrectly. --- src/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd.c b/src/cmd.c index e4d68213c..3222dc833 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -5160,7 +5160,7 @@ yn_function( #endif /* should not happen but cq.key has been observed to not obey 'resp'; do this after dumplog has recorded the potentially bad value */ - if (!res || (resp && !strchr(resp, res))) { + if (resp && res && !strchr(resp, res)) { /* this probably needs refinement since caller is expecting something within 'resp' and ESC won't be (it could be present, but as a flag for unshown possibilities rather than as acceptable input) */ From ee08c05e03febe94797f3d4b8032b415becc33a0 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2024 02:48:05 -0700 Subject: [PATCH 024/121] quest leader|guardians seeing hero attack peaceful If the quest leader observes the hero attacking a peaceful monster, only become angry if that peaceful monster is a quest guardian. And when becoming angry, stop waiting for the hero to approach. If a quest guardian observes the hero attacking any peaceful monster, don't run away. --- doc/fixes3-7-0.txt | 3 +++ src/mon.c | 13 ++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index eef59eac7..cc4a5883e 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1983,6 +1983,9 @@ fix regression of a post-3.6 fix: if 2 Wizards of Yendor were in play and 1 sometimes a repeat count from the preceding command carried over to most recent one when using do-again (^A); if the most recent one was an extended command, the spurious repeat was for '#' +if peaceful monsters react when seeing hero attack a peaceful monster, don't + have quest guardians run away; also, quest leader only becomes angry + if the monster being attacked is a quest guardian Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index a436dc897..b7114e9d9 100644 --- a/src/mon.c +++ b/src/mon.c @@ -4050,14 +4050,20 @@ peacefuls_respond(struct monst *mtmp) } } /* shopkeepers and temple priests might gasp in - surprise, but they won't become angry here */ - if (mon->isshk || mon->ispriest) { + surprise, but they won't become angry here; + quest leader will only get angry if hero attacks + own quest guardians */ + if (mon->isshk || mon->ispriest + || (mon->data == &mons[quest_info(MS_LEADER)] + && mtmp->data != &mons[gu.urole.guardnum])) { if (exclaimed) pline_mon(mon, "%s%s", buf, " then shrugs."); continue; } - if (mon->data->mlevel < rn2(10)) { + if (mon->data->mlevel < rn2(10) + /* don't have quest guardians turn to flee */ + && (mon->data != &mons[gu.urole.guardnum])) { alreadyfleeing = (mon->mflee || mon->mfleetim); monflee(mon, rn2(50) + 25, TRUE, !exclaimed); if (exclaimed) { @@ -4075,6 +4081,7 @@ peacefuls_respond(struct monst *mtmp) * perhaps reduce tameness? */ } else { mon->mpeaceful = 0; + mon->mstrategy &= ~STRAT_WAITMASK; adjalign(-1); if (!exclaimed) pline_mon(mon, "%s gets angry!", Monnam(mon)); From cf44c3046e8682a2bdbaabb3da59e7fcbdce8e9f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 9 Jul 2024 18:08:19 +0300 Subject: [PATCH 025/121] Join wall spines with walls of water and lava --- doc/fixes3-7-0.txt | 1 + src/mkmaze.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index cc4a5883e..1bb0acfe1 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1438,6 +1438,7 @@ using #loot -> 'i'n to put multiple items into a shop-owned container would 'q' to not sell the current one or any beyond it, but the sell vs don't-sell state was being reset for each item so 'a' and 'q' didn't stick beyond the current one +join wall "spines" with walls of water and lava Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/mkmaze.c b/src/mkmaze.c index 5acf97cc6..040d466f3 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -40,6 +40,7 @@ staticfn boolean is_exclusion_zone(xint16, coordxy, coordxy); } \ } while (0) +/* used to determine if wall spines can join this location */ staticfn int iswall(coordxy x, coordxy y) { @@ -49,9 +50,11 @@ iswall(coordxy x, coordxy y) return 0; type = levl[x][y].typ; return (IS_WALL(type) || IS_DOOR(type) + || type == LAVAWALL || type == WATER || type == SDOOR || type == IRONBARS); } +/* used to determine if wall spines can join this location */ staticfn int iswall_or_stone(coordxy x, coordxy y) { From a59cd7154069b11159bd6ed6802651e50a23bc3a Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2024 12:42:45 -0700 Subject: [PATCH 026/121] nowrap_add() vs final score The old nowrap_add() had different semantics from its replacement, performing an assignment as well as an addition. Now just does the addition; its caller needs to perform the assignment. --- src/end.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/end.c b/src/end.c index 6287bfc5c..fc1215775 100644 --- a/src/end.c +++ b/src/end.c @@ -910,7 +910,7 @@ artifact_score( value = arti_cost(otmp); /* zorkmid value */ points = value * 5 / 2; /* score value */ if (counting) { - nowrap_add(u.urexp, points); + u.urexp = nowrap_add(u.urexp, points); } else { discover_object(otmp->otyp, TRUE, FALSE); otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; @@ -1320,7 +1320,7 @@ really_done(int how) tmp += 50L * (long) (deepest - 1); if (deepest > 20) tmp += 1000L * (long) ((deepest > 30) ? 10 : deepest - 20); - nowrap_add(u.urexp, tmp); + u.urexp = nowrap_add(u.urexp, tmp); /* ascension gives a score bonus iff offering to original deity */ if (how == ASCENDED && u.ualign.type == u.ualignbase[A_ORIGINAL]) { @@ -1329,7 +1329,7 @@ really_done(int how) tmp = (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL]) ? u.urexp : (u.urexp / 2L); - nowrap_add(u.urexp, tmp); + u.urexp = nowrap_add(u.urexp, tmp); } } @@ -1427,7 +1427,7 @@ really_done(int how) if (val->list[i].count != 0L) { tmp = val->list[i].count * (long) objects[val->list[i].typ].oc_cost; - nowrap_add(u.urexp, tmp); + u.urexp = nowrap_add(u.urexp, tmp); } /* count the points for artifacts */ @@ -1440,7 +1440,7 @@ really_done(int how) while (mtmp) { Sprintf(eos(pbuf), " and %s", mon_nam(mtmp)); if (mtmp->mtame) - nowrap_add(u.urexp, mtmp->mhp); + u.urexp = nowrap_add(u.urexp, mtmp->mhp); mtmp = mtmp->nmon; } /* [it might be more robust to create a housecat and add it to @@ -1449,7 +1449,7 @@ really_done(int how) int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]); mhp = d(m_lev, 8); - nowrap_add(u.urexp, mhp); + u.urexp = nowrap_add(u.urexp, mhp); Strcat(eos(pbuf), " and Schroedinger's cat"); } dump_forward_putstr(endwin, 0, pbuf, done_stopprint); From 0b30a7b18a620db45bd8f12f23ebbcb424d11ab9 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 9 Jul 2024 15:49:48 -0700 Subject: [PATCH 027/121] farlook vs "wall of lava" Implement a couple of missing bits for wall of lava terrain. It was immune to being distorted by hallucination, unlike molten lava and wall of water. And the presence of wall of lava made molten lava, after being shortened to "lava", no longer be listed as something represented by the "}" character. I started to renumber S_water, which would eliminate some hackery from farlook's do_screen_description(), but that will require an EDITLEVEL increment and make it necessary to reorder/renumber the corresponding tiles so I stopped short. This adds NHDT tags to the first line of defsym.h. --- doc/fixes3-7-0.txt | 3 +++ include/defsym.h | 6 ++++-- src/pager.c | 42 ++++++++++++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 1bb0acfe1..0db220b28 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1987,6 +1987,9 @@ sometimes a repeat count from the preceding command carried over to most if peaceful monsters react when seeing hero attack a peaceful monster, don't have quest guardians run away; also, quest leader only becomes angry if the monster being attacked is a quest guardian +farlook of water/lava location listed wall of lava before molten lava; because + of that, lava was omitted ("molten" suppressed to reduce vebosity, + resulting in "lava" which got skipped as substring of "wall of lava") Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/include/defsym.h b/include/defsym.h index f51fd96ae..3370f6d2d 100644 --- a/include/defsym.h +++ b/include/defsym.h @@ -1,8 +1,7 @@ -/* NetHack 3.7 defsym.h */ +/* NetHack 3.7 defsym.h $NHDT-Date: 1720565306 2024/07/09 22:48:26 $ $NHDT-Branch: NetHack-3.7 $ $NHDT-Revision: 1.24 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ - /* This header is included in multiple places to produce different code depending on its use. Its purpose is to @@ -131,6 +130,7 @@ PCHAR2(35, '\\', S_throne, "throne", "opulent throne", HI_GOLD) PCHAR( 36, '{', S_sink, "sink", CLR_WHITE) PCHAR( 37, '{', S_fountain, "fountain", CLR_BRIGHT_BLUE) + /* the S_pool symbol is used for both POOL terrain and MOAT terrain */ PCHAR2(38, '}', S_pool, "pool", "water", CLR_BLUE) PCHAR( 39, '.', S_ice, "ice", CLR_CYAN) PCHAR( 40, '}', S_lava, "molten lava", CLR_RED) @@ -145,6 +145,8 @@ "raised drawbridge", CLR_BROWN) PCHAR( 46, ' ', S_air, "air", CLR_CYAN) PCHAR( 47, '#', S_cloud, "cloud", CLR_GRAY) + /* the S_water symbol is used for WATER terrain: wall of water in the + dungeon and Plane of Water in the endgame */ PCHAR( 48, '}', S_water, "water", CLR_BRIGHT_BLUE) /* end dungeon characters */ /* */ diff --git a/src/pager.c b/src/pager.c index c1536421e..05078f7a4 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1713334816 2024/04/17 06:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1720565361 2024/07/09 22:49:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.275 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -580,6 +580,8 @@ ice_descr(coordxy x, coordxy y, char *outbuf) } else { long time_left = spot_time_left(x, y, MELT_ICE_AWAY); + /* other, real ice thickness/strength terminology exists but seems + to be too unfamiliar for nethack's use */ iflags.ice_rating = !time_left ? 0 /* solid */ : (time_left > 1000L) ? 1 /* sturdy */ : (time_left > 100L) ? 2 /* steady */ @@ -713,8 +715,9 @@ lookat(coordxy x, coordxy y, char *buf, char *monbuf) Is_airlevel(&u.uz) ? "cloudy area" : "fog/vapor cloud"); break; case S_pool: - case S_water: + case S_water: /* was Plane of Water, now that or "wall of water" */ case S_lava: + case S_lavawall: case S_ice: /* for hallucination; otherwise defsyms[] would be fine */ Strcpy(buf, waterbody_name(x, y)); break; @@ -1102,7 +1105,7 @@ add_cmap_descr( if (absidx == S_pool) idx = S_pool; } else if (absidx == S_pool || idx == S_water - || idx == S_lava || idx == S_ice) { + || idx == S_lava || idx == S_lavawall || idx == S_ice) { /* replace some descriptions (x_str) with waterbody_name() */ schar save_ltyp = levl[cc.x][cc.y].typ; long save_prop = EHalluc_resistance; @@ -1121,26 +1124,34 @@ add_cmap_descr( it's not pool so must be one of water/lava/ice to get here */ levl[cc.x][cc.y].typ = (idx == S_water) ? WATER : (idx == S_lava) ? LAVAPOOL - : ICE; + : (idx == S_lavawall) ? LAVAWALL + : ICE; } EHalluc_resistance = 1; Strcpy(mbuf, waterbody_name(cc.x, cc.y)); EHalluc_resistance = save_prop; levl[cc.x][cc.y].typ = save_ltyp; - /* shorten the feedback for farlook/quicklook: "a pool or ..." */ + /* shorten the feedback for farlook/quicklook: "pool or ..." */ if (!strcmp(mbuf, "pool of water")) mbuf[4] = '\0'; else if (!strcmp(mbuf, "molten lava")) Strcpy(mbuf, "lava"); x_str = mbuf; + /* avoid "an ice" and so forth; "a pool", "a moat", and + "a wall of ..." are grammatically correct but make + "a pool or a moat or a wall of water" become too verbose */ article = !(!strncmp(x_str, "water", 5) || !strncmp(x_str, "ice", 3) + || !strncmp(x_str, "pool", 4) + || !strncmp(x_str, "moat", 4) || !strncmp(x_str, "lava", 4) || !strncmp(x_str, "swamp", 5) || !strncmp(x_str, "molten", 6) || !strncmp(x_str, "shallow", 7) || !strncmp(x_str, "limitless", 9) + || !strncmp(x_str, "wall of lava", 12) + || !strncmp(x_str, "wall of water", 13) /* ice while hallucinating */ || !strncmp(x_str, "frozen", 6) /* thawing ice ("solid ice", "thin ice", &c) */ @@ -1379,15 +1390,24 @@ do_screen_description( for (hit_trap = FALSE, i = 0; i < MAXPCHARS; i++) { /* * Index hackery: we want - * "a pool or a moat or a wall of water or lava" + * "pool or moat or wall of water or lava or wall of lava" * rather than - * "a pool or a moat or lava or a wall of water" + * "pool or moat or lava or wall of lava or wall of water" * but S_lava comes before S_water so 'i' reaches it sooner. * Use 'alt_i' for the rest of the loop to behave as if their * places were swapped. + * This was much simpler when it just exchanged water and lava. + * Now it rotates water to the first of (lava, lavawall, water) + * lava to the middle of (lava, lavawall, water), and lavawall + * to last of (lava, lavawall, water); other values are used + * as-is. + * If S_water (and corresponding tile) were renumbered, this + * hackery could go away. */ - alt_i = ((i != S_water && i != S_lava) ? i /* as-is */ - : (S_water + S_lava - i)); /* swap water and lava */ + alt_i = (i == S_lava) ? S_water /* do water first (of these 3) */ + : (i == S_lavawall) ? S_lava /* process lava second */ + : (i == S_water) ? S_lavawall /* and wall of lava third */ + : i; /* other; handle in defsyms[] order */ x_str = defsyms[alt_i].explanation; /* cmap includes beams, shield effects, swallow boundaries, and explosions; skip all of those */ @@ -1424,7 +1444,9 @@ do_screen_description( if (alt_i == S_altar || is_cmap_trap(alt_i) || (hallucinate && (alt_i == S_water /* S_pool already done */ - || alt_i == S_lava || alt_i == S_ice)) + || alt_i == S_lava + || alt_i == S_lavawall + || alt_i == S_ice)) || alt_i == S_engroom || alt_i == S_engrcorr || alt_i == S_grave) /* 'need_to_look' to report engraving */ need_to_look = TRUE; From b844632dfd93a211ab167a209798119e85a0f423 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Thu, 11 Jul 2024 16:35:24 +0200 Subject: [PATCH 028/121] bump EDITLEVEL for 0447a1f10 Commit 0447a1f10 accidentally broke save compatibility. --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index 6bbe25e57..6455239bd 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 103 +#define EDITLEVEL 104 /* * Development status possibilities. From 0e4083153c0b754535f02bf65a6616b37b09a929 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 11 Jul 2024 10:22:40 -0700 Subject: [PATCH 029/121] another EDITLEVEL increment Since save and bones files just got clobbered, make another clobbering change. The 'queuedpay' field added to shop's ESHK(shkp)->bill[] was replaced last week by a similar field in the transient itemizing bill. At the time, the old field was left in place to avoid incrementing EDITLEVEL. shkp->mextra->bill[] is saved and restored, so its queuedpay field was too. Eliminate that no longer used field. Unrelated: bill[]->useup is declared as boolean but being assigned 1 or 0. Change the assignments to use TRUE or FALSE. --- include/mextra.h | 3 +-- include/patchlevel.h | 4 ++-- src/shk.c | 15 +++++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/mextra.h b/include/mextra.h index 13ba7f254..1d044406b 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mextra.h $NHDT-Date: 1596498545 2020/08/03 23:49:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 mextra.h $NHDT-Date: 1720717969 2024/07/11 17:12:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -113,7 +113,6 @@ struct epri { struct bill_x { unsigned bo_id; boolean useup; - boolean queuedpay; long price; /* price per unit */ long bquan; /* amount used up */ }; diff --git a/include/patchlevel.h b/include/patchlevel.h index 6455239bd..f589da6a7 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 patchlevel.h $NHDT-Date: 1703294869 2023/12/23 01:27:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ */ +/* NetHack 3.7 patchlevel.h $NHDT-Date: 1720717988 2024/07/11 17:13:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.261 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 104 +#define EDITLEVEL 105 /* * Development status possibilities. diff --git a/src/shk.c b/src/shk.c index 2f999d2a3..5bd1abe1d 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1652299941 2022/05/11 20:12:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1720717993 2024/07/11 17:13:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.298 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1134,7 +1134,7 @@ obfree(struct obj *obj, struct obj *merge) if ((bp = onbill(obj, shkp, FALSE)) != 0) { if (!merge) { - bp->useup = 1; + bp->useup = TRUE; obj->unpaid = 0; /* only for doinvbill */ /* for used up glob, put back original weight in case it gets formatted ('I x' or itemized billing) with 'wizweight' On */ @@ -1483,7 +1483,6 @@ make_itemized_bill( n = 0; /* number of entries in ibill[]; won't necessary match ebillct */ for (i = 0; i < ebillct; ++i) { bp = &eshkp->bill_p[i]; - bp->queuedpay = FALSE; /* [no longer used] */ /* find the object on the bill */ otmp = bp_to_obj(bp); if (!otmp) { @@ -1496,7 +1495,7 @@ make_itemized_bill( was first unpaid; otmp is on billobjs list where it can only be seen via Ix and itemized billing while paying shk */ otmp->quan = bp->bquan; - bp->useup = 1; /* (expected to be set already) */ + bp->useup = TRUE; /* (expected to be set already) */ } else if (otmp->quan < bp->bquan) { /* item is partly used up; we will create two entries in the augmented bill: one for the used up part here, another for @@ -3253,10 +3252,10 @@ add_one_tobill( bp->bo_id = obj->o_id; bp->bquan = obj->quan; if (dummy) { /* a dummy object must be inserted into */ - bp->useup = 1; /* the gb.billobjs chain here. crucial for */ + bp->useup = TRUE; /* the gb.billobjs chain here. crucial for */ add_to_billobjs(obj); /* eating floorfood in shop. see eat.c */ } else - bp->useup = 0; + bp->useup = FALSE; bp->price = get_cost(obj, shkp); if (obj->globby) { /* for globs, the amt charged for quan 1 depends on owt */ @@ -3556,7 +3555,7 @@ splitbill(struct obj *obj, struct obj *otmp) bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]); bp->bo_id = otmp->o_id; bp->bquan = otmp->quan; - bp->useup = 0; + bp->useup = FALSE; bp->price = tmp; ESHK(shkp)->billct++; } @@ -3579,7 +3578,7 @@ sub_one_frombill(struct obj *obj, struct monst *shkp) otmp->where = OBJ_FREE; otmp->quan = (bp->bquan -= obj->quan); otmp->owt = 0; /* superfluous */ - bp->useup = 1; + bp->useup = TRUE; add_to_billobjs(otmp); return; } From 6c0ae092c6ca0b5c2e99524f79043e3cd79f6201 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 13 Jul 2024 14:57:50 -0400 Subject: [PATCH 030/121] distinguish global variables that get written to savefile The g? structs had a mix of variables that were written to the savefile, and those that were not. For better clarity and to distinguish those that end up in the savefile, relocate some g? variables that get written directly to the savefile into different structs. This updates EDITLEVEL, although technically it probably didn't need to, since savefile contents are not changing. Details: gb.bases -> svb.bases gb.bbubbles -> svb.bbubbles gb.branches -> svb.branches gc.context -> svc.context gd.disco -> svd.disco gd.dndest -> svd.dndest gd.doors -> svd.doors gd.doors_alloc -> svd.doors_alloc gd.dungeon_topology -> svd.dungeon_topology gd.dungeons -> svd.dungeons ge.exclusion_zones -> sve.exclusion_zones gh.hackpid -> svh.hackpid gi.inv_pos -> svi.inv_pos gk.killer -> svk.killer gl.lastseentyp -> svl.lastseentyp gl.level -> svl.level gl.level_info -> svl.level_info gm.mapseenchn -> svm.mapseenchn gm.moves -> svm.moves gm.mvitals -> svm.mvitals gn.n_dgns -> svn.n_dgns gn.n_regions -> svn.n_regions gn.nroom -> svn.nroom go.oracle_cnt -> svo.oracle_cnt gp.pl_character -> svp.pl_character gp.pl_fruit -> svp.pl_fruit gp.plname -> svp.plname gp.program_state -> svp.program_state gq.quest_status -> svq.quest_status gr.rooms -> svr.rooms gs.sp_levchn -> svs.sp_levchn gs.spl_book -> svs.spl_book gt.timer_id -> svt.timer_id gt.tune -> svt.tune gu.updest -> svu.updest gx.xmax -> svx.xmax gx.xmin -> svx.xmin gy.ymax -> svy.ymax gy.ymin -> svy.ymin Related note: There are some pointer variables that are heads of chains that were not moved from 'g?' to 'sv?', because they are not actually written to the savefile directly, but the objects/monst/trap/lightsource/timer in the chains they point to are. That can be changed, if desired. Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons, gf.ftrap, gl.light_base, gt.timer_base --- include/align.h | 2 +- include/context.h | 2 +- include/decl.h | 197 +++++++++++----- include/display.h | 6 +- include/dungeon.h | 2 +- include/flag.h | 2 +- include/hack.h | 72 +++--- include/mextra.h | 4 +- include/mkroom.h | 14 +- include/monflag.h | 2 +- include/monst.h | 4 +- include/obj.h | 6 +- include/patchlevel.h | 2 +- include/rm.h | 38 ++-- include/spell.h | 6 +- outdated/sys/amiga/amirip.c | 2 +- outdated/sys/amiga/winamenu.c | 2 +- outdated/sys/amiga/winami.c | 24 +- outdated/sys/be/bemain.c | 16 +- outdated/sys/mac/macfile.c | 2 +- outdated/sys/mac/macmain.c | 2 +- outdated/sys/mac/macmenu.c | 18 +- outdated/sys/mac/macunix.c | 2 +- outdated/sys/wince/mhdlg.c | 2 +- outdated/sys/wince/mhinput.c | 6 +- outdated/sys/wince/mhmain.c | 2 +- outdated/sys/wince/mhmenu.c | 2 +- outdated/sys/wince/mhstatus.c | 4 +- outdated/sys/wince/mhtext.c | 2 +- outdated/sys/wince/mswproc.c | 2 +- outdated/sys/wince/winhack.c | 4 +- outdated/win/Qt3/qt3_win.cpp | 30 +-- outdated/win/gem/wingem.c | 4 +- outdated/win/gnome/gnbind.c | 8 +- outdated/win/gnome/gnstatus.c | 4 +- src/allmain.c | 82 +++---- src/apply.c | 36 +-- src/artifact.c | 36 +-- src/attrib.c | 22 +- src/ball.c | 2 +- src/bones.c | 42 ++-- src/botl.c | 30 +-- src/cmd.c | 114 +++++----- src/dbridge.c | 38 ++-- src/decl.c | 228 ++++++++++++++----- src/detect.c | 46 ++-- src/dig.c | 146 ++++++------ src/display.c | 50 ++--- src/do.c | 70 +++--- src/do_name.c | 12 +- src/do_wear.c | 126 +++++------ src/dog.c | 38 ++-- src/dogmove.c | 32 +-- src/dokick.c | 32 +-- src/dothrow.c | 42 ++-- src/dungeon.c | 410 +++++++++++++++++----------------- src/eat.c | 326 +++++++++++++-------------- src/end.c | 138 ++++++------ src/engrave.c | 84 +++---- src/exper.c | 6 +- src/explode.c | 40 ++-- src/extralev.c | 24 +- src/files.c | 94 ++++---- src/fountain.c | 12 +- src/getpos.c | 4 +- src/hack.c | 236 +++++++++---------- src/insight.c | 88 ++++---- src/invent.c | 36 +-- src/lock.c | 14 +- src/mail.c | 12 +- src/makemon.c | 74 +++--- src/mcastu.c | 14 +- src/mhitm.c | 6 +- src/mhitu.c | 24 +- src/minion.c | 8 +- src/mklev.c | 294 ++++++++++++------------ src/mkmap.c | 34 +-- src/mkmaze.c | 162 +++++++------- src/mkobj.c | 112 +++++----- src/mkroom.c | 86 +++---- src/mon.c | 126 +++++------ src/mondata.c | 2 +- src/monmove.c | 16 +- src/mthrowu.c | 4 +- src/muse.c | 26 +-- src/music.c | 22 +- src/nhlobj.c | 2 +- src/nhlsel.c | 2 +- src/nhlua.c | 32 +-- src/o_init.c | 76 +++---- src/objnam.c | 46 ++-- src/options.c | 90 ++++---- src/pager.c | 20 +- src/pickup.c | 40 ++-- src/pline.c | 22 +- src/polyself.c | 52 ++--- src/potion.c | 10 +- src/pray.c | 24 +- src/priest.c | 26 +-- src/quest.c | 8 +- src/questpgr.c | 18 +- src/read.c | 50 ++--- src/region.c | 84 +++---- src/restore.c | 142 ++++++------ src/rip.c | 2 +- src/role.c | 52 ++--- src/rumors.c | 40 ++-- src/save.c | 132 +++++------ src/selvar.c | 2 +- src/sfstruct.c | 4 +- src/shk.c | 136 +++++------ src/shknam.c | 40 ++-- src/sit.c | 4 +- src/sounds.c | 54 ++--- src/sp_lev.c | 176 +++++++-------- src/spell.c | 146 ++++++------ src/stairs.c | 2 +- src/steed.c | 4 +- src/teleport.c | 128 +++++------ src/timeout.c | 100 ++++----- src/topten.c | 26 +-- src/trap.c | 48 ++-- src/u_init.c | 4 +- src/uhitm.c | 38 ++-- src/vault.c | 30 +-- src/vision.c | 16 +- src/weapon.c | 2 +- src/were.c | 2 +- src/wield.c | 10 +- src/windows.c | 14 +- src/wizard.c | 14 +- src/wizcmds.c | 80 +++---- src/worm.c | 14 +- src/worn.c | 12 +- src/write.c | 6 +- src/zap.c | 82 +++---- sys/libnh/libnhmain.c | 34 +-- sys/msdos/pckeys.c | 2 +- sys/msdos/vidvesa.c | 2 +- sys/msdos/vidvga.c | 2 +- sys/share/pcmain.c | 16 +- sys/share/pcunix.c | 4 +- sys/unix/unixmain.c | 32 +-- sys/unix/unixunix.c | 10 +- sys/vms/vmsmain.c | 16 +- sys/vms/vmstty.c | 2 +- sys/vms/vmsunix.c | 6 +- sys/windows/consoletty.c | 10 +- sys/windows/windmain.c | 24 +- win/Qt/qt_bind.cpp | 14 +- win/Qt/qt_main.cpp | 10 +- win/Qt/qt_menu.cpp | 2 +- win/Qt/qt_plsel.cpp | 14 +- win/Qt/qt_stat.cpp | 8 +- win/Qt/qt_yndlg.cpp | 2 +- win/X11/winX.c | 18 +- win/X11/winmap.c | 4 +- win/X11/winmisc.c | 32 +-- win/X11/winstat.c | 8 +- win/X11/wintext.c | 4 +- win/curses/cursdial.c | 6 +- win/curses/cursmain.c | 8 +- win/curses/cursmisc.c | 2 +- win/curses/cursstat.c | 14 +- win/curses/curswins.c | 10 +- win/tty/getline.c | 2 +- win/tty/topl.c | 2 +- win/tty/wintty.c | 38 ++-- win/win32/mhdlg.c | 2 +- win/win32/mhinput.c | 6 +- win/win32/mhmain.c | 8 +- win/win32/mhmenu.c | 4 +- win/win32/mhrip.c | 2 +- win/win32/mswproc.c | 8 +- 174 files changed, 3502 insertions(+), 3305 deletions(-) diff --git a/include/align.h b/include/align.h index 538ac4047..0ccaf0e4d 100644 --- a/include/align.h +++ b/include/align.h @@ -14,7 +14,7 @@ typedef struct align { /* alignment & record */ } align; /* bounds for "record" -- respect initial alignments of 10 */ -#define ALIGNLIM (10L + (gm.moves / 200L)) +#define ALIGNLIM (10L + (svm.moves / 200L)) #define A_NONE (-128) /* the value range of type */ diff --git a/include/context.h b/include/context.h index 167885d6c..ab9baf3bb 100644 --- a/include/context.h +++ b/include/context.h @@ -142,7 +142,7 @@ struct context_info { * 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF-, * 8: travel */ unsigned startingpet_mid; /* monster id number for initial pet */ - int current_fruit; /* fruit->fid corresponding to gp.pl_fruit[] */ + int current_fruit; /* fruit->fid corresponding to svp.pl_fruit[] */ int mysteryforce; /* adjusts how often "mysterious force" kicks in */ int rndencode; /* randomized escape sequence introducer */ int warnlevel; /* threshold (digit) to warn about unseen mons */ diff --git a/include/decl.h b/include/decl.h index db8283ae8..f4c8abbe9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -194,13 +194,9 @@ struct instance_globals_b { #endif /* decl.c */ - int bases[MAXOCLASSES + 2]; /* make bases[MAXOCLASSES+1] available */ coord bhitpos; /* place where throw or zap hits or stops */ struct obj *billobjs; /* objects not yet paid for */ - /* dungeon.c */ - branch *branches; /* dungeon branch list */ - /* files.c */ char bones[BONESSIZE]; @@ -212,7 +208,6 @@ struct instance_globals_b { /* mkmaze.c */ lev_region bughack; /* for preserving the insect legs when wallifying * baalz level */ - struct bubble *bbubbles; /* pickup.c */ boolean bucx_filter; @@ -253,7 +248,6 @@ struct instance_globals_c { #ifdef DEF_PAGER const char *catmore; /* external pager; from getenv() or DEF_PAGER */ #endif - struct context_info context; /* dog.c */ char catname[PL_PSIZ]; @@ -317,12 +311,7 @@ struct instance_globals_d { long domove_succeeded; #define DOMOVE_WALK 0x00000001 #define DOMOVE_RUSH 0x00000002 - dungeon dungeons[MAXDUNGEON]; /* ini'ed by init_dungeon() */ - dest_area dndest; boolean defer_see_monsters; - struct dgn_topology dungeon_topology; - int doors_alloc; /* doors-array allocated size */ - coord *doors; /* array of door locations */ /* dig.c */ boolean did_dig_msg; @@ -341,9 +330,6 @@ struct instance_globals_d { /* mon.c */ boolean disintegested; - /* o_init.c */ - short disco[NUM_OBJECTS]; - /* objname.c */ /* distantname used by distant_name() to pass extra information to xname_flags(); it would be much cleaner if this were a parameter, @@ -372,7 +358,6 @@ struct instance_globals_e { struct bubble *ebubbles; /* new stuff */ - struct exclusion_zone *exclusion_zones; int early_raw_messages; /* if raw_prints occurred early prior to gb.beyond_savefile_load */ @@ -457,7 +442,6 @@ struct instance_globals_h { /* decl.c */ const char *hname; /* name of the game (argv[0] of main) */ - int hackpid; /* current process id */ #if defined(MICRO) || defined(WIN32) char hackdir[PATHLEN]; /* where rumors, help, record are */ #endif /* MICRO || WIN32 */ @@ -479,7 +463,6 @@ struct instance_globals_i { /* decl.c */ int in_doagain; - coord inv_pos; boolean in_mklev; boolean in_steed_dismounting; struct obj *invent; @@ -525,7 +508,6 @@ struct instance_globals_k { /* decl.c */ struct obj *kickedobj; /* object in flight due to kicking */ - struct kinfo killer; /* read.c */ boolean known; @@ -540,9 +522,6 @@ struct instance_globals_l { cmdcount_nht last_command_count; /* decl.c (before being incorporated into instance_globals_*) */ - schar lastseentyp[COLNO][ROWNO]; /* last seen/touched dungeon typ */ - struct linfo level_info[MAXLINFO]; - dlevel_t level; /* level map */ #if defined(UNIX) || defined(VMS) int locknum; /* max num of simultaneous users */ #endif @@ -620,20 +599,15 @@ struct instance_globals_m { struct multishot m_shot; boolean mrg_to_wielded; /* weapon picked is merged with wielded one */ struct menucoloring *menu_colorings; - long moves; /* turn counter */ struct obj *migrating_objs; /* objects moving to another dungeon level */ /* dog.c */ struct monst *mydogs; /* monsters that went down/up together with @ */ struct monst *migrating_mons; /* monsters moving to another level */ - struct mvitals mvitals[NUMMONS]; /* dokick.c */ struct rm *maploc; - /* dungeon.c */ - mapseen *mapseenchn; /*DUNGEON_OVERVIEW*/ - /* mhitu.c */ int mhitu_dieroll; @@ -682,15 +656,11 @@ struct instance_globals_n { /* decl.c */ const char *nomovemsg; - int nroom; int nsubroom; /* dokick.c */ struct rm nowhere; - /* dungeon.c */ - int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ - /* files.c */ int nesting; int no_sound_notified; /* run-time option processing: warn once if built @@ -713,9 +683,6 @@ struct instance_globals_n { /* questpgr.c */ char nambuf[CVT_BUF_SIZE]; - /* region.c */ - int n_regions; - /* restore.c */ int n_ids_mapped; @@ -779,7 +746,6 @@ struct instance_globals_o { /* rumors.c */ int oracle_flg; /* -1=>don't use, 0=>need init, 1=>init done */ - unsigned oracle_cnt; /* oracles are handled differently from rumors... */ unsigned long *oracle_loc; /* uhitm.c */ @@ -799,13 +765,9 @@ struct instance_globals_p { int polearm_range_max; /* decl.c */ - char plname[PL_NSIZ]; /* player name */ int plnamelen; /* length of plname[] if that came from getlogin() */ - char pl_character[PL_CSIZ]; char pl_race; /* character's race */ - char pl_fruit[PL_FSIZ]; struct plinemsg_type *plinemsg_types; - struct sinfo program_state; /* flags describing game's current state */ /* dog.c */ int petname_used; /* user preferred pet name has been used */ @@ -849,18 +811,12 @@ struct instance_globals_p { struct instance_globals_q { - /* quest.c */ - struct q_score quest_status; - boolean havestate; unsigned long magic; /* validate that structure layout is preserved */ }; struct instance_globals_r { - /* decl.c */ - struct mkroom rooms[(MAXNROFROOMS + 1) * 2]; - /* symbols.c */ nhsym rogue_syms[SYM_MAX]; /* loaded rogue symbols */ @@ -895,11 +851,9 @@ struct instance_globals_s { messages in artifact_hit() */ /* decl.c */ - s_level * sp_levchn; stairway *stairs; int smeq[MAXNROFROOMS + 1]; boolean stoned; /* done to monsters hit by 'c' */ - struct spell spl_book[MAXSPELL + 1]; struct mkroom *subrooms; /* do.c */ @@ -958,7 +912,7 @@ struct instance_globals_s { /* spells.c */ int spl_sortmode; /* index into spl_sortchoices[] */ - int *spl_orderindx; /* array of gs.spl_book[] indices */ + int *spl_orderindx; /* array of svs.spl_book[] indices */ /* steal.c */ unsigned int stealoid; /* object to be stolen */ @@ -977,7 +931,6 @@ struct instance_globals_t { struct trapinfo trapinfo; /* decl.c */ - char tune[6]; schar tbx; /* mthrowu: target x */ schar tby; /* mthrowu: target y */ char toplines[TBUFSZ]; @@ -1012,7 +965,6 @@ struct instance_globals_t { /* timeout.c */ /* ordered timer list */ struct fe *timer_base; /* "active" */ - unsigned long timer_id; /* topten.c */ winid toptenwin; @@ -1030,7 +982,6 @@ struct instance_globals_u { boolean update_all; /* decl.c */ - dest_area updest; boolean unweapon; /* role.c */ @@ -1115,9 +1066,6 @@ struct instance_globals_x { /* lock.c */ struct xlock_s xlock; - /* mkmaze.c */ - int xmin, xmax; /* level boundaries x */ - /* objnam.c */ char *xnamep; /* obuf[] returned by xname(), for use in doname() for * bounds checking; differs from xname() return value @@ -1137,9 +1085,6 @@ struct instance_globals_y { int y_maze_max; struct monst youmonst; - /* mkmaze.c */ - int ymin, ymax; /* level boundaries y */ - /* pline.c */ /* work buffer for You(), &c and verbalize() */ char *you_buf; @@ -1169,6 +1114,127 @@ struct instance_globals_z { unsigned long magic; /* validate that structure layout is preserved */ }; +struct instance_globals_saved_b { + /* dungeon.c */ + branch *branches; /* dungeon branch list */ + /* mkmaze.c */ + struct bubble *bbubbles; + /* o_init.c */ + int bases[MAXOCLASSES + 2]; /* make bases[MAXOCLASSES+1] available */ +}; + +struct instance_globals_saved_c { + /* decl.c */ + struct context_info context; +}; + +struct instance_globals_saved_d { + /* dungeon.c */ + dungeon dungeons[MAXDUNGEON]; /* ini'ed by init_dungeon() */ + struct dgn_topology dungeon_topology; + /* decl.c */ + dest_area dndest; + coord *doors; /* array of door locations */ + int doors_alloc; /* doors-array allocated size */ + /* o_init.c */ + short disco[NUM_OBJECTS]; +}; + +struct instance_globals_saved_e { + /* decl.c */ + struct exclusion_zone *exclusion_zones; +}; + +struct instance_globals_saved_h { + /* decl.c */ + int hackpid; /* current process id */ +}; + +struct instance_globals_saved_i { + /* decl.c */ + coord inv_pos; +}; + +struct instance_globals_saved_k { + /* decl.c */ + struct kinfo killer; +}; + +struct instance_globals_saved_l { + /* decl.c */ + schar lastseentyp[COLNO][ROWNO]; /* last seen/touched dungeon typ */ + dlevel_t level; /* level map */ + struct linfo level_info[MAXLINFO]; +}; + +struct instance_globals_saved_m { + /* dungeon.c */ + mapseen *mapseenchn; /*DUNGEON_OVERVIEW*/ + /* decl.c */ + long moves; /* turn counter */ + struct mvitals mvitals[NUMMONS]; +}; + +struct instance_globals_saved_n { + /* dungeon.c */ + int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ + /* mkroom.c */ + int nroom; + /* region.c */ + int n_regions; +}; + +struct instance_globals_saved_o { + /* rumors.c */ + unsigned oracle_cnt; /* oracles are handled differently from rumors... */ +}; + +struct instance_globals_saved_p { + /* decl.c */ + char plname[PL_NSIZ]; /* player name */ + char pl_character[PL_CSIZ]; + char pl_fruit[PL_FSIZ]; + struct sinfo program_state; /* flags describing game's current state */ +}; + +struct instance_globals_saved_q { + /* quest.c */ + struct q_score quest_status; +}; + +struct instance_globals_saved_r { + /* mkroom.c */ + struct mkroom rooms[(MAXNROFROOMS + 1) * 2]; +}; + +struct instance_globals_saved_s { + /* decl.c */ + struct spell spl_book[MAXSPELL + 1]; + s_level *sp_levchn; +}; + +struct instance_globals_saved_t { + /* decl.c */ + char tune[6]; + /* timeout.c */ + unsigned long timer_id; +}; + +struct instance_globals_saved_u { + /* decl.c */ + dest_area updest; +}; + +struct instance_globals_saved_x { + /* mkmaze.c */ + int xmin, xmax; /* level boundaries x */ +}; + +struct instance_globals_saved_y { + /* mkmaze.c */ + int ymin, ymax; /* level boundaries y */ +}; + extern struct instance_globals_a ga; extern struct instance_globals_b gb; extern struct instance_globals_c gc; @@ -1195,6 +1261,25 @@ extern struct instance_globals_w gw; extern struct instance_globals_x gx; extern struct instance_globals_y gy; extern struct instance_globals_z gz; +extern struct instance_globals_saved_b svb; +extern struct instance_globals_saved_c svc; +extern struct instance_globals_saved_d svd; +extern struct instance_globals_saved_e sve; +extern struct instance_globals_saved_h svh; +extern struct instance_globals_saved_i svi; +extern struct instance_globals_saved_k svk; +extern struct instance_globals_saved_l svl; +extern struct instance_globals_saved_m svm; +extern struct instance_globals_saved_n svn; +extern struct instance_globals_saved_o svo; +extern struct instance_globals_saved_p svp; +extern struct instance_globals_saved_q svq; +extern struct instance_globals_saved_r svr; +extern struct instance_globals_saved_s svs; +extern struct instance_globals_saved_t svt; +extern struct instance_globals_saved_u svu; +extern struct instance_globals_saved_x svx; +extern struct instance_globals_saved_y svy; struct const_globals { const struct obj zeroobj; /* used to zero out a struct obj */ diff --git a/include/display.h b/include/display.h index 649ca6837..e15f06285 100644 --- a/include/display.h +++ b/include/display.h @@ -19,7 +19,7 @@ * Returns the head of the list of objects that the player can see * at location (x,y). [Vestige of unimplemented invisible objects.] */ -#define vobj_at(x, y) (gl.level.objects[x][y]) +#define vobj_at(x, y) (svl.level.objects[x][y]) /* * sensemon() @@ -63,7 +63,7 @@ */ #define _mon_warning(mon) \ (Warning && !(mon)->mpeaceful && (mdistu(mon) < 100) \ - && (((int) ((mon)->m_lev / 4)) >= gc.context.warnlevel)) + && (((int) ((mon)->m_lev / 4)) >= svc.context.warnlevel)) /* * mon_visible() @@ -820,7 +820,7 @@ enum glyph_offsets { expression but there will always be sequence points in between */ #define obj_is_piletop(obj) \ ((obj)->where == OBJ_FLOOR \ - && (go.otg_otmp = gl.level.objects[(obj)->ox][(obj)->oy]->nexthere) != 0 \ + && (go.otg_otmp = svl.level.objects[(obj)->ox][(obj)->oy]->nexthere) != 0 \ && ((obj)->otyp != BOULDER || go.otg_otmp->otyp == BOULDER)) /* used to hide info such as potion and gem color when not seen yet; stones and rock are excluded for gem class; LAST_SPELL includes blank diff --git a/include/dungeon.h b/include/dungeon.h index 11efc6053..60b3cd6ab 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -246,7 +246,7 @@ typedef struct mapseen { struct mapseen_rooms { Bitfield(seen, 1); Bitfield(untended, 1); /* flag for shop without shk */ - } msrooms[(MAXNROFROOMS + 1) * 2]; /* same size as gr.rooms[] */ + } msrooms[(MAXNROFROOMS + 1) * 2]; /* same size as svr.rooms[] */ /* dead heroes; might not have graves or ghosts */ struct cemetery *final_resting_place; /* same as level.bonesinfo */ } mapseen; diff --git a/include/flag.h b/include/flag.h index abcadc11f..95c7943a8 100644 --- a/include/flag.h +++ b/include/flag.h @@ -234,7 +234,7 @@ struct instance_flags { boolean query_menu; /* use a menu for yes/no queries */ boolean showdamage; boolean debug_fuzzer; /* fuzz testing */ - boolean defer_plname; /* X11 hack: askname() might not set gp.plname */ + boolean defer_plname; /* X11 hack: askname() might not set svp.plname */ boolean herecmd_menu; /* use menu when mouseclick on yourself */ boolean invis_goldsym; /* gold symbol is ' '? */ boolean in_lua; /* executing a lua script */ diff --git a/include/hack.h b/include/hack.h index 81f97632b..1a08246fb 100644 --- a/include/hack.h +++ b/include/hack.h @@ -372,40 +372,40 @@ struct dgn_topology { /* special dungeon levels for speed */ /* macros for accessing the dungeon levels by their old names */ /* clang-format off */ -#define oracle_level (gd.dungeon_topology.d_oracle_level) -#define bigroom_level (gd.dungeon_topology.d_bigroom_level) -#define rogue_level (gd.dungeon_topology.d_rogue_level) -#define medusa_level (gd.dungeon_topology.d_medusa_level) -#define stronghold_level (gd.dungeon_topology.d_stronghold_level) -#define valley_level (gd.dungeon_topology.d_valley_level) -#define wiz1_level (gd.dungeon_topology.d_wiz1_level) -#define wiz2_level (gd.dungeon_topology.d_wiz2_level) -#define wiz3_level (gd.dungeon_topology.d_wiz3_level) -#define juiblex_level (gd.dungeon_topology.d_juiblex_level) -#define orcus_level (gd.dungeon_topology.d_orcus_level) -#define baalzebub_level (gd.dungeon_topology.d_baalzebub_level) -#define asmodeus_level (gd.dungeon_topology.d_asmodeus_level) -#define portal_level (gd.dungeon_topology.d_portal_level) -#define sanctum_level (gd.dungeon_topology.d_sanctum_level) -#define earth_level (gd.dungeon_topology.d_earth_level) -#define water_level (gd.dungeon_topology.d_water_level) -#define fire_level (gd.dungeon_topology.d_fire_level) -#define air_level (gd.dungeon_topology.d_air_level) -#define astral_level (gd.dungeon_topology.d_astral_level) -#define tower_dnum (gd.dungeon_topology.d_tower_dnum) -#define sokoban_dnum (gd.dungeon_topology.d_sokoban_dnum) -#define mines_dnum (gd.dungeon_topology.d_mines_dnum) -#define quest_dnum (gd.dungeon_topology.d_quest_dnum) -#define tutorial_dnum (gd.dungeon_topology.d_tutorial_dnum) -#define qstart_level (gd.dungeon_topology.d_qstart_level) -#define qlocate_level (gd.dungeon_topology.d_qlocate_level) -#define nemesis_level (gd.dungeon_topology.d_nemesis_level) -#define knox_level (gd.dungeon_topology.d_knox_level) -#define mineend_level (gd.dungeon_topology.d_mineend_level) -#define sokoend_level (gd.dungeon_topology.d_sokoend_level) +#define oracle_level (svd.dungeon_topology.d_oracle_level) +#define bigroom_level (svd.dungeon_topology.d_bigroom_level) +#define rogue_level (svd.dungeon_topology.d_rogue_level) +#define medusa_level (svd.dungeon_topology.d_medusa_level) +#define stronghold_level (svd.dungeon_topology.d_stronghold_level) +#define valley_level (svd.dungeon_topology.d_valley_level) +#define wiz1_level (svd.dungeon_topology.d_wiz1_level) +#define wiz2_level (svd.dungeon_topology.d_wiz2_level) +#define wiz3_level (svd.dungeon_topology.d_wiz3_level) +#define juiblex_level (svd.dungeon_topology.d_juiblex_level) +#define orcus_level (svd.dungeon_topology.d_orcus_level) +#define baalzebub_level (svd.dungeon_topology.d_baalzebub_level) +#define asmodeus_level (svd.dungeon_topology.d_asmodeus_level) +#define portal_level (svd.dungeon_topology.d_portal_level) +#define sanctum_level (svd.dungeon_topology.d_sanctum_level) +#define earth_level (svd.dungeon_topology.d_earth_level) +#define water_level (svd.dungeon_topology.d_water_level) +#define fire_level (svd.dungeon_topology.d_fire_level) +#define air_level (svd.dungeon_topology.d_air_level) +#define astral_level (svd.dungeon_topology.d_astral_level) +#define tower_dnum (svd.dungeon_topology.d_tower_dnum) +#define sokoban_dnum (svd.dungeon_topology.d_sokoban_dnum) +#define mines_dnum (svd.dungeon_topology.d_mines_dnum) +#define quest_dnum (svd.dungeon_topology.d_quest_dnum) +#define tutorial_dnum (svd.dungeon_topology.d_tutorial_dnum) +#define qstart_level (svd.dungeon_topology.d_qstart_level) +#define qlocate_level (svd.dungeon_topology.d_qlocate_level) +#define nemesis_level (svd.dungeon_topology.d_nemesis_level) +#define knox_level (svd.dungeon_topology.d_knox_level) +#define mineend_level (svd.dungeon_topology.d_mineend_level) +#define sokoend_level (svd.dungeon_topology.d_sokoend_level) /* clang-format on */ -#define dunlev_reached(x) (gd.dungeons[(x)->dnum].dunlev_ureached) +#define dunlev_reached(x) (svd.dungeons[(x)->dnum].dunlev_ureached) #define MAXLINFO (MAXDUNGEON * MAXLEVEL) enum lua_theme_group { @@ -1073,10 +1073,10 @@ typedef struct { #define MATCH_WARN_OF_MON(mon) \ (Warn_of_mon \ - && ((gc.context.warntype.obj & (mon)->data->mflags2) != 0 \ - || (gc.context.warntype.polyd & (mon)->data->mflags2) != 0 \ - || (gc.context.warntype.species \ - && (gc.context.warntype.species == (mon)->data)))) + && ((svc.context.warntype.obj & (mon)->data->mflags2) != 0 \ + || (svc.context.warntype.polyd & (mon)->data->mflags2) != 0 \ + || (svc.context.warntype.species \ + && (svc.context.warntype.species == (mon)->data)))) typedef uint32_t mmflags_nht; /* makemon MM_ flags */ diff --git a/include/mextra.h b/include/mextra.h index 1d044406b..1942f9dc7 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -122,8 +122,8 @@ struct eshk { long credit; /* amount credited to customer */ long debit; /* amount of debt for using unpaid items */ long loan; /* shop-gold picked (part of debit) */ - int shoptype; /* the value of gr.rooms[shoproom].rtype */ - schar shoproom; /* index in gr.rooms; set by inshop() */ + int shoptype; /* the value of svr.rooms[shoproom].rtype */ + schar shoproom; /* index in svr.rooms; set by inshop() */ schar unused; /* to force alignment for stupid compilers */ boolean following; /* following customer since he owes us sth */ boolean surcharge; /* angry shk inflates prices */ diff --git a/include/mkroom.h b/include/mkroom.h index a7889f272..39fb09976 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -40,10 +40,10 @@ struct shclass { const char *const *shknms; /* list of shopkeeper names for this type */ }; -/* the normal rooms on the current level are described in gr.rooms[0..n] for +/* the normal rooms on the current level are described in svr.rooms[0..n] for * some n= gr.rooms && (x) < gr.rooms + MAXNROFROOMS) +#define IS_ROOM_PTR(x) ((x) >= svr.rooms && (x) < svr.rooms + MAXNROFROOMS) #define IS_ROOM_INDEX(x) ((x) >= 0 && (x) < MAXNROFROOMS) #define IS_SUBROOM_PTR(x) \ ((x) >= gs.subrooms && (x) < gs.subrooms + MAXNROFROOMS) #define IS_SUBROOM_INDEX(x) ((x) > MAXNROFROOMS && (x) <= (MAXNROFROOMS * 2)) -#define ROOM_INDEX(x) ((x) - gr.rooms) +#define ROOM_INDEX(x) ((x) - svr.rooms) #define SUBROOM_INDEX(x) ((x) - gs.subrooms) -#define IS_LAST_ROOM_PTR(x) (ROOM_INDEX(x) == gn.nroom) +#define IS_LAST_ROOM_PTR(x) (ROOM_INDEX(x) == svn.nroom) #define IS_LAST_SUBROOM_PTR(x) (!gn.nsubroom || SUBROOM_INDEX(x) == gn.nsubroom) #endif /* MKROOM_H */ diff --git a/include/monflag.h b/include/monflag.h index e5d4f4ece..43400fea9 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -204,7 +204,7 @@ enum ms_sounds { passed to mkclass() as if it dealt with mons[].geno bits */ #define G_IGNORE 0x8000 /* for mkclass(), ignore G_GENOD|G_EXTINCT */ -/* for gm.mvitals[].mvflags (variant during game), along with G_NOCORPSE */ +/* for svm.mvitals[].mvflags (variant during game), along with G_NOCORPSE */ #define G_KNOWN 0x04 /* have been encountered */ #define G_GENOD 0x02 /* have been genocided */ #define G_EXTINCT 0x01 /* population control; create no more */ diff --git a/include/monst.h b/include/monst.h index 4c0c19531..a7f39c18e 100644 --- a/include/monst.h +++ b/include/monst.h @@ -212,7 +212,7 @@ struct monst { /* dead monsters stay on the fmon list until dmonsfree() at end of turn */ #define DEADMONSTER(mon) ((mon)->mhp < 1) -#define is_starting_pet(mon) ((mon)->m_id == gc.context.startingpet_mid) +#define is_starting_pet(mon) ((mon)->m_id == svc.context.startingpet_mid) #define is_vampshifter(mon) \ ((mon)->cham == PM_VAMPIRE || (mon)->cham == PM_VAMPIRE_LEADER \ || (mon)->cham == PM_VLAD_THE_IMPALER) @@ -226,7 +226,7 @@ struct monst { #define mundisplaceable(mon) \ ((mon)->ispriest || (mon)->isshk \ || (mon)->isgd || (mon)->data == &mons[PM_ORACLE] \ - || (mon)->m_id == gq.quest_status.leader_m_id) + || (mon)->m_id == svq.quest_status.leader_m_id) /* mimic appearances that block vision/light */ #define is_lightblocker_mappear(mon) \ diff --git a/include/obj.h b/include/obj.h index b1e95091b..7053772d6 100644 --- a/include/obj.h +++ b/include/obj.h @@ -302,7 +302,7 @@ struct obj { /* Eggs and other food */ #define MAX_EGG_HATCH_TIME 200 /* longest an egg can remain unhatched */ #define stale_egg(egg) \ - ((gm.moves - (egg)->age) > (2 * MAX_EGG_HATCH_TIME)) + ((svm.moves - (egg)->age) > (2 * MAX_EGG_HATCH_TIME)) #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN) /* note: sometimes eggs and tins have special corpsenm values that shouldn't be used as an index into mons[] */ @@ -420,8 +420,8 @@ struct obj { || (o)->otyp == AMULET_OF_UNCHANGING) /* achievement tracking; 3.6.x did this differently */ -#define is_mines_prize(o) ((o)->o_id == gc.context.achieveo.mines_prize_oid) -#define is_soko_prize(o) ((o)->o_id == gc.context.achieveo.soko_prize_oid) +#define is_mines_prize(o) ((o)->o_id == svc.context.achieveo.mines_prize_oid) +#define is_soko_prize(o) ((o)->o_id == svc.context.achieveo.soko_prize_oid) /* is_art() is now a function in artifact.c */ /* #define is_art(o,art) ((o) && (o)->oartifact == (art)) */ diff --git a/include/patchlevel.h b/include/patchlevel.h index f589da6a7..c8784d7da 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 105 +#define EDITLEVEL 106 /* * Development status possibilities. diff --git a/include/rm.h b/include/rm.h index 4c5dd546c..61e6f013d 100644 --- a/include/rm.h +++ b/include/rm.h @@ -107,7 +107,7 @@ enum levl_typ_types { #define IS_DOOR(typ) ((typ) == DOOR) #define IS_DOORJOIN(typ) (IS_ROCK(typ) || (typ) == IRONBARS) #define IS_TREE(typ) \ - ((typ) == TREE || (gl.level.flags.arboreal && (typ) == STONE)) + ((typ) == TREE || (svl.level.flags.arboreal && (typ) == STONE)) #define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */ #define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM, STAIRS, furniture.. */ #define ZAP_POS(typ) ((typ) >= POOL) @@ -374,7 +374,7 @@ struct damage { an existing bones level; if so, most recent victim will be first in list */ struct cemetery { struct cemetery *next; /* next struct is previous dead character... */ - /* "gp.plname" + "-ROLe" + "-RACe" + "-GENder" + "-ALIgnment" + \0 */ + /* "svp.plname" + "-ROLe" + "-RACe" + "-GENder" + "-ALIgnment" + \0 */ char who[PL_NSIZ + 4 * (1 + 3) + 1]; /* death reason, same as in score/log file */ char how[100 + 1]; /* [DTHSZ+1] */ @@ -441,9 +441,9 @@ typedef struct { /* * Macros for compatibility with old code. Someday these will go away. */ -#define levl gl.level.locations -#define fobj gl.level.objlist -#define fmon gl.level.monlist +#define levl svl.level.locations +#define fobj svl.level.objlist +#define fmon svl.level.monlist /* * Covert a trap number into the defsym graphics array. @@ -453,45 +453,45 @@ typedef struct { #define trap_to_defsym(t) (S_arrow_trap + (t) - 1) #define defsym_to_trap(d) ((d) - S_arrow_trap + 1) -#define OBJ_AT(x, y) (gl.level.objects[x][y] != (struct obj *) 0) +#define OBJ_AT(x, y) (svl.level.objects[x][y] != (struct obj *) 0) /* * Macros for encapsulation of level.monsters references. */ #if 0 /* these wouldn't allow buried monster and surface monster at same location */ #define MON_AT(x, y) \ - (gl.level.monsters[x][y] && !gl.level.monsters[x][y]->mburied) + (svl.level.monsters[x][y] && !svl.level.monsters[x][y]->mburied) #define MON_BURIED_AT(x, y) \ - (gl.level.monsters[x][y] && gl.level.monsters[x][y]->mburied) + (svl.level.monsters[x][y] && svl.level.monsters[x][y]->mburied) #define m_at(x, y) \ - (MON_AT(x, y) ? gl.level.monsters[x][y] : (struct monst *) 0) + (MON_AT(x, y) ? svl.level.monsters[x][y] : (struct monst *) 0) #define m_buried_at(x, y) \ - (MON_BURIED_AT(x, y) ? gl.level.monsters[x][y] : (struct monst *) 0) + (MON_BURIED_AT(x, y) ? svl.level.monsters[x][y] : (struct monst *) 0) #else /* without 'mburied' */ -#define MON_AT(x, y) (gl.level.monsters[x][y] != (struct monst *) 0) -#define m_at(x, y) (gl.level.monsters[x][y]) +#define MON_AT(x, y) (svl.level.monsters[x][y] != (struct monst *) 0) +#define m_at(x, y) (svl.level.monsters[x][y]) #define m_buried_at(x, y) ((struct monst *) 0) #endif #ifdef EXTRA_SANITY_CHECKS #define place_worm_seg(m, x, y) \ do { \ - if (gl.level.monsters[x][y] && gl.level.monsters[x][y] != m) \ + if (svl.level.monsters[x][y] && svl.level.monsters[x][y] != m) \ impossible("place_worm_seg over mon"); \ - gl.level.monsters[x][y] = m; \ + svl.level.monsters[x][y] = m; \ } while(0) #define remove_monster(x, y) \ do { \ - if (!gl.level.monsters[x][y]) \ + if (!svl.level.monsters[x][y]) \ impossible("no monster to remove"); \ - gl.level.monsters[x][y] = (struct monst *) 0; \ + svl.level.monsters[x][y] = (struct monst *) 0; \ } while(0) #else -#define place_worm_seg(m, x, y) gl.level.monsters[x][y] = m -#define remove_monster(x, y) gl.level.monsters[x][y] = (struct monst *) 0 +#define place_worm_seg(m, x, y) svl.level.monsters[x][y] = m +#define remove_monster(x, y) svl.level.monsters[x][y] = (struct monst *) 0 #endif /* restricted movement, potential luck penalties */ -#define Sokoban gl.level.flags.sokoban_rules +#define Sokoban svl.level.flags.sokoban_rules /* * These prototypes are in extern.h but some of the code which uses them diff --git a/include/spell.h b/include/spell.h index 66208434c..9299282e2 100644 --- a/include/spell.h +++ b/include/spell.h @@ -28,9 +28,9 @@ enum spellknowledge { #define ALL_MAP 0x1 #define ALL_SPELLS 0x2 -#define decrnknow(spell) gs.spl_book[spell].sp_know-- -#define spellid(spell) gs.spl_book[spell].sp_id -#define spellknow(spell) gs.spl_book[spell].sp_know +#define decrnknow(spell) svs.spl_book[spell].sp_know-- +#define spellid(spell) svs.spl_book[spell].sp_id +#define spellknow(spell) svs.spl_book[spell].sp_know /* how much Pw a spell of level lvl costs to cast? */ #define SPELL_LEV_PW(lvl) ((lvl) * 5) diff --git a/outdated/sys/amiga/amirip.c b/outdated/sys/amiga/amirip.c index ddfd405ee..b14689f80 100644 --- a/outdated/sys/amiga/amirip.c +++ b/outdated/sys/amiga/amirip.c @@ -185,7 +185,7 @@ time_t when; SetDrMd(rp, JAM1); /* Put name on stone */ - Sprintf(buf, "%s", gp.plname); + Sprintf(buf, "%s", svp.plname); buf[STONE_LINE_LEN] = 0; tomb_text(buf); diff --git a/outdated/sys/amiga/winamenu.c b/outdated/sys/amiga/winamenu.c index 31c7deeb2..013e3c792 100644 --- a/outdated/sys/amiga/winamenu.c +++ b/outdated/sys/amiga/winamenu.c @@ -357,7 +357,7 @@ menu_item **retmip; nw->Screen = HackScreen; if (win == WIN_INVEN) { - sprintf(title, "%s the %s's Inventory", gp.plname, gp.pl_character); + sprintf(title, "%s the %s's Inventory", svp.plname, svp.pl_character); nw->Title = title; if (lastinvent.MaxX != 0) { nw->LeftEdge = lastinvent.MinX; diff --git a/outdated/sys/amiga/winami.c b/outdated/sys/amiga/winami.c index f80490a83..fc860d603 100644 --- a/outdated/sys/amiga/winami.c +++ b/outdated/sys/amiga/winami.c @@ -438,10 +438,10 @@ amii_askname() amii_getlin("Who are you?", plnametmp); } while (strlen(plnametmp) == 0); - strncpy(gp.plname, plnametmp, PL_NSIZ - 1); /* Avoid overflowing plname[] */ - gp.plname[PL_NSIZ - 1] = 0; + strncpy(svp.plname, plnametmp, PL_NSIZ - 1); /* Avoid overflowing plname[] */ + svp.plname[PL_NSIZ - 1] = 0; - if (*gp.plname == '\33') { + if (*svp.plname == '\33') { clearlocks(); exit_nhwindows(NULL); nh_terminate(0); @@ -475,9 +475,9 @@ amii_player_selection() #if 0 /* Don't query the user ... instead give random character -jhsa */ #if 0 /* OBSOLETE */ - if( *gp.pl_character ){ - gp.pl_character[ 0 ] = toupper( gp.pl_character[ 0 ] ); - if( strchr( pl_classes, gp.pl_character[ 0 ] ) ) + if( *svp.pl_character ){ + svp.pl_character[ 0 ] = toupper( svp.pl_character[ 0 ] ); + if( strchr( pl_classes, svp.pl_character[ 0 ] ) ) return; } #endif @@ -531,19 +531,19 @@ amii_player_selection() case VANILLAKEY: if( strchr( pl_classes, toupper( code ) ) ) { - gp.pl_character[0] = toupper( code ); + svp.pl_character[0] = toupper( code ); aredone = 1; } else if( code == ' ' || code == '\n' || code == '\r' ) { flags.initrole = randrole(FALSE); #if 0 /* OBSOLETE */ - strcpy( gp.pl_character, roles[ rnd( 11 ) ] ); + strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); #endif aredone = 1; amii_clear_nhwindow( WIN_BASE ); CloseShWindow( cwin ); - RandomWindow( gp.pl_character ); + RandomWindow( svp.pl_character ); return; } else if( code == 'q' || code == 'Q' ) @@ -563,15 +563,15 @@ amii_player_selection() case 1: /* Random Character */ flags.initrole = randrole(FALSE); #if 0 /* OBSOLETE */ - strcpy( gp.pl_character, roles[ rnd( 11 ) ] ); + strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); #endif amii_clear_nhwindow( WIN_BASE ); CloseShWindow( cwin ); - RandomWindow( gp.pl_character ); + RandomWindow( svp.pl_character ); return; default: - gp.pl_character[0] = gd->GadgetID; + svp.pl_character[0] = gd->GadgetID; break; } aredone = 1; diff --git a/outdated/sys/be/bemain.c b/outdated/sys/be/bemain.c index a480c9e1a..cf29af809 100644 --- a/outdated/sys/be/bemain.c +++ b/outdated/sys/be/bemain.c @@ -132,14 +132,14 @@ whoami(void) */ char *s; - if (*gp.plname) + if (*svp.plname) return; if (s = nh_getenv("USER")) { - (void) strncpy(gp.plname, s, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, s, sizeof(svp.plname) - 1); return; } if (s = nh_getenv("LOGNAME")) { - (void) strncpy(gp.plname, s, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, s, sizeof(svp.plname) - 1); return; } } @@ -177,11 +177,11 @@ process_options(int argc, char **argv) #endif case 'u': if (argv[0][2]) - (void) strncpy(gp.plname, argv[0] + 2, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0] + 2, sizeof(svp.plname) - 1); else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0], sizeof(svp.plname) - 1); } else raw_print("Player name expected after -u"); break; @@ -236,15 +236,15 @@ getlock(void) { int fd; - Sprintf(gl.lock, "%d%s", getuid(), gp.plname); + Sprintf(gl.lock, "%d%s", getuid(), svp.plname); regularize(gl.lock); set_levelfile_name(gl.lock, 0); fd = creat(gl.lock, FCMASK); if (fd == -1) { error("cannot creat lock file."); } else { - if (write(fd, (genericptr_t) &gh.hackpid, sizeof(gh.hackpid)) - != sizeof(gh.hackpid)) { + if (write(fd, (genericptr_t) &svh.hackpid, sizeof(svh.hackpid)) + != sizeof(svh.hackpid)) { error("cannot write lock"); } if (close(fd) == -1) { diff --git a/outdated/sys/mac/macfile.c b/outdated/sys/mac/macfile.c index bdf400b60..ce0d0e69d 100644 --- a/outdated/sys/mac/macfile.c +++ b/outdated/sys/mac/macfile.c @@ -228,7 +228,7 @@ macopen(const char *name, int flags, long fileType) Handle name; Str255 plnamep; - C2P(gp.plname, plnamep); + C2P(svp.plname, plnamep); name = (Handle)NewString(plnamep); if (name) replace_resource(name, 'STR ', PLAYER_NAME_RES_ID, diff --git a/outdated/sys/mac/macmain.c b/outdated/sys/mac/macmain.c index 5ffa3b72c..cd624543d 100644 --- a/outdated/sys/mac/macmain.c +++ b/outdated/sys/mac/macmain.c @@ -225,7 +225,7 @@ process_openfile(short src_vol, long src_dir, Str255 fName, OSType ftype) Handle name = Get1Resource('STR ', PLAYER_NAME_RES_ID); if (name) { Str255 save_f_p; - P2C(*(StringHandle) name, gp.plname); + P2C(*(StringHandle) name, svp.plname); set_savefile_name(TRUE); C2P(fqname(gs.SAVEF, SAVEPREFIX, 0), save_f_p); force_hdelete(theDirs.dataRefNum, theDirs.dataDirID, diff --git a/outdated/sys/mac/macmenu.c b/outdated/sys/mac/macmenu.c index 74d06fc33..497f9b53a 100644 --- a/outdated/sys/mac/macmenu.c +++ b/outdated/sys/mac/macmenu.c @@ -493,8 +493,8 @@ mac_askname() SetPortDialogPort(askdialog); /* Initialize the name text item */ - ask_restring(gp.plname, str); - if (gp.plname[0]) { + ask_restring(svp.plname, str); + if (svp.plname[0]) { GetDialogItem(askdialog, RSRC_ASK_NAME, &type, &handle, &rect); SetDialogItemText(handle, str); } @@ -502,8 +502,8 @@ mac_askname() { Str32 pName; pName [0] = 0; - if (gp.plname && gp.plname [0]) { - strcpy ((char *) pName, gp.plname); + if (svp.plname && svp.plname [0]) { + strcpy ((char *) pName, svp.plname); c2pstr ((char *) pName); } else { Handle h; @@ -548,7 +548,7 @@ mac_askname() if (flags.initrole >= 0) currrole = flags.initrole; /* Check for backward compatibility */ - else if ((currrole = str2role(gp.pl_character)) < 0) + else if ((currrole = str2role(svp.pl_character)) < 0) currrole = randrole(FALSE); /* Initialize the race popup menu */ @@ -735,8 +735,8 @@ mac_askname() GetDialogItemText(handle, str); if (str[0] > PL_NSIZ - 1) str[0] = PL_NSIZ - 1; - BlockMove(&str[1], gp.plname, str[0]); - gp.plname[str[0]] = '\0'; + BlockMove(&str[1], svp.plname, str[0]); + svp.plname[str[0]] = '\0'; /* Destroy the dialog */ for (i = RSRC_ASK_ROLE; i <= RSRC_ASK_MODE; i++) { @@ -758,14 +758,14 @@ mac_askname() break; case 2: /* Debug */ wizard = 1; - strcpy(gp.plname, WIZARD_NAME); + strcpy(svp.plname, WIZARD_NAME); break; default: /* Quit */ ExitToShell(); } /* Process the role */ - strcpy(gp.pl_character, roles[currrole].name.m); + strcpy(svp.pl_character, roles[currrole].name.m); flags.initrole = currrole; /* Process the race */ diff --git a/outdated/sys/mac/macunix.c b/outdated/sys/mac/macunix.c index a0b5c0d02..f590cfeff 100644 --- a/outdated/sys/mac/macunix.c +++ b/outdated/sys/mac/macunix.c @@ -24,7 +24,7 @@ getlock(void) int fd; int pid = getpid(); /* Process ID */ - Sprintf(gl.lock, "%d%s", getuid(), gp.plname); + Sprintf(gl.lock, "%d%s", getuid(), svp.plname); set_levelfile_name(gl.lock, 0); if ((fd = open(gl.lock, O_RDWR | O_EXCL | O_CREAT, LEVL_TYPE)) == -1) { diff --git a/outdated/sys/wince/mhdlg.c b/outdated/sys/wince/mhdlg.c index 60ce3f65d..b56923222 100644 --- a/outdated/sys/wince/mhdlg.c +++ b/outdated/sys/wince/mhdlg.c @@ -459,7 +459,7 @@ plselInitDialog(HWND hWnd) TCHAR wbuf[BUFSZ]; /* set player name */ - SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(gp.plname, wbuf, sizeof(wbuf))); + SetDlgItemText(hWnd, IDC_PLSEL_NAME, NH_A2W(svp.plname, wbuf, sizeof(wbuf))); /* check flags for consistency */ if (flags.initrole >= 0) { diff --git a/outdated/sys/wince/mhinput.c b/outdated/sys/wince/mhinput.c index 8758324e7..4d0f8db47 100644 --- a/outdated/sys/wince/mhinput.c +++ b/outdated/sys/wince/mhinput.c @@ -39,7 +39,7 @@ mswin_have_input() return #ifdef SAFERHANGUP /* we always have input (ESC) if hangup was requested */ - gp.program_state.done_hup || + svp.program_state.done_hup || #endif (nhi_read_pos != nhi_write_pos); } @@ -69,7 +69,7 @@ mswin_input_pop() #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.kbd.ch = '\033'; @@ -98,7 +98,7 @@ mswin_input_peek() #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.kbd.ch = '\033'; diff --git a/outdated/sys/wince/mhmain.c b/outdated/sys/wince/mhmain.c index cd2a0865a..2c98410ec 100644 --- a/outdated/sys/wince/mhmain.c +++ b/outdated/sys/wince/mhmain.c @@ -826,7 +826,7 @@ mswin_layout_main_window(HWND changed_child) /* show command window only if it exists and the game is ready (plname is set) */ if (GetNHApp()->bCmdPad && cmd_size.cx > 0 && cmd_size.cy > 0 - && *gp.plname) { + && *svp.plname) { MoveWindow(GetNHApp()->hCmdWnd, cmd_org.x, cmd_org.y, cmd_size.cx, cmd_size.cy, TRUE); ShowWindow(GetNHApp()->hCmdWnd, SW_SHOW); diff --git a/outdated/sys/wince/mhmenu.c b/outdated/sys/wince/mhmenu.c index 8db3afdcc..e69ddeb62 100644 --- a/outdated/sys/wince/mhmenu.c +++ b/outdated/sys/wince/mhmenu.c @@ -533,7 +533,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) if (!data->text.text) { data->text.text = mswin_init_text_buffer( - gp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); + svp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); if (!data->text.text) break; } diff --git a/outdated/sys/wince/mhstatus.c b/outdated/sys/wince/mhstatus.c index 41f4e5d1b..7cdcc0b5c 100644 --- a/outdated/sys/wince/mhstatus.c +++ b/outdated/sys/wince/mhstatus.c @@ -182,7 +182,7 @@ FormatStatusString(char *text, int format) int hp, hpmax; int cap = near_capacity(); - Strcpy(text, gp.plname); + Strcpy(text, svp.plname); if ('a' <= text[0] && text[0] <= 'z') text[0] += 'A' - 'a'; text[10] = 0; @@ -253,7 +253,7 @@ FormatStatusString(char *text, int format) /* forth line */ if (flags.time) - Sprintf(nb = eos(nb), "T:%ld ", gm.moves); + Sprintf(nb = eos(nb), "T:%ld ", svm.moves); if (strcmp(hu_stat[u.uhs], " ")) { Strcat(text, hu_stat[u.uhs]); diff --git a/outdated/sys/wince/mhtext.c b/outdated/sys/wince/mhtext.c index 4dfcf6575..e99b900ba 100644 --- a/outdated/sys/wince/mhtext.c +++ b/outdated/sys/wince/mhtext.c @@ -39,7 +39,7 @@ mswin_init_text_window() ZeroMemory(data, sizeof(NHTextWindow)); data->window_text = mswin_init_text_buffer( - gp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); + svp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); SetWindowLong(ret, GWL_USERDATA, (LONG) data); return ret; } diff --git a/outdated/sys/wince/mswproc.c b/outdated/sys/wince/mswproc.c index 45de197f5..e84dab8e1 100644 --- a/outdated/sys/wince/mswproc.c +++ b/outdated/sys/wince/mswproc.c @@ -646,7 +646,7 @@ mswin_askname(void) { logDebug("mswin_askname()\n"); - if (mswin_getlin_window("who are you?", gp.plname, PL_NSIZ) == IDCANCEL) { + if (mswin_getlin_window("who are you?", svp.plname, PL_NSIZ) == IDCANCEL) { bail("bye-bye"); /* not reached */ } diff --git a/outdated/sys/wince/winhack.c b/outdated/sys/wince/winhack.c index 2e1f9266a..72f225a5f 100644 --- a/outdated/sys/wince/winhack.c +++ b/outdated/sys/wince/winhack.c @@ -226,8 +226,8 @@ gotlock: if (fd == -1) { error("cannot creat lock file (%s.)", fq_lock); } else { - if (write(fd, (char *) &gh.hackpid, sizeof(gh.hackpid)) - != sizeof(gh.hackpid)) { + if (write(fd, (char *) &svh.hackpid, sizeof(svh.hackpid)) + != sizeof(svh.hackpid)) { error("cannot write lock (%s)", fq_lock); } if (close(fd) == -1) { diff --git a/outdated/win/Qt3/qt3_win.cpp b/outdated/win/Qt3/qt3_win.cpp index 2233b3823..0f9b028cd 100644 --- a/outdated/win/Qt3/qt3_win.cpp +++ b/outdated/win/Qt3/qt3_win.cpp @@ -1031,9 +1031,9 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks) : QButtonGroup* namebox = new QButtonGroup(1,Horizontal,"Name",this); QLineEdit* name = new QLineEdit(namebox); - name->setMaxLength(sizeof(gp.plname)-1); - if ( strncmp(gp.plname,"player",6) && strncmp(gp.plname,"games",5) ) - name->setText(gp.plname); + name->setMaxLength(sizeof(svp.plname)-1); + if ( strncmp(svp.plname,"player",6) && strncmp(svp.plname,"games",5) ) + name->setText(svp.plname); connect(name, SIGNAL(textChanged(const QString&)), this, SLOT(selectName(const QString&)) ); name->setFocus(); @@ -1189,7 +1189,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks) : void NetHackQtPlayerSelector::selectName(const QString& n) { - strncpy(gp.plname,n.latin1(),sizeof(gp.plname)-1); + strncpy(svp.plname,n.latin1(),sizeof(svp.plname)-1); } void NetHackQtPlayerSelector::selectRole() @@ -2535,7 +2535,7 @@ void NetHackQtStatusWindow::updateStats() encumber.setLabel(enc); encumber.show(); } - Strcpy(buf, gp.plname); + Strcpy(buf, svp.plname); if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a'; Strcat(buf, " the "); if (u.mtimedone) { @@ -2598,7 +2598,7 @@ void NetHackQtStatusWindow::updateStats() align.setLabel("Lawful"); } - if (::flags.time) time.setLabel("Time:",(long)gm.moves); + if (::flags.time) time.setLabel("Time:",(long)svm.moves); else time.setLabel(""); #ifdef SCORE_ON_BOTL if (::flags.showscore) { @@ -3310,7 +3310,7 @@ static char** rip_line=0; long year; /* Put name on stone */ - Sprintf(rip_line[NAME_LINE], "%s", gp.plname); + Sprintf(rip_line[NAME_LINE], "%s", svp.plname); /* Put $ on stone */ Sprintf(rip_line[GOLD_LINE], "%ld Au", done_money); @@ -4037,7 +4037,7 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) void NetHackQtMainWindow::closeEvent(QCloseEvent* e) { - if ( gp.program_state.something_worth_saving ) { + if ( svp.program_state.something_worth_saving ) { switch ( QMessageBox::information( this, "NetHack", "This will end your NetHack session", "&Save", "&Cancel", 0, 1 ) ) @@ -4629,7 +4629,7 @@ void NetHackQtBind::qt_askname() NetHackQtSavedGameSelector sgsel((const char**)saved); ch = sgsel.choose(); if ( ch >= 0 ) - strcpy(gp.plname,saved[ch]); + strcpy(svp.plname,saved[ch]); } free_saved_games(saved); @@ -4849,7 +4849,7 @@ void NetHackQtBind::qt_update_inventory() if (main) main->updateInventory(); /* doesn't work yet - if (gp.program_state.something_worth_saving && iflags.perm_invent) + if (svp.program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, FALSE); */ } @@ -4903,14 +4903,14 @@ int NetHackQtBind::qt_nhgetch() // while (keybuffer.Empty() #ifdef SAFERHANGUP - && !gp.program_state.done_hup + && !svp.program_state.done_hup #endif ) { qApp->enter_loop(); } #ifdef SAFERHANGUP - if (gp.program_state.done_hup && keybuffer.Empty()) return '\033'; + if (svp.program_state.done_hup && keybuffer.Empty()) return '\033'; #endif return keybuffer.GetAscii(); } @@ -4924,13 +4924,13 @@ int NetHackQtBind::qt_nh_poskey(int *x, int *y, int *mod) // while (keybuffer.Empty() && clickbuffer.Empty() #ifdef SAFERHANGUP - && !gp.program_state.done_hup + && !svp.program_state.done_hup #endif ) { qApp->enter_loop(); } #ifdef SAFERHANGUP - if (gp.program_state.done_hup && keybuffer.Empty()) return '\033'; + if (svp.program_state.done_hup && keybuffer.Empty()) return '\033'; #endif if (!keybuffer.Empty()) { return keybuffer.GetAscii(); @@ -5179,7 +5179,7 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) bool result=QApplication::notify(receiver,event); #ifdef SAFERHANGUP - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { keybuffer.Put('\033'); qApp->exit_loop(); return TRUE; diff --git a/outdated/win/gem/wingem.c b/outdated/win/gem/wingem.c index 5ed289070..df8d1d81c 100644 --- a/outdated/win/gem/wingem.c +++ b/outdated/win/gem/wingem.c @@ -501,7 +501,7 @@ Gem_player_selection() void Gem_askname() { - strncpy(gp.plname, mar_ask_name(), PL_NSIZ); + strncpy(svp.plname, mar_ask_name(), PL_NSIZ); } void @@ -1074,7 +1074,7 @@ time_t when; } /* Follows same algorithm as genl_outrip() */ /* Put name on stone */ - Sprintf(rip_line[NAME_LINE], "%s", gp.plname); + Sprintf(rip_line[NAME_LINE], "%s", svp.plname); /* Put $ on stone */ Sprintf(rip_line[GOLD_LINE], "%ld Au", done_money); /* Put together death description */ diff --git a/outdated/win/gnome/gnbind.c b/outdated/win/gnome/gnbind.c index 49ed10251..0eeb57f98 100644 --- a/outdated/win/gnome/gnbind.c +++ b/outdated/win/gnome/gnbind.c @@ -354,7 +354,7 @@ gnome_askname() /* Ask for a name and stuff the response into plname, a nethack global */ ret = ghack_ask_string_dialog("What is your name?", "gandalf", - "GnomeHack", gp.plname); + "GnomeHack", svp.plname); /* Quit if they want to quit... */ if (ret == -1) { @@ -907,7 +907,7 @@ gnome_nhgetch() g_askingQuestion = 1; /* Process events until a key press event arrives. */ while (g_numKeys == 0) { - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) return '\033'; gtk_main_iteration(); } @@ -945,7 +945,7 @@ gnome_nh_poskey(int *x, int *y, int *mod) g_askingQuestion = 0; /* Process events until a key or map-click arrives. */ while (g_numKeys == 0 && g_numClicks == 0) { - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) return '\033'; gtk_main_iteration(); } @@ -1169,7 +1169,7 @@ gnome_outrip(winid wid, int how, time_t when) long year; /* Put name on stone */ - Sprintf(buf, "%s\n", gp.plname); + Sprintf(buf, "%s\n", svp.plname); Strcat(ripString, buf); /* Put $ on stone */ diff --git a/outdated/win/gnome/gnstatus.c b/outdated/win/gnome/gnstatus.c index 0ac29823a..045b40fa6 100644 --- a/outdated/win/gnome/gnstatus.c +++ b/outdated/win/gnome/gnstatus.c @@ -440,7 +440,7 @@ ghack_status_window_update_stats() long umoney; /* First, fill in the player name and the dungeon level */ - strcpy(buf, gp.plname); + strcpy(buf, svp.plname); if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A' - 'a'; strcat(buf, " the "); @@ -662,7 +662,7 @@ ghack_status_window_update_stats() } if (flags.time) { - sprintf(buf, "Time:%ld", gm.moves); + sprintf(buf, "Time:%ld", svm.moves); gtk_label_set(GTK_LABEL(timeLabel), buf); } else gtk_label_set(GTK_LABEL(timeLabel), ""); diff --git a/src/allmain.c b/src/allmain.c index 86a0aeb9e..fd22e17a2 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -71,15 +71,15 @@ moveloop_preamble(boolean resuming) } if (!resuming) { /* new game */ - gp.program_state.beyond_savefile_load = 1; /* for TTY_PERM_INVENT */ - gc.context.rndencode = rnd(9000); + svp.program_state.beyond_savefile_load = 1; /* for TTY_PERM_INVENT */ + svc.context.rndencode = rnd(9000); set_wear((struct obj *) 0); /* for side-effects of starting gear */ reset_justpicked(gi.invent); (void) pickup(1); /* autopickup at initial location */ /* only matters if someday a character is able to start with clairvoyance (wizard with cornuthaum perhaps?); without this, first "random" occurrence would always kick in on turn 1 */ - gc.context.seer_turn = (long) rnd(30); + svc.context.seer_turn = (long) rnd(30); /* give hero initial movement points; new game only--for restore, pending movement points were included in the save file */ u.umovement = NORMAL_SPEED; @@ -98,9 +98,9 @@ moveloop_preamble(boolean resuming) } u.uz0.dlevel = u.uz.dlevel; - gc.context.move = 0; + svc.context.move = 0; - gp.program_state.in_moveloop = 1; + svp.program_state.in_moveloop = 1; /* for perm_invent preset at startup, display persistent inventory after invent is fully populated and the in_moveloop flag has been set */ if (iflags.perm_invent) @@ -166,7 +166,7 @@ moveloop_core(void) boolean monscanmove = FALSE; #ifdef SAFERHANGUP - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) end_of_input(); #endif get_nh_event(); @@ -176,26 +176,26 @@ moveloop_core(void) dobjsfree(); - if (gc.context.bypasses) + if (svc.context.bypasses) clear_bypasses(); if (iflags.sanity_check || iflags.debug_fuzzer) sanity_check(); - if (gc.context.move) { + if (svc.context.move) { /* actual time passed */ u.umovement -= NORMAL_SPEED; do { /* hero can't move this turn loop */ mvl_wtcap = encumber_msg(); - gc.context.mon_moving = TRUE; + svc.context.mon_moving = TRUE; do { monscanmove = movemon(); if (u.umovement >= NORMAL_SPEED) break; /* it's now your turn */ } while (monscanmove); - gc.context.mon_moving = FALSE; + svc.context.mon_moving = FALSE; if (!monscanmove && u.umovement < NORMAL_SPEED) { /* both hero and monsters are out of steam this round */ @@ -222,7 +222,7 @@ moveloop_core(void) u_calc_moveamt(mvl_wtcap); settrack(); - gm.moves++; + svm.moves++; /* * Never allow 'moves' to grow big enough to wrap. * We don't care what the maximum possible 'long int' @@ -231,16 +231,16 @@ moveloop_core(void) * When imposing the limit, use a mystic decimal value * instead of a magic binary one such as 0x7fffffffL. */ - if (gm.moves >= 1000000000L) { + if (svm.moves >= 1000000000L) { display_nhwindow(WIN_MESSAGE, TRUE); urgent_pline("The dungeon capitulates."); done(ESCAPED); } /* 'moves' is misnamed; it represents turns; hero_seq is a value that is distinct every time the hero moves */ - gh.hero_seq = gm.moves << 3; + gh.hero_seq = svm.moves << 3; - if (flags.time && !gc.context.run) + if (flags.time && !svc.context.run) disp.time_botl = TRUE; /* 'moves' just changed */ /********************************/ @@ -277,8 +277,8 @@ moveloop_core(void) /* moving around while encumbered is hard work */ if (mvl_wtcap > MOD_ENCUMBER && u.umoved) { - if (!(mvl_wtcap < EXT_ENCUMBER ? gm.moves % 30 - : gm.moves % 10)) { + if (!(mvl_wtcap < EXT_ENCUMBER ? svm.moves % 30 + : svm.moves % 10)) { overexert_hp(); } } @@ -320,7 +320,7 @@ moveloop_core(void) } } - if (!gl.level.flags.noautosearch && Searching && gm.multi >= 0) + if (!svl.level.flags.noautosearch && Searching && gm.multi >= 0) (void) dosearch0(1); if (Warning) warnreveal(); @@ -349,7 +349,7 @@ moveloop_core(void) /* vision will be updated as bubbles move */ if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); - else if (gl.level.flags.fumaroles) + else if (svl.level.flags.fumaroles) fumaroles(); /* when immobile, count is in turns */ @@ -382,13 +382,13 @@ moveloop_core(void) if (iflags.hilite_delta) status_eval_next_unhilite(); #endif - if (gm.moves >= gc.context.seer_turn) { + if (svm.moves >= svc.context.seer_turn) { if ((u.uhave.amulet || Clairvoyant) && !In_endgame(&u.uz) && !BClairvoyant) do_vicinity_map((struct obj *) 0); /* we maintain this counter even when clairvoyance isn't taking place; on average, go again 30 turns from now */ - gc.context.seer_turn = gm.moves + (long) rn1(31, 15); /*15..45*/ + svc.context.seer_turn = svm.moves + (long) rn1(31, 15); /*15..45*/ /* [it used to be that on every 15th turn, there was a 50% chance of farsight, so it could happen as often as every 15 turns or theoretically never happen at all; but when @@ -417,7 +417,7 @@ moveloop_core(void) clear_splitobjs(); find_ac(); - if (!gc.context.mv || Blind) { + if (!svc.context.mv || Blind) { /* redo monsters if hallu or wearing a helm of telepathy */ if (Hallucination) { /* update screen randomly */ see_monsters(); @@ -443,7 +443,7 @@ moveloop_core(void) m_everyturn_effect(&gy.youmonst); - gc.context.move = 1; + svc.context.move = 1; if (gm.multi >= 0 && go.occupation) { #if defined(MICRO) || defined(WIN32CON) @@ -485,10 +485,10 @@ moveloop_core(void) runmode_delay_output(); if (!gm.multi) { /* lookaround may clear multi */ - gc.context.move = 0; + svc.context.move = 0; return; } - if (gc.context.mv) { + if (svc.context.mv) { if (gm.multi < COLNO && !--gm.multi) end_running(TRUE); domove(); @@ -509,10 +509,10 @@ moveloop_core(void) if (gv.vision_full_recalc) vision_recalc(0); /* vision! */ /* when running in non-tport mode, this gets done through domove() */ - if ((!gc.context.run || flags.runmode == RUN_TPORT) - && (gm.multi && (!gc.context.travel ? !(gm.multi % 7) - : !(gm.moves % 7L)))) { - if (flags.time && gc.context.run) + if ((!svc.context.run || flags.runmode == RUN_TPORT) + && (gm.multi && (!svc.context.travel ? !(gm.multi % 7) + : !(svm.moves % 7L)))) { + if (flags.time && svc.context.run) disp.botl = TRUE; /* [should this be flush_screen() instead?] */ display_nhwindow(WIN_MAP, FALSE); @@ -564,7 +564,7 @@ regen_pw(int wtcap) { if (u.uen < u.uenmax && ((wtcap < MOD_ENCUMBER - && (!(gm.moves % ((MAXULEV + 8 - u.ulevel) + && (!(svm.moves % ((MAXULEV + 8 - u.ulevel) * (Role_if(PM_WIZARD) ? 3 : 4) / 6)))) || Energy_regeneration)) { int upper = (int) (ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1; @@ -597,10 +597,10 @@ regen_hp(int wtcap) /* eel out of water loses hp, similar to monster eels; as hp gets lower, rate of further loss slows down */ if (u.mh > 1 && !Regeneration && rn2(u.mh) > rn2(8) - && (!Half_physical_damage || !(gm.moves % 2L))) + && (!Half_physical_damage || !(svm.moves % 2L))) heal = -1; } else if (u.mh < u.mhmax) { - if (U_CAN_REGEN() || (encumbrance_ok && !(gm.moves % 20L))) + if (U_CAN_REGEN() || (encumbrance_ok && !(svm.moves % 20L))) heal = 1; } if (heal) { @@ -726,14 +726,14 @@ newgame(void) /* make sure welcome messages are given before noticing monsters */ notice_mon_off(); disp.botlx = TRUE; - gc.context.ident = 1; - gc.context.warnlevel = 1; - gc.context.next_attrib_check = 600L; /* arbitrary first setting */ - gc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ - gc.context.tribute.tributesz = sizeof(struct tribute_info); + svc.context.ident = 1; + svc.context.warnlevel = 1; + svc.context.next_attrib_check = 600L; /* arbitrary first setting */ + svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ + svc.context.tribute.tributesz = sizeof(struct tribute_info); for (i = LOW_PM; i < NUMMONS; i++) - gm.mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; + svm.mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; init_objects(); /* must be before u_init() */ @@ -781,7 +781,7 @@ newgame(void) #ifdef INSURANCE save_currentstate(); #endif - gp.program_state.something_worth_saving++; /* useful data now exists */ + svp.program_state.something_worth_saving++; /* useful data now exists */ /* Success! */ welcome(TRUE); @@ -833,12 +833,12 @@ welcome(boolean new_game) /* false => restoring an old game */ pline(new_game ? "%s %s, welcome to NetHack! You are a%s." : "%s %s, the%s, welcome back to NetHack!", - Hello((struct monst *) 0), gp.plname, buf); + Hello((struct monst *) 0), svp.plname, buf); if (new_game) { /* guarantee that 'major' event category is never empty */ livelog_printf(LL_ACHIEVE, "%s the%s entered the dungeon", - gp.plname, buf); + svp.plname, buf); } else { /* if restoring in Gehennom, give same hot/smoky message as when first entering it */ @@ -895,7 +895,7 @@ do_positionbar(void) staticfn void interrupt_multi(const char *msg) { - if (gm.multi > 0 && !gc.context.travel && !gc.context.run) { + if (gm.multi > 0 && !svc.context.travel && !svc.context.run) { nomul(0); if (flags.verbose && msg) Norep("%s", msg); diff --git a/src/apply.c b/src/apply.c index 4773d3c86..32a9b14ad 100644 --- a/src/apply.c +++ b/src/apply.c @@ -331,8 +331,8 @@ use_stethoscope(struct obj *obj) if (!getdir((char *) 0)) return ECMD_CANCEL; - res = (gh.hero_seq == gc.context.stethoscope_seq) ? ECMD_TIME : ECMD_OK; - gc.context.stethoscope_seq = gh.hero_seq; + res = (gh.hero_seq == svc.context.stethoscope_seq) ? ECMD_TIME : ECMD_OK; + svc.context.stethoscope_seq = gh.hero_seq; gb.bhitpos.x = u.ux, gb.bhitpos.y = u.uy; /* tentative, reset below */ gn.notonhead = u.uswallow; @@ -1208,9 +1208,9 @@ use_bell(struct obj **optr) } else if (ordinary) { if (obj->cursed && !rn2(4) /* note: once any of them are gone, we stop all of them */ - && !(gm.mvitals[PM_WOOD_NYMPH].mvflags & G_GONE) - && !(gm.mvitals[PM_WATER_NYMPH].mvflags & G_GONE) - && !(gm.mvitals[PM_MOUNTAIN_NYMPH].mvflags & G_GONE) + && !(svm.mvitals[PM_WOOD_NYMPH].mvflags & G_GONE) + && !(svm.mvitals[PM_WATER_NYMPH].mvflags & G_GONE) + && !(svm.mvitals[PM_MOUNTAIN_NYMPH].mvflags & G_GONE) && (mtmp = makemon(mkclass(S_NYMPH, 0), u.ux, u.uy, NO_MINVENT | MM_NOMSG)) != 0) { You("summon %s!", a_monnam(mtmp)); @@ -1254,7 +1254,7 @@ use_bell(struct obj **optr) } else if (invoking) { pline("%s an unsettling shrill sound...", Tobjnam(obj, "issue")); - obj->age = gm.moves; + obj->age = svm.moves; learno = TRUE; wakem = TRUE; @@ -2391,7 +2391,7 @@ fig_transform(anything *arg, long timeout) impossible("null figurine in fig_transform()"); return; } - silent = (timeout != gm.moves); /* happened while away */ + silent = (timeout != svm.moves); /* happened while away */ okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0); if (figurine->where == OBJ_INVENT || figurine->where == OBJ_MINVENT) okay_spot = enexto(&cc, cc.x, cc.y, &mons[figurine->corpsenm]); @@ -2406,7 +2406,7 @@ fig_transform(anything *arg, long timeout) mtmp = make_familiar(figurine, cc.x, cc.y, TRUE); if (mtmp) { char and_vanish[BUFSZ]; - struct obj *mshelter = gl.level.objects[mtmp->mx][mtmp->my]; + struct obj *mshelter = svl.level.objects[mtmp->mx][mtmp->my]; /* [m_monnam() yields accurate mon type, overriding hallucination] */ Sprintf(monnambuf, "%s", an(m_monnam(mtmp))); @@ -2535,7 +2535,7 @@ use_figurine(struct obj **optr) return ECMD_OK; } if (!getdir((char *) 0)) { - gc.context.move = gm.multi = 0; + svc.context.move = gm.multi = 0; return ECMD_CANCEL; } x = u.ux + u.dx; @@ -3018,7 +3018,7 @@ use_whip(struct obj *obj) /* Have a shot at snaring something on the floor. A flyer can reach the floor so could just pick an item up, but allow snagging by whip too. */ - otmp = gl.level.objects[u.ux][u.uy]; + otmp = svl.level.objects[u.ux][u.uy]; if (otmp && otmp->otyp == CORPSE && (otmp->corpsenm == PM_HORSE || otmp->corpsenm == little_to_big(PM_HORSE) /* warhorse */ @@ -3340,7 +3340,7 @@ use_pole(struct obj *obj, boolean autohit) int res = ECMD_OK, typ, max_range, min_range, glyph; coord cc; struct monst *mtmp; - struct monst *hitm = gc.context.polearm.hitmon; + struct monst *hitm = svc.context.polearm.hitmon; /* Are you allowed to use the pole? */ if (u.uswallow) { @@ -3421,19 +3421,19 @@ use_pole(struct obj *obj, boolean autohit) return ECMD_FAIL; } - gc.context.polearm.hitmon = (struct monst *) 0; + svc.context.polearm.hitmon = (struct monst *) 0; /* Attack the monster there */ gb.bhitpos = cc; if ((mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y)) != (struct monst *) 0) { if (attack_checks(mtmp, uwep)) /* can attack proceed? */ /* no, abort the attack attempt; result depends on res: 1 => polearm became wielded, 0 => already wielded; - gc.context.move: 1 => discovered hidden monster at target spot, + svc.context.move: 1 => discovered hidden monster at target spot, 0 => answered 'n' to "Really attack?" prompt */ - return res | (gc.context.move ? ECMD_TIME : ECMD_OK); + return res | (svc.context.move ? ECMD_TIME : ECMD_OK); if (overexertion()) return ECMD_TIME; /* burn nutrition; maybe pass out */ - gc.context.polearm.hitmon = mtmp; + svc.context.polearm.hitmon = mtmp; check_caitiff(mtmp); gn.notonhead = (gb.bhitpos.x != mtmp->mx || gb.bhitpos.y != mtmp->my); (void) thitmonst(mtmp, uwep); @@ -3733,7 +3733,7 @@ use_grapple(struct obj *obj) /* FIXME -- untrap needs to deal with non-adjacent traps */ break; case 1: /* Object */ - if ((otmp = gl.level.objects[cc.x][cc.y]) != 0) { + if ((otmp = svl.level.objects[cc.x][cc.y]) != 0) { You("snag an object from the %s!", surface(cc.x, cc.y)); (void) pickup_object(otmp, 1L, FALSE); /* If pickup fails, leave it alone */ @@ -3992,7 +3992,7 @@ do_break_wand(struct obj *obj) (void) bhitm(mon, obj); /* if (disp.botl) bot(); */ } - if (affects_objects && gl.level.objects[x][y]) { + if (affects_objects && svl.level.objects[x][y]) { (void) bhitpile(obj, bhito, x, y, 0); if (disp.botl) bot(); /* potion effects */ @@ -4010,7 +4010,7 @@ do_break_wand(struct obj *obj) * of obj->bypass in the zap code to accomplish that last case * since it's also used by retouch_equipment() for polyself.) */ - if (affects_objects && gl.level.objects[x][y]) { + if (affects_objects && svl.level.objects[x][y]) { (void) bhitpile(obj, bhito, x, y, 0); if (disp.botl) bot(); /* potion effects */ diff --git a/src/artifact.c b/src/artifact.c index 7bbad3c62..80599729d 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -510,7 +510,7 @@ restrict_name(struct obj *otmp, const char *name) if (!objects[otyp].oc_name_known && (odesc = OBJ_DESCR(objects[otyp])) != 0) { obj_shuffle_range(otyp, &lo, &hi); - for (i = gb.bases[ocls]; i < NUM_OBJECTS; i++) { + for (i = svb.bases[ocls]; i < NUM_OBJECTS; i++) { if (objects[i].oc_class != ocls) break; if (!objects[i].oc_name_known @@ -705,7 +705,7 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask) * when restoring a game */ (void) make_hallucinated((long) !on, - gp.program_state.restoring ? FALSE : TRUE, + svp.program_state.restoring ? FALSE : TRUE, wp_mask); } if (spfx & SPFX_ESP) { @@ -738,10 +738,10 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask) if (spec_m2(otmp)) { if (on) { EWarn_of_mon |= wp_mask; - gc.context.warntype.obj |= spec_m2(otmp); + svc.context.warntype.obj |= spec_m2(otmp); } else { EWarn_of_mon &= ~wp_mask; - gc.context.warntype.obj &= ~spec_m2(otmp); + svc.context.warntype.obj &= ~spec_m2(otmp); } see_monsters(); } else { @@ -1695,7 +1695,7 @@ arti_invoke(struct obj *obj) if (oart->inv_prop > LAST_PROP) { /* It's a special power, not "just" a property */ - if (obj->age > gm.moves) { + if (obj->age > svm.moves) { /* the artifact is tired :-) */ You_feel("that %s %s ignoring you.", the(xname(obj)), otense(obj, "are")); @@ -1703,7 +1703,7 @@ arti_invoke(struct obj *obj) obj->age += (long) d(3, 10); return ECMD_TIME; } - obj->age = gm.moves + rnz(100); + obj->age = svm.moves + rnz(100); switch (oart->inv_prop) { case TAMING: { @@ -1802,15 +1802,15 @@ arti_invoke(struct obj *obj) any = cg.zeroany; /* set all bits to zero */ start_menu(tmpwin, MENU_BEHAVE_STANDARD); /* use index+1 (cant use 0) as identifier */ - for (i = num_ok_dungeons = 0; i < gn.n_dgns; i++) { - if (!gd.dungeons[i].dunlev_ureached) + for (i = num_ok_dungeons = 0; i < svn.n_dgns; i++) { + if (!svd.dungeons[i].dunlev_ureached) continue; if (i == tutorial_dnum) /* can't portal into tutorial */ continue; any.a_int = i + 1; add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, - gd.dungeons[i].dname, MENU_ITEMFLAGS_NONE); + svd.dungeons[i].dname, MENU_ITEMFLAGS_NONE); num_ok_dungeons++; last_ok_dungeon = i; } @@ -1839,10 +1839,10 @@ arti_invoke(struct obj *obj) * The closest level is either the entry or dunlev_ureached. */ newlev.dnum = i; - if (gd.dungeons[i].depth_start >= depth(&u.uz)) - newlev.dlevel = gd.dungeons[i].entry_lev; + if (svd.dungeons[i].depth_start >= depth(&u.uz)) + newlev.dlevel = svd.dungeons[i].entry_lev; else - newlev.dlevel = gd.dungeons[i].dunlev_ureached; + newlev.dlevel = svd.dungeons[i].dunlev_ureached; if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev) || newlev.dnum == u.uz.dnum || !next_to_u()) { @@ -1905,7 +1905,7 @@ arti_invoke(struct obj *obj) if (mtmp->data->msound == MS_NEMESIS) continue; - if (In_quest(&u.uz) && !gq.quest_status.killed_nemesis) + if (In_quest(&u.uz) && !svq.quest_status.killed_nemesis) chance += 10; if (is_dprince(mtmp->data)) chance += 2; @@ -1968,7 +1968,7 @@ arti_invoke(struct obj *obj) } else { /* no direction picked */ pline("%s", Never_mind); - obj->age = gm.moves; + obj->age = svm.moves; } break; default: @@ -1980,7 +1980,7 @@ arti_invoke(struct obj *obj) iprop = u.uprops[oart->inv_prop].intrinsic; boolean on = (eprop & W_ARTI) != 0; /* true if prop just set */ - if (on && obj->age > gm.moves) { + if (on && obj->age > svm.moves) { /* the artifact is tired :-) */ u.uprops[oart->inv_prop].extrinsic ^= W_ARTI; You_feel("that %s %s ignoring you.", the(xname(obj)), @@ -1991,7 +1991,7 @@ arti_invoke(struct obj *obj) } else if (!on) { /* when turning off property, determine downtime */ /* arbitrary for now until we can tune this -dlc */ - obj->age = gm.moves + rnz(100); + obj->age = svm.moves + rnz(100); } if ((eprop & ~W_ARTI) || iprop) { @@ -2191,7 +2191,7 @@ what_gives(long *abil) for (obj = gi.invent; obj; obj = obj->nobj) { if (obj->oartifact - && (abil != &EWarn_of_mon || gc.context.warntype.obj)) { + && (abil != &EWarn_of_mon || svc.context.warntype.obj)) { const struct artifact *art = get_artifact(obj); if (art != &artilist[ART_NONARTIFACT]) { @@ -2527,7 +2527,7 @@ count_surround_traps(coordxy x, coordxy y) ++ret; continue; } - for (otmp = gl.level.objects[dx][dy]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[dx][dy]; otmp; otmp = otmp->nexthere) if (Is_container(otmp) && otmp->otrapped) { ++ret; /* we're counting locations, so just */ break; /* count the first one in a pile */ diff --git a/src/attrib.c b/src/attrib.c index 8ab5618d7..c7ad35dca 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -191,7 +191,7 @@ adjattrib( disp.botl = TRUE; if (msgflg <= 0) You_feel("%s%s!", (incr > 1 || incr < -1) ? "very " : "", attrstr); - if (gp.program_state.in_moveloop && (ndx == A_STR || ndx == A_CON)) + if (svp.program_state.in_moveloop && (ndx == A_STR || ndx == A_CON)) (void) encumber_msg(); return TRUE; } @@ -387,8 +387,8 @@ poisoned( } if (u.uhp < 1) { - gk.killer.format = kprefix; - Strcpy(gk.killer.name, pkiller); + svk.killer.format = kprefix; + Strcpy(svk.killer.name, pkiller); /* "Poisoned by a poisoned ___" is redundant */ done(strstri(pkiller, "poison") ? DIED : POISONING); } @@ -501,14 +501,14 @@ exercise(int i, boolean inc_or_dec) : "Con", (inc_or_dec) ? "inc" : "dec", AEXE(i)); } - if (gm.moves > 0 && (i == A_STR || i == A_CON)) + if (svm.moves > 0 && (i == A_STR || i == A_CON)) (void) encumber_msg(); } staticfn void exerper(void) { - if (!(gm.moves % 10)) { + if (!(svm.moves % 10)) { /* Hunger Checks */ int hs = (u.uhunger > 1000) ? SATIATED : (u.uhunger > 150) ? NOT_HUNGRY @@ -555,7 +555,7 @@ exerper(void) } /* status checks */ - if (!(gm.moves % 5)) { + if (!(svm.moves % 5)) { debugpline0("exerper: Status checks"); if ((HClairvoyant & (INTRINSIC | TIMEOUT)) && !BClairvoyant) exercise(A_WIS, TRUE); @@ -590,11 +590,11 @@ exerchk(void) /* Check out the periodic accumulations */ exerper(); - if (gm.moves >= gc.context.next_attrib_check) { + if (svm.moves >= svc.context.next_attrib_check) { debugpline1("exerchk: ready to test. multi = %ld.", gm.multi); } /* Are we ready for a test? */ - if (gm.moves >= gc.context.next_attrib_check && !gm.multi) { + if (svm.moves >= svc.context.next_attrib_check && !gm.multi) { debugpline0("exerchk: testing."); /* * Law of diminishing returns (Part II): @@ -658,9 +658,9 @@ exerchk(void) platform-dependent rounding/truncation for negative vals */ AEXE(i) = (abs(ax) / 2) * mod_val; } - gc.context.next_attrib_check += rn1(200, 800); + svc.context.next_attrib_check += rn1(200, 800); debugpline1("exerchk: next check at %ld.", - gc.context.next_attrib_check); + svc.context.next_attrib_check); } } @@ -1072,7 +1072,7 @@ newhp(void) hp += rnd(gu.urole.hpadv.inrnd); if (gu.urace.hpadv.inrnd > 0) hp += rnd(gu.urace.hpadv.inrnd); - if (gm.moves <= 1L) { /* initial hero; skip for polyself to new man */ + if (svm.moves <= 1L) { /* initial hero; skip for polyself to new man */ /* Initialize alignment stuff */ u.ualign.type = aligns[flags.initalign].value; u.ualign.record = gu.urole.initrecord; diff --git a/src/ball.c b/src/ball.c index fe264eaf8..f09a45efa 100644 --- a/src/ball.c +++ b/src/ball.c @@ -359,7 +359,7 @@ bc_order(void) || u.uswallow) return BCPOS_DIFFER; - for (obj = gl.level.objects[uball->ox][uball->oy]; obj; + for (obj = svl.level.objects[uball->ox][uball->oy]; obj; obj = obj->nexthere) { if (obj == uchain) return BCPOS_CHAIN; diff --git a/src/bones.c b/src/bones.c index 2ed70ad91..2fce425ed 100644 --- a/src/bones.c +++ b/src/bones.c @@ -22,7 +22,7 @@ no_bones_level(d_level *lev) assign_level(lev, &gs.save_dlevel); return (boolean) (((sptr = Is_special(lev)) != 0 && !sptr->boneid) - || !gd.dungeons[lev->dnum].boneid + || !svd.dungeons[lev->dnum].boneid /* no bones on the last or multiway branch levels in any dungeon (level 1 isn't multiway) */ || Is_botlevel(lev) @@ -94,7 +94,7 @@ resetobjs(struct obj *ochain, boolean restore) result depends upon hero's location */ && inside_shop(ox, oy) && *(p = in_rooms(ox, oy, SHOPBASE)) - && tended_shop(&gr.rooms[*p - ROOMOFFSET])); + && tended_shop(&svr.rooms[*p - ROOMOFFSET])); } } else { /* saving */ /* do not zero out o_ids for ghost levels anymore */ @@ -317,7 +317,7 @@ fixuporacle(struct monst *oracle) oracle->mpeaceful = 1; /* for behavior toward next character */ o_ridx = levl[oracle->mx][oracle->my].roomno - ROOMOFFSET; - if (o_ridx >= 0 && gr.rooms[o_ridx].rtype == DELPHI) + if (o_ridx >= 0 && svr.rooms[o_ridx].rtype == DELPHI) return TRUE; /* no fixup needed */ /* @@ -328,14 +328,14 @@ fixuporacle(struct monst *oracle) */ /* find original delphi chamber; should always succeed */ - for (ridx = 0; ridx < SIZE(gr.rooms); ++ridx) - if (gr.rooms[ridx].orig_rtype == DELPHI) + for (ridx = 0; ridx < SIZE(svr.rooms); ++ridx) + if (svr.rooms[ridx].orig_rtype == DELPHI) break; - if (o_ridx != ridx && ridx < SIZE(gr.rooms)) { + if (o_ridx != ridx && ridx < SIZE(svr.rooms)) { /* room found and she's not in it, so try to move her there */ - cc.x = (gr.rooms[ridx].lx + gr.rooms[ridx].hx) / 2; - cc.y = (gr.rooms[ridx].ly + gr.rooms[ridx].hy) / 2; + cc.x = (svr.rooms[ridx].lx + svr.rooms[ridx].hx) / 2; + cc.y = (svr.rooms[ridx].ly + svr.rooms[ridx].hy) / 2; if (enexto(&cc, cc.x, cc.y, oracle->data)) { rloc_to(oracle, cc.x, cc.y); o_ridx = levl[oracle->mx][oracle->my].roomno - ROOMOFFSET; @@ -345,7 +345,7 @@ fixuporacle(struct monst *oracle) same as used to happen before this fixup was introduced] */ } if (ridx == o_ridx) /* if she's in her room, mark it as such */ - gr.rooms[ridx].rtype = DELPHI; + svr.rooms[ridx].rtype = DELPHI; return TRUE; /* keep oracle in new bones file */ } @@ -462,7 +462,7 @@ savebones(int how, time_t when, struct obj *corpse) return; } give_u_to_m_resistances(mtmp); - mtmp = christen_monst(mtmp, gp.plname); + mtmp = christen_monst(mtmp, svp.plname); newsym(u.ux, u.uy); /* ["Your body rises from the dead as an ..." used to be given here, but it has been moved to done() so that @@ -478,7 +478,7 @@ savebones(int how, time_t when, struct obj *corpse) /* embed your possessions in your statue */ otmp = mk_named_object(STATUE, &mons[u.umonnum], u.ux, u.uy, - gp.plname); + svp.plname); drop_upon_death((struct monst *) 0, otmp, u.ux, u.uy); if (!otmp) @@ -495,7 +495,7 @@ savebones(int how, time_t when, struct obj *corpse) gi.in_mklev = FALSE; if (!mtmp) return; - mtmp = christen_monst(mtmp, gp.plname); + mtmp = christen_monst(mtmp, svp.plname); if (corpse) (void) obj_attach_mid(corpse, mtmp->m_id); } @@ -521,8 +521,8 @@ savebones(int how, time_t when, struct obj *corpse) } set_ghostly_objlist(fobj); resetobjs(fobj, FALSE); - set_ghostly_objlist(gl.level.buriedobjlist); - resetobjs(gl.level.buriedobjlist, FALSE); + set_ghostly_objlist(svl.level.buriedobjlist); + resetobjs(svl.level.buriedobjlist, FALSE); /* Hero is no longer on the map. */ u.ux0 = u.ux, u.uy0 = u.uy; @@ -534,7 +534,7 @@ savebones(int how, time_t when, struct obj *corpse) levl[x][y].seenv = 0; levl[x][y].waslit = 0; levl[x][y].glyph = GLYPH_UNEXPLORED; - gl.lastseentyp[x][y] = 0; + svl.lastseentyp[x][y] = 0; } /* Attach bones info to the current level before saving. */ @@ -546,7 +546,7 @@ savebones(int how, time_t when, struct obj *corpse) gender and alignment reflect final values rather than what the character started out as, same as topten and logfile entries */ Sprintf(newbones->who, "%s-%.3s-%.3s-%.3s-%.3s", - gp.plname, gu.urole.filecode, + svp.plname, gu.urole.filecode, gu.urace.filecode, genders[flags.female].filecode, aligns[1 - u.ualign.type].filecode); formatkiller(newbones->how, sizeof newbones->how, how, TRUE); @@ -556,13 +556,13 @@ savebones(int how, time_t when, struct obj *corpse) newbones->bonesknown = FALSE; /* if current character died on a bones level, the cemetery list will have multiple entries, most recent (this dead hero) first */ - newbones->next = gl.level.bonesinfo; - gl.level.bonesinfo = newbones; + newbones->next = svl.level.bonesinfo; + svl.level.bonesinfo = newbones; /* flag these bones if they are being created in wizard mode; they might already be flagged as such, even when we're playing in normal mode, if this level came from a previous bones file */ if (wizard) - gl.level.flags.wizard_bones = 1; + svl.level.flags.wizard_bones = 1; nhfp = create_bonesfile(&u.uz, &bonesid, whynot); if (!nhfp) { @@ -690,7 +690,7 @@ getbones(void) resetobjs(mtmp->minvent, TRUE); } resetobjs(fobj, TRUE); - resetobjs(gl.level.buriedobjlist, TRUE); + resetobjs(svl.level.buriedobjlist, TRUE); fix_shop_damage(); } } @@ -731,7 +731,7 @@ bones_include_name(const char *name) Strcat(buf, "-"); len = strlen(buf); - for (bp = gl.level.bonesinfo; bp; bp = bp->next) { + for (bp = svl.level.bonesinfo; bp; bp = bp->next) { if (!strncmp(bp->who, buf, len)) return TRUE; } diff --git a/src/botl.c b/src/botl.c index 6f6234f4a..ba671c94a 100644 --- a/src/botl.c +++ b/src/botl.c @@ -58,7 +58,7 @@ do_statusline1(void) if (suppress_map_output()) return strcpy(newbot1, ""); - Strcpy(newbot1, gp.plname); + Strcpy(newbot1, svp.plname); if ('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A' - 'a'; newbot1[10] = 0; @@ -160,7 +160,7 @@ do_statusline2(void) /* time/move counter */ if (flags.time) - Sprintf(tmmv, "T:%ld", gm.moves); + Sprintf(tmmv, "T:%ld", svm.moves); else tmmv[0] = '\0'; tln = strlen(tmmv); @@ -281,7 +281,7 @@ timebot(void) if (gb.bot_disabled) return; /* we're called when disp.time_botl is set and general disp.botl - is clear; disp.time_botl gets set whenever gm.moves changes value + is clear; disp.time_botl gets set whenever svm.moves changes value so there's no benefit in tracking previous value to decide whether to skip update; suppress_map_output() handles program_state.restoring and program_state.done_hup (tty hangup => no further output at all) @@ -451,7 +451,7 @@ describe_level( int ret = 1; if (Is_knox(&u.uz)) { - Sprintf(buf, "%s", gd.dungeons[u.uz.dnum].dname); + Sprintf(buf, "%s", svd.dungeons[u.uz.dnum].dname); addbranch = FALSE; } else if (In_quest(&u.uz)) { Sprintf(buf, "Home %d", dunlev(&u.uz)); @@ -471,7 +471,7 @@ describe_level( ret = 0; } if (addbranch) { - Sprintf(eos(buf), ", %s", gd.dungeons[u.uz.dnum].dname); + Sprintf(eos(buf), ", %s", svd.dungeons[u.uz.dnum].dname); (void) strsubst(buf, "The ", "the "); } if (addspace) @@ -769,7 +769,7 @@ bot_via_windowport(void) /* * Player name and title. */ - Strcpy(nb = buf, gp.plname); + Strcpy(nb = buf, svp.plname); nb[0] = highc(nb[0]); titl = !Upolyd ? rank() : pmname(&mons[u.umonnum], Ugender); i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof ""); @@ -873,7 +873,7 @@ bot_via_windowport(void) gb.blstats[idx][BL_EXP].a.a_long = u.uexp; /* Time (moves) */ - gb.blstats[idx][BL_TIME].a.a_long = gm.moves; + gb.blstats[idx][BL_TIME].a.a_long = svm.moves; /* Hunger */ /* note: u.uhs is unsigned, and 3.6.1's STATUS_HILITE defined @@ -1042,7 +1042,7 @@ stat_update_time(void) int fld = BL_TIME; /* Time (moves) */ - gb.blstats[idx][fld].a.a_long = gm.moves; + gb.blstats[idx][fld].a.a_long = svm.moves; gv.valset[fld] = FALSE; eval_notify_windowport_field(fld, gv.valset, idx); @@ -1298,17 +1298,17 @@ eval_notify_windowport_field( } /* Temporary? hack: moveloop()'s prolog for a new game sets - * gc.context.rndencode after the status window has been init'd, + * svc.context.rndencode after the status window has been init'd, * so $:0 has already been encoded and cached by the window * port. Without this hack, gold's \G sequence won't be * recognized and ends up being displayed as-is for 'gu.update_all'. * - * Also, even if gc.context.rndencode hasn't changed and the + * Also, even if svc.context.rndencode hasn't changed and the * gold amount itself hasn't changed, the glyph portion of the * encoding may have changed if a new symset was put into effect. * * \GXXXXNNNN:25 - * XXXX = the gc.context.rndencode portion + * XXXX = the svc.context.rndencode portion * NNNN = the glyph portion * 25 = the gold amount * @@ -1316,10 +1316,10 @@ eval_notify_windowport_field( * not to honor an initial highlight, so force 'gu.update_all = TRUE'. */ if (fld == BL_GOLD - && (gc.context.rndencode != oldrndencode + && (svc.context.rndencode != oldrndencode || gs.showsyms[COIN_CLASS + SYM_OFF_O] != oldgoldsym)) { gu.update_all = TRUE; /* chg = 2; */ - oldrndencode = gc.context.rndencode; + oldrndencode = svc.context.rndencode; oldgoldsym = gs.showsyms[COIN_CLASS + SYM_OFF_O]; } @@ -2023,7 +2023,7 @@ status_eval_next_unhilite(void) struct istat_s *curr; long next_unhilite, this_unhilite; - gb.bl_hilite_moves = gm.moves; /* simplified; at one point we used to + gb.bl_hilite_moves = svm.moves; /* simplified; at one point we used to * try to encode fractional amounts for * multiple moves within same turn */ /* figure out whether an unhilight needs to be performed now */ @@ -2276,7 +2276,7 @@ get_hilite( txtstr = gb.blstats[idx][fldidx].val; if (fldidx == BL_TITLE) /* " the ", skip past " the " */ - txtstr += (strlen(gp.plname) + sizeof " the " - sizeof ""); + txtstr += (strlen(svp.plname) + sizeof " the " - sizeof ""); if (hl->rel == TXT_VALUE && hl->textmatch[0]) { if (fuzzymatch(hl->textmatch, txtstr, "\" -_", TRUE)) { rule = hl; diff --git a/src/cmd.c b/src/cmd.c index 3222dc833..ea3caa5de 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -978,11 +978,11 @@ makemap_prepost(boolean pre, boolean wiztower) if (Is_mineend_level(&u.uz)) { if (remove_achievement(ACH_MINE_PRIZE)) pline(Unachieve, "Mine's-end"); - gc.context.achieveo.mines_prize_oid = 0; + svc.context.achieveo.mines_prize_oid = 0; } else if (Is_sokoend_level(&u.uz)) { if (remove_achievement(ACH_SOKO_PRIZE)) pline(Unachieve, "Soko-prize"); - gc.context.achieveo.soko_prize_oid = 0; + svc.context.achieveo.soko_prize_oid = 0; } } if (Punished) { @@ -992,17 +992,17 @@ makemap_prepost(boolean pre, boolean wiztower) /* reset lock picking unless it's for a carried container */ maybe_reset_pick((struct obj *) 0); /* reset interrupted digging if it was taking place on this level */ - if (on_level(&gc.context.digging.level, &u.uz)) - (void) memset((genericptr_t) &gc.context.digging, 0, + if (on_level(&svc.context.digging.level, &u.uz)) + (void) memset((genericptr_t) &svc.context.digging, 0, sizeof (struct dig_info)); /* reset cached targets */ iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */ - gc.context.polearm.hitmon = (struct monst *) 0; /* polearm target */ + svc.context.polearm.hitmon = (struct monst *) 0; /* polearm target */ /* escape from trap */ reset_utrap(FALSE); check_special_room(TRUE); /* room exit */ - (void) memset((genericptr_t) &gd.dndest, 0, sizeof (dest_area)); - (void) memset((genericptr_t) &gu.updest, 0, sizeof (dest_area)); + (void) memset((genericptr_t) &svd.dndest, 0, sizeof (dest_area)); + (void) memset((genericptr_t) &svu.updest, 0, sizeof (dest_area)); u.ustuck = (struct monst *) 0; u.uswallow = u.uswldtim = 0; set_uinwater(0); /* u.uinwater = 0 */ @@ -1354,10 +1354,10 @@ set_move_cmd(int dir, int run) u.dy = ydir[dir]; /* #reqmenu -prefix disables autopickup during movement */ if (iflags.menu_requested) - gc.context.nopick = 1; - gc.context.travel = gc.context.travel1 = 0; + svc.context.nopick = 1; + svc.context.travel = svc.context.travel1 = 0; if (!gd.domove_attempting && !u.dz) { - gc.context.run = run; + svc.context.run = run; gd.domove_attempting |= (!run ? DOMOVE_WALK : DOMOVE_RUSH); } } @@ -1554,12 +1554,12 @@ do_rush(void) { if ((gd.domove_attempting & DOMOVE_RUSH)) { Norep("Double rush prefix, canceled."); - gc.context.run = 0; + svc.context.run = 0; gd.domove_attempting = 0; return ECMD_CANCEL; } - gc.context.run = 2; + svc.context.run = 2; gd.domove_attempting |= DOMOVE_RUSH; return ECMD_OK; } @@ -1570,12 +1570,12 @@ do_run(void) { if ((gd.domove_attempting & DOMOVE_RUSH)) { Norep("Double run prefix, canceled."); - gc.context.run = 0; + svc.context.run = 0; gd.domove_attempting = 0; return ECMD_CANCEL; } - gc.context.run = 3; + svc.context.run = 3; gd.domove_attempting |= DOMOVE_RUSH; return ECMD_OK; } @@ -1584,14 +1584,14 @@ do_run(void) int do_fight(void) { - if (gc.context.forcefight) { + if (svc.context.forcefight) { Norep("Double fight prefix, canceled."); - gc.context.forcefight = 0; + svc.context.forcefight = 0; gd.domove_attempting = 0; return ECMD_CANCEL; } - gc.context.forcefight = 1; + svc.context.forcefight = 1; gd.domove_attempting |= DOMOVE_WALK; return ECMD_OK; } @@ -1616,7 +1616,7 @@ do_repeat(void) cmdq_clear(CQ_REPEAT); gc.command_queue[CQ_REPEAT] = repeat_copy; iflags.menu_requested = FALSE; - if (gc.context.move) + if (svc.context.move) res = ECMD_TIME; } return res; @@ -3264,13 +3264,13 @@ rnd_extcmd_idx(void) staticfn void reset_cmd_vars(boolean reset_cmdq) { - gc.context.run = 0; - gc.context.nopick = gc.context.forcefight = FALSE; - gc.context.move = gc.context.mv = FALSE; + svc.context.run = 0; + svc.context.nopick = svc.context.forcefight = FALSE; + svc.context.move = svc.context.mv = FALSE; gd.domove_attempting = 0; gm.multi = 0; iflags.menu_requested = FALSE; - gc.context.travel = gc.context.travel1 = 0; + svc.context.travel = svc.context.travel1 = 0; if (gt.travelmap) { selection_free(gt.travelmap, TRUE); gt.travelmap = NULL; @@ -3291,10 +3291,10 @@ rhack(int key) int (*func)(void) = dummyfunction; iflags.menu_requested = FALSE; - gc.context.nopick = 0; + svc.context.nopick = 0; got_prefix_input: #ifdef SAFERHANGUP - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) end_of_input(); #endif if ((cmdq = cmdq_pop()) != 0) { @@ -3329,7 +3329,7 @@ rhack(int key) } /* handle most movement commands */ - gc.context.travel = gc.context.travel1 = 0; + svc.context.travel = svc.context.travel1 = 0; { const struct ext_func_tab *tlist; int res; @@ -3433,16 +3433,16 @@ rhack(int key) ; /* just do nothing */ } else if (((gd.domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L) - && !gc.context.travel && !dxdy_moveok()) { + && !svc.context.travel && !dxdy_moveok()) { /* trying to move diagonally as a grid bug */ You_cant("get there from here..."); reset_cmd_vars(TRUE); return; } else if ((gd.domove_attempting & DOMOVE_WALK) != 0L) { if (gm.multi) - gc.context.mv = TRUE; + svc.context.mv = TRUE; domove(); - gc.context.forcefight = 0; + svc.context.forcefight = 0; iflags.menu_requested = FALSE; return; } else if ((gd.domove_attempting & DOMOVE_RUSH) != 0L) { @@ -3451,7 +3451,7 @@ rhack(int key) gm.multi = max(COLNO, ROWNO); u.last_str_turn = 0; } - gc.context.mv = TRUE; + svc.context.mv = TRUE; domove(); iflags.menu_requested = FALSE; return; @@ -3474,7 +3474,7 @@ rhack(int key) /* reset_cmd_vars() sets context.move to False so we might need to change it [back] to True */ if ((res & ECMD_TIME) != 0) { - gc.context.move = TRUE; + svc.context.move = TRUE; if (func != dokick) { /* hero did something else than kicking a location; reset the location, so pets don't avoid it */ @@ -3493,7 +3493,7 @@ rhack(int key) cmdq_clear(CQ_REPEAT); } /* didn't move */ - gc.context.move = FALSE; + svc.context.move = FALSE; gm.multi = 0; return; } @@ -3634,7 +3634,7 @@ getdir(const char *s) } retry: - gp.program_state.input_state = getdirInp; + svp.program_state.input_state = getdirInp; if (gi.in_doagain || *readchar_queue) dirsym = readchar(); else @@ -4114,7 +4114,7 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) #endif if (OBJ_AT(x, y)) { - struct obj *otmp = gl.level.objects[x][y]; + struct obj *otmp = svl.level.objects[x][y]; Sprintf(buf, "Pick up %s", otmp->nexthere ? "items" : doname(otmp)); mcmd_addmenu(win, MCMD_PICKUP, buf), ++K; @@ -4648,7 +4648,7 @@ get_count( unsigned gc_flags) /* control flags: GC_SAVEHIST, GC_ECHOFIRST */ { char qbuf[QBUFSZ]; - int key, save_input_state = gp.program_state.input_state; + int key, save_input_state = svp.program_state.input_state; long cnt = 0L, first = inkey ? (long) (inkey - '0') : 0L; boolean backspaced = FALSE, showzero = TRUE, /* should "Count: 123" go into message history? */ @@ -4670,7 +4670,7 @@ get_count( } else { /* if readchar() has already been called in this loop, it will have reset input_state; put that back to its previous value */ - gp.program_state.input_state = save_input_state; + svp.program_state.input_state = save_input_state; key = readchar(); } @@ -4732,12 +4732,12 @@ parse(void) iflags.in_parse = TRUE; gc.command_count = 0; - gc.context.move = TRUE; /* assume next command will take game time */ + svc.context.move = TRUE; /* assume next command will take game time */ flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ /* affects readchar() behavior for ESC iff 'altmeta' option is On; is always reset to otherInp by readchar() */ - gp.program_state.input_state = commandInp; + svp.program_state.input_state = commandInp; if (!gc.Cmd.num_pad || (foo = readchar()) == gc.Cmd.spkeys[NHKF_COUNT]) { /* if 'num_pad' is On then readchar() has just reset input_state; @@ -4745,7 +4745,7 @@ parse(void) otherwise "nESC" becomes "nESC" (with not read from keyboard yet) rather than intended count and meta keystroke "nM-" */ - gp.program_state.input_state = commandInp; + svp.program_state.input_state = commandInp; foo = get_count((char *) 0, '\0', LARGEST_INT, &gc.command_count, GC_NOFLAGS); @@ -4791,8 +4791,8 @@ hangup( int sig_unused UNUSED) /* called as signal() handler, so sent * at least one arg */ { - if (gp.program_state.exiting) - gp.program_state.in_moveloop = 0; + if (svp.program_state.exiting) + svp.program_state.in_moveloop = 0; nhwindows_hangup(); #ifdef SAFERHANGUP /* When using SAFERHANGUP, the done_hup flag is tested in rhack @@ -4801,10 +4801,10 @@ hangup( protects against losing objects in the process of being thrown, but also potentially riskier because the disconnected program must continue running longer before attempting a hangup save. */ - gp.program_state.done_hup++; + svp.program_state.done_hup++; /* defer hangup iff game appears to be in progress */ - if (gp.program_state.in_moveloop - && gp.program_state.something_worth_saving) + if (svp.program_state.in_moveloop + && svp.program_state.something_worth_saving) return; #endif /* SAFERHANGUP */ end_of_input(); @@ -4815,16 +4815,16 @@ end_of_input(void) { #ifdef NOSAVEONHANGUP #ifdef INSURANCE - if (flags.ins_chkpt && gp.program_state.something_worth_saving) + if (flags.ins_chkpt && svp.program_state.something_worth_saving) program_state.preserve_locks = 1; /* keep files for recovery */ #endif - gp.program_state.something_worth_saving = 0; /* don't save */ + svp.program_state.something_worth_saving = 0; /* don't save */ #endif #ifndef SAFERHANGUP - if (!gp.program_state.done_hup++) + if (!svp.program_state.done_hup++) #endif - if (gp.program_state.something_worth_saving) + if (svp.program_state.something_worth_saving) (void) dosave0(); if (soundprocs.sound_exit_nhsound) (*soundprocs.sound_exit_nhsound)("end_of_input"); @@ -4875,7 +4875,7 @@ readchar_core(coordxy *x, coordxy *y, int *mod) sym = '\033'; #ifdef ALTMETA } else if (sym == '\033' && iflags.altmeta - && gp.program_state.input_state != otherInp) { + && svp.program_state.input_state != otherInp) { /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' but only when we're called by parse() [possibly via get_count()] or getpos() [to support Alt+digit] or getdir() [for arrow keys @@ -4895,7 +4895,7 @@ readchar_core(coordxy *x, coordxy *y, int *mod) readchar_done: /* next readchar() will be for an ordinary char unless parse() sets this back to non-zero */ - gp.program_state.input_state = otherInp; + svp.program_state.input_state = otherInp; return (char) sym; } @@ -4917,7 +4917,7 @@ readchar_poskey(coordxy *x, coordxy *y, int *mod) { char ch; - gp.program_state.input_state = getposInp; + svp.program_state.input_state = getposInp; ch = readchar_core(x, y, mod); return ch; } @@ -4989,16 +4989,16 @@ dotravel_target(void) iflags.getloc_travelmode = FALSE; - gc.context.travel = 1; - gc.context.travel1 = 1; - gc.context.run = 8; - gc.context.nopick = 1; + svc.context.travel = 1; + svc.context.travel1 = 1; + svc.context.run = 8; + svc.context.nopick = 1; gd.domove_attempting |= DOMOVE_RUSH; if (!gm.multi) gm.multi = max(COLNO, ROWNO); u.last_str_turn = 0; - gc.context.mv = TRUE; + svc.context.mv = TRUE; domove(); return ECMD_TIME; @@ -5011,7 +5011,7 @@ doclicklook(void) if (!isok(gc.clicklook_cc.x, gc.clicklook_cc.y)) return ECMD_OK; - gc.context.move = FALSE; + svc.context.move = FALSE; auto_describe(gc.clicklook_cc.x, gc.clicklook_cc.y); return ECMD_OK; @@ -5171,7 +5171,7 @@ yn_function( res = altres; } /* in case we're called via getdir() which sets input_state */ - gp.program_state.input_state = otherInp; + svp.program_state.input_state = otherInp; return res; } diff --git a/src/dbridge.c b/src/dbridge.c index 72c73cb93..565572ef2 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -401,18 +401,18 @@ e_died(struct entity *etmp, int xkill_flags, int how) { if (is_u(etmp)) { if (how == DROWNING) { - gk.killer.name[0] = 0; /* drown() sets its own killer */ + svk.killer.name[0] = 0; /* drown() sets its own killer */ (void) drown(); } else if (how == BURNING) { - gk.killer.name[0] = 0; /* lava_effects() sets own killer */ + svk.killer.name[0] = 0; /* lava_effects() sets own killer */ (void) lava_effects(); } else { coord xy; /* use more specific killer if specified */ - if (!gk.killer.name[0]) { - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "falling drawbridge"); + if (!svk.killer.name[0]) { + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "falling drawbridge"); } done(how); /* So, you didn't die */ @@ -432,12 +432,12 @@ e_died(struct entity *etmp, int xkill_flags, int how) } else { int entitycnt; - gk.killer.name[0] = 0; + svk.killer.name[0] = 0; /* fake "digested to death" damage-type suppresses corpse */ #define mk_message(dest) (((dest & XKILL_NOMSG) != 0) ? (char *) 0 : "") #define mk_corpse(dest) (((dest & XKILL_NOCORPSE) != 0) ? AD_DGST : AD_PHYS) /* if monsters are moving, one of them caused the destruction */ - if (gc.context.mon_moving) + if (svc.context.mon_moving) monkilled(etmp->emon, mk_message(xkill_flags), mk_corpse(xkill_flags)); else /* you caused it */ @@ -570,8 +570,8 @@ do_entity(struct entity *etmp) } else { if (crm->typ == DRAWBRIDGE_DOWN) { if (is_u(etmp)) { - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "crushed to death underneath a drawbridge"); } pline("%s crushed underneath the drawbridge.", @@ -690,8 +690,8 @@ do_entity(struct entity *etmp) E_phrase(etmp, "disappear")); } if (!e_survives_at(etmp, etmp->ex, etmp->ey)) { - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "closing drawbridge"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "closing drawbridge"); e_died(etmp, XKILL_NOMSG, CRUSHING); return; } @@ -723,8 +723,8 @@ do_entity(struct entity *etmp) pline("%s into the %s.", E_phrase(etmp, "fall"), lava ? hliquid("lava") : "moat"); } - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "fell from a drawbridge"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "fell from a drawbridge"); e_died(etmp, /* CRUSHING is arbitrary */ XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG), is_pool(etmp->ex, etmp->ey) ? DROWNING @@ -738,8 +738,8 @@ do_entity(struct entity *etmp) staticfn void nokiller(void) { - gk.killer.name[0] = '\0'; - gk.killer.format = 0; + svk.killer.name[0] = '\0'; + svk.killer.format = 0; m_to_e((struct monst *) 0, 0, 0, &go.occupants[0]); m_to_e((struct monst *) 0, 0, 0, &go.occupants[1]); } @@ -947,8 +947,8 @@ destroy_drawbridge(coordxy x, coordxy y) if (e_inview) pline("%s blown apart by flying debris.", E_phrase(etmp2, "are")); - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "exploding drawbridge"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "exploding drawbridge"); e_died(etmp2, XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG), CRUSHING); /*no corpse*/ @@ -980,8 +980,8 @@ destroy_drawbridge(coordxy x, coordxy y) debugpline1("%s from shrapnel", E_phrase(etmp1, "die")); } } - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "collapsing drawbridge"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "collapsing drawbridge"); e_died(etmp1, XKILL_NOCORPSE | (e_inview ? XKILL_GIVEMSG : XKILL_NOMSG), CRUSHING); /*no corpse*/ diff --git a/src/decl.c b/src/decl.c index a27e3eed0..2fd8f2ea4 100644 --- a/src/decl.c +++ b/src/decl.c @@ -244,11 +244,8 @@ static const struct instance_globals_b g_init_b = { 0L, /* bl_hilite_moves */ #endif /* decl.c */ - DUMMY, /* bases */ { 0, 0 }, /* bhitpos */ UNDEFINED_PTR, /* billobjs */ - /* dungeon.c */ - UNDEFINED_PTR, /* branches */ /* files.c */ BONESINIT, /* bones */ /* hack.c */ @@ -257,7 +254,6 @@ static const struct instance_globals_b g_init_b = { /* mkmaze.c */ { {COLNO, ROWNO, 0, 0}, {COLNO, ROWNO, 0, 0}, FALSE, FALSE, 0, 0, { 0 } }, /* bughack */ - UNDEFINED_PTR, /* bbubbles */ /* pickup.c */ FALSE, /* bucx_filter */ /* zap.c */ @@ -285,7 +281,6 @@ static const struct instance_globals_c g_init_c = { #ifdef DEF_PAGER NULL, /* catmore */ #endif - DUMMY, /* context */ /* dog.c */ DUMMY, /* catname */ /* end.c */ @@ -326,16 +321,7 @@ static const struct instance_globals_d g_init_d = { 0L, /* done_money */ 0L, /* domove_attempting */ 0L, /* domove_succeeded */ - { { {0},{0},{0},{0}, 0, {0}, 0, 0, 0, 0, 0 } }, /* dungeons */ - { 0, 0, 0, 0, 0, 0, 0, 0 }, /* dndest */ FALSE, /* defer_see_monsters */ - { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - 0, 0, 0, 0, 0, - {0}, {0}, {0}, - {0}, {0}, {0} }, /* dungeon_topology */ - 0, /* doors_alloc */ - NULL, /* doors */ /* dig.c */ UNDEFINED_VALUE, /* did_dig_msg */ /* do.c */ @@ -348,8 +334,6 @@ static const struct instance_globals_d g_init_d = { 0L, /* done_seq */ /* mon.c */ FALSE, /* disintegested */ - /* o_init.c */ - DUMMY, /* disco */ /* objname.c */ 0, /* distantname */ /* pickup.c */ @@ -369,7 +353,6 @@ static const struct instance_globals_e g_init_e = { /* mkmaze.c */ UNDEFINED_PTR, /* ebubbles */ /* new */ - NULL, /* exclusion_zones */ 0, /* early_raw_messages */ TRUE, /* havestate*/ IVMAGIC /* e_magic to validate that structure layout has been preserved */ @@ -434,7 +417,6 @@ static const struct instance_globals_g g_init_g = { static const struct instance_globals_h g_init_h = { /* decl.c */ NULL, /* hname */ - 0, /* hackpid */ #if defined(MICRO) || defined(WIN32) UNDEFINED_VALUES, /* hackdir */ #endif /* MICRO || WIN32 */ @@ -454,7 +436,6 @@ static const struct instance_globals_h g_init_h = { static const struct instance_globals_i g_init_i = { /* decl.c */ 0, /* in_doagain */ - { 0, 0 } , /* inv_pos */ FALSE, /* in_mklev */ FALSE, /* in_steed_dismounting */ UNDEFINED_PTR, /* invent */ @@ -486,7 +467,6 @@ static const struct instance_globals_k g_init_k = { { 0, 0 }, /* kickedloc */ /* decl.c */ UNDEFINED_PTR, /* kickedobj */ - DUMMY, /* killer */ /* read.c */ UNDEFINED_VALUE, /* known */ TRUE, /* havestate*/ @@ -497,12 +477,6 @@ static const struct instance_globals_l g_init_l = { /* cmd.c */ UNDEFINED_VALUE, /* last_command_count */ /* decl.c */ - { { 0 } }, /* lastseentyp */ - { UNDEFINED_VALUES }, /* level_info */ - { { { UNDEFINED_VALUES } }, /* level.locations */ - { { UNDEFINED_PTR } }, /* level.objects */ - { { UNDEFINED_PTR } }, /* level.monsters */ - NULL, NULL, NULL, NULL, NULL, {0} }, /* level */ #if defined(UNIX) || defined(VMS) 0, /* locknum */ #endif @@ -563,16 +537,12 @@ static const struct instance_globals_m g_init_m = { { 0, 0, STRANGE_OBJECT, FALSE }, /* m_shot */ FALSE, /* mrg_to_wielded */ UNDEFINED_PTR, /* menu_colorings */ - 1L, /* moves; misnamed turn counter */ UNDEFINED_PTR, /* migrating_objs */ /* dog.c */ UNDEFINED_PTR, /* mydogs */ UNDEFINED_PTR, /* migrating_mons */ - { UNDEFINED_VALUES }, /* mvitals */ /* dokick.c */ UNDEFINED_PTR, /* maploc */ - /* dungeon.c */ - UNDEFINED_PTR, /* mapseenchn */ /* mhitu.c */ UNDEFINED_VALUE, /* mhitu_dieroll */ /* mklev.c */ @@ -607,12 +577,9 @@ static const struct instance_globals_n g_init_n = { 0, /* now_or_before_idx */ /* decl.c */ NULL, /* nomovemsg */ - 0, /* nroom */ 0, /* nsubroom */ /* dokick.c */ UNDEFINED_VALUES, /* nowhere */ - /* dungeon.c */ - 0, /* n_dgns */ /* files.c */ 0, /* nesting */ 0, /* no_sound_notified */ @@ -627,8 +594,6 @@ static const struct instance_globals_n g_init_n = { FALSE, /* notonhead */ /* questpgr.c */ UNDEFINED_VALUES, /* nambuf */ - /* region.c */ - 0, /* n_regions */ /* restore.c */ 0, /* n_ids_mapped */ /* sp_lev.c */ @@ -677,7 +642,6 @@ static const struct instance_globals_o g_init_o = { 0L, /* omoves */ /* rumors.c */ 0, /* oracle_flag */ - 0U, /* oracle_cnt */ UNDEFINED_PTR, /* oracle_loc */ /* uhitm.c */ FALSE, /* override_confirmation */ @@ -692,13 +656,9 @@ static const struct instance_globals_p g_init_p = { -1, /* polearm_range_min */ -1, /* polearm_range_max */ /* decl.c */ - DUMMY, /* plname */ 0, /* plnamelen */ - DUMMY, /* pl_character */ '\0', /* pl_race */ - DUMMY, /* pl_fruit */ UNDEFINED_PTR, /* plinemsg_types */ - UNDEFINED_VALUES, /* program_state */ /* dog.c */ 0, /* petname_used */ UNDEFINED_VALUE, /* preferred_pet */ @@ -728,15 +688,11 @@ static const struct instance_globals_p g_init_p = { }; static const struct instance_globals_q g_init_q = { - /* quest.c */ - DUMMY, /* quest_status */ TRUE, /* havestate*/ IVMAGIC /* q_magic to validate that structure layout has been preserved */ }; static const struct instance_globals_r g_init_r = { - /* decl.c */ - { DUMMY }, /* rooms */ /* symbols.c */ DUMMY, /* rogue_syms */ /* extralev.c */ @@ -761,11 +717,9 @@ static const struct instance_globals_s g_init_s = { /* artifact.c */ 0, /* spec_dbon_applies */ /* decl.c */ - UNDEFINED_PTR, /* sp_levchn */ UNDEFINED_PTR, /* stairs */ DUMMY, /* smeq */ FALSE, /* stoned */ - { DUMMY }, /* spl_book */ UNDEFINED_PTR, /* subrooms */ /* do.c */ { 0, 0 }, /* save_dlevel */ @@ -820,7 +774,6 @@ static const struct instance_globals_t g_init_t = { /* apply.c */ UNDEFINED_VALUES, /* trapinfo */ /* decl.c */ - DUMMY, /* tune */ 0, /* tbx */ 0, /* tby */ UNDEFINED_VALUES, /* toplines */ @@ -843,7 +796,6 @@ static const struct instance_globals_t g_init_t = { FALSE, /* themeroom_failed */ /* timeout.c */ UNDEFINED_PTR, /* timer_base */ - 1UL, /* timer_id */ /* topten.c */ WIN_ERR, /* toptenwin */ /* uhitm.c */ @@ -857,7 +809,6 @@ static const struct instance_globals_u g_init_u = { /* botl.c */ FALSE, /* update_all */ /* decl.c */ - { 0, 0, 0, 0, 0, 0, 0, 0 }, /* updest */ FALSE, /* unweapon */ /* role.c */ UNDEFINED_ROLE, /* urole */ @@ -917,9 +868,6 @@ static const struct instance_globals_x g_init_x = { (COLNO - 1) & ~1, /* x_maze_max */ /* lock.c */ UNDEFINED_VALUES, /* xlock */ - /* mkmaze.c */ - UNDEFINED_VALUE, /* xmin */ - UNDEFINED_VALUE, /* xmax */ /* objnam.c */ NULL, /* xnamep */ /* sp_lev.c */ @@ -933,9 +881,6 @@ static const struct instance_globals_y g_init_y = { /* decl.c */ (ROWNO - 1) & ~1, /* y_maze_max */ DUMMY, /* youmonst */ - /* mkmaze.c */ - UNDEFINED_VALUE, /* ymin */ - UNDEFINED_VALUE, /* ymax */ /* pline.c */ NULL, /* you_buf */ 0, /* you_buf_siz */ @@ -955,6 +900,135 @@ static const struct instance_globals_z g_init_z = { IVMAGIC /* z_magic to validate that structure layout has been preserved */ }; +static const struct instance_globals_saved_b init_svb = { + /* dungeon.c */ + UNDEFINED_PTR, /* branches */ + /* mkmaze.c */ + UNDEFINED_PTR, /* bbubbles */ + DUMMY /* bases */ +}; + +static const struct instance_globals_saved_c init_svc = { + /* decl.c */ + DUMMY, /* context */ +}; + +static const struct instance_globals_saved_d init_svd = { + /* dungeon.c */ + { { {0},{0},{0},{0}, 0, {0}, 0, 0, 0, 0, 0 } }, /* dungeons */ + { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, + 0, 0, 0, 0, 0, + {0}, {0}, {0}, + {0}, {0}, {0} }, /* dungeon_topology */ + /* decl.c */ + { 0, 0, 0, 0, 0, 0, 0, 0 }, /* dndest */ + NULL, /* doors */ + 0, /* doors_alloc */ + /* o_init.c */ + DUMMY, /* disco */ +}; + +static const struct instance_globals_saved_e init_sve = { + /* decl.c */ + NULL /* exclusion_zones */ +}; + +static const struct instance_globals_saved_h init_svh = { + /* decl.c */ + 0 /* hackpid */ +}; + +static const struct instance_globals_saved_i init_svi = { + /* decl.c */ + { 0, 0 } /* inv_pos */ +}; + +static const struct instance_globals_saved_k init_svk = { + /* decl.c */ + DUMMY /* killer */ +}; + +static const struct instance_globals_saved_l init_svl = { + /* decl.c */ + { { 0 } }, /* lastseentyp */ + { { { UNDEFINED_VALUES } }, /* level.locations */ + { { UNDEFINED_PTR } }, /* level.objects */ + { { UNDEFINED_PTR } }, /* level.monsters */ + NULL, NULL, NULL, NULL, NULL, {0} }, /* level */ + { UNDEFINED_VALUES } /* level_info */ +}; + +static const struct instance_globals_saved_m init_svm = { + /* dungeon.c */ + UNDEFINED_PTR, /* mapseenchn */ + /* decl.c */ + 1L, /* moves; misnamed turn counter */ + { UNDEFINED_VALUES } /* mvitals */ +}; + +static const struct instance_globals_saved_n init_svn = { + /* dungeon.c */ + 0, /* n_dgns */ + /* mkroom.c */ + 0, /* nroom */ + /* region.c */ + 0 /* n_regions */ +}; + +static const struct instance_globals_saved_o init_svo = { + /* rumors.c */ + 0U /* oracle_cnt */ +}; + +static const struct instance_globals_saved_p init_svp = { + /* decl.c */ + DUMMY, /* plname */ + DUMMY, /* pl_character */ + DUMMY, /* pl_fruit */ + UNDEFINED_VALUES, /* program_state */ +}; + +static const struct instance_globals_saved_q init_svq = { + /* quest.c */ + DUMMY /* quest_status */ +}; + +static const struct instance_globals_saved_r init_svr = { + /* mkroom.c */ + { DUMMY }, /* rooms */ +}; + +static const struct instance_globals_saved_s init_svs = { + /* decl.c */ + { DUMMY }, /* spl_book */ + UNDEFINED_PTR /* sp_levchn */ +}; + +static const struct instance_globals_saved_t init_svt = { + /* decl.c */ + DUMMY, /* tune */ + /* timeout.c */ + 1UL, /* timer_id */ +}; + +static const struct instance_globals_saved_u init_svu = { + /* decl.c */ + { 0, 0, 0, 0, 0, 0, 0, 0 }, /* updest */ +}; + +static const struct instance_globals_saved_x init_svx = { + /* mkmaze.c */ + UNDEFINED_VALUE, /* xmin */ + UNDEFINED_VALUE /* xmax */ +}; + +static const struct instance_globals_saved_y init_svy = { + /* mkmaze.c */ + UNDEFINED_VALUE, /* ymin */ + UNDEFINED_VALUE /* ymax */ +}; + #if 0 struct instance_globals g; #endif /* 0 */ @@ -985,6 +1059,25 @@ struct instance_globals_w gw; struct instance_globals_x gx; struct instance_globals_y gy; struct instance_globals_z gz; +struct instance_globals_saved_b svb; +struct instance_globals_saved_c svc; +struct instance_globals_saved_d svd; +struct instance_globals_saved_e sve; +struct instance_globals_saved_h svh; +struct instance_globals_saved_i svi; +struct instance_globals_saved_k svk; +struct instance_globals_saved_l svl; +struct instance_globals_saved_m svm; +struct instance_globals_saved_n svn; +struct instance_globals_saved_o svo; +struct instance_globals_saved_p svp; +struct instance_globals_saved_q svq; +struct instance_globals_saved_r svr; +struct instance_globals_saved_s svs; +struct instance_globals_saved_t svt; +struct instance_globals_saved_u svu; +struct instance_globals_saved_x svx; +struct instance_globals_saved_y svy; const struct const_globals cg = { DUMMY, /* zeroobj */ @@ -1042,6 +1135,25 @@ decl_globals_init(void) gx = g_init_x; gy = g_init_y; gz = g_init_z; + svb = init_svb; + svc = init_svc; + svd = init_svd; + sve = init_sve; + svh = init_svh; + svi = init_svi; + svk = init_svk; + svl = init_svl; + svm = init_svm; + svn = init_svn; + svo = init_svo; + svp = init_svp; + svq = init_svq; + svr = init_svr; + svs = init_svs; + svt = init_svt; + svu = init_svu; + svx = init_svx; + svy = init_svy; gv.valuables[0].list = gg.gems; gv.valuables[0].size = SIZE(gg.gems); @@ -1084,7 +1196,7 @@ decl_globals_init(void) sfrestinfo = default_sfinfo; sfsaveinfo = default_sfinfo; - gs.subrooms = &gr.rooms[MAXNROFROOMS + 1]; + gs.subrooms = &svr.rooms[MAXNROFROOMS + 1]; ZERO(flags); ZERO(iflags); @@ -1107,11 +1219,11 @@ decl_globals_init(void) /* fields in 'hands_obj' don't matter, just its distinct address */ struct obj hands_obj = DUMMY; -/* gcc 12.2's static analyzer thinks that some fields of gc.context.victual +/* gcc 12.2's static analyzer thinks that some fields of svc.context.victual are uninitialized when compiling 'bite(eat.c)' but that's impossible; it is defined at global scope so guaranteed to be given implicit initialization for fields that aren't explicitly initialized (all of - 'context'); having bite() pass &gc.context.victual to this no-op + 'context'); having bite() pass &svc.context.victual to this no-op eliminates the analyzer's very verbose complaint */ void sa_victual( diff --git a/src/detect.c b/src/detect.c index d5f78f151..ed85b92d7 100644 --- a/src/detect.c +++ b/src/detect.c @@ -254,13 +254,13 @@ check_map_spot(coordxy x, coordxy y, char oclass, unsigned material) if (glyph_is_object(glyph)) { /* there's some object shown here */ if (oclass == ALL_CLASSES) { - return !(gl.level.objects[x][y] /* stale if nothing here */ + return !(svl.level.objects[x][y] /* stale if nothing here */ || ((mtmp = m_at(x, y)) != 0 && mtmp->minvent)); } else { if (material && objects[glyph_to_obj(glyph)].oc_material == material) { /* object shown here is of interest because material matches */ - for (otmp = gl.level.objects[x][y]; otmp; + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (o_material(otmp, GOLD)) return FALSE; @@ -275,7 +275,7 @@ check_map_spot(coordxy x, coordxy y, char oclass, unsigned material) } if (oclass && objects[glyph_to_obj(glyph)].oc_class == oclass) { /* obj shown here is of interest because its class matches */ - for (otmp = gl.level.objects[x][y]; otmp; + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (o_in(otmp, oclass)) return FALSE; @@ -636,7 +636,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ do_dknown_of(obj); } - for (obj = gl.level.buriedobjlist; obj; obj = obj->nobj) { + for (obj = svl.level.buriedobjlist; obj; obj = obj->nobj) { if (!class || o_in(obj, class)) { if (u_at(obj->ox, obj->oy)) ctu++; @@ -684,7 +684,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ /* * Map all buried objects first. */ - for (obj = gl.level.buriedobjlist; obj; obj = obj->nobj) + for (obj = svl.level.buriedobjlist; obj; obj = obj->nobj) if (!class || (otmp = o_in(obj, class)) != 0) { if (class) { if (otmp != obj) { @@ -705,7 +705,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ */ for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) - for (obj = gl.level.objects[x][y]; obj; obj = obj->nexthere) + for (obj = svl.level.objects[x][y]; obj; obj = obj->nexthere) if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0 || (otmp = o_in(obj, boulder)) != 0) { if (class || boulder) { @@ -933,7 +933,7 @@ display_trap_map(int cursed_src) /* show chest traps first, first buried chests then floor chests, so that subsequent floor trap display will override if both types are present at the same location */ - (void) detect_obj_traps(gl.level.buriedobjlist, TRUE, cursed_src); + (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src); (void) detect_obj_traps(fobj, TRUE, cursed_src); for (mon = fmon; mon; mon = mon->nmon) { if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) @@ -947,7 +947,7 @@ display_trap_map(int cursed_src) dummytrap.ttyp = TRAPPED_DOOR; for (door = 0; door < gd.doorindex; door++) { - cc = gd.doors[door]; + cc = svd.doors[door]; if (levl[cc.x][cc.y].typ == SDOOR) /* see above */ continue; if (levl[cc.x][cc.y].doormask & D_TRAPPED) { @@ -1004,7 +1004,7 @@ trap_detect( } found = TRUE; } - if ((tr = detect_obj_traps(gl.level.buriedobjlist, FALSE, 0)) + if ((tr = detect_obj_traps(svl.level.buriedobjlist, FALSE, 0)) != OTRAP_NONE) { if (tr & OTRAP_THERE) { display_trap_map(cursed_src); @@ -1027,7 +1027,7 @@ trap_detect( found = TRUE; /* door traps */ for (door = 0; door < gd.doorindex; door++) { - cc = gd.doors[door]; + cc = svd.doors[door]; /* levl[][].doormask and .wall_info both overlay levl[][].flags; the bit in doormask for D_TRAPPED is also a bit in wall_info; secret doors use wall_info so can't be marked as trapped */ @@ -1362,7 +1362,7 @@ show_map_spot(coordxy x, coordxy y, boolean cnf) * opposite to how normal vision behaves. */ oldglyph = glyph_at(x, y); - if (gl.level.flags.hero_memory) { + if (svl.level.flags.hero_memory) { magic_map_background(x, y, 0); newsym(x, y); /* show it, if not blocked */ } else { @@ -1375,7 +1375,7 @@ show_map_spot(coordxy x, coordxy y, boolean cnf) map_engraving(ep, 1); } else if (glyph_is_trap(oldglyph) || glyph_is_object(oldglyph)) { show_glyph(x, y, oldglyph); - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) lev->glyph = oldglyph; } } @@ -1395,7 +1395,7 @@ do_mapping(void) for (zy = 0; zy < ROWNO; zy++) show_map_spot(zx, zy, Confusion); - if (!gl.level.flags.hero_memory || unconstrained) { + if (!svl.level.flags.hero_memory || unconstrained) { flush_screen(1); /* flush temp screen */ /* browse_map() instead of display_nhwindow(WIN_MAP, TRUE) */ browse_map(TER_DETECT | TER_MAP | TER_TRP | TER_OBJ, @@ -1472,7 +1472,7 @@ do_vicinity_map( if (OBJ_AT(zx, zy)) { /* not vobj_at(); this is not vision-based access; unlike object detection, we don't notice buried items */ - otmp = gl.level.objects[zx][zy]; + otmp = svl.level.objects[zx][zy]; if (extended) otmp->dknown = 1; map_object(otmp, TRUE); @@ -1489,7 +1489,7 @@ do_vicinity_map( the map and we're not doing extended/blessed clairvoyance (hence must be swallowed or underwater), show "unseen creature" unless map already displayed a monster here */ - if ((unconstrained || !gl.level.flags.hero_memory) + if ((unconstrained || !svl.level.flags.hero_memory) && !extended && (zx != u.ux || zy != u.uy) && !glyph_is_monster(oldglyph)) map_invisible(zx, zy); @@ -1512,7 +1512,7 @@ do_vicinity_map( if (random_farsight && flags.quick_farsight) mdetected = odetected = FALSE; - if (!gl.level.flags.hero_memory || unconstrained + if (!svl.level.flags.hero_memory || unconstrained || mdetected || odetected) { flush_screen(1); /* flush temp screen */ /* the getpos() prompt from browse_map() is only shown when @@ -1639,7 +1639,7 @@ openone(coordxy zx, coordxy zy, genericptr_t num) int *num_p = (int *) num; if (OBJ_AT(zx, zy)) { - for (otmp = gl.level.objects[zx][zy]; otmp; otmp = otmp->nexthere) { + for (otmp = svl.level.objects[zx][zy]; otmp; otmp = otmp->nexthere) { if (Is_box(otmp) && otmp->olocked) { otmp->olocked = 0; (*num_p)++; @@ -2041,14 +2041,14 @@ reveal_terrain_getglyph( /* for 'full', show the actual terrain for the entire level, otherwise what the hero remembers for seen locations with monsters, objects, and/or traps removed as caller dictates */ - seenv = (full || gl.level.flags.hero_memory) + seenv = (full || svl.level.flags.hero_memory) ? levl[x][y].seenv : cansee(x, y) ? SVALL : 0; if (full) { levl[x][y].seenv = SVALL; glyph = back_to_glyph(x, y); levl[x][y].seenv = seenv; } else { - levl_glyph = gl.level.flags.hero_memory ? levl[x][y].glyph + levl_glyph = svl.level.flags.hero_memory ? levl[x][y].glyph : seenv ? back_to_glyph(x, y) : default_glyph; /* glyph_at() returns the displayed glyph, which might @@ -2074,7 +2074,7 @@ reveal_terrain_getglyph( || glyph_is_invisible(glyph)) { if (!seenv) { glyph = default_glyph; - } else if (gl.lastseentyp[x][y] == levl[x][y].typ) { + } else if (svl.lastseentyp[x][y] == levl[x][y].typ) { glyph = back_to_glyph(x, y); } else { /* look for a mimic here posing as furniture; @@ -2098,7 +2098,7 @@ reveal_terrain_getglyph( * doormask==D_OPEN for an open door remembered as a wall. */ save_spot = levl[x][y]; - levl[x][y].typ = gl.lastseentyp[x][y]; + levl[x][y].typ = svl.lastseentyp[x][y]; if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR) xy_set_wall_state(x, y); /* levl[x][y].wall_info */ glyph = back_to_glyph(x, y); @@ -2122,7 +2122,7 @@ dump_map(void) coordxy x, y; int glyph, skippedrows, lastnonblank; unsigned subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON; - int default_glyph = cmap_to_glyph(gl.level.flags.arboreal ? S_tree + int default_glyph = cmap_to_glyph(svl.level.flags.arboreal ? S_tree : S_stone); char buf[COLBUFSZ]; boolean blankrow, toprow; @@ -2197,7 +2197,7 @@ reveal_terrain( if (unconstrain_map()) docrt(); - default_glyph = cmap_to_glyph(gl.level.flags.arboreal ? S_tree + default_glyph = cmap_to_glyph(svl.level.flags.arboreal ? S_tree : S_stone); for (x = 1; x < COLNO; x++) diff --git a/src/dig.c b/src/dig.c index 7ec2b59ad..26b327c99 100644 --- a/src/dig.c +++ b/src/dig.c @@ -187,7 +187,7 @@ dig_typ(struct obj *otmp, coordxy x, coordxy y) : IS_TREE(levl[x][y].typ) ? (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE) : (ispick && IS_ROCK(levl[x][y].typ) - && (!gl.level.flags.arboreal + && (!svl.level.flags.arboreal || IS_WALL(levl[x][y].typ))) ? DIGTYP_ROCK : DIGTYP_UNDIGGABLE); @@ -264,7 +264,7 @@ staticfn int dig(void) { struct rm *lev; - coordxy dpx = gc.context.digging.pos.x, dpy = gc.context.digging.pos.y; + coordxy dpx = svc.context.digging.pos.x, dpy = svc.context.digging.pos.y; boolean ispick = uwep && is_pick(uwep); const char *verb = (!uwep || is_pick(uwep)) ? "dig into" : "chop through"; @@ -272,15 +272,15 @@ dig(void) /* perhaps a nymph stole your pick-axe while you were busy digging */ /* or perhaps you teleported away */ if (u.uswallow || !uwep || (!ispick && !is_axe(uwep)) - || !on_level(&gc.context.digging.level, &u.uz) - || ((gc.context.digging.down ? (dpx != u.ux || dpy != u.uy) + || !on_level(&svc.context.digging.level, &u.uz) + || ((svc.context.digging.down ? (dpx != u.ux || dpy != u.uy) : !next2u(dpx, dpy)))) return 0; - if (gc.context.digging.down) { + if (svc.context.digging.down) { if (!dig_check(BY_YOU, TRUE, u.ux, u.uy)) return 0; - } else { /* !gc.context.digging.down */ + } else { /* !svc.context.digging.down */ if (IS_TREE(lev->typ) && !may_dig(dpx, dpy) && dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) { pline("This tree seems to be petrified."); @@ -322,21 +322,21 @@ dig(void) return 0; } - gc.context.digging.effort += + svc.context.digging.effort += 10 + rn2(5) + abon() + uwep->spe - greatest_erosion(uwep) + u.udaminc; if (Race_if(PM_DWARF)) - gc.context.digging.effort *= 2; - if (gc.context.digging.down) { + svc.context.digging.effort *= 2; + if (svc.context.digging.down) { struct trap *ttmp = t_at(dpx, dpy); - if (gc.context.digging.effort > 250 || (ttmp && ttmp->ttyp == HOLE)) { + if (svc.context.digging.effort > 250 || (ttmp && ttmp->ttyp == HOLE)) { (void) dighole(FALSE, FALSE, (coord *) 0); - (void) memset((genericptr_t) &gc.context.digging, 0, - sizeof gc.context.digging); + (void) memset((genericptr_t) &svc.context.digging, 0, + sizeof svc.context.digging); return 0; /* done with digging */ } - if (gc.context.digging.effort <= 50 + if (svc.context.digging.effort <= 50 || (ttmp && (ttmp->ttyp == TRAPDOOR || is_pit(ttmp->ttyp)))) { return 1; } else if (ttmp && (ttmp->ttyp == LANDMINE @@ -345,8 +345,8 @@ dig(void) hero should have used #untrap first */ dotrap(ttmp, FORCETRAP); /* restart completely from scratch if we resume digging */ - (void) memset((genericptr_t) &gc.context.digging, 0, - sizeof gc.context.digging); + (void) memset((genericptr_t) &svc.context.digging, 0, + sizeof svc.context.digging); return 0; } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) { if (rnl(7) > (Fumbling ? 1 : 4)) { @@ -368,7 +368,7 @@ dig(void) reset_utrap(TRUE); /* release from trap, maybe Lev or Fly */ } /* we haven't made any progress toward a pit yet */ - gc.context.digging.effort = 0; + svc.context.digging.effort = 0; return 0; } @@ -379,13 +379,13 @@ dig(void) /* make pit at */ if (dighole(TRUE, FALSE, (coord *) 0)) { - gc.context.digging.level.dnum = 0; - gc.context.digging.level.dlevel = -1; + svc.context.digging.level.dnum = 0; + svc.context.digging.level.dlevel = -1; } return 0; } - if (gc.context.digging.effort > 100) { + if (svc.context.digging.effort > 100) { const char *digtxt, *dmgtxt = (const char *) 0; struct obj *obj; boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE); @@ -436,9 +436,9 @@ dig(void) add_damage(dpx, dpy, SHOP_WALL_DMG); dmgtxt = "damage"; } - if (gl.level.flags.is_maze_lev) { + if (svl.level.flags.is_maze_lev) { lev->typ = ROOM, lev->flags = 0; - } else if (gl.level.flags.is_cavernous_lev && !in_town(dpx, dpy)) { + } else if (svl.level.flags.is_cavernous_lev && !in_town(dpx, dpy)) { lev->typ = CORR, lev->flags = 0; } else { lev->typ = DOOR, lev->doormask = D_NODOOR; @@ -463,7 +463,7 @@ dig(void) if (!does_block(dpx, dpy, &levl[dpx][dpy])) unblock_point(dpx, dpy); /* vision: can see through */ feel_newsym(dpx, dpy); - if (digtxt && !gc.context.digging.quiet) + if (digtxt && !svc.context.digging.quiet) pline1(digtxt); /* after newsym */ if (dmgtxt) pay_for_damage(dmgtxt, FALSE); @@ -489,10 +489,10 @@ dig(void) newsym(dpx, dpy); } cleanup: - gc.context.digging.lastdigtime = gm.moves; - gc.context.digging.quiet = FALSE; - gc.context.digging.level.dnum = 0; - gc.context.digging.level.dlevel = -1; + svc.context.digging.lastdigtime = svm.moves; + svc.context.digging.quiet = FALSE; + svc.context.digging.level.dnum = 0; + svc.context.digging.level.dlevel = -1; return 0; } else { /* not enough effort has been spent yet */ static const char *const d_target[6] = { "", "rock", "statue", @@ -549,7 +549,7 @@ holetime(void) { if (go.occupation != dig || !*u.ushops) return -1; - return ((250 - gc.context.digging.effort) / 20); + return ((250 - svc.context.digging.effort) / 20); } /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */ @@ -636,11 +636,11 @@ digactualhole(coordxy x, coordxy y, struct monst *madeby, int ttyp) surface_type = surface(x, y); } shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE); - oldobjs = gl.level.objects[x][y]; + oldobjs = svl.level.objects[x][y]; ttmp = maketrap(x, y, ttyp); if (!ttmp) return; - newobjs = gl.level.objects[x][y]; + newobjs = svl.level.objects[x][y]; ttmp->madeby_u = heros_fault; ttmp->tseen = 0; if (cansee(x, y)) @@ -810,7 +810,7 @@ liquid_flow( if (fillmsg) pline(fillmsg, hliquid(typ == LAVAPOOL ? "lava" : "water")); /* handle object damage before hero damage; affects potential bones */ - if ((objchain = gl.level.objects[x][y]) != 0) { + if ((objchain = svl.level.objects[x][y]) != 0) { if (typ == LAVAPOOL) fire_damage_chain(objchain, TRUE, TRUE, x, y); else @@ -1220,32 +1220,32 @@ use_pick_axe2(struct obj *obj) "cutting the tree" }; gd.did_dig_msg = FALSE; - gc.context.digging.quiet = FALSE; - if (gc.context.digging.pos.x != rx - || gc.context.digging.pos.y != ry - || !on_level(&gc.context.digging.level, &u.uz) - || gc.context.digging.down) { + svc.context.digging.quiet = FALSE; + if (svc.context.digging.pos.x != rx + || svc.context.digging.pos.y != ry + || !on_level(&svc.context.digging.level, &u.uz) + || svc.context.digging.down) { if (flags.autodig && dig_target == DIGTYP_ROCK - && !gc.context.digging.down - && u_at(gc.context.digging.pos.x, gc.context.digging.pos.y) - && (gm.moves <= gc.context.digging.lastdigtime + 2 - && gm.moves >= gc.context.digging.lastdigtime)) { + && !svc.context.digging.down + && u_at(svc.context.digging.pos.x, svc.context.digging.pos.y) + && (svm.moves <= svc.context.digging.lastdigtime + 2 + && svm.moves >= svc.context.digging.lastdigtime)) { /* avoid messages if repeated autodigging */ gd.did_dig_msg = TRUE; - gc.context.digging.quiet = TRUE; + svc.context.digging.quiet = TRUE; } - gc.context.digging.down = gc.context.digging.chew = FALSE; - gc.context.digging.warned = FALSE; - gc.context.digging.pos.x = rx; - gc.context.digging.pos.y = ry; - assign_level(&gc.context.digging.level, &u.uz); - gc.context.digging.effort = 0; - if (!gc.context.digging.quiet) + svc.context.digging.down = svc.context.digging.chew = FALSE; + svc.context.digging.warned = FALSE; + svc.context.digging.pos.x = rx; + svc.context.digging.pos.y = ry; + assign_level(&svc.context.digging.level, &u.uz); + svc.context.digging.effort = 0; + if (!svc.context.digging.quiet) You("start %s.", d_action[dig_target]); } else { - You("%s %s.", gc.context.digging.chew ? "begin" : "continue", + You("%s %s.", svc.context.digging.chew ? "begin" : "continue", d_action[dig_target]); - gc.context.digging.chew = FALSE; + svc.context.digging.chew = FALSE; } set_occupation(dig, verbing, 0); } @@ -1273,16 +1273,16 @@ use_pick_axe2(struct obj *obj) surface(u.ux, u.uy)); u_wipe_engr(3); } else { - if (gc.context.digging.pos.x != u.ux || gc.context.digging.pos.y != u.uy - || !on_level(&gc.context.digging.level, &u.uz) - || !gc.context.digging.down) { - gc.context.digging.chew = FALSE; - gc.context.digging.down = TRUE; - gc.context.digging.warned = FALSE; - gc.context.digging.pos.x = u.ux; - gc.context.digging.pos.y = u.uy; - assign_level(&gc.context.digging.level, &u.uz); - gc.context.digging.effort = 0; + if (svc.context.digging.pos.x != u.ux || svc.context.digging.pos.y != u.uy + || !on_level(&svc.context.digging.level, &u.uz) + || !svc.context.digging.down) { + svc.context.digging.chew = FALSE; + svc.context.digging.down = TRUE; + svc.context.digging.warned = FALSE; + svc.context.digging.pos.x = u.ux; + svc.context.digging.pos.y = u.uy; + assign_level(&svc.context.digging.level, &u.uz); + svc.context.digging.effort = 0; You("start %s downward.", verbing); if (*u.ushops) { shopdig(0); @@ -1324,7 +1324,7 @@ watch_dig(struct monst *mtmp, coordxy x, coordxy y, boolean zap) if (mtmp) { SetVoice(mtmp, 0, 80, 0); - if (zap || gc.context.digging.warned) { + if (zap || svc.context.digging.warned) { verbalize("Halt, vandal! You're under arrest!"); (void) angry_guards(!!Deaf); } else { @@ -1339,7 +1339,7 @@ watch_dig(struct monst *mtmp, coordxy x, coordxy y, boolean zap) else str = "fountain"; verbalize("Hey, stop damaging that %s!", str); - gc.context.digging.warned = TRUE; + svc.context.digging.warned = TRUE; } if (is_digging()) stop_occupation(); @@ -1409,9 +1409,9 @@ mdig_tunnel(struct monst *mtmp) } if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE)) add_damage(mtmp->mx, mtmp->my, 0L); - if (gl.level.flags.is_maze_lev) { + if (svl.level.flags.is_maze_lev) { here->typ = ROOM, here->flags = 0; - } else if (gl.level.flags.is_cavernous_lev + } else if (svl.level.flags.is_cavernous_lev && !in_town(mtmp->mx, mtmp->my)) { here->typ = CORR, here->flags = 0; } else { @@ -1549,7 +1549,7 @@ zap_dig(void) /* normal case: digging across the level */ shopdoor = shopwall = FALSE; - maze_dig = gl.level.flags.is_maze_lev && !Is_earthlevel(&u.uz); + maze_dig = svl.level.flags.is_maze_lev && !Is_earthlevel(&u.uz); zx = u.ux + u.dx; zy = u.uy + u.dy; if (u.utrap && u.utraptype == TT_PIT @@ -1654,7 +1654,7 @@ zap_dig(void) shopwall = TRUE; } watch_dig((struct monst *) 0, zx, zy, TRUE); - if (gl.level.flags.is_cavernous_lev && !in_town(zx, zy)) { + if (svl.level.flags.is_cavernous_lev && !in_town(zx, zy)) { room->typ = CORR, room->flags = 0; } else { room->typ = DOOR, room->doormask = D_NODOOR; @@ -1829,7 +1829,7 @@ buried_ball(coord *cc) * criterium (within 2 steps of tethered hero's present location) * it will find an arbitrary one rather than the one which used * to be uball. Once 3.6.{0,1} save file compatibility is broken, - * we should add gc.context.buriedball_oid and then we can find the + * we should add svc.context.buriedball_oid and then we can find the * actual former uball, which might be extra heavy or christened * or not the one buried directly underneath the target spot. * @@ -1841,7 +1841,7 @@ buried_ball(coord *cc) of u.utraptype is no longer meaningful; if u.utrap is still set then u.utraptype needs to be for buried ball */ if (!u.utrap || u.utraptype == TT_BURIEDBALL) { - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) { + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) { if (otmp->otyp != HEAVY_IRON_BALL) continue; /* if found at the target spot, we're done */ @@ -1994,11 +1994,11 @@ bury_objs(int x, int y) costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) && costly_spot(x, y)); - if (gl.level.objects[x][y] != (struct obj *) 0) { + if (svl.level.objects[x][y] != (struct obj *) 0) { debugpline2("bury_objs: at <%d,%d>", x, y); } - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp2) { - if (costly && !gc.context.mon_moving) { + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp2) { + if (costly && !svc.context.mon_moving) { loss += stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE); if (otmp->oclass != COIN_CLASS) otmp->no_charge = 1; @@ -2028,7 +2028,7 @@ unearth_objs(int x, int y) cc.x = x; cc.y = y; bball = buried_ball(&cc); - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp2) { + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp2) { otmp2 = otmp->nobj; if (otmp->ox == x && otmp->oy == y) { if (bball && otmp == bball @@ -2230,7 +2230,7 @@ wiz_debug_cmd_bury(void) for (y = u.uy - 1; y <= u.uy + 1; y++) { if (!isok(x, y)) continue; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) ++before; bury_objs(x, y); @@ -2243,7 +2243,7 @@ wiz_debug_cmd_bury(void) for (y = u.uy - 1; y <= u.uy + 1; y++) { if (!isok(x, y)) continue; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) ++after; } diff = before - after; diff --git a/src/display.c b/src/display.c index 82d27558c..8a47e5058 100644 --- a/src/display.c +++ b/src/display.c @@ -248,7 +248,7 @@ magic_map_background(coordxy x, coordxy y, int show) else if (lev->typ == CORR && glyph == cmap_to_glyph(S_litcorr)) glyph = cmap_to_glyph(S_corr); } - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) lev->glyph = glyph; if (show) show_glyph(x, y, glyph); @@ -279,7 +279,7 @@ map_background(coordxy x, coordxy y, int show) { int glyph = back_to_glyph(x, y); - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) levl[x][y].glyph = glyph; if (show) show_glyph(x, y, glyph); @@ -297,7 +297,7 @@ map_trap(struct trap *trap, int show) coordxy x = trap->tx, y = trap->ty; int glyph = trap_to_glyph(trap); - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) levl[x][y].glyph = glyph; if (show) show_glyph(x, y, glyph); @@ -314,7 +314,7 @@ map_engraving(struct engr *ep, int show) coordxy x = ep->engr_x, y = ep->engr_y; int glyph = engraving_to_glyph(ep); - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) levl[x][y].glyph = glyph; if (show) show_glyph(x, y, glyph); @@ -350,7 +350,7 @@ map_object(struct obj *obj, int show) } } - if (gl.level.flags.hero_memory) { + if (svl.level.flags.hero_memory) { /* MRKR: While hallucinating, statues are seen as random monsters */ /* but remembered as random objects. */ @@ -377,7 +377,7 @@ void map_invisible(coordxy x, coordxy y) { if (x != u.ux || y != u.uy) { /* don't display I at hero's location */ - if (gl.level.flags.hero_memory) + if (svl.level.flags.hero_memory) levl[x][y].glyph = GLYPH_INVISIBLE; show_glyph(x, y, GLYPH_INVISIBLE); } @@ -410,7 +410,7 @@ unmap_object(coordxy x, coordxy y) struct trap *trap; struct engr *ep; - if (!gl.level.flags.hero_memory) + if (!svl.level.flags.hero_memory) return; if ((trap = t_at(x, y)) != 0 && trap->tseen && !covers_traps(x, y)) { @@ -545,7 +545,7 @@ display_monster( if (!sensed) { show_glyph(x, y, glyph); /* override real topology with mimic's fake one */ - gl.lastseentyp[x][y] = cmap_to_type(sym); + svl.lastseentyp[x][y] = cmap_to_type(sym); } break; } @@ -676,10 +676,10 @@ next_to_gas( boolean suppress_map_output(void) { - if (gi.in_mklev || gp.program_state.saving || gp.program_state.restoring) + if (gi.in_mklev || svp.program_state.saving || svp.program_state.restoring) return TRUE; #ifdef HANGUPHANDLING - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) return TRUE; #endif return FALSE; @@ -842,14 +842,14 @@ feel_location(coordxy x, coordxy y) */ if (uchain && uchain->where == OBJ_FLOOR && uchain->ox == x && uchain->oy == y - && gl.level.objects[x][y] == uchain) + && svl.level.objects[x][y] == uchain) u.bc_felt |= BC_CHAIN; else u.bc_felt &= ~BC_CHAIN; /* do not feel the chain */ if (uball && uball->where == OBJ_FLOOR && uball->ox == x && uball->oy == y - && gl.level.objects[x][y] == uball) + && svl.level.objects[x][y] == uball) u.bc_felt |= BC_BALL; else u.bc_felt &= ~BC_BALL; /* do not feel the ball */ @@ -1255,7 +1255,7 @@ flash_glyph_at(coordxy x, coordxy y, int tg, int rpt) rpt *= 2; /* two loop iterations per 'count' */ glyph[0] = tg; - glyph[1] = (gl.level.flags.hero_memory) ? levl[x][y].glyph + glyph[1] = (svl.level.flags.hero_memory) ? levl[x][y].glyph : back_to_glyph(x, y); /* even iteration count (guaranteed) ends with glyph[1] showing; caller might want to override that, but no newsym() calls here @@ -1456,7 +1456,7 @@ see_monsters(void) if (mon->wormno) see_wsegs(mon); if (Warn_of_mon - && (gc.context.warntype.obj & mon->data->mflags2) != 0L) + && (svc.context.warntype.obj & mon->data->mflags2) != 0L) new_warn_obj_cnt++; } @@ -1658,10 +1658,10 @@ docrt_flags(int refresh_flags) redrawonly = (refresh_flags & docrtRefresh) != 0, nocls = (refresh_flags & docrtNocls) != 0; - if (!u.ux || gp.program_state.in_docrt) + if (!u.ux || svp.program_state.in_docrt) return; /* display isn't ready yet */ - gp.program_state.in_docrt = TRUE; + svp.program_state.in_docrt = TRUE; if (redrawonly) { redraw_map(FALSE); @@ -1713,7 +1713,7 @@ docrt_flags(int refresh_flags) disp.botlx = TRUE; /* force a redraw of the bottom lines */ /* note: caller needs to call bot() to actually redraw status */ } - gp.program_state.in_docrt = FALSE; + svp.program_state.in_docrt = FALSE; } /* for panning beyond a clipped region; resend the current map data to @@ -1949,8 +1949,8 @@ show_glyph(coordxy x, coordxy y, int glyph) oldglyph = gg.gbuf[y][x].glyphinfo.glyph; if (a11y.glyph_updates && !a11y.mon_notices_blocked - && !gp.program_state.in_docrt - && !gp.program_state.in_getlev + && !svp.program_state.in_docrt + && !svp.program_state.in_getlev && (oldglyph != glyph || gg.gbuf[y][x].gnew)) { int c = glyph_to_cmap(glyph); if ((glyph_is_nothing(oldglyph) || glyph_is_unexplored(oldglyph) @@ -2165,7 +2165,7 @@ flush_screen(int cursor_on_u) return; /* if already flushing then return */ flushing = 1; #ifdef HANGUPHANDLING - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) return; #endif @@ -2228,7 +2228,7 @@ back_to_glyph(coordxy x, coordxy y) switch (ptr->typ) { case SCORR: case STONE: - idx = gl.level.flags.arboreal ? S_tree : S_stone; + idx = svl.level.flags.arboreal ? S_tree : S_stone; break; case ROOM: idx = S_room; @@ -2446,7 +2446,7 @@ get_bkglyph_and_framecolor( switch (lev->typ) { case SCORR: case STONE: - idx = gl.level.flags.arboreal ? S_tree : S_stone; + idx = svl.level.flags.arboreal ? S_tree : S_stone; break; case ROOM: idx = S_room; @@ -2624,8 +2624,8 @@ int wallcolors[sokoban_walls + 1] = { #if 0 #define is_objpile(x, y) \ - (!Hallucination && gl.level.objects[(x)][(y)] \ - && gl.level.objects[(x)][(y)]->nexthere) + (!Hallucination && svl.level.objects[(x)][(y)] \ + && svl.level.objects[(x)][(y)]->nexthere) #endif staticfn int cmap_to_roguecolor(int); @@ -3017,7 +3017,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger) color = NO_COLOR; gmap->sym.color = color; } - gg.glyph_reset_timestamp = gm.moves; + gg.glyph_reset_timestamp = svm.moves; } /* ------------------------------------------------------------------------ */ diff --git a/src/do.c b/src/do.c index 779e7eca3..8f7aa4293 100644 --- a/src/do.c +++ b/src/do.c @@ -200,7 +200,7 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) might have been thrown by a giant or launched by a rolling boulder trap triggered by a monster or dropped by a scroll of earth read by a monster */ - if (gc.context.mon_moving) { + if (svc.context.mon_moving) { /* normally we'd use ohitmon() but it can call drop_throw() which calls flooreffects() */ damage = dmgval(obj, mtmp); @@ -304,10 +304,10 @@ flooreffects(struct obj *obj, coordxy x, coordxy y, const char *verb) (void) obj_meld(&globbyobj, &otmp); } res = (boolean) !globbyobj; - } else if (gc.context.mon_moving && IS_ALTAR(levl[x][y].typ) + } else if (svc.context.mon_moving && IS_ALTAR(levl[x][y].typ) && cansee(x,y)) { doaltarobj(obj); - } else if (obj->oclass == POTION_CLASS && gl.level.flags.temperature > 0 + } else if (obj->oclass == POTION_CLASS && svl.level.flags.temperature > 0 && (levl[x][y].typ == ROOM || levl[x][y].typ == CORR)) { /* Potions are sometimes destroyed when landing on very hot ground. The basic odds are 50% for nonblessed potions and @@ -359,7 +359,7 @@ doaltarobj(struct obj *obj) if (obj->oclass != COIN_CLASS) { /* KMH, conduct */ - if (!gc.context.mon_moving && !u.uconduct.gnostic++) + if (!svc.context.mon_moving && !u.uconduct.gnostic++) livelog_printf(LL_CONDUCT, "eschewed atheism, by dropping %s on an altar", doname(obj)); @@ -403,7 +403,7 @@ polymorph_sink(void) return; sinklooted = levl[u.ux][u.uy].looted != 0; - /* gl.level.flags.nsinks--; // set_levltyp() will update this */ + /* svl.level.flags.nsinks--; // set_levltyp() will update this */ levl[u.ux][u.uy].flags = 0; switch (rn2(4)) { default: @@ -547,7 +547,7 @@ dosinkring(struct obj *obj) break; case RIN_HUNGER: ideed = FALSE; - for (otmp = gl.level.objects[u.ux][u.uy]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[u.ux][u.uy]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; if (otmp != uball && otmp != uchain && !obj_resists(otmp, 1, 99)) { @@ -822,7 +822,7 @@ dropz(struct obj *obj, boolean with_impact) impact_disturbs_zombies(obj, with_impact); if (obj == uball) drop_ball(u.ux, u.uy); - else if (gl.level.flags.has_shop) + else if (svl.level.flags.has_shop) sellobj(obj, u.ux, u.uy); stackobj(obj); if (Blind && Levitation) @@ -900,7 +900,7 @@ obj_no_longer_held(struct obj *obj) */ if (!obj->oerodeproof || !rn2(10)) { /* if monsters aren't moving, assume player is responsible */ - if (!gc.context.mon_moving && !gp.program_state.gameover) + if (!svc.context.mon_moving && !svp.program_state.gameover) costly_alteration(obj, COST_DEGRD); obj->otyp = WORM_TOOTH; obj->oerodeproof = 0; @@ -1133,8 +1133,8 @@ dodown(void) for (obj = gi.invent; obj; obj = obj->nobj) { if (obj->oartifact && artifact_has_invprop(obj, LEVITATION)) { - if (obj->age < gm.moves) - obj->age = gm.moves; + if (obj->age < svm.moves) + obj->age = svm.moves; obj->age += rnz(100); } } @@ -1201,7 +1201,7 @@ dodown(void) return ECMD_TIME; } else if (!trap || !is_hole(trap->ttyp) || !Can_fall_thru(&u.uz) || !trap->tseen) { - if (flags.autodig && !gc.context.nopick && uwep && is_pick(uwep)) { + if (flags.autodig && !svc.context.nopick && uwep && is_pick(uwep)) { return use_pick_axe2(uwep); } else { You_cant("go down here%s.", @@ -1348,7 +1348,7 @@ save_currentstate(void) { NHFILE *nhfp; - gp.program_state.in_checkpoint++; + svp.program_state.in_checkpoint++; if (flags.ins_chkpt) { /* write out just-attained level, with pets and everything */ nhfp = currentlevel_rewrite(); @@ -1363,7 +1363,7 @@ save_currentstate(void) /* write out non-level state */ savestateinlock(); - gp.program_state.in_checkpoint--; + svp.program_state.in_checkpoint--; } #endif @@ -1468,7 +1468,7 @@ goto_level( char whynot[BUFSZ]; int dist = depth(newlevel) - depth(&u.uz); boolean do_fall_dmg = FALSE; - schar prev_temperature = gl.level.flags.temperature; + schar prev_temperature = svl.level.flags.temperature; if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) newlevel->dlevel = dunlevs_in_dungeon(newlevel); @@ -1512,7 +1512,7 @@ goto_level( */ if (Inhell && up && u.uhave.amulet && !newdungeon && !portal && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) { - if (!rn2(4 + gc.context.mysteryforce)) { + if (!rn2(4 + svc.context.mysteryforce)) { int odds = 3 + (int) u.ualign.type, /* 2..4 */ diff = (odds <= 1) ? 0 : rn2(odds); /* paranoia */ @@ -1532,7 +1532,7 @@ goto_level( that drops faster, on average, when being sent down farther so while the impact is reduced for everybody compared to earlier versions, it is reduced least for chaotics, most for lawfuls */ - gc.context.mysteryforce += rn2(diff + 2); /* L:0-4, N:0-3, C:0-2 */ + svc.context.mysteryforce += rn2(diff + 2); /* L:0-4, N:0-3, C:0-2 */ if (on_level(newlevel, &u.uz)) { (void) safe_teleds(TELEDS_NO_FLAGS); @@ -1577,7 +1577,7 @@ goto_level( maybe_reset_pick((struct obj *) 0); reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */ iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination cache */ - gc.context.polearm.hitmon = (struct monst *) 0; /* polearm target */ + svc.context.polearm.hitmon = (struct monst *) 0; /* polearm target */ /* digging context is level-aware and can actually be resumed if hero returns to the previous level without any intervening dig */ @@ -1628,7 +1628,7 @@ goto_level( if (!leaving_tutorial || ledger_to_dnum(l_idx) == tutorial_dnum) delete_levelfile(l_idx); /* mark #overview data for all dungeon branches as uninteresting */ - for (l_idx = 0; l_idx < gn.n_dgns; ++l_idx) + for (l_idx = 0; l_idx < svn.n_dgns; ++l_idx) if (!leaving_tutorial || l_idx == tutorial_dnum) remdun_mapseen(l_idx); /* get rid of mons & objs scheduled to migrate to discarded levels */ @@ -1659,18 +1659,18 @@ goto_level( stairway_free_all(); /* set default level change destination areas */ /* the special level code may override these */ - (void) memset((genericptr_t) &gu.updest, 0, sizeof gu.updest); - (void) memset((genericptr_t) &gd.dndest, 0, sizeof gd.dndest); + (void) memset((genericptr_t) &svu.updest, 0, sizeof svu.updest); + (void) memset((genericptr_t) &svd.dndest, 0, sizeof svd.dndest); - if (!(gl.level_info[new_ledger].flags & LFILE_EXISTS)) { + if (!(svl.level_info[new_ledger].flags & LFILE_EXISTS)) { /* entering this level for first time; make it now */ - if (gl.level_info[new_ledger].flags & (VISITED)) { + if (svl.level_info[new_ledger].flags & (VISITED)) { impossible("goto_level: returning to discarded level?"); - gl.level_info[new_ledger].flags &= ~(VISITED); + svl.level_info[new_ledger].flags &= ~(VISITED); } mklev(); new = TRUE; /* made the level */ - familiar = bones_include_name(gp.plname); + familiar = bones_include_name(svp.plname); } else { /* returning to previously visited level; reload it */ nhfp = open_levelfile(new_ledger, whynot); @@ -1681,7 +1681,7 @@ goto_level( reseed_random(rn2); reseed_random(rn2_on_display_rng); minit(); /* ZEROCOMP */ - getlev(nhfp, gh.hackpid, new_ledger); + getlev(nhfp, svh.hackpid, new_ledger); close_nhfile(nhfp); oinit(); /* reassign level dependent obj probabilities */ } @@ -1803,7 +1803,7 @@ goto_level( /* initial movement of bubbles just before vision_recalc */ if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) movebubbles(); - else if (gl.level.flags.fumaroles) + else if (svl.level.flags.fumaroles) fumaroles(); /* Reset the screen. */ @@ -1865,7 +1865,7 @@ goto_level( onquest(); /* might be reaching locate|goal level */ } else if (Is_knox(&u.uz)) { /* alarm stops working once Croesus has died */ - if (new || !gm.mvitals[PM_CROESUS].died) { + if (new || !svm.mvitals[PM_CROESUS].died) { You("have penetrated a high security area!"); Soundeffect(se_alarm, 100); pline("An alarm sounds!"); @@ -1890,7 +1890,7 @@ goto_level( /* main dungeon message from your quest leader */ if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") && !(u.uevent.qcompleted || u.uevent.qexpelled - || gq.quest_status.leader_is_dead)) { + || svq.quest_status.leader_is_dead)) { /* [TODO: copy of same TODO below; if an achievement for receiving quest call from leader gets added, that should come after logging new level entry] */ @@ -1960,11 +1960,11 @@ goto_level( void hellish_smoke_mesg(void) { - if (gl.level.flags.temperature) + if (svl.level.flags.temperature) pline("It is %s here.", - gl.level.flags.temperature > 0 ? "hot" : "cold"); + svl.level.flags.temperature > 0 ? "hot" : "cold"); - if (In_hell(&u.uz) && gl.level.flags.temperature > 0) + if (In_hell(&u.uz) && svl.level.flags.temperature > 0) You("%s smoke...", olfaction(gy.youmonst.data) ? "smell" : "sense"); } @@ -1973,8 +1973,8 @@ hellish_smoke_mesg(void) staticfn void temperature_change_msg(schar prev_temperature) { - if (prev_temperature != gl.level.flags.temperature) { - if (gl.level.flags.temperature) + if (prev_temperature != svl.level.flags.temperature) { + if (svl.level.flags.temperature) hellish_smoke_mesg(); else if (prev_temperature > 0) pline_The("heat %s gone.", @@ -2238,7 +2238,7 @@ revive_mon(anything *arg, long timeout UNUSED) if (!obj_has_timer(body, ROT_CORPSE)) You_feel("%sless hassled.", is_rider(mptr) ? "much " : ""); action = ROT_CORPSE; - when = (long) d(5, 50) - (gm.moves - body->age); + when = (long) d(5, 50) - (svm.moves - body->age); if (when < 1L) when = 1L; } @@ -2254,7 +2254,7 @@ zombify_mon(anything *arg, long timeout) struct obj *body = arg->a_obj; int zmon = zombie_form(&mons[body->corpsenm]); - if (zmon != NON_PM && !(gm.mvitals[zmon].mvflags & G_GENOD)) { + if (zmon != NON_PM && !(svm.mvitals[zmon].mvflags & G_GENOD)) { if (has_omid(body)) free_omid(body); if (has_omonst(body)) diff --git a/src/do_name.c b/src/do_name.c index 01b5d0cf3..a30e65073 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -220,7 +220,7 @@ do_mgivenname(void) mtmp = u.usteed; } else { pline("This %s creature is called %s and cannot be renamed.", - beautiful(), gp.plname); + beautiful(), svp.plname); return; } } else @@ -769,7 +769,7 @@ const char * rndghostname(void) { return rn2(7) ? ROLL_FROM(ghostnames) - : (const char *) gp.plname; + : (const char *) svp.plname; } /* @@ -839,7 +839,7 @@ x_monnam( if (mtmp == &gy.youmonst) return strcpy(buf, "you"); /* ignore article, "invisible", &c */ - if (gp.program_state.gameover) + if (svp.program_state.gameover) suppress |= SUPPRESS_HALLUCINATION; if (article == ARTICLE_YOUR && !mtmp->mtame) article = ARTICLE_THE; @@ -857,7 +857,7 @@ x_monnam( do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION); do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE); do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR - && !gp.program_state.gameover && mtmp != u.usteed + && !svp.program_state.gameover && mtmp != u.usteed && !engulfing_u(mtmp) && !(suppress & SUPPRESS_IT); do_saddle = !(suppress & SUPPRESS_SADDLE); do_mappear = mappear_as_mon && !(suppress & SUPPRESS_MAPPEARANCE); @@ -1254,7 +1254,7 @@ minimal_monnam(struct monst *mon, boolean ckloc) fmt_ptr((genericptr_t) mon->data), fmt_ptr((genericptr_t) &mons[NUMMONS])); } else if (ckloc && ptr == &mons[PM_LONG_WORM] && mon->mx - && gl.level.monsters[mon->mx][mon->my] != mon) { + && svl.level.monsters[mon->mx][mon->my] != mon) { Sprintf(outbuf, "%s <%d,%d>", pmname(&mons[PM_LONG_WORM_TAIL], Mgender(mon)), mon->mx, mon->my); @@ -1478,7 +1478,7 @@ const char * hliquid( const char *liquidpref) /* use as-is when not hallucintg (unless empty) */ { - boolean hallucinate = Hallucination && !gp.program_state.gameover; + boolean hallucinate = Hallucination && !svp.program_state.gameover; if (hallucinate || !liquidpref || !*liquidpref) { int indx, count = SIZE(hliquids); diff --git a/src/do_wear.c b/src/do_wear.c index 67c059ef5..0d49b2c1d 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -98,7 +98,7 @@ toggle_stealth( long oldprop, /* prop[].extrinsic, with obj->owornmask pre-stripped */ boolean on) { - if (on ? gi.initial_don : gc.context.takeoff.cancelled_don) + if (on ? gi.initial_don : svc.context.takeoff.cancelled_don) return; if (!oldprop /* extrinsic stealth from something else */ @@ -140,7 +140,7 @@ toggle_displacement( stripped by caller */ boolean on) { - if (on ? gi.initial_don : gc.context.takeoff.cancelled_don) + if (on ? gi.initial_don : svc.context.takeoff.cancelled_don) return; if (!oldprop /* extrinsic displacement from something else */ @@ -240,14 +240,14 @@ Boots_off(void) int otyp = otmp->otyp; long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_BOOTS; - gc.context.takeoff.mask &= ~W_ARMF; + svc.context.takeoff.mask &= ~W_ARMF; /* For levitation, float_down() returns if Levitation, so we * must do a setworn() _before_ the levitation case. */ setworn((struct obj *) 0, W_ARMF); switch (otyp) { case SPEED_BOOTS: - if (!Very_fast && !gc.context.takeoff.cancelled_don) { + if (!Very_fast && !svc.context.takeoff.cancelled_don) { makeknown(otyp); You_feel("yourself slow down%s.", Fast ? " a bit" : ""); } @@ -257,7 +257,7 @@ Boots_off(void) if ((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) && !Levitation && !Flying && !(is_clinger(gy.youmonst.data) && has_ceiling(&u.uz)) - && !gc.context.takeoff.cancelled_don + && !svc.context.takeoff.cancelled_don /* avoid recursive call to lava_effects() */ && !iflags.in_lava_effects) { /* make boots known in case you survive the drowning */ @@ -274,7 +274,7 @@ Boots_off(void) break; case LEVITATION_BOOTS: if (!oldprop && !HLevitation && !(BLevitation & FROMOUTSIDE) - && !gc.context.takeoff.cancelled_don) { + && !svc.context.takeoff.cancelled_don) { /* lava_effects() sets in_lava_effects and calls Boots_off() so hero is already in midst of floating down */ if (!iflags.in_lava_effects) @@ -293,7 +293,7 @@ Boots_off(void) default: impossible(unknown_type, c_boots, otyp); } - gc.context.takeoff.cancelled_don = FALSE; + svc.context.takeoff.cancelled_don = FALSE; return 0; } @@ -361,7 +361,7 @@ Cloak_off(void) int otyp = otmp->otyp; long oldprop = u.uprops[objects[otyp].oc_oprop].extrinsic & ~WORN_CLOAK; - gc.context.takeoff.mask &= ~W_ARMC; + svc.context.takeoff.mask &= ~W_ARMC; /* For mummy wrapping, taking it off first resets `Invisible'. */ setworn((struct obj *) 0, W_ARMC); switch (otyp) { @@ -488,7 +488,7 @@ Helmet_on(void) int Helmet_off(void) { - gc.context.takeoff.mask &= ~W_ARMH; + svc.context.takeoff.mask &= ~W_ARMH; switch (uarmh->otyp) { case FEDORA: @@ -502,7 +502,7 @@ Helmet_off(void) disp.botl = TRUE; break; case CORNUTHAUM: - if (!gc.context.takeoff.cancelled_don) { + if (!svc.context.takeoff.cancelled_don) { ABON(A_CHA) += (Role_if(PM_WIZARD) ? -1 : 1); disp.botl = TRUE; } @@ -514,7 +514,7 @@ Helmet_off(void) see_monsters(); return 0; case HELM_OF_BRILLIANCE: - if (!gc.context.takeoff.cancelled_don) + if (!svc.context.takeoff.cancelled_don) adj_abon(uarmh, -uarmh->spe); break; case HELM_OF_OPPOSITE_ALIGNMENT: @@ -527,7 +527,7 @@ Helmet_off(void) impossible(unknown_type, c_helmet, uarmh->otyp); } setworn((struct obj *) 0, W_ARMH); - gc.context.takeoff.cancelled_don = FALSE; + svc.context.takeoff.cancelled_don = FALSE; return 0; } @@ -616,9 +616,9 @@ Gloves_off(void) struct obj *gloves = uarmg; /* needed after uarmg has been set to Null */ long oldprop = u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES; - boolean on_purpose = !gc.context.mon_moving && !uarmg->in_use; + boolean on_purpose = !svc.context.mon_moving && !uarmg->in_use; - gc.context.takeoff.mask &= ~W_ARMG; + svc.context.takeoff.mask &= ~W_ARMG; switch (uarmg->otyp) { case LEATHER_GLOVES: @@ -632,14 +632,14 @@ Gloves_off(void) disp.botl = TRUE; /* taken care of in attrib.c */ break; case GAUNTLETS_OF_DEXTERITY: - if (!gc.context.takeoff.cancelled_don) + if (!svc.context.takeoff.cancelled_don) adj_abon(uarmg, -uarmg->spe); break; default: impossible(unknown_type, c_gloves, uarmg->otyp); } setworn((struct obj *) 0, W_ARMG); - gc.context.takeoff.cancelled_don = FALSE; + svc.context.takeoff.cancelled_don = FALSE; (void) encumber_msg(); /* immediate feedback for GoP */ /* usually can't remove gloves when they're slippery but it can @@ -698,7 +698,7 @@ Shield_on(void) int Shield_off(void) { - gc.context.takeoff.mask &= ~W_ARMS; + svc.context.takeoff.mask &= ~W_ARMS; /* no shield currently requires special handling when taken off, but we keep this uncommented in case somebody adds a new one which does */ @@ -741,7 +741,7 @@ Shirt_on(void) int Shirt_off(void) { - gc.context.takeoff.mask &= ~W_ARMU; + svc.context.takeoff.mask &= ~W_ARMU; /* no shirt currently requires special handling when taken off, but we keep this uncommented in case somebody adds a new one which does */ @@ -786,7 +786,7 @@ dragon_armor_handling( EFast |= W_ARM; } else { EFast &= ~W_ARM; - if (!Very_fast && !gc.context.takeoff.cancelled_don) + if (!Very_fast && !svc.context.takeoff.cancelled_don) You("slow down."); } break; @@ -810,7 +810,7 @@ dragon_armor_handling( case GOLD_DRAGON_SCALES: case GOLD_DRAGON_SCALE_MAIL: (void) make_hallucinated((long) !puton, - gp.program_state.restoring ? FALSE : TRUE, + svp.program_state.restoring ? FALSE : TRUE, W_ARM); break; case ORANGE_DRAGON_SCALES: @@ -875,9 +875,9 @@ Armor_off(void) struct obj *otmp = uarm; boolean was_arti_light = otmp && otmp->lamplit && artifact_light(otmp); - gc.context.takeoff.mask &= ~W_ARM; + svc.context.takeoff.mask &= ~W_ARM; setworn((struct obj *) 0, W_ARM); - gc.context.takeoff.cancelled_don = FALSE; + svc.context.takeoff.cancelled_don = FALSE; /* taking off yellow dragon scales/mail might be fatal; arti_light comes from gold dragon scales/mail so they don't overlap, but @@ -905,9 +905,9 @@ Armor_gone(void) struct obj *otmp = uarm; boolean was_arti_light = otmp && otmp->lamplit && artifact_light(otmp); - gc.context.takeoff.mask &= ~W_ARM; + svc.context.takeoff.mask &= ~W_ARM; setnotworn(uarm); - gc.context.takeoff.cancelled_don = FALSE; + svc.context.takeoff.cancelled_don = FALSE; /* losing yellow dragon scales/mail might be fatal; arti_light comes from gold dragon scales/mail so they don't overlap, but @@ -1022,7 +1022,7 @@ Amulet_on(void) void Amulet_off(void) { - gc.context.takeoff.mask &= ~W_AMUL; + svc.context.takeoff.mask &= ~W_AMUL; switch (uamul->otyp) { case AMULET_OF_ESP: @@ -1252,7 +1252,7 @@ Ring_off_or_gone(struct obj *obj, boolean gone) long mask = (obj->owornmask & W_RING); boolean observable; - gc.context.takeoff.mask &= ~mask; + svc.context.takeoff.mask &= ~mask; if (!(u.uprops[objects[obj->otyp].oc_oprop].extrinsic & mask)) impossible("Strange... I didn't know you had that ring."); if (gone) @@ -1406,7 +1406,7 @@ Blindf_off(struct obj *otmp) impossible("Blindf_off without eyewear?"); return; } - gc.context.takeoff.mask &= ~W_TOOL; + svc.context.takeoff.mask &= ~W_TOOL; setworn((struct obj *) 0, otmp->owornmask); if (!nooffmsg) off_msg(otmp); @@ -1505,7 +1505,7 @@ donning(struct obj *otmp) boolean doffing(struct obj *otmp) { - long what = gc.context.takeoff.what; + long what = svc.context.takeoff.what; boolean result = FALSE; /* 'T' (or 'R' used for armor) sets ga.afternmv, 'A' sets takeoff.what */ @@ -1556,9 +1556,9 @@ cancel_doff(struct obj *obj, long slotmask) * matter whether cancel_don() gets called here--the item has already * been removed by now.] */ - if (!(gc.context.takeoff.mask & I_SPECIAL) && donning(obj)) + if (!(svc.context.takeoff.mask & I_SPECIAL) && donning(obj)) cancel_don(); /* applies to doffing too */ - gc.context.takeoff.mask &= ~slotmask; + svc.context.takeoff.mask &= ~slotmask; } /* despite their names, cancel_don() and cancel_doff() both apply to both @@ -1572,7 +1572,7 @@ cancel_don(void) * every item of the corresponding armor category takes 1 turn to wear, * but check all of them anyway */ - gc.context.takeoff.cancelled_don = (ga.afternmv == Cloak_on + svc.context.takeoff.cancelled_don = (ga.afternmv == Cloak_on || ga.afternmv == Armor_on || ga.afternmv == Shirt_on || ga.afternmv == Helmet_on @@ -1582,8 +1582,8 @@ cancel_don(void) ga.afternmv = (int (*)(void)) 0; gn.nomovemsg = (char *) 0; gm.multi = 0; - gc.context.takeoff.delay = 0; - gc.context.takeoff.what = 0L; + svc.context.takeoff.delay = 0; + svc.context.takeoff.what = 0L; } /* called by steal() during theft from hero; interrupt donning/doffing */ @@ -1701,7 +1701,7 @@ armor_or_accessory_off(struct obj *obj) reset_remarm(); /* clear context.takeoff.mask and context.takeoff.what */ (void) select_off(obj); - if (!gc.context.takeoff.mask) + if (!svc.context.takeoff.mask) return ECMD_OK; /* none of armoroff()/Ring_/Amulet/Blindf_off() use context.takeoff.mask */ reset_remarm(); @@ -1889,7 +1889,7 @@ armoroff(struct obj *otmp) avoid "You were wearing ____ (being worn)." */ off_msg(otmp); } - gc.context.takeoff.mask = gc.context.takeoff.what = 0L; + svc.context.takeoff.mask = svc.context.takeoff.what = 0L; return 1; } @@ -2285,7 +2285,7 @@ accessory_or_armor_on(struct obj *obj) unmul(""); /* call afternmv, clear it+nomovemsg+multi_reason */ on_msg(obj); } - gc.context.takeoff.mask = gc.context.takeoff.what = 0L; + svc.context.takeoff.mask = svc.context.takeoff.what = 0L; } else { /* not armor */ boolean give_feedback = FALSE; @@ -2668,33 +2668,33 @@ select_off(struct obj *otmp) } if (otmp == uarm) - gc.context.takeoff.mask |= WORN_ARMOR; + svc.context.takeoff.mask |= WORN_ARMOR; else if (otmp == uarmc) - gc.context.takeoff.mask |= WORN_CLOAK; + svc.context.takeoff.mask |= WORN_CLOAK; else if (otmp == uarmf) - gc.context.takeoff.mask |= WORN_BOOTS; + svc.context.takeoff.mask |= WORN_BOOTS; else if (otmp == uarmg) - gc.context.takeoff.mask |= WORN_GLOVES; + svc.context.takeoff.mask |= WORN_GLOVES; else if (otmp == uarmh) - gc.context.takeoff.mask |= WORN_HELMET; + svc.context.takeoff.mask |= WORN_HELMET; else if (otmp == uarms) - gc.context.takeoff.mask |= WORN_SHIELD; + svc.context.takeoff.mask |= WORN_SHIELD; else if (otmp == uarmu) - gc.context.takeoff.mask |= WORN_SHIRT; + svc.context.takeoff.mask |= WORN_SHIRT; else if (otmp == uleft) - gc.context.takeoff.mask |= LEFT_RING; + svc.context.takeoff.mask |= LEFT_RING; else if (otmp == uright) - gc.context.takeoff.mask |= RIGHT_RING; + svc.context.takeoff.mask |= RIGHT_RING; else if (otmp == uamul) - gc.context.takeoff.mask |= WORN_AMUL; + svc.context.takeoff.mask |= WORN_AMUL; else if (otmp == ublindf) - gc.context.takeoff.mask |= WORN_BLINDF; + svc.context.takeoff.mask |= WORN_BLINDF; else if (otmp == uwep) - gc.context.takeoff.mask |= W_WEP; + svc.context.takeoff.mask |= W_WEP; else if (otmp == uswapwep) - gc.context.takeoff.mask |= W_SWAPWEP; + svc.context.takeoff.mask |= W_SWAPWEP; else if (otmp == uquiver) - gc.context.takeoff.mask |= W_QUIVER; + svc.context.takeoff.mask |= W_QUIVER; else impossible("select_off: %s???", doname(otmp)); @@ -2707,9 +2707,9 @@ do_takeoff(void) { struct obj *otmp = (struct obj *) 0; boolean was_twoweap = u.twoweap; - struct takeoff_info *doff = &gc.context.takeoff; + struct takeoff_info *doff = &svc.context.takeoff; - gc.context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */ + svc.context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */ if (doff->what == W_WEP) { if (!cursed(uwep)) { setuwep((struct obj *) 0); @@ -2772,7 +2772,7 @@ do_takeoff(void) } else { impossible("do_takeoff: taking off %lx", doff->what); } - gc.context.takeoff.mask &= ~I_SPECIAL; /* clear cancel_doff() flag */ + svc.context.takeoff.mask &= ~I_SPECIAL; /* clear cancel_doff() flag */ return otmp; } @@ -2783,7 +2783,7 @@ take_off(void) { int i; struct obj *otmp; - struct takeoff_info *doff = &gc.context.takeoff; + struct takeoff_info *doff = &svc.context.takeoff; if (doff->what) { if (doff->delay > 0) { @@ -2872,8 +2872,8 @@ take_off(void) void reset_remarm(void) { - gc.context.takeoff.what = gc.context.takeoff.mask = 0L; - gc.context.takeoff.disrobing[0] = '\0'; + svc.context.takeoff.what = svc.context.takeoff.mask = 0L; + svc.context.takeoff.disrobing[0] = '\0'; } /* the #takeoffall command -- remove multiple worn items */ @@ -2882,9 +2882,9 @@ doddoremarm(void) { int result = 0; - if (gc.context.takeoff.what || gc.context.takeoff.mask) { - You("continue %s.", gc.context.takeoff.disrobing); - set_occupation(take_off, gc.context.takeoff.disrobing, 0); + if (svc.context.takeoff.what || svc.context.takeoff.mask) { + You("continue %s.", svc.context.takeoff.disrobing); + set_occupation(take_off, svc.context.takeoff.disrobing, 0); return ECMD_OK; } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf && !uleft && !uright && !wearing_armor()) { @@ -2898,9 +2898,9 @@ doddoremarm(void) (unsigned *) 0)) < -1) result = menu_remarm(result); - if (gc.context.takeoff.mask) { - (void) strncpy(gc.context.takeoff.disrobing, - (((gc.context.takeoff.mask & ~W_WEAPONS) != 0) + if (svc.context.takeoff.mask) { + (void) strncpy(svc.context.takeoff.disrobing, + (((svc.context.takeoff.mask & ~W_WEAPONS) != 0) /* default activity for armor and/or accessories, possibly combined with weapons */ ? "disrobing" @@ -2940,7 +2940,7 @@ remarm_swapwep(void) * can't be unwielded even though things * don't work that way... */ reset_remarm(); - gc.context.takeoff.what = gc.context.takeoff.mask = W_SWAPWEP; + svc.context.takeoff.what = svc.context.takeoff.mask = W_SWAPWEP; (void) do_takeoff(); return (!uswapwep || uswapwep->bknown != oldbknown) ? ECMD_TIME : ECMD_OK; } diff --git a/src/dog.c b/src/dog.c index d1f0ae6ae..cf9adc4f2 100644 --- a/src/dog.c +++ b/src/dog.c @@ -53,7 +53,7 @@ initedog(struct monst *mtmp) EDOG(mtmp)->dropdist = 10000; EDOG(mtmp)->apport = ACURR(A_CHA); EDOG(mtmp)->whistletime = 0; - EDOG(mtmp)->hungrytime = 1000 + gm.moves; + EDOG(mtmp)->hungrytime = 1000 + svm.moves; EDOG(mtmp)->ogoal.x = -1; /* force error if used before set */ EDOG(mtmp)->ogoal.y = -1; EDOG(mtmp)->abuse = 0; @@ -89,7 +89,7 @@ pick_familiar_pm(struct obj *otmp, boolean quietly) /* activating a figurine provides one way to exceed the maximum number of the target critter created--unless it has a special limit (erinys, Nazgul) */ - if ((gm.mvitals[mndx].mvflags & G_EXTINCT) + if ((svm.mvitals[mndx].mvflags & G_EXTINCT) && mbirth_limit(mndx) != MAXMONNO) { if (!quietly) /* have just been given "You @@ -221,7 +221,7 @@ makedog(void) if (!mtmp) return ((struct monst *) 0); /* pets were genocided */ - gc.context.startingpet_mid = mtmp->m_id; + svc.context.startingpet_mid = mtmp->m_id; /* Horses already wear a saddle */ if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) { otmp->dknown = otmp->bknown = otmp->rknown = 1; @@ -238,7 +238,7 @@ makedog(void) staticfn void set_mon_lastmove(struct monst *mtmp) { - mtmp->mlstmv = gm.moves; + mtmp->mlstmv = svm.moves; } /* record `last move time' for all monsters prior to level save so that @@ -432,9 +432,9 @@ mon_arrive(struct monst *mtmp, int when) * specify its final destination. */ - if (mtmp->mlstmv < gm.moves - 1L) { + if (mtmp->mlstmv < svm.moves - 1L) { /* heal monster for time spent in limbo */ - long nmv = gm.moves - 1L - mtmp->mlstmv; + long nmv = svm.moves - 1L - mtmp->mlstmv; mon_catchup_elapsed_time(mtmp, nmv); @@ -489,8 +489,8 @@ mon_arrive(struct monst *mtmp, int when) that we know that the current endgame levels always build upwards and never have any exclusion subregion inside their TELEPORT_REGION settings. */ - xlocale = rn1(gu.updest.hx - gu.updest.lx + 1, gu.updest.lx); - ylocale = rn1(gu.updest.hy - gu.updest.ly + 1, gu.updest.ly); + xlocale = rn1(svu.updest.hx - svu.updest.lx + 1, svu.updest.lx); + ylocale = rn1(svu.updest.hy - svu.updest.ly + 1, svu.updest.ly); break; } /* find the arrival portal */ @@ -529,7 +529,7 @@ mon_arrive(struct monst *mtmp, int when) coord c; /* somexy() handles irregular rooms */ - if (somexy(&gr.rooms[*r - ROOMOFFSET], &c)) + if (somexy(&svr.rooms[*r - ROOMOFFSET], &c)) xlocale = c.x, ylocale = c.y; else xlocale = ylocale = 0; @@ -642,8 +642,8 @@ mon_catchup_elapsed_time( && (carnivorous(mtmp->data) || herbivorous(mtmp->data))) { struct edog *edog = EDOG(mtmp); - if ((gm.moves > edog->hungrytime + 500 && mtmp->mhp < 3) - || (gm.moves > edog->hungrytime + 750)) + if ((svm.moves > edog->hungrytime + 500 && mtmp->mhp < 3) + || (svm.moves > edog->hungrytime + 750)) mtmp->mtame = mtmp->mpeaceful = 0; } @@ -805,7 +805,7 @@ keepdogs( relmon(mtmp, &gm.mydogs); /* mtmp->mx,my retain current value */ mtmp->mx = mtmp->my = 0; /* mx==0 implies migrating */ mtmp->wormno = num_segs; - mtmp->mlstmv = gm.moves; + mtmp->mlstmv = svm.moves; } else if (keep_mon_accessible(mtmp)) { /* we want to be able to find the Wizard when his next resurrection chance comes up, but have him resume his @@ -856,7 +856,7 @@ migrate_to_level( if (In_W_tower(mx, my, &u.uz)) xyflags |= 2; mtmp->wormno = num_segs; - mtmp->mlstmv = gm.moves; + mtmp->mlstmv = svm.moves; mtmp->mtrack[2].x = u.uz.dnum; /* migrating from this dungeon */ mtmp->mtrack[2].y = u.uz.dlevel; /* migrating from this dungeon level */ mtmp->mtrack[1].x = cc ? cc->x : mx; @@ -974,7 +974,7 @@ dogfood(struct monst *mon, struct obj *obj) when starving; they never eat stone-to-flesh'd meat */ if (mptr == &mons[PM_GHOUL]) { if (obj->otyp == CORPSE) - return (peek_at_iced_corpse_age(obj) + 50L <= gm.moves + return (peek_at_iced_corpse_age(obj) + 50L <= svm.moves && !(fx == PM_LIZARD || fx == PM_LICHEN)) ? DOGFOOD : (starving && !vegan(fptr)) ? ACCFOOD : POISON; @@ -995,7 +995,7 @@ dogfood(struct monst *mon, struct obj *obj) return POISON; return carni ? CADAVER : MANFOOD; case CORPSE: - if ((peek_at_iced_corpse_age(obj) + 50L <= gm.moves + if ((peek_at_iced_corpse_age(obj) + 50L <= svm.moves && !(fx == PM_LIZARD || fx == PM_LICHEN) && mptr->mlet != S_FUNGUS) || (acidic(fptr) && !resists_acid(mon)) @@ -1117,7 +1117,7 @@ tamedog(struct monst *mtmp, struct obj *obj, boolean givemsg) if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating && ((tasty = dogfood(mtmp, obj)) == DOGFOOD || (tasty <= ACCFOOD - && EDOG(mtmp)->hungrytime <= gm.moves))) { + && EDOG(mtmp)->hungrytime <= svm.moves))) { /* pet will "catch" and eat this thrown food */ if (canseemon(mtmp)) { boolean big_corpse = @@ -1161,7 +1161,7 @@ tamedog(struct monst *mtmp, struct obj *obj, boolean givemsg) || (obj && dogfood(mtmp, obj) >= MANFOOD)) return FALSE; - if (mtmp->m_id == gq.quest_status.leader_m_id) + if (mtmp->m_id == svq.quest_status.leader_m_id) return FALSE; /* add the pet extension */ @@ -1254,8 +1254,8 @@ wary_dog(struct monst *mtmp, boolean was_dead) edog->killed_by_u = 0; edog->abuse = 0; edog->ogoal.x = edog->ogoal.y = -1; - if (was_dead || edog->hungrytime < gm.moves + 500L) - edog->hungrytime = gm.moves + 500L; + if (was_dead || edog->hungrytime < svm.moves + 500L) + edog->hungrytime = svm.moves + 500L; if (was_dead) { edog->droptime = 0L; edog->dropdist = 10000; diff --git a/src/dogmove.c b/src/dogmove.c index 90171c6f8..6452d8123 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -142,7 +142,7 @@ cursed_object_at(coordxy x, coordxy y) { struct obj *otmp; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (otmp->cursed) return TRUE; return FALSE; @@ -223,8 +223,8 @@ dog_eat(struct monst *mtmp, char objnambuf[BUFSZ], *obj_name; objnambuf[0] = '\0'; - if (edog->hungrytime < gm.moves) - edog->hungrytime = gm.moves; + if (edog->hungrytime < svm.moves) + edog->hungrytime = svm.moves; nutrit = dog_nutrition(mtmp, obj); if (devour) { @@ -309,7 +309,7 @@ dog_eat(struct monst *mtmp, /* It's a reward if it's DOGFOOD and the player dropped/threw it. We know the player had it if invlet is set. -dlc */ if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet) - edog->apport += (int) (200L / ((long) edog->dropdist + gm.moves + edog->apport += (int) (200L / ((long) edog->dropdist + svm.moves - edog->droptime)); if (obj->unpaid) { /* edible item owned by shop has been thrown or kicked @@ -342,9 +342,9 @@ dog_starve(struct monst *mtmp) staticfn boolean dog_hunger(struct monst *mtmp, struct edog *edog) { - if (gm.moves > edog->hungrytime + DOG_WEAK) { + if (svm.moves > edog->hungrytime + DOG_WEAK) { if (!carnivorous(mtmp->data) && !herbivorous(mtmp->data)) { - edog->hungrytime = gm.moves + DOG_WEAK; + edog->hungrytime = svm.moves + DOG_WEAK; /* but not too high; it might polymorph */ } else if (!edog->mhpmax_penalty) { /* starving pets are limited in healing */ @@ -365,7 +365,7 @@ dog_hunger(struct monst *mtmp, struct edog *edog) else You_feel("worried about %s.", y_monnam(mtmp)); stop_occupation(); - } else if (gm.moves > edog->hungrytime + DOG_STARVE + } else if (svm.moves > edog->hungrytime + DOG_STARVE || DEADMONSTER(mtmp)) { dog_starve(mtmp); return TRUE; @@ -401,10 +401,10 @@ dog_invent(struct monst *mtmp, struct edog *edog, int udist) if (edog->apport > 1) edog->apport--; edog->dropdist = udist; /* hpscdi!jon */ - edog->droptime = gm.moves; + edog->droptime = svm.moves; } } else { - if ((obj = gl.level.objects[omx][omy]) != 0 + if ((obj = svl.level.objects[omx][omy]) != 0 && !strchr(nofetch, obj->oclass) #ifdef MAIL_STRUCTURES && obj->otyp != SCR_MAIL @@ -545,7 +545,7 @@ dog_goal( /* follow player if appropriate */ if (gg.gtyp == UNDEF || (gg.gtyp != DOGFOOD && gg.gtyp != APPORT - && gm.moves < edog->hungrytime)) { + && svm.moves < edog->hungrytime)) { gg.gx = u.ux; gg.gy = u.uy; if (after && udist <= 4 && u_at(gg.gx, gg.gy)) @@ -875,7 +875,7 @@ pet_ranged_attk(struct monst *mtmp) if (!mtmp->isminion) { struct edog *dog = EDOG(mtmp); - hungry = (gm.moves > (dog->hungrytime + DOG_HUNGRY)); + hungry = (svm.moves > (dog->hungrytime + DOG_HUNGRY)); } /* Identify the best target in a straight line from the pet; @@ -1015,7 +1015,7 @@ dog_move( else if (j == 1) goto newdogpos; /* eating something */ - whappr = (gm.moves - edog->whistletime < 5); + whappr = (svm.moves - edog->whistletime < 5); } else whappr = 0; @@ -1122,7 +1122,7 @@ dog_move( if ((mstatus & (M_ATTK_HIT | M_ATTK_DEF_DIED)) == M_ATTK_HIT && rn2(4) - && mtmp2->mlstmv != gm.moves + && mtmp2->mlstmv != svm.moves && !onscary(mtmp->mx, mtmp->my, mtmp2) /* monnear check needed: long worms hit on tail */ && monnear(mtmp2, mtmp->mx, mtmp->my)) { @@ -1179,13 +1179,13 @@ dog_move( /* (minion isn't interested; `cursemsg' stays FALSE) */ if (edog) { boolean can_reach_food = could_reach_item(mtmp, nx, ny); - for (obj = gl.level.objects[nx][ny]; obj; obj = obj->nexthere) { + for (obj = svl.level.objects[nx][ny]; obj; obj = obj->nexthere) { if (obj->cursed) { cursemsg[i] = TRUE; } else if (can_reach_food && (otyp = dogfood(mtmp, obj)) < MANFOOD && (otyp < ACCFOOD - || edog->hungrytime <= gm.moves)) { + || edog->hungrytime <= svm.moves)) { /* Note: our dog likes the food so much that he * might eat it even when it conceals a cursed object */ nix = nx; @@ -1264,7 +1264,7 @@ dog_move( /* describe top item of pile, not necessarily cursed item itself; don't use glyph_at() here--it would return the pet but we want to know whether an object is remembered at this map location */ - struct obj *o = (!Hallucination && gl.level.flags.hero_memory + struct obj *o = (!Hallucination && svl.level.flags.hero_memory && glyph_is_object(levl[nix][niy].glyph)) ? vobj_at(nix, niy) : 0; const char *what = o ? distant_name(o, doname) : something; diff --git a/src/dokick.c b/src/dokick.c index 7fcd7f99f..78eb5b728 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -126,18 +126,18 @@ staticfn boolean maybe_kick_monster(struct monst *mon, coordxy x, coordxy y) { if (mon) { - boolean save_forcefight = gc.context.forcefight; + boolean save_forcefight = svc.context.forcefight; gb.bhitpos.x = x; gb.bhitpos.y = y; if (!mon->mpeaceful || !canspotmon(mon)) - gc.context.forcefight = TRUE; /* attack even if invisible */ + svc.context.forcefight = TRUE; /* attack even if invisible */ /* kicking might be halted by discovery of hidden monster, by player declining to attack peaceful monster, or by passing out due to encumbrance */ if (attack_checks(mon, (struct obj *) 0) || overexertion()) mon = 0; /* don't kick after all */ - gc.context.forcefight = save_forcefight; + svc.context.forcefight = save_forcefight; } return (boolean) (mon != 0); } @@ -491,7 +491,7 @@ kick_object(coordxy x, coordxy y, char *kickobjnam) *kickobjnam = '\0'; /* if a pile, the "top" object gets kicked */ - gk.kickedobj = gl.level.objects[x][y]; + gk.kickedobj = svl.level.objects[x][y]; if (gk.kickedobj) { /* kick object; if doing is fatal, done() will clean up gk.kickedobj */ Strcpy(kickobjnam, killer_xname(gk.kickedobj)); /* matters iff res==0 */ @@ -547,9 +547,9 @@ really_kick_object(coordxy x, coordxy y) ; /* hero has been transformed but kick continues */ } else { /* normalize body shape here; foot, not body_part(FOOT) */ - Sprintf(gk.killer.name, "kicking %s barefoot", + Sprintf(svk.killer.name, "kicking %s barefoot", killer_xname(gk.kickedobj)); - instapetrify(gk.killer.name); + instapetrify(svk.killer.name); } } @@ -1130,7 +1130,7 @@ kick_nondoor(coordxy x, coordxy y, int avrg_attrib) /* nothing, fruit or trouble? 75:23.5:1.5% */ if (rn2(3)) { - if (!rn2(6) && !(gm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) + if (!rn2(6) && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) You_hear("a low buzzing."); /* a warning */ kick_ouch(x, y, ""); return ECMD_TIME; @@ -1200,7 +1200,7 @@ kick_nondoor(coordxy x, coordxy y, int avrg_attrib) exercise(A_DEX, TRUE); return ECMD_TIME; } else if (!(gm.maploc->looted & S_LPUDDING) && !rn2(3) - && !(gm.mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) { + && !(svm.mvitals[PM_BLACK_PUDDING].mvflags & G_GONE)) { Soundeffect(se_gushing_sound, 100); if (Blind) { if (!Deaf) @@ -1215,7 +1215,7 @@ kick_nondoor(coordxy x, coordxy y, int avrg_attrib) gm.maploc->looted |= S_LPUDDING; return ECMD_TIME; } else if (!(gm.maploc->looted & S_LDWASHER) && !rn2(3) - && !(gm.mvitals[PM_AMOROUS_DEMON].mvflags & G_GONE)) { + && !(svm.mvitals[PM_AMOROUS_DEMON].mvflags & G_GONE)) { /* can't resist... */ pline("%s returns!", (Blind ? Something : "The dish washer")); if (makemon(&mons[PM_AMOROUS_DEMON], x, y, @@ -1364,12 +1364,12 @@ dokick(void) mtmp = isok(x, y) ? m_at(x, y) : 0; /* might not kick monster if it is hidden and becomes revealed, if it is peaceful and player declines to attack, or if the - hero passes out due to encumbrance with low hp; gc.context.move + hero passes out due to encumbrance with low hp; svc.context.move will be 1 unless player declines to kick peaceful monster */ if (mtmp) { oldglyph = glyph_at(x, y); if (!maybe_kick_monster(mtmp, x, y)) - return (gc.context.move ? ECMD_TIME : ECMD_OK); + return (svc.context.move ? ECMD_TIME : ECMD_OK); } wake_nearby(FALSE); @@ -1417,7 +1417,7 @@ dokick(void) map_invisible(x, y); } /* recoil if floating */ - if ((Is_airlevel(&u.uz) || Levitation) && gc.context.move) { + if ((Is_airlevel(&u.uz) || Levitation) && svc.context.move) { int range; range = @@ -1547,7 +1547,7 @@ impact_drop( isrock = (missile && missile->otyp == ROCK); oct = dct = 0L; - for (obj = gl.level.objects[x][y]; obj; obj = obj2) { + for (obj = svl.level.objects[x][y]; obj; obj = obj2) { obj2 = obj->nexthere; if (obj == missile) continue; @@ -1603,11 +1603,11 @@ impact_drop( You("removed %ld %s worth of goods!", price, currency(price)); if (cansee(shkp->mx, shkp->my)) { if (ESHK(shkp)->customer[0] == 0) - (void) strncpy(ESHK(shkp)->customer, gp.plname, PL_NSIZ); + (void) strncpy(ESHK(shkp)->customer, svp.plname, PL_NSIZ); if (angry) pline("%s is infuriated!", Shknam(shkp)); else - pline("\"%s, you are a thief!\"", gp.plname); + pline("\"%s, you are a thief!\"", svp.plname); } else You_hear("a scream, \"Thief!\""); hot_pursuit(shkp); @@ -1654,7 +1654,7 @@ ship_object(struct obj *otmp, coordxy x, coordxy y, boolean shop_floor_obj) unpaid = is_unpaid(otmp); if (OBJ_AT(x, y)) { - for (obj = gl.level.objects[x][y]; obj; obj = obj->nexthere) { + for (obj = svl.level.objects[x][y]; obj; obj = obj->nexthere) { if (obj == uchain) chainthere = TRUE; else if (obj != otmp) diff --git a/src/dothrow.c b/src/dothrow.c index 34b4c4c2c..5b4b24e92 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -89,7 +89,7 @@ throw_obj(struct obj *obj, int shotlimit) long wep_mask; boolean twoweap, weakmultishot; int res = ECMD_TIME; - struct obj_split save_osplit = gc.context.objsplit; + struct obj_split save_osplit = svc.context.objsplit; /* ask "in what direction?" */ if (!getdir((char *) 0)) { @@ -140,8 +140,8 @@ throw_obj(struct obj *obj, int shotlimit) /* throwing with one hand, but pluralize since the expression "with your bare hands" sounds better */ makeplural(body_part(HAND))); - Sprintf(gk.killer.name, "throwing %s bare-handed", killer_xname(obj)); - instapetrify(gk.killer.name); + Sprintf(svk.killer.name, "throwing %s bare-handed", killer_xname(obj)); + instapetrify(svk.killer.name); } if (welded(obj)) { weldmsg(obj); @@ -280,7 +280,7 @@ throw_obj(struct obj *obj, int shotlimit) || obj->o_id == save_osplit.child_oid)) { /* futureproofing: objsplit will have been affected if partial stack was thrown; objects will have been split off stack to throw. */ - gc.context.objsplit = save_osplit; + svc.context.objsplit = save_osplit; (void) unsplitobj(obj); } return res; @@ -579,7 +579,7 @@ void endmultishot(boolean verbose) { if (gm.m_shot.i < gm.m_shot.n) { - if (verbose && !gc.context.mon_moving) { + if (verbose && !svc.context.mon_moving) { You("stop %s after the %d%s %s.", gm.m_shot.s ? "firing" : "throwing", gm.m_shot.i, ordin(gm.m_shot.i), @@ -873,9 +873,9 @@ hurtle_step(genericptr_t arg, coordxy x, coordxy y) if (touch_petrifies(mon->data) /* this is a bodily collision, so check for body armor */ && !uarmu && !uarm && !uarmc) { - Sprintf(gk.killer.name, "bumping into %s", + Sprintf(svk.killer.name, "bumping into %s", an(pmname(mon->data, NEUTRAL))); - instapetrify(gk.killer.name); + instapetrify(svk.killer.name); } if (touch_petrifies(gy.youmonst.data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { @@ -1031,17 +1031,17 @@ mhurtle_step(genericptr_t arg, coordxy x, coordxy y) if ((mtmp = m_at(x, y)) != 0 && mtmp != mon) { if (canseemon(mon) || canseemon(mtmp)) pline("%s bumps into %s.", Monnam(mon), a_monnam(mtmp)); - wakeup(mtmp, !gc.context.mon_moving); + wakeup(mtmp, !svc.context.mon_moving); /* check whether 'mon' is turned to stone by touching 'mtmp' */ if (touch_petrifies(mtmp->data) && !which_armor(mon, W_ARMU | W_ARM | W_ARMC)) { - minstapetrify(mon, !gc.context.mon_moving); + minstapetrify(mon, !svc.context.mon_moving); newsym(mon->mx, mon->my); } /* and whether 'mtmp' is turned to stone by being touched by 'mon' */ if (touch_petrifies(mon->data) && !which_armor(mtmp, W_ARMU | W_ARM | W_ARMC)) { - minstapetrify(mtmp, !gc.context.mon_moving); + minstapetrify(mtmp, !svc.context.mon_moving); newsym(mtmp->mx, mtmp->my); } } else if (u_at(x, y)) { @@ -1057,12 +1057,12 @@ mhurtle_step(genericptr_t arg, coordxy x, coordxy y) } /* and whether hero is turned to stone by being touched by 'mon' */ if (touch_petrifies(mon->data) && !(uarmu || uarm || uarmc)) { - Snprintf(gk.killer.name, sizeof gk.killer.name, "being hit by %s", + Snprintf(svk.killer.name, sizeof svk.killer.name, "being hit by %s", /* combine m_monnam() and noname_monnam(): "{your,a} hurtling cockatrice" w/o assigned name */ x_monnam(mon, mon->mtame ? ARTICLE_YOUR : ARTICLE_A, "hurtling", EXACT_NAME | SUPPRESS_NAME, FALSE)); - instapetrify(gk.killer.name); + instapetrify(svk.killer.name); newsym(u.ux, u.uy); } } @@ -1134,7 +1134,7 @@ mhurtle(struct monst *mon, int dx, int dy, int range) { coord mc, cc; - wakeup(mon, !gc.context.mon_moving); + wakeup(mon, !svc.context.mon_moving); /* At the very least, debilitate the monster */ mon->movement = 0; mon->mstun = 1; @@ -1397,8 +1397,8 @@ toss_up(struct obj *obj, boolean hitsroof) && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { petrify: - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "elementary physics"); /* what goes up... */ + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "elementary physics"); /* what goes up... */ You("turn to stone."); if (obj) dropy(obj); /* bypass most of hitfloor() */ @@ -1818,8 +1818,8 @@ return_throw_to_inv( /* if 'obj' is from a stack split, we can put it back by undoing split so there's no chance of merging with some other compatible stack */ - if (obj->o_id == gc.context.objsplit.parent_oid - || obj->o_id == gc.context.objsplit.child_oid) { + if (obj->o_id == svc.context.objsplit.parent_oid + || obj->o_id == svc.context.objsplit.child_oid) { obj->nobj = gi.invent; gi.invent = obj; obj->where = OBJ_INVENT; @@ -1925,7 +1925,7 @@ tmiss(struct obj *obj, struct monst *mon, boolean maybe_wakeup) #define special_obj_hits_leader(obj, mon) \ ((is_quest_artifact(obj) || objects[obj->otyp].oc_unique \ || (obj->otyp == FAKE_AMULET_OF_YENDOR && !obj->known)) \ - && mon->m_id == gq.quest_status.leader_m_id) + && mon->m_id == svq.quest_status.leader_m_id) /* whether or not object should be destroyed when it hits its target */ boolean @@ -1944,7 +1944,7 @@ should_mulch_missile(struct obj *obj) around longer on average. */ chance = 3 + greatest_erosion(obj) - obj->spe; broken = chance > 1 ? rn2(chance) : !rn2(4); - if (obj->blessed && (gc.context.mon_moving ? !rn2(3) : !rnl(4))) + if (obj->blessed && (svc.context.mon_moving ? !rn2(3) : !rnl(4))) broken = FALSE; /* Flint and hard gems don't break easily */ @@ -2614,8 +2614,8 @@ throw_gold(struct obj *obj) You("cannot throw gold at yourself."); /* If we tried to throw part of a stack, force it to merge back together (same as in throw_obj). Essential for gold. */ - if (obj->o_id == gc.context.objsplit.parent_oid - || obj->o_id == gc.context.objsplit.child_oid) + if (obj->o_id == svc.context.objsplit.parent_oid + || obj->o_id == svc.context.objsplit.child_oid) (void) unsplitobj(obj); return ECMD_CANCEL; } diff --git a/src/dungeon.c b/src/dungeon.c index 8b3730bfd..06f27d379 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -85,7 +85,7 @@ staticfn void dumpit(void); staticfn void dumpit(void) { -#define DD gd.dungeons[i] +#define DD svd.dungeons[i] int i; s_level *x; branch *br; @@ -93,7 +93,7 @@ dumpit(void) if (!explicitdebug(__FILE__)) return; - for (i = 0; i < gn.n_dgns; i++) { + for (i = 0; i < svn.n_dgns; i++) { fprintf(stderr, "\n#%d \"%s\" (%s):\n", i, DD.dname, DD.proto); fprintf(stderr, " num_dunlevs %d, dunlev_ureached %d\n", DD.num_dunlevs, DD.dunlev_ureached); @@ -106,7 +106,7 @@ dumpit(void) (void) getchar(); } fprintf(stderr, "\nSpecial levels:\n"); - for (x = gs.sp_levchn; x; x = x->next) { + for (x = svs.sp_levchn; x; x = x->next) { fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs); fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel); fprintf(stderr, "flags:%s%s%s%s\n", @@ -117,7 +117,7 @@ dumpit(void) (void) getchar(); } fprintf(stderr, "\nBranches:\n"); - for (br = gb.branches; br; br = br->next) { + for (br = svb.branches; br; br = br->next) { fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n", br->id, br->type == BR_STAIR ? "stair" @@ -152,48 +152,48 @@ save_dungeon( if (perform_write) { if(nhfp->structlevel) { - bwrite(nhfp->fd, (genericptr_t) &gn.n_dgns, sizeof gn.n_dgns); - bwrite(nhfp->fd, (genericptr_t) gd.dungeons, - sizeof(dungeon) * (unsigned) gn.n_dgns); - bwrite(nhfp->fd, (genericptr_t) &gd.dungeon_topology, - sizeof gd.dungeon_topology); - bwrite(nhfp->fd, (genericptr_t) gt.tune, sizeof tune); + bwrite(nhfp->fd, (genericptr_t) &svn.n_dgns, sizeof svn.n_dgns); + bwrite(nhfp->fd, (genericptr_t) svd.dungeons, + sizeof(dungeon) * (unsigned) svn.n_dgns); + bwrite(nhfp->fd, (genericptr_t) &svd.dungeon_topology, + sizeof svd.dungeon_topology); + bwrite(nhfp->fd, (genericptr_t) svt.tune, sizeof tune); } - for (count = 0, curr = gb.branches; curr; curr = curr->next) + for (count = 0, curr = svb.branches; curr; curr = curr->next) count++; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); - for (curr = gb.branches; curr; curr = curr->next) { + for (curr = svb.branches; curr; curr = curr->next) { if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) curr, sizeof *curr); } count = maxledgerno(); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); - bwrite(nhfp->fd, (genericptr_t) gl.level_info, + bwrite(nhfp->fd, (genericptr_t) svl.level_info, (unsigned) count * sizeof (struct linfo)); - bwrite(nhfp->fd, (genericptr_t) &gi.inv_pos, sizeof gi.inv_pos); + bwrite(nhfp->fd, (genericptr_t) &svi.inv_pos, sizeof svi.inv_pos); } - for (count = 0, curr_ms = gm.mapseenchn; curr_ms; + for (count = 0, curr_ms = svm.mapseenchn; curr_ms; curr_ms = curr_ms->next) count++; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &count, sizeof count); - for (curr_ms = gm.mapseenchn; curr_ms; curr_ms = curr_ms->next) { + for (curr_ms = svm.mapseenchn; curr_ms; curr_ms = curr_ms->next) { save_mapseen(nhfp, curr_ms); } } if (free_data) { - for (curr = gb.branches; curr; curr = next) { + for (curr = svb.branches; curr; curr = next) { next = curr->next; free((genericptr_t) curr); } - gb.branches = 0; - for (curr_ms = gm.mapseenchn; curr_ms; curr_ms = next_ms) { + svb.branches = 0; + for (curr_ms = svm.mapseenchn; curr_ms; curr_ms = next_ms) { next_ms = curr_ms->next; if (curr_ms->custom) free((genericptr_t) curr_ms->custom); @@ -201,7 +201,7 @@ save_dungeon( savecemetery(nhfp, &curr_ms->final_resting_place); free((genericptr_t) curr_ms); } - gm.mapseenchn = 0; + svm.mapseenchn = 0; } } @@ -214,14 +214,14 @@ restore_dungeon(NHFILE *nhfp) mapseen *curr_ms, *last_ms; if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t) &gn.n_dgns, sizeof gn.n_dgns); - mread(nhfp->fd, (genericptr_t) gd.dungeons, - sizeof (dungeon) * (unsigned) gn.n_dgns); - mread(nhfp->fd, (genericptr_t) &gd.dungeon_topology, - sizeof gd.dungeon_topology); - mread(nhfp->fd, (genericptr_t) gt.tune, sizeof tune); + mread(nhfp->fd, (genericptr_t) &svn.n_dgns, sizeof svn.n_dgns); + mread(nhfp->fd, (genericptr_t) svd.dungeons, + sizeof (dungeon) * (unsigned) svn.n_dgns); + mread(nhfp->fd, (genericptr_t) &svd.dungeon_topology, + sizeof svd.dungeon_topology); + mread(nhfp->fd, (genericptr_t) svt.tune, sizeof tune); } - last = gb.branches = (branch *) 0; + last = svb.branches = (branch *) 0; if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) &count, sizeof count); @@ -234,7 +234,7 @@ restore_dungeon(NHFILE *nhfp) if (last) last->next = curr; else - gb.branches = curr; + svb.branches = curr; last = curr; } @@ -245,11 +245,11 @@ restore_dungeon(NHFILE *nhfp) panic("level information count larger (%d) than allocated size", count); if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) gl.level_info, + mread(nhfp->fd, (genericptr_t) svl.level_info, (unsigned) count * sizeof (struct linfo)); if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t) &gi.inv_pos, sizeof gi.inv_pos); + mread(nhfp->fd, (genericptr_t) &svi.inv_pos, sizeof svi.inv_pos); mread(nhfp->fd, (genericptr_t) &count, sizeof count); } @@ -260,7 +260,7 @@ restore_dungeon(NHFILE *nhfp) if (last_ms) last_ms->next = curr_ms; else - gm.mapseenchn = curr_ms; + svm.mapseenchn = curr_ms; last_ms = curr_ms; } } @@ -287,8 +287,8 @@ dname_to_dnum(const char *s) { xint16 i; - for (i = 0; i < gn.n_dgns; i++) - if (!strcmp(gd.dungeons[i].dname, s)) + for (i = 0; i < svn.n_dgns; i++) + if (!strcmp(svd.dungeons[i].dname, s)) return i; panic("Couldn't resolve dungeon number for name \"%s\".", s); @@ -302,7 +302,7 @@ s_level * find_level(const char *s) { s_level *curr; - for (curr = gs.sp_levchn; curr; curr = curr->next) + for (curr = svs.sp_levchn; curr; curr = curr->next) if (!strcmpi(s, curr->proto)) break; return curr; @@ -327,8 +327,8 @@ find_branch( branch *br; const char *dnam; - for (br = gb.branches; br; br = br->next) { - dnam = gd.dungeons[br->end2.dnum].dname; + for (br = svb.branches; br; br = br->next) { + dnam = svd.dungeons[br->end2.dnum].dname; if (!strcmpi(dnam, s) || (!strncmpi(dnam, "The ", 4) && !strcmpi(dnam + 4, s))) break; @@ -385,7 +385,7 @@ level_range( struct proto_dungeon *pd, int *adjusted_base) { - int lmax = gd.dungeons[dgn].num_dunlevs; + int lmax = svd.dungeons[dgn].num_dunlevs; if (chain >= 0) { /* relative to a special level */ s_level *levtmp = pd->final_lev[chain]; @@ -429,7 +429,7 @@ parent_dlevel(const char *s, struct proto_dungeon *pd) do { if (++i >= num) i = 0; - for (curr = gb.branches; curr; curr = curr->next) + for (curr = svb.branches; curr; curr = curr->next) if ((curr->end1.dnum == dnum && curr->end1.dlevel == base + i) || (curr->end2.dnum == dnum && curr->end2.dlevel == base + i)) break; @@ -468,7 +468,7 @@ insert_branch(branch *new_branch, boolean extract_first) long new_val, curr_val, prev_val; if (extract_first) { - for (prev = 0, curr = gb.branches; curr; + for (prev = 0, curr = svb.branches; curr; prev = curr, curr = curr->next) if (curr == new_branch) break; @@ -478,7 +478,7 @@ insert_branch(branch *new_branch, boolean extract_first) if (prev) prev->next = curr->next; else - gb.branches = curr->next; + svb.branches = curr->next; } new_branch->next = (branch *) 0; @@ -494,7 +494,7 @@ insert_branch(branch *new_branch, boolean extract_first) prev = (branch *) 0; prev_val = -1; new_val = branch_val(new_branch); - for (curr = gb.branches; curr; + for (curr = svb.branches; curr; prev_val = curr_val, prev = curr, curr = curr->next) { curr_val = branch_val(curr); if (prev_val < new_val && new_val <= curr_val) @@ -504,8 +504,8 @@ insert_branch(branch *new_branch, boolean extract_first) new_branch->next = curr; prev->next = new_branch; } else { - new_branch->next = gb.branches; - gb.branches = new_branch; + new_branch->next = svb.branches; + svb.branches = new_branch; } } @@ -521,14 +521,14 @@ add_branch( int branch_num; branch *new_branch; - branch_num = find_branch(gd.dungeons[dgn].dname, pd); + branch_num = find_branch(svd.dungeons[dgn].dname, pd); new_branch = (branch *) alloc(sizeof(branch)); (void) memset((genericptr_t) new_branch, 0, sizeof(branch)); new_branch->next = (branch *) 0; new_branch->id = branch_id++; new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]); - new_branch->end1.dnum = parent_dnum(gd.dungeons[dgn].dname, pd); - new_branch->end1.dlevel = parent_dlevel(gd.dungeons[dgn].dname, pd); + new_branch->end1.dnum = parent_dnum(svd.dungeons[dgn].dname, pd); + new_branch->end1.dlevel = parent_dlevel(svd.dungeons[dgn].dname, pd); new_branch->end2.dnum = dgn; new_branch->end2.dlevel = child_entry_level; new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE; @@ -549,15 +549,15 @@ add_level(s_level *new_lev) s_level *prev, *curr; prev = (s_level *) 0; - for (curr = gs.sp_levchn; curr; curr = curr->next) { + for (curr = svs.sp_levchn; curr; curr = curr->next) { if (curr->dlevel.dnum == new_lev->dlevel.dnum && curr->dlevel.dlevel > new_lev->dlevel.dlevel) break; prev = curr; } if (!prev) { - new_lev->next = gs.sp_levchn; - gs.sp_levchn = new_lev; + new_lev->next = svs.sp_levchn; + svs.sp_levchn = new_lev; } else { new_lev->next = curr; prev->next = new_lev; @@ -945,16 +945,16 @@ init_dungeon_set_entry(struct proto_dungeon *pd, int dngidx) * redundant. It is used only here and in print_dungeon(). */ if (dgn_entry < 0) { - gd.dungeons[dngidx].entry_lev = - gd.dungeons[dngidx].num_dunlevs + dgn_entry + 1; - if (gd.dungeons[dngidx].entry_lev <= 0) - gd.dungeons[dngidx].entry_lev = 1; + svd.dungeons[dngidx].entry_lev = + svd.dungeons[dngidx].num_dunlevs + dgn_entry + 1; + if (svd.dungeons[dngidx].entry_lev <= 0) + svd.dungeons[dngidx].entry_lev = 1; } else if (dgn_entry > 0) { - gd.dungeons[dngidx].entry_lev = dgn_entry; - if (gd.dungeons[dngidx].entry_lev > gd.dungeons[dngidx].num_dunlevs) - gd.dungeons[dngidx].entry_lev = gd.dungeons[dngidx].num_dunlevs; + svd.dungeons[dngidx].entry_lev = dgn_entry; + if (svd.dungeons[dngidx].entry_lev > svd.dungeons[dngidx].num_dunlevs) + svd.dungeons[dngidx].entry_lev = svd.dungeons[dngidx].num_dunlevs; } else { /* default */ - gd.dungeons[dngidx].entry_lev = 1; /* defaults to top level */ + svd.dungeons[dngidx].entry_lev = 1; /* defaults to top level */ } } @@ -965,7 +965,7 @@ init_dungeon_set_depth(struct proto_dungeon *pd, int dngidx) schar from_depth; boolean from_up; - br = add_branch(dngidx, gd.dungeons[dngidx].entry_lev, pd); + br = add_branch(dngidx, svd.dungeons[dngidx].entry_lev, pd); /* Get the depth of the connecting end. */ if (br->end1.dnum == dngidx) { @@ -990,9 +990,9 @@ init_dungeon_set_depth(struct proto_dungeon *pd, int dngidx) * * We'll say that portals stay on the same depth. */ - gd.dungeons[dngidx].depth_start = + svd.dungeons[dngidx].depth_start = from_depth + (br->type == BR_PORTAL ? 0 : (from_up ? -1 : 1)) - - (gd.dungeons[dngidx].entry_lev - 1); + - (svd.dungeons[dngidx].entry_lev - 1); } staticfn boolean @@ -1022,7 +1022,7 @@ init_dungeon_dungeons( if (!wizard && dgn_chance && (dgn_chance <= rn2(100))) { debugpline1("IGNORING %s", dgn_name); - gn.n_dgns--; + svn.n_dgns--; free((genericptr_t) dgn_name); free((genericptr_t) dgn_bonetag); free((genericptr_t) dgn_protoname); @@ -1059,47 +1059,47 @@ init_dungeon_dungeons( pd->tmpdungeon[dngidx].chance = dgn_chance; pd->tmpdungeon[dngidx].entry_lev = dgn_entry; - Strcpy(gd.dungeons[dngidx].fill_lvl, dgn_fill); /* FIXME: fill_lvl len */ - Strcpy(gd.dungeons[dngidx].dname, dgn_name); /* FIXME: dname length */ - Strcpy(gd.dungeons[dngidx].proto, dgn_protoname); /* FIXME: proto length */ - Strcpy(gd.dungeons[dngidx].themerms, dgn_themerms); /* FIXME: length */ - gd.dungeons[dngidx].boneid = *dgn_bonetag ? *dgn_bonetag : 0; + Strcpy(svd.dungeons[dngidx].fill_lvl, dgn_fill); /* FIXME: fill_lvl len */ + Strcpy(svd.dungeons[dngidx].dname, dgn_name); /* FIXME: dname length */ + Strcpy(svd.dungeons[dngidx].proto, dgn_protoname); /* FIXME: proto length */ + Strcpy(svd.dungeons[dngidx].themerms, dgn_themerms); /* FIXME: length */ + svd.dungeons[dngidx].boneid = *dgn_bonetag ? *dgn_bonetag : 0; free((genericptr) dgn_fill); /* free((genericptr) dgn_protoname); -- stored in pd.tmpdungeon[] */ free((genericptr) dgn_bonetag); free((genericptr) dgn_themerms); if (dgn_range) - gd.dungeons[dngidx].num_dunlevs = (xint16) rn1(dgn_range, dgn_base); + svd.dungeons[dngidx].num_dunlevs = (xint16) rn1(dgn_range, dgn_base); else - gd.dungeons[dngidx].num_dunlevs = (xint16) dgn_base; + svd.dungeons[dngidx].num_dunlevs = (xint16) dgn_base; if (!dngidx) { - gd.dungeons[dngidx].ledger_start = 0; - gd.dungeons[dngidx].depth_start = 1; - gd.dungeons[dngidx].dunlev_ureached = 1; + svd.dungeons[dngidx].ledger_start = 0; + svd.dungeons[dngidx].depth_start = 1; + svd.dungeons[dngidx].dunlev_ureached = 1; } else { - gd.dungeons[dngidx].ledger_start = gd.dungeons[dngidx - 1].ledger_start - + gd.dungeons[dngidx - 1].num_dunlevs; - gd.dungeons[dngidx].dunlev_ureached = 0; + svd.dungeons[dngidx].ledger_start = svd.dungeons[dngidx - 1].ledger_start + + svd.dungeons[dngidx - 1].num_dunlevs; + svd.dungeons[dngidx].dunlev_ureached = 0; } - gd.dungeons[dngidx].flags.hellish = !!(dgn_flags & HELLISH); - gd.dungeons[dngidx].flags.maze_like = !!(dgn_flags & MAZELIKE); - gd.dungeons[dngidx].flags.rogue_like = !!(dgn_flags & ROGUELIKE); - gd.dungeons[dngidx].flags.align = dgn_align; - gd.dungeons[dngidx].flags.unconnected = !!(dgn_flags & UNCONNECTED); + svd.dungeons[dngidx].flags.hellish = !!(dgn_flags & HELLISH); + svd.dungeons[dngidx].flags.maze_like = !!(dgn_flags & MAZELIKE); + svd.dungeons[dngidx].flags.rogue_like = !!(dgn_flags & ROGUELIKE); + svd.dungeons[dngidx].flags.align = dgn_align; + svd.dungeons[dngidx].flags.unconnected = !!(dgn_flags & UNCONNECTED); init_dungeon_set_entry(pd, dngidx); - if (gd.dungeons[dngidx].flags.unconnected) { - gd.dungeons[dngidx].depth_start = 1; + if (svd.dungeons[dngidx].flags.unconnected) { + svd.dungeons[dngidx].depth_start = 1; } else if (dngidx) { /* set depth */ init_dungeon_set_depth(pd, dngidx); } - if (gd.dungeons[dngidx].num_dunlevs > MAXLEVEL) - gd.dungeons[dngidx].num_dunlevs = MAXLEVEL; + if (svd.dungeons[dngidx].num_dunlevs > MAXLEVEL) + svd.dungeons[dngidx].num_dunlevs = MAXLEVEL; return TRUE; } @@ -1111,8 +1111,8 @@ init_castle_tune(void) int i; for (i = 0; i < 5; i++) - gt.tune[i] = 'A' + rn2(7); - gt.tune[5] = 0; + svt.tune[i] = 'A' + rn2(7); + svt.tune[5] = 0; } /* fix up the special level names and locations for quick access */ @@ -1144,12 +1144,12 @@ fixup_level_locations(void) * specify a floating entrance by the fact that its * entrance (end1) has a bogus dnum, namely n_dgns. */ - for (br = gb.branches; br; br = br->next) + for (br = svb.branches; br; br = br->next) if (on_level(&br->end2, &knox_level)) break; if (br) - br->end1.dnum = gn.n_dgns; + br->end1.dnum = svn.n_dgns; /* adjust the branch's position on the list */ insert_branch(br, TRUE); } @@ -1171,8 +1171,8 @@ fixup_level_locations(void) making the dummy level overlay level 1; but the whole reason for having the dummy level is to make earth have depth -1 instead of 0, so adjust the start point to shift endgame up */ - if (dunlevs_in_dungeon(&x->dlevel) > 1 - gd.dungeons[i].depth_start) - gd.dungeons[i].depth_start -= 1; + if (dunlevs_in_dungeon(&x->dlevel) > 1 - svd.dungeons[i].depth_start) + svd.dungeons[i].depth_start -= 1; /* TODO: strip "dummy" out all the way here, so that it's hidden from '#wizwhere' feedback. */ } @@ -1191,7 +1191,7 @@ free_proto_dungeon(struct proto_dungeon *pd) if (pd->tmplevel[i].chainlvl) free((genericptr_t) pd->tmplevel[i].chainlvl); } - for (i = 0; i < gn.n_dgns; i++) { + for (i = 0; i < svn.n_dgns; i++) { free((genericptr_t) pd->tmpdungeon[i].name); free((genericptr_t) pd->tmpdungeon[i].protoname); } @@ -1244,7 +1244,7 @@ init_dungeons(void) if (iflags.window_inited) clear_nhwindow(WIN_MAP); - gs.sp_levchn = (s_level *) 0; + svs.sp_levchn = (s_level *) 0; lua_settop(L, 0); @@ -1253,7 +1253,7 @@ init_dungeons(void) panic("dungeon is not a lua table"); lua_len(L, -1); - gn.n_dgns = (int) lua_tointeger(L, -1); + svn.n_dgns = (int) lua_tointeger(L, -1); lua_pop(L, 1); pd.start = 0; @@ -1265,7 +1265,7 @@ init_dungeons(void) * dungeon arrays. */ - if (gn.n_dgns >= MAXDUNGEON) + if (svn.n_dgns >= MAXDUNGEON) panic("init_dungeons: too many dungeons"); tidx = lua_gettop(L); @@ -1328,7 +1328,7 @@ dunlev(d_level *lev) xint16 dunlevs_in_dungeon(d_level *lev) { - return gd.dungeons[lev->dnum].num_dunlevs; + return svd.dungeons[lev->dnum].num_dunlevs; } /* return the lowest level explored in the game*/ @@ -1354,10 +1354,10 @@ deepest_lev_reached(boolean noquest) d_level tmp; xint16 ret = 0; - for (i = 0; i < gn.n_dgns; i++) { + for (i = 0; i < svn.n_dgns; i++) { if (noquest && i == quest_dnum) continue; - tmp.dlevel = gd.dungeons[i].dunlev_ureached; + tmp.dlevel = svd.dungeons[i].dunlev_ureached; if (tmp.dlevel == 0) continue; tmp.dnum = i; @@ -1372,12 +1372,12 @@ deepest_lev_reached(boolean noquest) xint16 ledger_no(d_level *lev) { - return (xint16) (lev->dlevel + gd.dungeons[lev->dnum].ledger_start); + return (xint16) (lev->dlevel + svd.dungeons[lev->dnum].ledger_start); } /* * The last level in the bookkeeping list of level is the bottom of the last - * dungeon in the gd.dungeons[] array. + * dungeon in the svd.dungeons[] array. * * Maxledgerno() -- which is the max number of levels in the bookkeeping * list, should not be confused with dunlevs_in_dungeon(lev) -- which @@ -1388,8 +1388,8 @@ ledger_no(d_level *lev) xint16 maxledgerno(void) { - return (xint16) (gd.dungeons[gn.n_dgns - 1].ledger_start - + gd.dungeons[gn.n_dgns - 1].num_dunlevs); + return (xint16) (svd.dungeons[svn.n_dgns - 1].ledger_start + + svd.dungeons[svn.n_dgns - 1].num_dunlevs); } DISABLE_WARNING_UNREACHABLE_CODE @@ -1401,10 +1401,10 @@ ledger_to_dnum(xint16 ledgerno) xint16 i; /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */ - for (i = 0; i < gn.n_dgns; i++) - if (gd.dungeons[i].ledger_start < ledgerno + for (i = 0; i < svn.n_dgns; i++) + if (svd.dungeons[i].ledger_start < ledgerno && (ledgerno - <= gd.dungeons[i].ledger_start + gd.dungeons[i].num_dunlevs)) + <= svd.dungeons[i].ledger_start + svd.dungeons[i].num_dunlevs)) return i; panic("level number out of range [ledger_to_dnum(%d)]", (int) ledgerno); @@ -1419,7 +1419,7 @@ xint16 ledger_to_dlev(xint16 ledgerno) { return (xint16) (ledgerno - - gd.dungeons[ledger_to_dnum(ledgerno)].ledger_start); + - svd.dungeons[ledger_to_dnum(ledgerno)].ledger_start); } /* returns the depth of a level, in floors below the surface @@ -1427,7 +1427,7 @@ ledger_to_dlev(xint16 ledgerno) schar depth(d_level *lev) { - return (schar) (gd.dungeons[lev->dnum].depth_start + lev->dlevel - 1); + return (schar) (svd.dungeons[lev->dnum].depth_start + lev->dlevel - 1); } /* are "lev1" and "lev2" actually the same? */ @@ -1444,7 +1444,7 @@ Is_special(d_level *lev) { s_level *levtmp; - for (levtmp = gs.sp_levchn; levtmp; levtmp = levtmp->next) + for (levtmp = svs.sp_levchn; levtmp; levtmp = levtmp->next) if (on_level(lev, &levtmp->dlevel)) return levtmp; @@ -1460,7 +1460,7 @@ Is_branchlev(d_level *lev) { branch *curr; - for (curr = gb.branches; curr; curr = curr->next) { + for (curr = svb.branches; curr; curr = curr->next) { if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2)) return curr; } @@ -1471,14 +1471,14 @@ Is_branchlev(d_level *lev) boolean builds_up(d_level *lev) { - dungeon *dptr = &gd.dungeons[lev->dnum]; + dungeon *dptr = &svd.dungeons[lev->dnum]; branch *br; if (dptr->num_dunlevs > 1) return (boolean) (dptr->entry_lev == dptr->num_dunlevs); /* else, single-level branch; find the branch connection that connects this * dungeon from a parent dungeon and determine whether it builds up from * that */ - for (br = gb.branches; br; br = br->next) { + for (br = svb.branches; br; br = br->next) { if (on_level(lev, &br->end2)) { return br->end1_up; } @@ -1583,20 +1583,20 @@ u_on_rndspot(int upflag) destination instead of its enclosing region. Note: up vs down doesn't matter in this case because both specify the same exclusion area. */ - place_lregion(gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy, + place_lregion(svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy, 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0); else if (up) - place_lregion(gu.updest.lx, gu.updest.ly, - gu.updest.hx, gu.updest.hy, - gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy, + place_lregion(svu.updest.lx, svu.updest.ly, + svu.updest.hx, svu.updest.hy, + svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy, LR_UPTELE, (d_level *) 0); else - place_lregion(gd.dndest.lx, gd.dndest.ly, - gd.dndest.hx, gd.dndest.hy, - gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy, + place_lregion(svd.dndest.lx, svd.dndest.ly, + svd.dndest.hx, svd.dndest.hy, + svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy, LR_DOWNTELE, (d_level *) 0); /* might have just left solid rock and unblocked levitation */ @@ -1606,13 +1606,13 @@ u_on_rndspot(int upflag) boolean Is_botlevel(d_level *lev) { - return (boolean) (lev->dlevel == gd.dungeons[lev->dnum].num_dunlevs); + return (boolean) (lev->dlevel == svd.dungeons[lev->dnum].num_dunlevs); } boolean Can_dig_down(d_level *lev) { - return (boolean) (!gl.level.flags.hardfloor + return (boolean) (!svl.level.flags.hardfloor && !Is_botlevel(lev) && !Invocation_lev(lev)); } @@ -1645,7 +1645,7 @@ Can_rise_up(coordxy x, coordxy y, d_level *lev) || (Is_wiz1_level(lev) && In_W_tower(x, y, lev))) return FALSE; return (boolean) (lev->dlevel > 1 - || (gd.dungeons[lev->dnum].entry_lev == 1 + || (svd.dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 && stway && stway->up)); } @@ -1771,10 +1771,10 @@ get_level(d_level *newlevel, int levnum) if (levnum <= 0) { /* can only currently happen in endgame */ levnum = u.uz.dlevel; - } else if (levnum > (gd.dungeons[dgn].depth_start - + gd.dungeons[dgn].num_dunlevs - 1)) { + } else if (levnum > (svd.dungeons[dgn].depth_start + + svd.dungeons[dgn].num_dunlevs - 1)) { /* beyond end of dungeon, jump to last level */ - levnum = gd.dungeons[dgn].num_dunlevs; + levnum = svd.dungeons[dgn].num_dunlevs; } else { /* The desired level is in this dungeon or a "higher" one. */ @@ -1782,7 +1782,7 @@ get_level(d_level *newlevel, int levnum) * Branch up the tree until we reach a dungeon that contains the * levnum. */ - if (levnum < gd.dungeons[dgn].depth_start) { + if (levnum < svd.dungeons[dgn].depth_start) { do { /* * Find the parent dungeon of this dungeon. @@ -1790,18 +1790,18 @@ get_level(d_level *newlevel, int levnum) * This assumes that end2 is always the "child" and it is * unique. */ - for (br = gb.branches; br; br = br->next) + for (br = svb.branches; br; br = br->next) if (br->end2.dnum == dgn) break; if (!br) panic("get_level: can't find parent dungeon"); dgn = br->end1.dnum; - } while (levnum < gd.dungeons[dgn].depth_start); + } while (levnum < svd.dungeons[dgn].depth_start); } /* We're within the same dungeon; calculate the level. */ - levnum = levnum - gd.dungeons[dgn].depth_start + 1; + levnum = levnum - svd.dungeons[dgn].depth_start + 1; } newlevel->dnum = dgn; @@ -1839,7 +1839,7 @@ dungeon_branch(const char *s) dnum = dname_to_dnum(s); /* Find the branch that connects to dungeon i's branch. */ - for (br = gb.branches; br; br = br->next) + for (br = svb.branches; br; br = br->next) if (br->end2.dnum == dnum) break; @@ -1888,24 +1888,24 @@ In_W_tower(coordxy x, coordxy y, d_level *lev) { if (!On_W_tower_level(lev)) return FALSE; - if (!gd.dndest.nlx) { + if (!svd.dndest.nlx) { impossible("No boundary for Wizard's Tower?"); return FALSE; } /* * Both of the exclusion regions for arriving via level teleport * (from above or below) define the tower's boundary. - * assert( gu.updest.nIJ == gd.dndest.nIJ for I={l|h},J={x|y} ); + * assert( svu.updest.nIJ == svd.dndest.nIJ for I={l|h},J={x|y} ); */ - return (boolean) within_bounded_area(x, y, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy); + return (boolean) within_bounded_area(x, y, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy); } /* are you in one of the Hell levels? */ boolean In_hell(d_level *lev) { - return (boolean) (gd.dungeons[lev->dnum].flags.hellish); + return (boolean) (svd.dungeons[lev->dnum].flags.hellish); } /* sets *lev to be the gateway to Gehennom... */ @@ -1969,9 +1969,9 @@ induced_align(int pct) if (rn2(100) < pct) return lev->flags.align; - if (gd.dungeons[u.uz.dnum].flags.align) + if (svd.dungeons[u.uz.dnum].flags.align) if (rn2(100) < pct) - return gd.dungeons[u.uz.dnum].flags.align; + return svd.dungeons[u.uz.dnum].flags.align; al = rn2(3) - 1; return Align2amask(al); @@ -1981,7 +1981,7 @@ boolean Invocation_lev(d_level *lev) { return (boolean) (In_hell(lev) - && lev->dlevel == gd.dungeons[lev->dnum].num_dunlevs - 1); + && lev->dlevel == svd.dungeons[lev->dnum].num_dunlevs - 1); } /* use instead of depth() wherever a degree of difficulty is made @@ -2004,7 +2004,7 @@ level_difficulty(void) they were easier; adjust for the extra effort involved in going down to the entrance and then up to the location */ if (builds_up(&u.uz)) - res += 2 * (gd.dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1); + res += 2 * (svd.dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1); /* * 'Proof' by example: suppose the entrance to sokoban is * on dungeon level 9, leading up to bottom sokoban level @@ -2104,7 +2104,7 @@ lev_by_name(const char *nam) /* either wizard mode or else seen and not forgotten; note: used to be '(flags & (FORGOTTEN|VISITED)) == VISITED' back when amnesia could cause levels to be forgotten */ - && (wizard || (gl.level_info[idx].flags & (VISITED)) == VISITED)) { + && (wizard || (svl.level_info[idx].flags & (VISITED)) == VISITED)) { lev = depth(&dlev); } } else { /* not a specific level; try branch names */ @@ -2117,8 +2117,8 @@ lev_by_name(const char *nam) idxtoo = (idx >> 8) & 0x00FF; idx &= 0x00FF; /* either wizard mode, or else _both_ sides of branch seen */ - if (wizard || (((gl.level_info[idx].flags & (VISITED)) == VISITED) - && ((gl.level_info[idxtoo].flags & (VISITED)) + if (wizard || (((svl.level_info[idx].flags & (VISITED)) == VISITED) + && ((svl.level_info[idxtoo].flags & (VISITED)) == VISITED))) { if (ledger_to_dnum(idxtoo) == u.uz.dnum) idx = idxtoo; @@ -2138,13 +2138,13 @@ staticfn boolean unplaced_floater(struct dungeon *dptr) { branch *br; - int idx = (int) (dptr - gd.dungeons); + int idx = (int) (dptr - svd.dungeons); /* if other floating branches are added, this will need to change */ if (idx != knox_level.dnum) return FALSE; - for (br = gb.branches; br; br = br->next) - if (br->end1.dnum == gn.n_dgns && br->end2.dnum == idx) + for (br = svb.branches; br; br = br->next) + if (br->end1.dnum == svn.n_dgns && br->end2.dnum == idx) return TRUE; return FALSE; } @@ -2232,13 +2232,13 @@ print_branch( char buf[BUFSZ]; /* This assumes that end1 is the "parent". */ - for (br = gb.branches; br; br = br->next) { + for (br = svb.branches; br; br = br->next) { if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel && br->end1.dlevel <= upper_bound) { Sprintf(buf, "%c %s to %s: %d", bymenu ? chr_u_on_lvl(&br->end1) : ' ', br_string(br->type), - gd.dungeons[br->end2.dnum].dname, depth(&br->end1)); + svd.dungeons[br->end2.dnum].dname, depth(&br->end1)); if (bymenu) tport_menu(win, buf, lchoices_p, &br->end1, unreachable_level(&br->end1, FALSE)); @@ -2268,7 +2268,7 @@ print_dungeon(boolean bymenu, schar *rlev, xint16 *rdgn) lchoices.menuletter = 'a'; } - for (i = 0, dptr = gd.dungeons; i < gn.n_dgns; i++, dptr++) { + for (i = 0, dptr = svd.dungeons; i < svn.n_dgns; i++, dptr++) { if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum) continue; unplaced = unplaced_floater(dptr); @@ -2299,7 +2299,7 @@ print_dungeon(boolean bymenu, schar *rlev, xint16 *rdgn) * Circle through the special levels to find levels that are in * this dungeon. */ - for (slev = gs.sp_levchn, last_level = 0; slev; slev = slev->next) { + for (slev = svs.sp_levchn, last_level = 0; slev; slev = slev->next) { if (slev->dlevel.dnum != i) continue; @@ -2311,7 +2311,7 @@ print_dungeon(boolean bymenu, schar *rlev, xint16 *rdgn) chr_u_on_lvl(&slev->dlevel), slev->proto, depth(&slev->dlevel)); if (Is_stronghold(&slev->dlevel)) - Sprintf(eos(buf), " (tune %s)", gt.tune); + Sprintf(eos(buf), " (tune %s)", svt.tune); if (bymenu) tport_menu(win, buf, &lchoices, &slev->dlevel, unreachable_level(&slev->dlevel, unplaced)); @@ -2345,15 +2345,15 @@ print_dungeon(boolean bymenu, schar *rlev, xint16 *rdgn) } /* Print out floating branches (if any). */ - for (first = TRUE, br = gb.branches; br; br = br->next) { - if (br->end1.dnum == gn.n_dgns) { + for (first = TRUE, br = svb.branches; br; br = br->next) { + if (br->end1.dnum == svn.n_dgns) { if (first) { putstr(win, 0, ""); putstr(win, 0, "Floating branches"); first = FALSE; } Sprintf(buf, " %s to %s", br_string(br->type), - gd.dungeons[br->end2.dnum].dname); + svd.dungeons[br->end2.dnum].dname); putstr(win, 0, buf); } } @@ -2362,7 +2362,7 @@ print_dungeon(boolean bymenu, schar *rlev, xint16 *rdgn) if (Invocation_lev(&u.uz)) { putstr(win, 0, ""); Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)", - gi.inv_pos.x, gi.inv_pos.y, u.ux, u.uy); + svi.inv_pos.x, svi.inv_pos.y, u.ux, u.uy); putstr(win, 0, buf); } else { struct trap *trap; @@ -2416,7 +2416,7 @@ recbranch_mapseen(d_level *source, d_level *dest) return; /* we only care about forward branches */ - for (br = gb.branches; br; br = br->next) { + for (br = svb.branches; br; br = br->next) { if (on_level(source, &br->end1) && on_level(dest, &br->end2)) break; if (on_level(source, &br->end2) && on_level(dest, &br->end1)) @@ -2539,7 +2539,7 @@ donamelevel(void) void free_exclusions(void) { - struct exclusion_zone *ez = ge.exclusion_zones; + struct exclusion_zone *ez = sve.exclusion_zones; while (ez) { struct exclusion_zone *nxtez = ez->next; @@ -2547,7 +2547,7 @@ free_exclusions(void) free(ez); ez = nxtez; } - ge.exclusion_zones = (struct exclusion_zone *) 0; + sve.exclusion_zones = (struct exclusion_zone *) 0; } void @@ -2556,13 +2556,13 @@ save_exclusions(NHFILE *nhfp) struct exclusion_zone *ez; int nez; - for (nez = 0, ez = ge.exclusion_zones; ez; ez = ez->next, ++nez) + for (nez = 0, ez = sve.exclusion_zones; ez; ez = ez->next, ++nez) ; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &nez, sizeof nez); - for (ez = ge.exclusion_zones; ez; ez = ez->next) { + for (ez = sve.exclusion_zones; ez; ez = ez->next) { if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &ez->zonetype, sizeof ez->zonetype); @@ -2592,8 +2592,8 @@ load_exclusions(NHFILE *nhfp) mread(nhfp->fd, (genericptr_t) &ez->hx, sizeof ez->hx); mread(nhfp->fd, (genericptr_t) &ez->hy, sizeof ez->hy); } - ez->next = ge.exclusion_zones; - ge.exclusion_zones = ez; + ez->next = sve.exclusion_zones; + sve.exclusion_zones = ez; } } @@ -2603,7 +2603,7 @@ find_mapseen(d_level *lev) { mapseen *mptr; - for (mptr = gm.mapseenchn; mptr; mptr = mptr->next) + for (mptr = svm.mapseenchn; mptr; mptr = mptr->next) if (on_level(&(mptr->lev), lev)) break; @@ -2615,7 +2615,7 @@ find_mapseen_by_str(const char *s) { mapseen *mptr; - for (mptr = gm.mapseenchn; mptr; mptr = mptr->next) + for (mptr = svm.mapseenchn; mptr; mptr = mptr->next) if (mptr->custom && !strcmpi(s, mptr->custom)) break; @@ -2629,8 +2629,8 @@ rm_mapseen(int ledger_num) mapseen *mptr, *mprev = (mapseen *) 0; struct cemetery *bp, *bpnext; - for (mptr = gm.mapseenchn; mptr; mprev = mptr, mptr = mptr->next) - if (gd.dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel + for (mptr = svm.mapseenchn; mptr; mprev = mptr, mptr = mptr->next) + if (svd.dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num) break; @@ -2651,7 +2651,7 @@ rm_mapseen(int ledger_num) mprev->next = mptr->next; free(mptr); } else { - gm.mapseenchn = mptr->next; + svm.mapseenchn = mptr->next; free(mptr); } } @@ -2662,7 +2662,7 @@ save_mapseen(NHFILE *nhfp, mapseen *mptr) branch *curr; int brindx; - for (brindx = 0, curr = gb.branches; curr; curr = curr->next, ++brindx) + for (brindx = 0, curr = svb.branches; curr; curr = curr->next, ++brindx) if (curr == mptr->br) break; if (nhfp->structlevel) @@ -2698,7 +2698,7 @@ load_mapseen(NHFILE *nhfp) if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) &branchnum, sizeof branchnum); - for (brindx = 0, curr = gb.branches; curr; curr = curr->next, ++brindx) + for (brindx = 0, curr = svb.branches; curr; curr = curr->next, ++brindx) if (brindx == branchnum) break; load->br = curr; @@ -2743,7 +2743,7 @@ overview_stats( mapseen *mptr = find_mapseen(&u.uz); ocount = bcount = acount = osize = bsize = asize = 0L; - for (mptr = gm.mapseenchn; mptr; mptr = mptr->next) { + for (mptr = svm.mapseenchn; mptr; mptr = mptr->next) { ++ocount; osize += (long) sizeof *mptr; for (ce = mptr->final_resting_place; ce; ce = ce->next) { @@ -2786,7 +2786,7 @@ remdun_mapseen(int dnum) { mapseen *mptr, **mptraddr; - mptraddr = &gm.mapseenchn; + mptraddr = &svm.mapseenchn; while ((mptr = *mptraddr) != 0) { if (mptr->lev.dnum == dnum) { #if 1 /* use this... */ @@ -2819,22 +2819,22 @@ init_mapseen(d_level *lev) explicitly initialize pointers to null */ init->next = 0, init->br = 0, init->custom = 0; init->final_resting_place = 0; - /* gl.lastseentyp[][] is reused for each level, so get rid of + /* svl.lastseentyp[][] is reused for each level, so get rid of previous level's data */ - (void) memset((genericptr_t) gl.lastseentyp, 0, sizeof gl.lastseentyp); + (void) memset((genericptr_t) svl.lastseentyp, 0, sizeof svl.lastseentyp); init->lev.dnum = lev->dnum; init->lev.dlevel = lev->dlevel; /* walk until we get to the place where we should insert init */ - for (mptr = gm.mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next) + for (mptr = svm.mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next) if (mptr->lev.dnum > init->lev.dnum || (mptr->lev.dnum == init->lev.dnum && mptr->lev.dlevel > init->lev.dlevel)) break; if (!prev) { - init->next = gm.mapseenchn; - gm.mapseenchn = init; + init->next = svm.mapseenchn; + svm.mapseenchn = init; } else { mptr = prev->next; prev->next = init; @@ -2891,7 +2891,7 @@ interest_mapseen(mapseen *mptr) && (mptr->flags.knownbones || wizard)) || mptr->custom || mptr->br || (mptr->lev.dlevel - == gd.dungeons[mptr->lev.dnum].dunlev_ureached)); + == svd.dungeons[mptr->lev.dnum].dunlev_ureached)); } /* update the lastseentyp at x,y */ @@ -2906,7 +2906,7 @@ update_lastseentyp(coordxy x, coordxy y) if ((mtmp = m_at(x, y)) != 0 && M_AP_TYPE(mtmp) == M_AP_FURNITURE && canseemon(mtmp)) ltyp = cmap_to_type(mtmp->mappearance); - gl.lastseentyp[x][y] = ltyp; + svl.lastseentyp[x][y] = ltyp; } /* for some cases where deferred update needs to be done immediately; @@ -2915,7 +2915,7 @@ int update_mapseen_for(coordxy x, coordxy y) { recalc_mapseen(); /* whole level */ - return gl.lastseentyp[x][y]; + return svl.lastseentyp[x][y]; } /* count mapseen feature from lastseentyp at x,y */ @@ -2927,7 +2927,7 @@ count_feat_lastseentyp( int count; unsigned atmp; - switch (gl.lastseentyp[x][y]) { + switch (svl.lastseentyp[x][y]) { #if 0 /* levels that have these tend of have a lot of them */ /* * FIXME? due to theme rooms, lots of levels have an increased @@ -3069,7 +3069,7 @@ recalc_mapseen(void) if (mptr->flags.unreachable) { mptr->flags.unreachable = 0; /* reached it; Eye of the Aethiopica? */ if (In_quest(&u.uz)) { - mapseen *mptrtmp = gm.mapseenchn; + mapseen *mptrtmp = svm.mapseenchn; /* when quest was unreachable due to ejection and portal removal, getting back to it via arti-invoke should revive annotation @@ -3098,9 +3098,9 @@ recalc_mapseen(void) && u.uevent.qcalled && !(u.uevent.qcompleted || u.uevent.qexpelled - || gq.quest_status.leader_is_dead)); + || svq.quest_status.leader_is_dead)); mptr->flags.questing = (on_level(&u.uz, &qstart_level) - && gq.quest_status.got_quest); + && svq.quest_status.got_quest); /* flags.msanctum, .valley, and .vibrating_square handled below */ /* track rooms the hero is in */ @@ -3108,9 +3108,9 @@ recalc_mapseen(void) ridx = (unsigned) uroom - ROOMOFFSET; mptr->msrooms[ridx].seen = 1; mptr->msrooms[ridx].untended = - (gr.rooms[ridx].rtype >= SHOPBASE) + (svr.rooms[ridx].rtype >= SHOPBASE) ? (!(mtmp = shop_keeper(uroom)) || !inhishop(mtmp)) - : (gr.rooms[ridx].rtype == TEMPLE) + : (svr.rooms[ridx].rtype == TEMPLE) ? (!(mtmp = findpriest(uroom)) || !inhistemple(mtmp)) : 0; } @@ -3120,28 +3120,28 @@ recalc_mapseen(void) */ for (i = 0; i < SIZE(mptr->msrooms); ++i) { if (mptr->msrooms[i].seen) { - if (gr.rooms[i].rtype >= SHOPBASE) { + if (svr.rooms[i].rtype >= SHOPBASE) { if (mptr->msrooms[i].untended) mptr->feat.shoptype = SHOPBASE - 1; else if (!mptr->feat.nshop) - mptr->feat.shoptype = gr.rooms[i].rtype; - else if (mptr->feat.shoptype != (unsigned) gr.rooms[i].rtype) + mptr->feat.shoptype = svr.rooms[i].rtype; + else if (mptr->feat.shoptype != (unsigned) svr.rooms[i].rtype) mptr->feat.shoptype = 0; count = mptr->feat.nshop + 1; if (count <= 3) mptr->feat.nshop = count; - } else if (gr.rooms[i].rtype == TEMPLE) { + } else if (svr.rooms[i].rtype == TEMPLE) { /* altar and temple alignment handled below */ count = mptr->feat.ntemple + 1; if (count <= 3) mptr->feat.ntemple = count; - } else if (gr.rooms[i].orig_rtype == DELPHI) { + } else if (svr.rooms[i].orig_rtype == DELPHI) { mptr->flags.oracle = 1; } } } - /* Update gl.lastseentyp with typ if and only if it is in sight or the + /* Update svl.lastseentyp with typ if and only if it is in sight or the * hero can feel it on their current location (i.e. not levitating). * This *should* give the "last known typ" for each dungeon location. * (At the very least, it's a better assumption than determining what @@ -3152,7 +3152,7 @@ recalc_mapseen(void) * we could track "features" and then update them all here, and keep * track of when new features are created or destroyed, but this * seemed the most elegant, despite adding more data to struct rm. - * [3.6.0: we're using gl.lastseentyp[][] rather than level.locations + * [3.6.0: we're using svl.lastseentyp[][] rather than level.locations * to track the features seen.] * * Although no current windowing systems (can) do this, this would add @@ -3208,11 +3208,11 @@ recalc_mapseen(void) || !oth_mptr->flags.msanctum); } - if (gl.level.bonesinfo && !mptr->final_resting_place) { + if (svl.level.bonesinfo && !mptr->final_resting_place) { /* clone the bonesinfo so we aren't dependent upon this level being in memory */ bonesaddr = &mptr->final_resting_place; - bp = gl.level.bonesinfo; + bp = svl.level.bonesinfo; do { *bonesaddr = (struct cemetery *) alloc(sizeof **bonesaddr); **bonesaddr = *bp; @@ -3225,7 +3225,7 @@ recalc_mapseen(void) guarantee of either a grave or a ghost, so we go by whether the current hero has seen the map location where each old one died */ for (bp = mptr->final_resting_place; bp; bp = bp->next) - if (gl.lastseentyp[bp->frpx][bp->frpy]) { + if (svl.lastseentyp[bp->frpx][bp->frpy]) { bp->bonesknown = TRUE; mptr->flags.knownbones = 1; } @@ -3321,7 +3321,7 @@ traverse_mapseenchn( mapseen *mptr; boolean showheader; - for (mptr = gm.mapseenchn; mptr; mptr = mptr->next) { + for (mptr = svm.mapseenchn; mptr; mptr = mptr->next) { if (viewendgame ^ In_endgame(&mptr->lev)) continue; @@ -3437,7 +3437,7 @@ tunesuffix( char tmp[BUFSZ]; if (u.uevent.uheard_tune == 2) - Sprintf(tmp, "notes \"%s\"", gt.tune); + Sprintf(tmp, "notes \"%s\"", svt.tune); else Strcpy(tmp, "5-note tune"); Snprintf(outbuf, bsz, " (play %s to open or close drawbridge)", tmp); @@ -3503,22 +3503,22 @@ print_mapseen( if (dnum == quest_dnum || dnum == knox_level.dnum) depthstart = 1; else - depthstart = gd.dungeons[dnum].depth_start; + depthstart = svd.dungeons[dnum].depth_start; if (printdun) { - if (gd.dungeons[dnum].dunlev_ureached == gd.dungeons[dnum].entry_lev + if (svd.dungeons[dnum].dunlev_ureached == svd.dungeons[dnum].entry_lev /* suppress the negative numbers in the endgame */ || In_endgame(&mptr->lev)) - Sprintf(buf, "%s:", gd.dungeons[dnum].dname); + Sprintf(buf, "%s:", svd.dungeons[dnum].dname); else if (builds_up(&mptr->lev)) Sprintf(buf, "%s: levels %d up to %d", - gd.dungeons[dnum].dname, - depthstart + gd.dungeons[dnum].entry_lev - 1, - depthstart + gd.dungeons[dnum].dunlev_ureached - 1); + svd.dungeons[dnum].dname, + depthstart + svd.dungeons[dnum].entry_lev - 1, + depthstart + svd.dungeons[dnum].dunlev_ureached - 1); else Sprintf(buf, "%s: levels %d to %d", - gd.dungeons[dnum].dname, depthstart, - depthstart + gd.dungeons[dnum].dunlev_ureached - 1); + svd.dungeons[dnum].dname, depthstart, + depthstart + svd.dungeons[dnum].dunlev_ureached - 1); add_menu_heading(win, buf); } @@ -3650,7 +3650,7 @@ print_mapseen( /* print out branches */ if (mptr->br) { Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br), - gd.dungeons[mptr->br->end2.dnum].dname); + svd.dungeons[mptr->br->end2.dnum].dname); /* Since mapseen objects are printed out in increasing order * of dlevel, clarify which level this branch is going to diff --git a/src/eat.c b/src/eat.c index 8868f89d9..dd52fd0b0 100644 --- a/src/eat.c +++ b/src/eat.c @@ -264,7 +264,7 @@ choke(struct obj *food) morehungry(Hunger ? (u.uhunger - 60) : 1000); /* you just got *very* sick! */ vomit(); } else { - gk.killer.format = KILLED_BY_AN; + svk.killer.format = KILLED_BY_AN; /* * Note all "killer"s below read "Choked on %s" on the * high score list & tombstone. So plan accordingly. @@ -272,14 +272,14 @@ choke(struct obj *food) if (food) { You("choke over your %s.", foodword(food)); if (food->oclass == COIN_CLASS) { - Strcpy(gk.killer.name, "very rich meal"); + Strcpy(svk.killer.name, "very rich meal"); } else { - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, killer_xname(food)); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, killer_xname(food)); } } else { You("choke over it."); - Strcpy(gk.killer.name, "quick snack"); + Strcpy(svk.killer.name, "quick snack"); } You("die..."); done(CHOKING); @@ -290,7 +290,7 @@ choke(struct obj *food) staticfn void recalc_wt(void) { - struct obj *piece = gc.context.victual.piece; + struct obj *piece = svc.context.victual.piece; if (!piece) { impossible("recalc_wt without piece"); @@ -298,7 +298,7 @@ recalc_wt(void) } debugpline1("Old weight = %d", piece->owt); debugpline2("Used time = %d, Req'd time = %d", - gc.context.victual.usedtime, gc.context.victual.reqtime); + svc.context.victual.usedtime, svc.context.victual.reqtime); piece->owt = weight(piece); debugpline1("New weight = %d", piece->owt); } @@ -310,9 +310,9 @@ reset_eat(void) /* we only set a flag here - the actual reset process is done after * the round is spent eating. */ - if (gc.context.victual.eating && !gc.context.victual.doreset) { + if (svc.context.victual.eating && !svc.context.victual.doreset) { debugpline0("reset_eat..."); - gc.context.victual.doreset = 1; + svc.context.victual.doreset = 1; } return; } @@ -336,9 +336,9 @@ obj_nutrition(struct obj *otmp) staticfn int adj_victual_nutrition(void) { - int otyp = gc.context.victual.piece->otyp; + int otyp = svc.context.victual.piece->otyp; /* note: adj_victual_nutrition() is only called when 'nmod' is negative */ - int nut = -gc.context.victual.nmod; /* convert 'nmod' to positive */ + int nut = -svc.context.victual.nmod; /* convert 'nmod' to positive */ assert(nut > 0); if (otyp == LEMBAS_WAFER) { @@ -394,8 +394,8 @@ touchfood(struct obj *otmp) void food_disappears(struct obj *obj) { - if (obj == gc.context.victual.piece) - gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + if (obj == svc.context.victual.piece) + svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ if (obj->timed) obj_stop_timers(obj); @@ -407,13 +407,13 @@ food_disappears(struct obj *obj) void food_substitution(struct obj *old_obj, struct obj *new_obj) { - if (old_obj == gc.context.victual.piece) { - gc.context.victual.piece = new_obj; - gc.context.victual.o_id = new_obj->o_id; + if (old_obj == svc.context.victual.piece) { + svc.context.victual.piece = new_obj; + svc.context.victual.o_id = new_obj->o_id; } - if (old_obj == gc.context.tin.tin) { - gc.context.tin.tin = new_obj; - gc.context.tin.o_id = new_obj->o_id; + if (old_obj == svc.context.tin.tin) { + svc.context.tin.tin = new_obj; + svc.context.tin.o_id = new_obj->o_id; } } @@ -421,20 +421,20 @@ staticfn void do_reset_eat(void) { debugpline0("do_reset_eat..."); - if (gc.context.victual.piece) { + if (svc.context.victual.piece) { struct obj *otmp; - gc.context.victual.o_id = 0; - otmp = touchfood(gc.context.victual.piece); - gc.context.victual.piece = otmp; + svc.context.victual.o_id = 0; + otmp = touchfood(svc.context.victual.piece); + svc.context.victual.piece = otmp; if (otmp) { - gc.context.victual.o_id = otmp->o_id; + svc.context.victual.o_id = otmp->o_id; recalc_wt(); } } - gc.context.victual.fullwarn - = gc.context.victual.eating - = gc.context.victual.doreset + svc.context.victual.fullwarn + = svc.context.victual.eating + = svc.context.victual.doreset = 0; /* Do not set canchoke to FALSE; if we continue eating the same object * we need to know if canchoke was set when they started eating it the @@ -477,7 +477,7 @@ eating_dangerous_corpse(int res) int mnum; if (go.occupation == eatfood - && (food = gc.context.victual.piece) != 0 + && (food = svc.context.victual.piece) != 0 && food->otyp == CORPSE && (mnum = food->corpsenm) >= LOW_PM && (carried(food) || obj_here(food, u.ux, u.uy))) { @@ -517,7 +517,7 @@ maybe_extend_timed_resist(int prop) staticfn int eatfood(void) { - struct obj *food = gc.context.victual.piece; + struct obj *food = svc.context.victual.piece; if (food && !carried(food) && !obj_here(food, u.ux, u.uy)) food = 0; @@ -526,10 +526,10 @@ eatfood(void) do_reset_eat(); return 0; } - if (!gc.context.victual.eating) + if (!svc.context.victual.eating) return 0; - if (++gc.context.victual.usedtime <= gc.context.victual.reqtime) { + if (++svc.context.victual.usedtime <= svc.context.victual.reqtime) { if (bite()) return 0; return 1; /* still busy */ @@ -542,7 +542,7 @@ eatfood(void) staticfn void done_eating(boolean message) { - struct obj *piece = gc.context.victual.piece; + struct obj *piece = svc.context.victual.piece; piece->in_use = TRUE; go.occupation = 0; /* do this early, so newuhs() knows we're done */ @@ -568,7 +568,7 @@ done_eating(boolean message) else useupf(piece, 1L); - gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ } void @@ -660,9 +660,9 @@ eat_brains( return M_ATTK_MISS; } else if (is_rider(pd)) { pline("Ingesting that is fatal."); - Sprintf(gk.killer.name, "unwisely ate the brain of %s", + Sprintf(svk.killer.name, "unwisely ate the brain of %s", pmname(pd, Mgender(mdef))); - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; done(DIED); /* life-saving needed to reach here */ exercise(A_WIS, FALSE); @@ -692,8 +692,8 @@ eat_brains( static NEARDATA const char brainlessness[] = "brainlessness"; if (Lifesaved) { - Strcpy(gk.killer.name, brainlessness); - gk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, brainlessness); + svk.killer.format = KILLED_BY; done(DIED); /* amulet of life saving has now been used up */ pline("Unfortunately your brain is still gone."); @@ -703,8 +703,8 @@ eat_brains( } else { Your("last thought fades away."); } - Strcpy(gk.killer.name, brainlessness); - gk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, brainlessness); + svk.killer.format = KILLED_BY; done(DIED); /* can only get here when in wizard or explore mode and user has explicitly chosen not to die; arbitrarily boost intelligence */ @@ -756,9 +756,9 @@ maybe_cannibal(int pm, boolean allowmsg) /* when poly'd into a mind flayer, multiple tentacle hits in one turn cause multiple digestion checks to occur; avoid giving multiple luck penalties for the same attack */ - if (gm.moves == ate_brains) + if (svm.moves == ate_brains) return FALSE; - ate_brains = gm.moves; /* ate_anything, not just brains... */ + ate_brains = svm.moves; /* ate_anything, not just brains... */ if (!CANNIBAL_ALLOWED() /* non-cannibalistic heroes shouldn't eat own species ever @@ -788,13 +788,13 @@ cprefx(int pm) if (!Stone_resistance && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { - Sprintf(gk.killer.name, "tasting %s meat", + Sprintf(svk.killer.name, "tasting %s meat", mons[pm].pmnames[NEUTRAL]); - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; You("turn to stone."); done(STONING); - if (gc.context.victual.piece) - gc.context.victual.eating = 0; + if (svc.context.victual.piece) + svc.context.victual.eating = 0; return; /* lifesaved */ } } @@ -821,9 +821,9 @@ cprefx(int pm) case PM_PESTILENCE: case PM_FAMINE: { pline("Eating that is instantly fatal."); - Sprintf(gk.killer.name, "unwisely ate the body of %s", + Sprintf(svk.killer.name, "unwisely ate the body of %s", mons[pm].pmnames[NEUTRAL]); - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; done(DIED); /* life-saving needed to reach here */ exercise(A_WIS, FALSE); @@ -831,10 +831,10 @@ cprefx(int pm) 3.7: this used to assume that such tins were impossible but they can be wished for in wizard mode; they can't make it to normal play though because bones creation empties them */ - if (gc.context.victual.piece /* Null for tins */ - && gc.context.victual.piece->otyp == CORPSE /* paranoia */ - && revive_corpse(gc.context.victual.piece)) - gc.context.victual = zero_victual; /* victual.piece=0, .o_id=0 */ + if (svc.context.victual.piece /* Null for tins */ + && svc.context.victual.piece->otyp == CORPSE /* paranoia */ + && revive_corpse(svc.context.victual.piece)) + svc.context.victual = zero_victual; /* victual.piece=0, .o_id=0 */ return; } case PM_GREEN_SLIME: @@ -1357,18 +1357,18 @@ violated_vegetarian(void) return; } -/* common code to check and possibly charge for 1 gc.context.tin.tin, - * will split() gc.context.tin.tin if necessary */ +/* common code to check and possibly charge for 1 svc.context.tin.tin, + * will split() svc.context.tin.tin if necessary */ staticfn struct obj * costly_tin(int alter_type) /* COST_xxx */ { - struct obj *tin = gc.context.tin.tin; + struct obj *tin = svc.context.tin.tin; if (carried(tin) ? tin->unpaid : (costly_spot(tin->ox, tin->oy) && !tin->no_charge)) { if (tin->quan > 1L) { - tin = gc.context.tin.tin = splitobj(tin, 1L); - gc.context.tin.o_id = tin->o_id; + tin = svc.context.tin.tin = splitobj(tin, 1L); + svc.context.tin.o_id = tin->o_id; } costly_alteration(tin, alter_type); } @@ -1490,7 +1490,7 @@ consume_tin(const char *mesg) { const char *what; int which, mnum, r; - struct obj *tin = gc.context.tin.tin; + struct obj *tin = svc.context.tin.tin; r = tin_variety(tin, FALSE); if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) { @@ -1540,7 +1540,7 @@ consume_tin(const char *mesg) } /* in case stop_occupation() was called on previous meal */ - gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ You("consume %s %s.", tintxts[r].txt, mons[mnum].pmnames[NEUTRAL]); @@ -1622,8 +1622,8 @@ consume_tin(const char *mesg) useup(tin); else useupf(tin, 1L); - gc.context.tin.tin = (struct obj *) 0; - gc.context.tin.o_id = 0; + svc.context.tin.tin = (struct obj *) 0; + svc.context.tin.o_id = 0; } /* called during each move whilst opening a tin */ @@ -1631,15 +1631,15 @@ staticfn int opentin(void) { /* perhaps it was stolen (although that should cause interruption) */ - if (!carried(gc.context.tin.tin) - && (!obj_here(gc.context.tin.tin, u.ux, u.uy) + if (!carried(svc.context.tin.tin) + && (!obj_here(svc.context.tin.tin, u.ux, u.uy) || !can_reach_floor(TRUE))) return 0; /* %% probably we should use tinoid */ - if (gc.context.tin.usedtime++ >= 50) { + if (svc.context.tin.usedtime++ >= 50) { You("give up your attempt to open the tin."); return 0; } - if (gc.context.tin.usedtime < gc.context.tin.reqtime) + if (svc.context.tin.usedtime < svc.context.tin.reqtime) return 1; /* still busy */ consume_tin("You succeed in opening the tin."); @@ -1711,13 +1711,13 @@ start_tin(struct obj *otmp) tmp = rn1(1 + 500 / ((int) (ACURR(A_DEX) + ACURRSTR)), 10); } - gc.context.tin.tin = otmp; - gc.context.tin.o_id = otmp->o_id; + svc.context.tin.tin = otmp; + svc.context.tin.o_id = otmp->o_id; if (!tmp) { consume_tin(mesg); /* begin immediately */ } else { - gc.context.tin.reqtime = tmp; - gc.context.tin.usedtime = 0; + svc.context.tin.reqtime = tmp; + svc.context.tin.usedtime = 0; set_occupation(opentin, "opening the tin", 0); } return; @@ -1811,7 +1811,7 @@ eatcorpse(struct obj *otmp) if (!nonrotting_corpse(mnum)) { long age = peek_at_iced_corpse_age(otmp); - rotted = (gm.moves - age) / (10L + rn2(20)); + rotted = (svm.moves - age) / (10L + rn2(20)); if (otmp->cursed) rotted += 2L; else if (otmp->blessed) @@ -1870,7 +1870,7 @@ eatcorpse(struct obj *otmp) } /* delay is weight dependent */ - gc.context.victual.reqtime + svc.context.victual.reqtime = 3 + ((!glob ? mons[mnum].cwt : otmp->owt) >> 6); if (!tp && !nonrotting_corpse(mnum) && (otmp->orotten || !rn2(7))) { @@ -1956,17 +1956,17 @@ start_eating(struct obj *otmp, boolean already_partly_eaten) several such so we don't need to copy the first result before calling it a second time */ fmt_ptr((genericptr_t) otmp), - fmt_ptr((genericptr_t) gc.context.victual.piece)); - debugpline1("reqtime = %d", gc.context.victual.reqtime); + fmt_ptr((genericptr_t) svc.context.victual.piece)); + debugpline1("reqtime = %d", svc.context.victual.reqtime); debugpline1("(original reqtime = %d)", objects[otmp->otyp].oc_delay); - debugpline1("nmod = %d", gc.context.victual.nmod); + debugpline1("nmod = %d", svc.context.victual.nmod); debugpline1("oeaten = %d", otmp->oeaten); - gc.context.victual.fullwarn = gc.context.victual.doreset = 0; - gc.context.victual.eating = 1; + svc.context.victual.fullwarn = svc.context.victual.doreset = 0; + svc.context.victual.eating = 1; if (otmp->otyp == CORPSE || otmp->globby) { - cprefx(gc.context.victual.piece->corpsenm); - if (!gc.context.victual.piece || !gc.context.victual.eating) { + cprefx(svc.context.victual.piece->corpsenm); + if (!svc.context.victual.piece || !svc.context.victual.eating) { /* rider revived, or hero died and was lifesaved */ return; } @@ -1976,7 +1976,7 @@ start_eating(struct obj *otmp, boolean already_partly_eaten) if (bite()) { /* survived choking, finish off food that's nearly done; need this to handle cockatrice eggs, fortune cookies, etc */ - if (++gc.context.victual.usedtime >= gc.context.victual.reqtime) { + if (++svc.context.victual.usedtime >= svc.context.victual.reqtime) { /* don't want done_eating() to issue gn.nomovemsg if it is due to vomit() called by bite() */ save_nomovemsg = gn.nomovemsg; @@ -1989,9 +1989,9 @@ start_eating(struct obj *otmp, boolean already_partly_eaten) return; } - if (++gc.context.victual.usedtime >= gc.context.victual.reqtime) { + if (++svc.context.victual.usedtime >= svc.context.victual.reqtime) { /* print "finish eating" message if they just resumed -dlc */ - done_eating((gc.context.victual.reqtime > 1 + done_eating((svc.context.victual.reqtime > 1 || already_partly_eaten) ? TRUE : FALSE); return; } @@ -2004,7 +2004,7 @@ start_eating(struct obj *otmp, boolean already_partly_eaten) boolean eating_glob(struct obj *glob) { - return (go.occupation == eatfood && glob == gc.context.victual.piece); + return (go.occupation == eatfood && glob == svc.context.victual.piece); } /* scare nearby monster when hero eats garlic */ @@ -2065,7 +2065,7 @@ fprefx(struct obj *otmp) /* not cannibalism, but we use similar criteria for deciding whether to be sickened by this meal */ if (rn2(2) && !CANNIBAL_ALLOWED()) - make_vomiting((long) rn1(gc.context.victual.reqtime, 14), + make_vomiting((long) rn1(svc.context.victual.reqtime, 14), FALSE); } break; @@ -2085,14 +2085,14 @@ fprefx(struct obj *otmp) goto give_feedback; case CLOVE_OF_GARLIC: if (is_undead(gy.youmonst.data)) { - make_vomiting((long) rn1(gc.context.victual.reqtime, 5), FALSE); + make_vomiting((long) rn1(svc.context.victual.reqtime, 5), FALSE); break; } iter_mons(garlic_breath); /*FALLTHRU*/ default: if (otmp->otyp == SLIME_MOLD && !otmp->cursed - && otmp->spe == gc.context.current_fruit) { + && otmp->spe == svc.context.current_fruit) { pline("My, this is a %s %s!", Hallucination ? "primo" : "yummy", singular(otmp, xname)); @@ -2335,13 +2335,13 @@ eataccessory(struct obj *otmp) staticfn void eatspecial(void) { - struct obj *otmp = gc.context.victual.piece; + struct obj *otmp = svc.context.victual.piece; /* lesshungry wants an occupation to handle choke messages correctly */ set_occupation(eatfood, "eating non-food", 0); - lesshungry(gc.context.victual.nmod); + lesshungry(svc.context.victual.nmod); go.occupation = 0; - gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ if (otmp->oclass == COIN_CLASS) { if (carried(otmp)) @@ -2471,8 +2471,8 @@ fpostfx(struct obj *otmp) setuhpmax(u.uhpmax + 1); u.uhp = u.uhpmax; } else if (u.uhp <= 0) { - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "rotten lump of royal jelly"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "rotten lump of royal jelly"); done(POISONING); } } @@ -2486,9 +2486,9 @@ fpostfx(struct obj *otmp) && !(poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM))) { if (!Stoned) { - Sprintf(gk.killer.name, "%s egg", + Sprintf(svk.killer.name, "%s egg", mons[otmp->corpsenm].pmnames[NEUTRAL]); - make_stoned(5L, (char *) 0, KILLED_BY_AN, gk.killer.name); + make_stoned(5L, (char *) 0, KILLED_BY_AN, svk.killer.name); } } /* note: no "tastes like chicken" message for eggs */ @@ -2577,7 +2577,7 @@ edibility_prompts(struct obj *otmp) /* worst case rather than random in this calculation to force prompt */ - rotted = (gm.moves - age) / (10L + 0 /* was rn2(20) */); + rotted = (svm.moves - age) / (10L + 0 /* was rn2(20) */); if (otmp->cursed) rotted += 2L; else if (otmp->blessed) @@ -2659,12 +2659,12 @@ doeat_nonfood(struct obj *otmp) boolean nodelicious = FALSE; int material; - gc.context.victual.reqtime = 1; - gc.context.victual.piece = otmp; - gc.context.victual.o_id = otmp->o_id; + svc.context.victual.reqtime = 1; + svc.context.victual.piece = otmp; + svc.context.victual.o_id = otmp->o_id; /* Don't split it, we don't need to if it's 1 move */ - gc.context.victual.usedtime = 0; - gc.context.victual.canchoke = (u.uhs == SATIATED); + svc.context.victual.usedtime = 0; + svc.context.victual.canchoke = (u.uhs == SATIATED); /* Note: gold weighs 1 pt. for each 1000 pieces (see pickup.c) so gold and non-gold is consistent. */ if (otmp->oclass == COIN_CLASS) @@ -2681,8 +2681,8 @@ doeat_nonfood(struct obj *otmp) nodelicious = TRUE; } #endif - gc.context.victual.nmod = basenutrit; - gc.context.victual.eating = 1; /* needed for lesshungry() */ + svc.context.victual.nmod = basenutrit; + svc.context.victual.eating = 1; /* needed for lesshungry() */ if (!u.uconduct.food++) { ll_conduct++; @@ -2841,9 +2841,9 @@ doeat(void) return doeat_nonfood(otmp); - if (otmp == gc.context.victual.piece) { + if (otmp == svc.context.victual.piece) { boolean one_bite_left - = (gc.context.victual.usedtime + 1 >= gc.context.victual.reqtime); + = (svc.context.victual.usedtime + 1 >= svc.context.victual.reqtime); /* If they weren't able to choke, they don't suddenly become able to * choke just because they were interrupted. On the other hand, if @@ -2851,12 +2851,12 @@ doeat(void) * they shouldn't be able to choke now. */ if (u.uhs != SATIATED) - gc.context.victual.canchoke = 0; - gc.context.victual.o_id = 0; + svc.context.victual.canchoke = 0; + svc.context.victual.o_id = 0; otmp = touchfood(otmp); if (otmp) { - gc.context.victual.piece = otmp; - gc.context.victual.o_id = otmp->o_id; + svc.context.victual.piece = otmp; + svc.context.victual.o_id = otmp->o_id; } else { do_reset_eat(); } @@ -2889,9 +2889,9 @@ doeat(void) already_partly_eaten = otmp->oeaten ? TRUE : FALSE; otmp = touchfood(otmp); if (otmp) { - gc.context.victual.piece = otmp; - gc.context.victual.o_id = otmp->o_id; - gc.context.victual.usedtime = 0; + svc.context.victual.piece = otmp; + svc.context.victual.o_id = otmp->o_id; + svc.context.victual.usedtime = 0; } else { do_reset_eat(); return ECMD_TIME; @@ -2907,7 +2907,7 @@ doeat(void) if (tmp == 2) { /* used up */ - gc.context.victual = zero_victual; /* victual.piece=0, .o_id=0 */ + svc.context.victual = zero_victual; /* victual.piece=0, .o_id=0 */ return ECMD_TIME; } else if (tmp) dont_start = TRUE; @@ -2944,10 +2944,10 @@ doeat(void) break; } - gc.context.victual.reqtime = objects[otmp->otyp].oc_delay; + svc.context.victual.reqtime = objects[otmp->otyp].oc_delay; if (otmp->otyp != FORTUNE_COOKIE && (otmp->cursed || (!nonrotting_food(otmp->otyp) - && (gm.moves - otmp->age) + && (svm.moves - otmp->age) > (otmp->blessed ? 50L : 30L) && (otmp->orotten || !rn2(7))))) { if (rottenfood(otmp)) { @@ -2962,7 +2962,7 @@ doeat(void) } } else { You("%s %s.", - (gc.context.victual.reqtime == 1) ? "eat" : "begin eating", + (svc.context.victual.reqtime == 1) ? "eat" : "begin eating", doname(otmp)); } } @@ -2972,30 +2972,30 @@ doeat(void) debugpline3( "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d", - gc.context.victual.reqtime, otmp->oeaten, basenutrit); + svc.context.victual.reqtime, otmp->oeaten, basenutrit); - gc.context.victual.reqtime + svc.context.victual.reqtime = (basenutrit == 0) ? 0 - : rounddiv(gc.context.victual.reqtime * (long) otmp->oeaten, + : rounddiv(svc.context.victual.reqtime * (long) otmp->oeaten, basenutrit); debugpline1("after rounddiv: victual.reqtime == %d", - gc.context.victual.reqtime); + svc.context.victual.reqtime); /* * calculate the modulo value (nutrit. units per round eating) * note: this isn't exact - you actually lose a little nutrition due * to this method. * TODO: add in a "remainder" value to be given at the end of the meal. */ - if (gc.context.victual.reqtime == 0 || otmp->oeaten == 0) + if (svc.context.victual.reqtime == 0 || otmp->oeaten == 0) /* possible if most has been eaten before */ - gc.context.victual.nmod = 0; - else if ((int) otmp->oeaten >= gc.context.victual.reqtime) - gc.context.victual.nmod = -((int) otmp->oeaten - / gc.context.victual.reqtime); + svc.context.victual.nmod = 0; + else if ((int) otmp->oeaten >= svc.context.victual.reqtime) + svc.context.victual.nmod = -((int) otmp->oeaten + / svc.context.victual.reqtime); else - gc.context.victual.nmod = gc.context.victual.reqtime % otmp->oeaten; - gc.context.victual.canchoke = (u.uhs == SATIATED); + svc.context.victual.nmod = svc.context.victual.reqtime % otmp->oeaten; + svc.context.victual.canchoke = (u.uhs == SATIATED); if (!dont_start) start_eating(otmp, already_partly_eaten); @@ -3054,25 +3054,25 @@ staticfn int bite(void) { /* hack to pacify static analyzer incorporated into gcc 12.2 */ - sa_victual(&gc.context.victual); + sa_victual(&svc.context.victual); - if (gc.context.victual.canchoke && u.uhunger >= 2000) { - choke(gc.context.victual.piece); + if (svc.context.victual.canchoke && u.uhunger >= 2000) { + choke(svc.context.victual.piece); return 1; } - if (gc.context.victual.doreset) { + if (svc.context.victual.doreset) { do_reset_eat(); return 0; } gf.force_save_hs = TRUE; - if (gc.context.victual.nmod < 0) { - lesshungry(adj_victual_nutrition(/*-gc.context.victual.nmod*/)); - consume_oeaten(gc.context.victual.piece, - gc.context.victual.nmod); /* -= -nmod */ - } else if (gc.context.victual.nmod > 0 - && (gc.context.victual.usedtime % gc.context.victual.nmod)) { + if (svc.context.victual.nmod < 0) { + lesshungry(adj_victual_nutrition(/*-svc.context.victual.nmod*/)); + consume_oeaten(svc.context.victual.piece, + svc.context.victual.nmod); /* -= -nmod */ + } else if (svc.context.victual.nmod > 0 + && (svc.context.victual.usedtime % svc.context.victual.nmod)) { lesshungry(1); - consume_oeaten(gc.context.victual.piece, -1); /* -= 1 */ + consume_oeaten(svc.context.victual.piece, -1); /* -= 1 */ } gf.force_save_hs = FALSE; recalc_wt(); @@ -3109,7 +3109,7 @@ gethungry(void) * Also causes melee-induced hunger to vary from turn-based hunger * instead of just replicating that. */ - accessorytime = rn2(20); /* rn2(20) replaces (int) (gm.moves % 20L) */ + accessorytime = rn2(20); /* rn2(20) replaces (int) (svm.moves % 20L) */ if (accessorytime % 2) { /* odd */ /* Regeneration uses up food, unless due to an artifact */ if ((HRegeneration & ~FROMFORM) @@ -3215,12 +3215,12 @@ lesshungry(int num) debugpline1("lesshungry(%d)", num); u.uhunger += num; if (u.uhunger >= 2000) { - if (!iseating || gc.context.victual.canchoke) { + if (!iseating || svc.context.victual.canchoke) { if (iseating) { - choke(gc.context.victual.piece); + choke(svc.context.victual.piece); reset_eat(); } else { - choke((go.occupation == opentin) ? gc.context.tin.tin : 0); + choke((go.occupation == opentin) ? svc.context.tin.tin : 0); /* no reset_eat() */ } } @@ -3229,18 +3229,18 @@ lesshungry(int num) * warns when you're about to choke. */ if (u.uhunger >= 1500 && !Hunger - && (!gc.context.victual.eating - || (gc.context.victual.eating - && !gc.context.victual.fullwarn))) { + && (!svc.context.victual.eating + || (svc.context.victual.eating + && !svc.context.victual.fullwarn))) { pline("You're having a hard time getting all of it down."); gn.nomovemsg = "You're finally finished."; - if (!gc.context.victual.eating) { + if (!svc.context.victual.eating) { gm.multi = -2; } else { - gc.context.victual.fullwarn = 1; - if (gc.context.victual.canchoke - && (gc.context.victual.reqtime - - gc.context.victual.usedtime) > 1) { + svc.context.victual.fullwarn = 1; + if (svc.context.victual.canchoke + && (svc.context.victual.reqtime + - svc.context.victual.usedtime) > 1) { /* food with one bite left will not survive a stop */ if (!paranoid_query(ParanoidEating, "Continue eating?")) { reset_eat(); @@ -3360,8 +3360,8 @@ newuhs(boolean incr) disp.botl = TRUE; bot(); You("die from starvation."); - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "starvation"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "starvation"); done(STARVING); /* if we return, we lifesaved, and that calls newuhs */ return; @@ -3425,8 +3425,8 @@ newuhs(boolean incr) bot(); if ((Upolyd ? u.mh : u.uhp) < 1) { You("die from hunger and exhaustion."); - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "exhaustion"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "exhaustion"); done(STARVING); return; } @@ -3562,10 +3562,10 @@ floorfood( pline("%s but you %s eat them.", qbuf, nodig ? "cannot" : "are too full to"); } else { - Strcat(qbuf, ((!gc.context.digging.chew - || gc.context.digging.pos.x != u.ux - || gc.context.digging.pos.y != u.uy - || !on_level(&gc.context.digging.level, &u.uz)) + Strcat(qbuf, ((!svc.context.digging.chew + || svc.context.digging.pos.x != u.ux + || svc.context.digging.pos.y != u.uy + || !on_level(&svc.context.digging.level, &u.uz)) ? "; eat them?" : "; resume eating them?")); c = yn_function(qbuf, ynqchars, 'n', TRUE); @@ -3593,7 +3593,7 @@ floorfood( } /* Is there some food (probably a heavy corpse) here on the ground? */ - for (otmp = gl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) { + for (otmp = svl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) { if (corpsecheck ? (otmp->otyp == CORPSE && (corpsecheck == 1 || tinnable(otmp))) @@ -3752,7 +3752,7 @@ consume_oeaten(struct obj *obj, int amt) * victual handling mechanism from scratch using a less complex * model. Alternatively, this routine could call done_eating() * or food_disappears() but its callers would need revisions to - * cope with gc.context.victual.piece unexpectedly going away. + * cope with svc.context.victual.piece unexpectedly going away. * * Multi-turn eating operates by setting the food's oeaten field * to its full nutritional value and then running a counter which @@ -3786,8 +3786,8 @@ consume_oeaten(struct obj *obj, int amt) /* mustn't let partly-eaten drop all the way to 0 or the item would become restored to untouched; set to no bites left */ if (obj->oeaten == 0) { - if (obj == gc.context.victual.piece) /* always true unless wishing */ - gc.context.victual.reqtime = gc.context.victual.usedtime; + if (obj == svc.context.victual.piece) /* always true unless wishing */ + svc.context.victual.reqtime = svc.context.victual.usedtime; obj->oeaten = 1; /* smallest possible positive value */ } } @@ -3799,10 +3799,10 @@ maybe_finished_meal(boolean stopping) { /* in case consume_oeaten() has decided that the food is all gone */ if (go.occupation == eatfood - && gc.context.victual.usedtime >= gc.context.victual.reqtime) { + && svc.context.victual.usedtime >= svc.context.victual.reqtime) { if (stopping) go.occupation = 0; /* for do_reset_eat */ - /* eatfood() calls done_eating() to use up gc.context.victual.piece */ + /* eatfood() calls done_eating() to use up svc.context.victual.piece */ (void) eatfood(); return TRUE; } @@ -3820,9 +3820,9 @@ cant_finish_meal(struct obj *corpse) * left for another bite. revive() needs continued access to the * corpse and will delete it when done. */ - if (go.occupation == eatfood && gc.context.victual.piece == corpse) { + if (go.occupation == eatfood && svc.context.victual.piece == corpse) { /* normally performed by done_eating() */ - gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ if (!corpse->oeaten) corpse->oeaten = 1; /* [see consume_oeaten()] */ @@ -3845,7 +3845,7 @@ Popeye(int threat) if (go.occupation != opentin) return FALSE; - otin = gc.context.tin.tin; + otin = svc.context.tin.tin; /* make sure hero still has access to tin */ if (!carried(otin) && (!obj_here(otin, u.ux, u.uy) || !can_reach_floor(TRUE))) diff --git a/src/end.c b/src/end.c index fc1215775..c894e7021 100644 --- a/src/end.c +++ b/src/end.c @@ -43,7 +43,7 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN; #define nethack_exit exit #endif -#define done_stopprint gp.program_state.stopprint +#define done_stopprint svp.program_state.stopprint /* * The order of these needs to match the macros in hack.h. @@ -175,7 +175,7 @@ staticfn void done_hangup(int sig) { #ifdef HANGUPHANDLING - gp.program_state.done_hup++; + svp.program_state.done_hup++; #endif sethanguphandler((void (*)(int)) SIG_IGN); done_intr(sig); @@ -201,19 +201,19 @@ done_in_by(struct monst *mtmp, int how) You((how == STONING) ? "turn to stone..." : "die..."); mark_synch(); /* flush buffered screen output */ buf[0] = '\0'; - gk.killer.format = KILLED_BY_AN; + svk.killer.format = KILLED_BY_AN; /* "killed by the high priest of Crom" is okay, "killed by the high priest" alone isn't */ if ((mptr->geno & G_UNIQ) != 0 && !(imitator && !mimicker) && !(mptr == &mons[PM_HIGH_CLERIC] && !mtmp->ispriest)) { if (!type_is_pname(mptr)) Strcat(buf, "the "); - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; } /* _the_ ghost of Dudley */ if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) { Strcat(buf, "the "); - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; } (void) monhealthdescr(mtmp, TRUE, eos(buf)); if (mtmp->minvis) @@ -264,7 +264,7 @@ done_in_by(struct monst *mtmp, int how) : mtmp->female ? "Ms. " : "Mr. "; Sprintf(eos(buf), "%s%s, the shopkeeper", honorific, shknm); - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; } else if (mtmp->ispriest || mtmp->isminion) { /* m_monnam() suppresses "the" prefix plus "invisible", and it overrides the effect of Hallucination on priestname() */ @@ -275,7 +275,7 @@ done_in_by(struct monst *mtmp, int how) Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp)); } - Strcpy(gk.killer.name, buf); + Strcpy(svk.killer.name, buf); /* might need to fix up multi_reason if 'mtmp' caused the reason */ if (gm.multi_reason @@ -330,7 +330,7 @@ done_in_by(struct monst *mtmp, int how) /* this could happen if a high-end vampire kills the hero when ordinary vampires are genocided; ditto for wraiths */ if (u.ugrave_arise >= LOW_PM - && (gm.mvitals[u.ugrave_arise].mvflags & G_GENOD)) + && (svm.mvitals[u.ugrave_arise].mvflags & G_GENOD)) u.ugrave_arise = NON_PM; done(how); @@ -391,7 +391,7 @@ panic VA_DECL(const char *, str) VA_START(str); VA_INIT(str, char *); - if (gp.program_state.panicking++) + if (svp.program_state.panicking++) NH_abort(NULL); /* avoid loops - this should never happen*/ gb.bot_disabled = TRUE; @@ -404,9 +404,9 @@ panic VA_DECL(const char *, str) iflags.window_inited = FALSE; /* they're gone; force raw_print()ing */ } - raw_print(gp.program_state.gameover + raw_print(svp.program_state.gameover ? "Postgame wrapup disrupted." - : !gp.program_state.something_worth_saving + : !svp.program_state.something_worth_saving ? "Program initialization has failed." : "Suddenly, the dungeon collapses."); #ifndef MICRO @@ -414,11 +414,11 @@ panic VA_DECL(const char *, str) if (!wizard) raw_printf("Report the following error to \"%s\" or at \"%s\".", DEVTEAM_EMAIL, DEVTEAM_URL); - else if (gp.program_state.something_worth_saving) + else if (svp.program_state.something_worth_saving) raw_print("\nError save file being written.\n"); #else /* !NOTIFY_NETHACK_BUGS */ if (!wizard) { - const char *maybe_rebuild = !gp.program_state.something_worth_saving + const char *maybe_rebuild = !svp.program_state.something_worth_saving ? "." : "\nand it may be possible to rebuild."; @@ -437,7 +437,7 @@ panic VA_DECL(const char *, str) /* XXX can we move this above the prints? Then we'd be able to * suppress "it may be possible to rebuild" based on dosave0() * or say it's NOT possible to rebuild. */ - if (gp.program_state.something_worth_saving && !iflags.debug_fuzzer) { + if (svp.program_state.something_worth_saving && !iflags.debug_fuzzer) { set_error_savefile(); if (dosave0()) { /* os/win port specific recover instructions */ @@ -566,7 +566,7 @@ dump_everything( /* character name and basic role info */ Sprintf(pbuf, "%s, %s %s %s %s", - gp.plname, aligns[1 - u.ualign.type].adj, + svp.plname, aligns[1 - u.ualign.type].adj, genders[flags.female].adj, gu.urace.adj, (flags.female && gu.urole.name.f) ? gu.urole.name.f : gu.urole.name.m); @@ -715,7 +715,7 @@ savelife(int how) make_sick(0L, (char *) 0, FALSE, SICK_ALL); } gn.nomovemsg = "You survived that attempt on your life."; - gc.context.move = 0; + svc.context.move = 0; gm.multi = -1; /* can't move again during the current turn */ /* in case being life-saved is immediately followed by being killed @@ -731,7 +731,7 @@ savelife(int how) u.ugrave_arise = NON_PM; HUnchanging = 0L; curs_on_u(); - if (!gc.context.mon_moving) + if (!svc.context.mon_moving) endmultishot(FALSE); if (u.uswallow) { /* might drop hero onto a trap that kills her all over again */ @@ -937,7 +937,7 @@ fuzzer_savelife(int how) * Some debugging code pulled out of done() to unclutter it. * 'done_seq' is maintained in done(). */ - if (!gp.program_state.panicking + if (!svp.program_state.panicking && how != PANICKED && how != TRICKED) { savelife(how); @@ -983,8 +983,8 @@ fuzzer_savelife(int how) } } /* clear stale cause of death info after life-saving */ - gk.killer.name[0] = '\0'; - gk.killer.format = 0; + svk.killer.name[0] = '\0'; + svk.killer.format = 0; /* Guard against getting stuck in a loop if we die in one of * the few ways where life-saving isn't effective (cited case @@ -1009,19 +1009,19 @@ done(int how) boolean survive = FALSE; if (how == TRICKED) { - if (gk.killer.name[0]) { - paniclog("trickery", gk.killer.name); - gk.killer.name[0] = '\0'; + if (svk.killer.name[0]) { + paniclog("trickery", svk.killer.name); + svk.killer.name[0] = '\0'; } if (wizard) { You("are a very tricky wizard, it seems."); - gk.killer.format = KILLED_BY_AN; /* reset to 0 */ + svk.killer.format = KILLED_BY_AN; /* reset to 0 */ return; } } - if (gp.program_state.panicking + if (svp.program_state.panicking #ifdef HANGUPHANDLING - || gp.program_state.done_hup + || svp.program_state.done_hup #endif || (how == QUIT && done_stopprint)) { /* skip status update if panicking or disconnected @@ -1045,13 +1045,13 @@ done(int how) return; } - if (how == ASCENDED || (!gk.killer.name[0] && how == GENOCIDED)) - gk.killer.format = NO_KILLER_PREFIX; + if (how == ASCENDED || (!svk.killer.name[0] && how == GENOCIDED)) + svk.killer.format = NO_KILLER_PREFIX; /* Avoid killed by "a" burning or "a" starvation */ - if (!gk.killer.name[0] && (how == STARVING || how == BURNING)) - gk.killer.format = KILLED_BY; - if (!gk.killer.name[0] || how >= PANICKED) - Strcpy(gk.killer.name, deaths[how]); + if (!svk.killer.name[0] && (how == STARVING || how == BURNING)) + svk.killer.format = KILLED_BY; + if (!svk.killer.name[0] || how >= PANICKED) + Strcpy(svk.killer.name, deaths[how]); if (how < PANICKED) { u.umortality++; @@ -1094,7 +1094,7 @@ done(int how) /* if hangup has occurred, the only possible answer to a paranoid query is 'no'; we want 'no' as the default for "Die?" but can't accept it more than once if there's no user supplying it */ - && !(gp.program_state.done_hup && gd.done_seq++ == gh.hero_seq) + && !(svp.program_state.done_hup && gd.done_seq++ == gh.hero_seq) #endif && !paranoid_query(ParanoidDie, "Die?")) { pline("OK, so you don't %s.", (how == CHOKING) ? "choke" : "die"); @@ -1104,8 +1104,8 @@ done(int how) } if (survive) { - gk.killer.name[0] = '\0'; - gk.killer.format = KILLED_BY_AN; /* reset to 0 */ + svk.killer.name[0] = '\0'; + svk.killer.format = KILLED_BY_AN; /* reset to 0 */ return; } really_done(how); @@ -1128,11 +1128,11 @@ really_done(int how) /* * The game is now over... */ - gp.program_state.gameover = 1; + svp.program_state.gameover = 1; /* in case of a subsequent panic(), there's no point trying to save */ - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; #ifdef HANGUPHANDLING - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) done_stopprint++; #endif /* render vision subsystem inoperative */ @@ -1140,7 +1140,7 @@ really_done(int how) /* maybe use up active invent item(s), place thrown/kicked missile, deal with ball and chain possibly being temporarily off the map */ - if (!gp.program_state.panicking) + if (!svp.program_state.panicking) done_object_cleanup(); /* in case we're panicking; normally cleared by done_object_cleanup() */ iflags.perm_invent = FALSE; @@ -1170,7 +1170,7 @@ really_done(int how) * On those rare occasions you get hosed immediately, go out * smiling... :-) -3. */ - if (gm.moves <= 1 && how < PANICKED && !done_stopprint) + if (svm.moves <= 1 && how < PANICKED && !done_stopprint) pline("Do not pass Go. Do not collect 200 %s.", currency(200L)); if (have_windows) @@ -1202,19 +1202,19 @@ really_done(int how) have been genocided: genocide could occur after hero is already infected or hero could eat a glob of one created before genocide; don't try to arise as one if they're gone */ - && !(gm.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD)) + && !(svm.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD)) u.ugrave_arise = PM_GREEN_SLIME; if (how == QUIT) { - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; if (u.uhp < 1) { how = DIED; u.umortality++; /* skipped above when how==QUIT */ - Strcpy(gk.killer.name, "quit while already on Charon's boat"); + Strcpy(svk.killer.name, "quit while already on Charon's boat"); } } if (how == ESCAPED || how == PANICKED) - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; fixup_death(how); /* actually, fixup gm.multi_reason */ @@ -1289,14 +1289,14 @@ really_done(int how) /* grave creation should be after disclosure so it doesn't have this grave in the current level's features for #overview */ if (bones_ok && u.ugrave_arise == NON_PM - && !(gm.mvitals[u.umonnum].mvflags & G_NOCORPSE)) { + && !(svm.mvitals[u.umonnum].mvflags & G_NOCORPSE)) { /* Base corpse on race when not poly'd since original u.umonnum is based on role, and all role monsters are human. */ int mnum = !Upolyd ? gu.urace.mnum : u.umonnum, was_already_grave = IS_GRAVE(levl[u.ux][u.uy].typ); - corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, gp.plname); - Sprintf(pbuf, "%s, ", gp.plname); + corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, svp.plname); + Sprintf(pbuf, "%s, ", svp.plname); formatkiller(eos(pbuf), sizeof pbuf - Strlen(pbuf), how, TRUE); make_grave(u.ux, u.uy, pbuf); if (IS_GRAVE(levl[u.ux][u.uy].typ) && !was_already_grave) @@ -1391,16 +1391,16 @@ really_done(int how) } #endif if (u.uhave.amulet) { - Strcat(gk.killer.name, " (with the Amulet)"); + Strcat(svk.killer.name, " (with the Amulet)"); } else if (how == ESCAPED) { if (Is_astralevel(&u.uz)) /* offered Amulet to wrong deity */ - Strcat(gk.killer.name, " (in celestial disgrace)"); + Strcat(svk.killer.name, " (in celestial disgrace)"); else if (carrying(FAKE_AMULET_OF_YENDOR)) - Strcat(gk.killer.name, " (with a fake Amulet)"); + Strcat(svk.killer.name, " (with a fake Amulet)"); /* don't bother counting to see whether it should be plural */ } - Sprintf(pbuf, "%s %s the %s...", Goodbye(), gp.plname, + Sprintf(pbuf, "%s %s the %s...", Goodbye(), svp.plname, (how != ASCENDED) ? (const char *) ((flags.female && gu.urole.name.f) ? gu.urole.name.f @@ -1511,7 +1511,7 @@ really_done(int how) (u.uz.dlevel < 0) ? "passed away" : ends[how]); } else { /* more conventional demise */ - const char *where = gd.dungeons[u.uz.dnum].dname; + const char *where = svd.dungeons[u.uz.dnum].dname; if (Is_astralevel(&u.uz)) where = "The Astral Plane"; @@ -1526,7 +1526,7 @@ really_done(int how) } Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.", umoney, - plur(umoney), gm.moves, plur(gm.moves)); + plur(umoney), svm.moves, plur(svm.moves)); dump_forward_putstr(endwin, 0, pbuf, done_stopprint); Sprintf(pbuf, "You were level %d with a maximum of %d hit point%s when you %s.", @@ -1657,7 +1657,7 @@ container_contents( ATTRNORETURN void nh_terminate(int status) { - gp.program_state.in_moveloop = 0; /* won't be returning to normal play */ + svp.program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); #ifdef MAC @@ -1665,7 +1665,7 @@ nh_terminate(int status) #endif /* don't bother to try to release memory if we're in panic mode, to avoid trouble in case that happens to be due to memory problems */ - if (!gp.program_state.panicking) { + if (!svp.program_state.panicking) { freedynamicdata(); dlb_cleanup(); l_nhcore_done(); @@ -1679,10 +1679,10 @@ nh_terminate(int status) */ /* don't call exit() if already executing within an exit handler; that would cancel any other pending user-mode handlers */ - if (gp.program_state.exiting) + if (svp.program_state.exiting) return; #endif - gp.program_state.exiting = 1; + svp.program_state.exiting = 1; nethack_exit(status); } @@ -1697,13 +1697,13 @@ delayed_killer(int id, int format, const char *killername) k = (struct kinfo *) alloc(sizeof (struct kinfo)); (void) memset((genericptr_t) k, 0, sizeof (struct kinfo)); k->id = id; - k->next = gk.killer.next; - gk.killer.next = k; + k->next = svk.killer.next; + svk.killer.next = k; } k->format = format; Strcpy(k->name, killername ? killername : ""); - gk.killer.name[0] = 0; + svk.killer.name[0] = 0; } struct kinfo * @@ -1711,7 +1711,7 @@ find_delayed_killer(int id) { struct kinfo *k; - for (k = gk.killer.next; k != (struct kinfo *) 0; k = k->next) { + for (k = svk.killer.next; k != (struct kinfo *) 0; k = k->next) { if (k->id == id) break; } @@ -1721,11 +1721,11 @@ find_delayed_killer(int id) void dealloc_killer(struct kinfo *kptr) { - struct kinfo *prev = &gk.killer, *k; + struct kinfo *prev = &svk.killer, *k; if (kptr == (struct kinfo *) 0) return; - for (k = gk.killer.next; k != (struct kinfo *) 0; k = k->next) { + for (k = svk.killer.next; k != (struct kinfo *) 0; k = k->next) { if (k == kptr) break; prev = k; @@ -1746,16 +1746,16 @@ save_killers(NHFILE *nhfp) struct kinfo *kptr; if (perform_bwrite(nhfp)) { - for (kptr = &gk.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) { + for (kptr = &svk.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) { if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) kptr, sizeof(struct kinfo)); } } if (release_data(nhfp)) { - while (gk.killer.next) { - kptr = gk.killer.next->next; - free((genericptr_t) gk.killer.next); - gk.killer.next = kptr; + while (svk.killer.next) { + kptr = svk.killer.next->next; + free((genericptr_t) svk.killer.next); + svk.killer.next = kptr; } } } @@ -1765,7 +1765,7 @@ restore_killers(NHFILE *nhfp) { struct kinfo *kptr; - for (kptr = &gk.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) { + for (kptr = &svk.killer; kptr != (struct kinfo *) 0; kptr = kptr->next) { if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) kptr, sizeof(struct kinfo)); if (kptr->next) { diff --git a/src/engrave.c b/src/engrave.c index 4d76ffe94..8e6232aeb 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -248,7 +248,7 @@ sengr_at(const char *s, coordxy x, coordxy y, boolean strict) { struct engr *ep = engr_at(x, y); - if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= gm.moves) { + if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= svm.moves) { if (strict ? !strcmpi(ep->engr_txt[actual_text], s) : (strstri(ep->engr_txt[actual_text], s) != 0)) return ep; @@ -355,7 +355,7 @@ read_engr_at(coordxy x, coordxy y) You("%s: \"%s\".", (Blind) ? "feel the words" : "read", et); Strcpy(ep->engr_txt[remembered_text], ep->engr_txt[actual_text]); ep->eread = 1; - if (gc.context.run > 0) + if (svc.context.run > 0) nomul(0); } } @@ -642,7 +642,7 @@ doengrave_sfx_item_WAN(struct _doengrave_ctx *de) ? "Chips fly out from the headstone." : de->frosted ? "Ice chips fly up from the ice surface!" - : (gl.level.locations[u.ux][u.uy].typ + : (svl.level.locations[u.ux][u.uy].typ == DRAWBRIDGE_DOWN) ? "Splinters fly up from the bridge." : "Gravel flies up from the floor."); @@ -1006,7 +1006,7 @@ doengrave(void) if (*de->buf) { struct engr *tmp_ep; - make_engr_at(u.ux, u.uy, de->buf, gm.moves, de->type); + make_engr_at(u.ux, u.uy, de->buf, svm.moves, de->type); tmp_ep = engr_at(u.ux, u.uy); if (!Blind) { if (tmp_ep != 0) { @@ -1167,13 +1167,13 @@ doengrave(void) de->disprefresh = TRUE; } - Strcpy(gc.context.engraving.text, de->ebuf); - gc.context.engraving.nextc = gc.context.engraving.text; - gc.context.engraving.stylus = de->otmp; - gc.context.engraving.type = de->type; - gc.context.engraving.pos.x = u.ux; - gc.context.engraving.pos.y = u.uy; - gc.context.engraving.actionct = 0; + Strcpy(svc.context.engraving.text, de->ebuf); + svc.context.engraving.nextc = svc.context.engraving.text; + svc.context.engraving.stylus = de->otmp; + svc.context.engraving.type = de->type; + svc.context.engraving.pos.x = u.ux; + svc.context.engraving.pos.y = u.uy; + svc.context.engraving.actionct = 0; set_occupation(engrave, "engraving", 0); if (de->post_engr_text[0]) @@ -1203,31 +1203,31 @@ engrave(void) char buf[BUFSZ]; /* holds the post-this-action engr text, including * anything already there */ const char *finishverb; /* "You finish [foo]." */ - struct obj * stylus; /* shorthand for gc.context.engraving.stylus */ - boolean firsttime = (gc.context.engraving.actionct == 0); + struct obj * stylus; /* shorthand for svc.context.engraving.stylus */ + boolean firsttime = (svc.context.engraving.actionct == 0); int rate = 10; /* # characters that can be engraved in this action */ boolean truncate = FALSE; - boolean neweng = (gc.context.engraving.actionct == 0); + boolean neweng = (svc.context.engraving.actionct == 0); - boolean carving = (gc.context.engraving.type == ENGRAVE - || gc.context.engraving.type == HEADSTONE); + boolean carving = (svc.context.engraving.type == ENGRAVE + || svc.context.engraving.type == HEADSTONE); boolean dulling_wep, marker; char *endc; /* points at character 1 beyond the last character to engrave * this action */ int i, space_left; - if (gc.context.engraving.pos.x != u.ux - || gc.context.engraving.pos.y != u.uy) { /* teleported? */ + if (svc.context.engraving.pos.x != u.ux + || svc.context.engraving.pos.y != u.uy) { /* teleported? */ You("are unable to continue engraving."); return 0; } /* Stylus might have been taken out of inventory and destroyed somehow. * Not safe to dereference stylus until after this. */ - if (gc.context.engraving.stylus == &hands_obj) { /* bare finger */ + if (svc.context.engraving.stylus == &hands_obj) { /* bare finger */ stylus = (struct obj *) 0; } else { for (stylus = gi.invent; stylus; stylus = stylus->nobj) { - if (stylus == gc.context.engraving.stylus) + if (stylus == svc.context.engraving.stylus) break; } if (!stylus) { @@ -1239,14 +1239,14 @@ engrave(void) dulling_wep = (carving && stylus && stylus->oclass == WEAPON_CLASS && (stylus->otyp != ATHAME || stylus->cursed)); marker = (stylus && stylus->otyp == MAGIC_MARKER - && gc.context.engraving.type == MARK); + && svc.context.engraving.type == MARK); - gc.context.engraving.actionct++; + svc.context.engraving.actionct++; /* sanity checks */ if (dulling_wep && !is_blade(stylus)) { impossible("carving with non-bladed weapon"); - } else if (gc.context.engraving.type == MARK && !marker) { + } else if (svc.context.engraving.type == MARK && !marker) { impossible("making graffiti with non-marker stylus"); } @@ -1263,7 +1263,7 @@ engrave(void) /* Step 2: Compute last character that can be engraved this action. */ i = rate; - for (endc = gc.context.engraving.nextc; *endc && i > 0; endc++) { + for (endc = svc.context.engraving.nextc; *endc && i > 0; endc++) { if (*endc != ' ') { i--; } @@ -1278,7 +1278,7 @@ engrave(void) if (stylus->quan > 1L) { if (firsttime) pline("One of %s gets dull.", yname(stylus)); - stylus = gc.context.engraving.stylus = splitobj(stylus, 1L); + stylus = svc.context.engraving.stylus = splitobj(stylus, 1L); /* if stack is wielded or quivered, the split-off one isn't */ stylus->owornmask = 0L; splitstack = TRUE; @@ -1295,7 +1295,7 @@ engrave(void) * engrave "Elbereth" all at once. * However, you can engrave "Elb", then "ere", then "th", by taking * advantage of the rounding down. */ - if (gc.context.engraving.actionct % 2 == 1) { /* 1st,3rd,... action */ + if (svc.context.engraving.actionct % 2 == 1) { /* 1st,3rd,... action */ /* deduct a point on 1st, 3rd, 5th, ... turns, unless this is the * last character being engraved (a rather convoluted way to round * down), but always deduct a point on the 1st turn to prevent @@ -1308,7 +1308,7 @@ engrave(void) impossible("<= -3 weapon valid for engraving"); } truncate = TRUE; - } else if (*endc || gc.context.engraving.actionct == 1) { + } else if (*endc || svc.context.engraving.actionct == 1) { stylus->spe -= 1; dulled = TRUE; } @@ -1340,7 +1340,7 @@ engrave(void) } } - switch (gc.context.engraving.type) { + switch (svc.context.engraving.type) { default: finishverb = "your weird engraving"; break; @@ -1371,9 +1371,9 @@ engrave(void) Strcpy(buf, oep->engr_txt[actual_text]); space_left = (int) (sizeof buf - strlen(buf) - 1U); - if (endc - gc.context.engraving.nextc > space_left) { + if (endc - svc.context.engraving.nextc > space_left) { You("run out of room to write."); - endc = gc.context.engraving.nextc + space_left; + endc = svc.context.engraving.nextc + space_left; truncate = TRUE; } @@ -1381,25 +1381,25 @@ engrave(void) * can't go any further. */ if (truncate && *endc != '\0') { *endc = '\0'; - You("are only able to write \"%s\".", gc.context.engraving.text); + You("are only able to write \"%s\".", svc.context.engraving.text); } else { /* input was not truncated; stylus may still have worn out on the last * character, though */ truncate = FALSE; } - (void) strncat(buf, gc.context.engraving.nextc, - min(space_left, endc - gc.context.engraving.nextc)); - make_engr_at(u.ux, u.uy, buf, gm.moves - gm.multi, - gc.context.engraving.type); + (void) strncat(buf, svc.context.engraving.nextc, + min(space_left, endc - svc.context.engraving.nextc)); + make_engr_at(u.ux, u.uy, buf, svm.moves - gm.multi, + svc.context.engraving.type); oep = engr_at(u.ux, u.uy); if (oep) oep->eread = 1; if (*endc) { - gc.context.engraving.nextc = endc; + svc.context.engraving.nextc = endc; if (neweng) { - newsym(gc.context.engraving.pos.x, gc.context.engraving.pos.y); + newsym(svc.context.engraving.pos.x, svc.context.engraving.pos.y); } return 1; /* not yet finished this turn */ } else { /* finished engraving */ @@ -1413,12 +1413,12 @@ engrave(void) /* only print this if engraving took multiple actions */ You("finish %s.", finishverb); } - gc.context.engraving.text[0] = '\0'; - gc.context.engraving.nextc = (char *) 0; - gc.context.engraving.stylus = (struct obj *) 0; + svc.context.engraving.text[0] = '\0'; + svc.context.engraving.nextc = (char *) 0; + svc.context.engraving.stylus = (struct obj *) 0; } if (neweng) - newsym(gc.context.engraving.pos.x, gc.context.engraving.pos.y); + newsym(svc.context.engraving.pos.x, svc.context.engraving.pos.y); return 0; } @@ -1521,7 +1521,7 @@ rest_engravings(NHFILE *nhfp) /* mark as finished for bones levels -- no problem for * normal levels as the player must have finished engraving * to be able to move again */ - ep->engr_time = gm.moves; + ep->engr_time = svm.moves; } } diff --git a/src/exper.c b/src/exper.c index 55cbef056..d55f9abab 100644 --- a/src/exper.c +++ b/src/exper.c @@ -231,9 +231,9 @@ losexp( SoundAchievement(0, sa2_xpleveldown, 0); } else { /* u.ulevel==1 */ if (drainer) { - gk.killer.format = KILLED_BY; - if (gk.killer.name != drainer) - Strcpy(gk.killer.name, drainer); + svk.killer.format = KILLED_BY; + if (svk.killer.name != drainer) + Strcpy(svk.killer.name, drainer); done(DIED); } /* no drainer or lifesaved */ diff --git a/src/explode.c b/src/explode.c index c2b76bf4a..1b0991dac 100644 --- a/src/explode.c +++ b/src/explode.c @@ -296,9 +296,9 @@ explode( */ if (olet == MON_EXPLODE && !you_exploding) { - /* when explode() is called recursively, gk.killer.name might change so + /* when explode() is called recursively, svk.killer.name might change so we need to retain a copy of the current value for this explosion */ - str = strcpy(killr_buf, gk.killer.name); + str = strcpy(killr_buf, svk.killer.name); do_hallu = (Hallucination && (strstri(str, "'s explosion") || strstri(str, "s' explosion"))); @@ -468,7 +468,7 @@ explode( * with an explosion attack, leave them (and their gear) * unharmed, to avoid punishing them from using such * polyforms creatively */ - if (!gc.context.mon_moving && you_exploding) + if (!svc.context.mon_moving && you_exploding) uhurt = 0; } else if (inside_engulfer) { /* for inside_engulfer, only is affected */ @@ -477,7 +477,7 @@ explode( /* Affect the floor unless the player caused the explosion * from inside their engulfer. */ - if (!(u.uswallow && !gc.context.mon_moving)) + if (!(u.uswallow && !svc.context.mon_moving)) (void) zap_over_floor(xx, yy, type, &shopdamage, FALSE, exploding_wand_typ); @@ -557,7 +557,7 @@ explode( && completelyburns(mtmp->data)) ? XKILL_NOCORPSE : 0); - if (!gc.context.mon_moving) { + if (!svc.context.mon_moving) { xkilled(mtmp, XKILL_GIVEMSG | xkflg); } else if (mdef && mtmp == mdef) { /* 'mdef' killed self trying to cure being turned @@ -579,7 +579,7 @@ explode( adtyp = AD_RBRE; /* no corpse */ monkilled(mtmp, "", (int) adtyp); } - } else if (!gc.context.mon_moving) { + } else if (!svc.context.mon_moving) { /* all affected monsters, even if mdef is set */ setmangry(mtmp, TRUE); } @@ -644,26 +644,26 @@ explode( } else { if (olet == MON_EXPLODE) { if (generic) /* explosion was unseen; str=="explosion", */ - ; /* gk.killer.name=="gas spore's explosion". */ - else if (str != gk.killer.name && str != hallu_buf) - Strcpy(gk.killer.name, str); - gk.killer.format = KILLED_BY_AN; + ; /* svk.killer.name=="gas spore's explosion". */ + else if (str != svk.killer.name && str != hallu_buf) + Strcpy(svk.killer.name, str); + svk.killer.format = KILLED_BY_AN; } else if (olet == TRAP_EXPLODE) { - gk.killer.format = NO_KILLER_PREFIX; - Snprintf(gk.killer.name, sizeof gk.killer.name, + svk.killer.format = NO_KILLER_PREFIX; + Snprintf(svk.killer.name, sizeof svk.killer.name, "caught %sself in a %s", uhim(), str); } else if (type >= 0 && olet != SCROLL_CLASS) { - gk.killer.format = NO_KILLER_PREFIX; - Snprintf(gk.killer.name, sizeof gk.killer.name, + svk.killer.format = NO_KILLER_PREFIX; + Snprintf(svk.killer.name, sizeof svk.killer.name, "caught %sself in %s own %s", uhim(), uhis(), str); } else { - gk.killer.format = (!strcmpi(str, "tower of flame") + svk.killer.format = (!strcmpi(str, "tower of flame") || !strcmpi(str, "fireball")) ? KILLED_BY_AN : KILLED_BY; - Strcpy(gk.killer.name, str); + Strcpy(svk.killer.name, str); } if (iflags.last_msg == PLNMSG_CAUGHT_IN_EXPLOSION || iflags.last_msg == PLNMSG_TOWER_OF_FLAME) /*seffects()*/ @@ -745,7 +745,7 @@ scatter(coordxy sx, coordxy sy, /* location of objects to scatter */ if (shop_origin) credit_report(shkp, 0, TRUE); /* establish baseline, without msgs */ - while ((otmp = (individual_object ? obj : gl.level.objects[sx][sy])) != 0) { + while ((otmp = (individual_object ? obj : svl.level.objects[sx][sy])) != 0) { if (otmp == uball || otmp == uchain) { boolean waschain = (otmp == uchain); @@ -1047,15 +1047,15 @@ mon_explodes(struct monst *mon, struct attack *mattk) /* This might end up killing you, too; you never know... * also, it is used in explode() messages */ - Sprintf(gk.killer.name, "%s explosion", + Sprintf(svk.killer.name, "%s explosion", s_suffix(pmname(mon->data, Mgender(mon)))); - gk.killer.format = KILLED_BY_AN; + svk.killer.format = KILLED_BY_AN; explode(mon->mx, mon->my, type, dmg, MON_EXPLODE, adtyp_to_expltype(mattk->adtyp)); /* reset killer */ - gk.killer.name[0] = '\0'; + svk.killer.name[0] = '\0'; } /*explode.c*/ diff --git a/src/extralev.c b/src/extralev.c index a6c733ff6..971bf08c1 100644 --- a/src/extralev.c +++ b/src/extralev.c @@ -60,7 +60,7 @@ roguecorr(coordxy x, coordxy y, int dir) fromy += 7 * y; if (!IS_WALL(levl[fromx][fromy].typ)) impossible("down: no wall at %d,%d?", fromx, fromy); - dodoor(fromx, fromy, &gr.rooms[gr.r[x][y].nroom]); + dodoor(fromx, fromy, &svr.rooms[gr.r[x][y].nroom]); levl[fromx][fromy].doormask = D_NODOOR; fromy++; } @@ -82,7 +82,7 @@ roguecorr(coordxy x, coordxy y, int dir) toy += 7 * y; if (!IS_WALL(levl[tox][toy].typ)) impossible("up: no wall at %d,%d?", tox, toy); - dodoor(tox, toy, &gr.rooms[gr.r[x][y].nroom]); + dodoor(tox, toy, &svr.rooms[gr.r[x][y].nroom]); levl[tox][toy].doormask = D_NODOOR; toy--; } @@ -102,7 +102,7 @@ roguecorr(coordxy x, coordxy y, int dir) fromy += 7 * y; if (!IS_WALL(levl[fromx][fromy].typ)) impossible("down: no wall at %d,%d?", fromx, fromy); - dodoor(fromx, fromy, &gr.rooms[gr.r[x][y].nroom]); + dodoor(fromx, fromy, &svr.rooms[gr.r[x][y].nroom]); levl[fromx][fromy].doormask = D_NODOOR; fromx++; } @@ -124,7 +124,7 @@ roguecorr(coordxy x, coordxy y, int dir) toy += 7 * y; if (!IS_WALL(levl[tox][toy].typ)) impossible("left: no wall at %d,%d?", tox, toy); - dodoor(tox, toy, &gr.rooms[gr.r[x][y].nroom]); + dodoor(tox, toy, &svr.rooms[gr.r[x][y].nroom]); levl[tox][toy].doormask = D_NODOOR; tox--; } @@ -211,13 +211,13 @@ makeroguerooms(void) */ #define here gr.r[x][y] - gn.nroom = 0; + svn.nroom = 0; for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) { /* Note: we want to insure at least 1 room. So, if the * first 8 are all dummies, force the last to be a room. */ - if (!rn2(5) && (gn.nroom || (x < 2 && y < 2))) { + if (!rn2(5) && (svn.nroom || (x < 2 && y < 2))) { /* Arbitrary: dummy rooms may only go where real * ones do. */ @@ -232,19 +232,19 @@ makeroguerooms(void) /* boundaries of room floor */ here.rlx = rnd(23 - here.dx + 1); here.rly = rnd(((y == 2) ? 5 : 4) - here.dy + 1); - gn.nroom++; + svn.nroom++; } here.doortable = 0; } miniwalk(rn2(3), rn2(3)); - gn.nroom = 0; + svn.nroom = 0; for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) { if (here.real) { /* Make a room */ coordxy lowx, lowy, hix, hiy; - gr.r[x][y].nroom = gn.nroom; - gs.smeq[gn.nroom] = gn.nroom; + gr.r[x][y].nroom = svn.nroom; + gs.smeq[svn.nroom] = svn.nroom; lowx = 1 + 26 * x + here.rlx; lowy = 7 * y + here.rly; @@ -292,9 +292,9 @@ makerogueghost(void) struct mkroom *croom; coordxy x, y; - if (!gn.nroom) + if (!svn.nroom) return; /* Should never happen */ - croom = &gr.rooms[rn2(gn.nroom)]; + croom = &svr.rooms[rn2(svn.nroom)]; x = somex(croom); y = somey(croom); if (!(ghost = makemon(&mons[PM_GHOST], x, y, NO_MM_FLAGS))) diff --git a/src/files.c b/src/files.c index 5771bc118..5ff98d560 100644 --- a/src/files.c +++ b/src/files.c @@ -632,7 +632,7 @@ create_levelfile(int lev, char errbuf[]) #endif /* MICRO || WIN32 */ if (nhfp->fd >= 0) - gl.level_info[lev].flags |= LFILE_EXISTS; + svl.level_info[lev].flags |= LFILE_EXISTS; else if (errbuf) /* failure explanation */ Sprintf(errbuf, "Cannot create file \"%s\" for level %d (errno %d).", @@ -690,10 +690,10 @@ delete_levelfile(int lev) * Level 0 might be created by port specific code that doesn't * call create_levfile(), so always assume that it exists. */ - if (lev == 0 || (gl.level_info[lev].flags & LFILE_EXISTS)) { + if (lev == 0 || (svl.level_info[lev].flags & LFILE_EXISTS)) { set_levelfile_name(gl.lock, lev); (void) unlink(fqname(gl.lock, LEVELPREFIX, 0)); - gl.level_info[lev].flags &= ~LFILE_EXISTS; + svl.level_info[lev].flags &= ~LFILE_EXISTS; } } @@ -703,7 +703,7 @@ clearlocks(void) int x; #ifdef HANGUPHANDLING - if (gp.program_state.preserve_locks) + if (svp.program_state.preserve_locks) return; #endif #ifndef NO_SIGNAL @@ -713,7 +713,7 @@ clearlocks(void) #endif #endif /* NO_SIGNAL */ /* can't access maxledgerno() before dungeons are created -dlc */ - for (x = (gn.n_dgns ? maxledgerno() : 0); x >= 0; x--) + for (x = (svn.n_dgns ? maxledgerno() : 0); x >= 0; x--) delete_levelfile(x); /* not all levels need be present */ } @@ -782,7 +782,7 @@ set_bonesfile_name(char *file, d_level *lev) dptr = eos(file); /* when this naming scheme was adopted, 'filecode' was one letter; 3.3.0 turned it into a three letter string for quest levels */ - Sprintf(dptr, "%c%s", gd.dungeons[lev->dnum].boneid, + Sprintf(dptr, "%c%s", svd.dungeons[lev->dnum].boneid, In_quest(lev) ? gu.urole.filecode : "0"); if ((sptr = Is_special(lev)) != 0) Sprintf(eos(dptr), ".%c", sptr->boneid); @@ -944,7 +944,7 @@ compress_bonesfile(void) /* ---------- BEGIN SAVE FILE HANDLING ----------- */ -/* set savefile name in OS-dependent manner from pre-existing gp.plname, +/* set savefile name in OS-dependent manner from pre-existing svp.plname, * avoiding troublesome characters */ void set_savefile_name(boolean regularize_it) @@ -958,7 +958,7 @@ set_savefile_name(boolean regularize_it) #endif #ifdef VMS - Sprintf(gs.SAVEF, "[.save]%d%s", getuid(), gp.plname); + Sprintf(gs.SAVEF, "[.save]%d%s", getuid(), svp.plname); regoffset = 7; indicator_spot = 1; postappend = ";1"; @@ -970,9 +970,9 @@ set_savefile_name(boolean regularize_it) const char *legal = okchars; ++legal; /* skip '*' wildcard character */ - (void) fname_encode(legal, '%', gp.plname, tmp, sizeof tmp); + (void) fname_encode(legal, '%', svp.plname, tmp, sizeof tmp); } else { - Sprintf(tmp, "%s", gp.plname); + Sprintf(tmp, "%s", svp.plname); } if (strlen(tmp) < (SAVESIZE - 1)) Strcpy(gs.SAVEF, tmp); @@ -982,7 +982,7 @@ set_savefile_name(boolean regularize_it) regularize_it = FALSE; #endif #ifdef UNIX - Sprintf(gs.SAVEF, "save/%d%s", (int) getuid(), gp.plname); + Sprintf(gs.SAVEF, "save/%d%s", (int) getuid(), svp.plname); regoffset = 5; indicator_spot = 2; #endif @@ -990,7 +990,7 @@ set_savefile_name(boolean regularize_it) if (strlen(gs.SAVEP) < (SAVESIZE - 1)) Strcpy(gs.SAVEF, gs.SAVEP); if (strlen(gs.SAVEF) < (SAVESIZE - 1)) - (void) strncat(gs.SAVEF, gp.plname, (SAVESIZE - strlen(gs.SAVEF))); + (void) strncat(gs.SAVEF, svp.plname, (SAVESIZE - strlen(gs.SAVEF))); #endif #if defined(MICRO) && !defined(VMS) && !defined(WIN32) && !defined(MSDOS) if (strlen(gs.SAVEP) < (SAVESIZE - 1)) @@ -1003,11 +1003,11 @@ set_savefile_name(boolean regularize_it) { int i = strlen(gs.SAVEP); #ifdef AMIGA - /* gp.plname has to share space with gs.SAVEP and ".sav" */ - (void) strncat(gs.SAVEF, gp.plname, + /* svp.plname has to share space with gs.SAVEP and ".sav" */ + (void) strncat(gs.SAVEF, svp.plname, FILENAME - i - strlen(SAVE_EXTENSION)); #else - (void) strncat(gs.SAVEF, gp.plname, 8); + (void) strncat(gs.SAVEF, svp.plname, 8); #endif regoffset = i; } @@ -1101,7 +1101,7 @@ create_savefile(void) nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_SAVEFILE; nhfp->mode = WRITING; - if (gp.program_state.in_self_recover || do_historical) { + if (svp.program_state.in_self_recover || do_historical) { do_historical = TRUE; /* force it */ nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; @@ -1155,7 +1155,7 @@ open_savefile(void) nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_SAVEFILE; nhfp->mode = READING; - if (gp.program_state.in_self_recover || do_historical) { + if (svp.program_state.in_self_recover || do_historical) { do_historical = TRUE; /* force it */ nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; @@ -1337,7 +1337,7 @@ get_saved_games(void) char **files = 0; int i, count_failures = 0; - Strcpy(gp.plname, "*"); + Strcpy(svp.plname, "*"); set_savefile_name(FALSE); #if defined(ZLIB_COMP) Strcat(gs.SAVEF, COMPRESS_EXTENSION); @@ -1372,7 +1372,7 @@ get_saved_games(void) if (r) { /* rename file if it is not named as expected */ - Strcpy(gp.plname, r); + Strcpy(svp.plname, r); set_savefile_name(TRUE); fq_new_save = fqname(gs.SAVEF, SAVEPREFIX, 0); fq_old_save = fqname(files[i], SAVEPREFIX, 1); @@ -1434,7 +1434,7 @@ get_saved_games(void) } #endif #ifdef VMS - Strcpy(gp.plname, "*"); + Strcpy(svp.plname, "*"); set_savefile_name(FALSE); j = vms_get_saved_games(gs.SAVEF, &result); #endif /* VMS */ @@ -1875,7 +1875,7 @@ static struct flock sflock; /* for unlocking, same as above */ #endif #if defined(HANGUPHANDLING) -#define HUP if (!gp.program_state.done_hup) +#define HUP if (!svp.program_state.done_hup) #else #define HUP #endif @@ -2728,7 +2728,7 @@ cnf_line_TROUBLEDIR(char *bufp) staticfn boolean cnf_line_NAME(char *bufp) { - (void) strncpy(gp.plname, bufp, PL_NSIZ - 1); + (void) strncpy(svp.plname, bufp, PL_NSIZ - 1); return TRUE; } @@ -3447,7 +3447,7 @@ config_error_init(boolean from_file, const char *sourcename, boolean secure) tmp->next = config_error_data; config_error_data = tmp; - gp.program_state.config_error_ready = TRUE; + svp.program_state.config_error_ready = TRUE; } staticfn boolean @@ -3513,7 +3513,7 @@ config_erradd(const char *buf) punct = c_eos((char *) buf) - 1; /* eos(buf)-1 is valid */ punct = strchr(".!?", *punct) ? "" : "."; - if (!gp.program_state.config_error_ready) { + if (!svp.program_state.config_error_ready) { /* either very early, where pline() will use raw_print(), or player gave bad value when prompted by interactive 'O' command */ pline("%s%s%s", !iflags.window_inited ? "config_error_add: " : "", @@ -3575,7 +3575,7 @@ config_error_done(void) } config_error_data = tmp->next; free(tmp); - gp.program_state.config_error_ready = (config_error_data != 0); + svp.program_state.config_error_ready = (config_error_data != 0); return n; } @@ -3978,14 +3978,14 @@ read_wizkit(void) if (!wizard || !(fp = fopen_wizkit_file())) return; - gp.program_state.wizkit_wishing = 1; + svp.program_state.wizkit_wishing = 1; config_error_init(TRUE, "WIZKIT", FALSE); parse_conf_file(fp, proc_wizkit_line); (void) fclose(fp); config_error_done(); - gp.program_state.wizkit_wishing = 0; + svp.program_state.wizkit_wishing = 0; return; } @@ -4195,13 +4195,13 @@ paniclog( #ifdef PANICLOG FILE *lfile; - if (!gp.program_state.in_paniclog) { - gp.program_state.in_paniclog = 1; + if (!svp.program_state.in_paniclog) { + svp.program_state.in_paniclog = 1; lfile = fopen_datafile(PANICLOG, "a", TROUBLEPREFIX); if (lfile) { #ifdef PANICLOG_FMT2 (void) fprintf(lfile, "%ld %s: %s %s\n", - ubirthday, (gp.plname[0] ? gp.plname : "(none)"), + ubirthday, (svp.plname[0] ? svp.plname : "(none)"), type, reason); #else char buf[BUFSZ]; @@ -4216,7 +4216,7 @@ paniclog( #endif /* !PANICLOG_FMT2 */ (void) fclose(lfile); } - gp.program_state.in_paniclog = 0; + svp.program_state.in_paniclog = 0; } #endif /* PANICLOG */ return; @@ -4323,9 +4323,9 @@ recover_savefile(void) /* * Set a flag for the savefile routines to know the * circumstances and act accordingly: - * gp.program_state.in_self_recover + * svp.program_state.in_self_recover */ - gp.program_state.in_self_recover = TRUE; + svp.program_state.in_self_recover = TRUE; set_savefile_name(TRUE); snhfp = create_savefile(); if (!snhfp) { @@ -4433,11 +4433,11 @@ recover_savefile(void) close_nhfile(gnhfp); close_nhfile(snhfp); close_nhfile(lnhfp); - gp.program_state.in_self_recover = FALSE; + svp.program_state.in_self_recover = FALSE; delete_savefile(); return FALSE; } - /* we don't clear gp.program_state.in_self_recover here, we + /* we don't clear svp.program_state.in_self_recover here, we leave it as a flag to reload the structlevel savefile in the caller. The caller should then clear it. */ return TRUE; @@ -4789,7 +4789,7 @@ reveal_paths(void) #define TITLESCOPE 2 #define PASSAGESCOPE 3 -#define MAXPASSAGES SIZE(gc.context.novel.pasg) /* 20 */ +#define MAXPASSAGES SIZE(svc.context.novel.pasg) /* 20 */ staticfn int choose_passage(int, unsigned); @@ -4807,32 +4807,32 @@ choose_passage(int passagecnt, /* total of available passages */ /* if a different book or we've used up all the passages already, reset in order to have all 'passagecnt' passages available */ - if (oid != gc.context.novel.id || gc.context.novel.count == 0) { + if (oid != svc.context.novel.id || svc.context.novel.count == 0) { int i, range = passagecnt, limit = MAXPASSAGES; - gc.context.novel.id = oid; + svc.context.novel.id = oid; if (range <= limit) { /* collect all of the N indices */ - gc.context.novel.count = passagecnt; + svc.context.novel.count = passagecnt; for (idx = 0; idx < MAXPASSAGES; idx++) - gc.context.novel.pasg[idx] = (xint16) ((idx < passagecnt) + svc.context.novel.pasg[idx] = (xint16) ((idx < passagecnt) ? idx + 1 : 0); } else { /* collect MAXPASSAGES of the N indices */ - gc.context.novel.count = MAXPASSAGES; + svc.context.novel.count = MAXPASSAGES; for (idx = i = 0; i < passagecnt; ++i, --range) if (range > 0 && rn2(range) < limit) { - gc.context.novel.pasg[idx++] = (xint16) (i + 1); + svc.context.novel.pasg[idx++] = (xint16) (i + 1); --limit; } } } - idx = rn2(gc.context.novel.count); - res = (int) gc.context.novel.pasg[idx]; + idx = rn2(svc.context.novel.count); + res = (int) svc.context.novel.pasg[idx]; /* move the last slot's passage index into the slot just used and reduce the number of passages available */ - gc.context.novel.pasg[idx] = gc.context.novel.pasg[--gc.context.novel.count]; + svc.context.novel.pasg[idx] = svc.context.novel.pasg[--svc.context.novel.count]; return res; } @@ -5061,10 +5061,10 @@ livelog_add(long ll_type, const char *str) "gender=%s" LLOG_SEP "align=%s" LLOG_SEP "turns=%ld" LLOG_SEP "starttime=%ld" LLOG_SEP "curtime=%ld" LLOG_SEP "message=%s" LLOG_EOL, - (ll_type & sysopt.livelog), gp.plname, + (ll_type & sysopt.livelog), svp.plname, gu.urole.filecode, gu.urace.filecode, genders[gindx].filecode, aligns[aindx].filecode, - gm.moves, timet_to_seconds(ubirthday), + svm.moves, timet_to_seconds(ubirthday), timet_to_seconds(now), str); (void) fclose(livelogfile); unlock_file(LIVELOGFILE); diff --git a/src/fountain.c b/src/fountain.c index 0ca38f795..a4db9898d 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -40,7 +40,7 @@ dowatersnakes(void) int num = rn1(5, 2); struct monst *mtmp; - if (!(gm.mvitals[PM_WATER_MOCCASIN].mvflags & G_GONE)) { + if (!(svm.mvitals[PM_WATER_MOCCASIN].mvflags & G_GONE)) { if (!Blind) { pline("An endless stream of %s pours forth!", Hallucination ? makeplural(rndmonnam(NULL)) : "snakes"); @@ -65,7 +65,7 @@ dowaterdemon(void) { struct monst *mtmp; - if (!(gm.mvitals[PM_WATER_DEMON].mvflags & G_GONE)) { + if (!(svm.mvitals[PM_WATER_DEMON].mvflags & G_GONE)) { if ((mtmp = makemon(&mons[PM_WATER_DEMON], u.ux, u.uy, MM_NOMSG)) != 0) { if (!Blind) @@ -95,7 +95,7 @@ dowaternymph(void) { struct monst *mtmp; - if (!(gm.mvitals[PM_WATER_NYMPH].mvflags & G_GONE) + if (!(svm.mvitals[PM_WATER_NYMPH].mvflags & G_GONE) && (mtmp = makemon(&mons[PM_WATER_NYMPH], u.ux, u.uy, MM_NOMSG)) != 0) { if (!Blind) @@ -152,7 +152,7 @@ gush(coordxy x, coordxy y, genericptr_t poolcnt) levl[x][y].flags = 0; /* No kelp! */ del_engr_at(x, y); - water_damage_chain(gl.level.objects[x][y], TRUE); + water_damage_chain(svl.level.objects[x][y], TRUE); if ((mtmp = m_at(x, y)) != 0) (void) minliquid(mtmp); @@ -613,7 +613,7 @@ drinksink(void) /* boiling water burns considered fire damage */ break; case 3: - if (gm.mvitals[PM_SEWER_RAT].mvflags & G_GONE) + if (svm.mvitals[PM_SEWER_RAT].mvflags & G_GONE) pline_The("sink seems quite dirty."); else { mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy, MM_NOMSG); @@ -655,7 +655,7 @@ drinksink(void) break; case 7: pline_The("%s moves as though of its own will!", hliquid("water")); - if ((gm.mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE) + if ((svm.mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE) || !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy, MM_NOMSG)) pline("But it quiets down."); break; diff --git a/src/getpos.c b/src/getpos.c index c6c9aa78b..3457d70e7 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -1054,7 +1054,7 @@ getpos(coord *ccp, boolean force, const char *goal) goto foundc; /* next, try glyph that's remembered here (might be trap or object) */ - if (gl.level.flags.hero_memory + if (svl.level.flags.hero_memory /* !terrainmode: don't move to remembered trap or object if not currently shown */ && !iflags.terrainmode) { @@ -1064,7 +1064,7 @@ getpos(coord *ccp, boolean force, const char *goal) goto foundc; } /* last, try actual terrain here (shouldn't - we be using gl.lastseentyp[][] instead?) */ + we be using svl.lastseentyp[][] instead?) */ if (levl[tx][ty].seenv) { k = back_to_glyph(tx, ty); if (glyph_is_cmap(k) diff --git a/src/hack.c b/src/hack.c index 886215770..8a47f5b69 100644 --- a/src/hack.c +++ b/src/hack.c @@ -43,7 +43,7 @@ staticfn boolean doorless_door(coordxy, coordxy); staticfn void maybe_wail(void); staticfn boolean water_turbulence(coordxy *, coordxy *); -#define IS_SHOP(x) (gr.rooms[x].rtype >= SHOPBASE) +#define IS_SHOP(x) (svr.rooms[x].rtype >= SHOPBASE) /* XXX: if more sources of water walking than just boots are added, cause_known(insight.c) should be externified and used for this */ @@ -100,7 +100,7 @@ revive_nasty(coordxy x, coordxy y, const char *msg) coord cc; boolean revived = FALSE; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; if (otmp->otyp == CORPSE && (is_rider(&mons[otmp->corpsenm]) @@ -184,7 +184,7 @@ moverock(void) firstboulder = FALSE; /* make sure that this boulder is visible as the top object */ - if (otmp != gl.level.objects[sx][sy]) + if (otmp != svl.level.objects[sx][sy]) movobj(otmp, sx, sy); rx = u.ux + 2 * u.dx; /* boulder destination position */ @@ -195,7 +195,7 @@ moverock(void) poly'd into a giant or squeezes under/beside it if small/light enough but is a no-op in other circumstances unless move attempt reveals an unseen boulder or lack of remembered, unseen monster */ - if (gc.context.nopick) { + if (svc.context.nopick) { int oldglyph = glyph_at(sx, sy); /* before feel_location() */ feel_location(sx, sy); /* same for all 3 if/else-if/else cases */ @@ -218,7 +218,7 @@ moverock(void) /* use a move if hero learns something; see test_move() for how/why 'context.door_opened' is being dragged into this */ if (glyph_at(sx, sy) != oldglyph) - gc.context.door_opened = gc.context.move = TRUE; + svc.context.door_opened = svc.context.move = TRUE; res = -1; /* don't move to , so no soko guilt */ } goto moverock_done; /* stop further push attempts */ @@ -435,11 +435,11 @@ moverock(void) unlike with Norep(), intervening messages don't cause it to repeat, only doing something else in the meantime */ if (otmp->o_id != gb.bldrpush_oid) { - gb.bldrpushtime = gm.moves + 1L; + gb.bldrpushtime = svm.moves + 1L; gb.bldrpush_oid = otmp->o_id; } - givemesg = (gm.moves > gb.bldrpushtime + 2L - || gm.moves < gb.bldrpushtime); + givemesg = (svm.moves > gb.bldrpushtime + 2L + || svm.moves < gb.bldrpushtime); what = givemesg ? the(xname(otmp)) : 0; if (!u.usteed) { easypush = throws_rocks(gy.youmonst.data); @@ -452,7 +452,7 @@ moverock(void) if (givemesg) pline("%s moves %s.", YMonnam(u.usteed), what); } - gb.bldrpushtime = gm.moves; + gb.bldrpushtime = svm.moves; } /* Move the boulder *after* the message. */ @@ -505,7 +505,7 @@ moverock(void) && (inv_cnt(FALSE) < invlet_basic || !carrying(BOULDER))), willpickup = (canpickup - && (flags.pickup && !gc.context.nopick) + && (flags.pickup && !svc.context.nopick) && autopick_testobj(otmp, TRUE)); if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) { @@ -549,7 +549,7 @@ moverock(void) res = 0; moverock_done: - for (otmp = gl.level.objects[sx][sy]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[sx][sy]; otmp; otmp = otmp->nexthere) if (otmp->otyp == BOULDER) otmp->next_boulder = 0; /* resume normal xname() for this obj */ @@ -569,8 +569,8 @@ still_chewing(coordxy x, coordxy y) struct obj *boulder = sobj_at(BOULDER, x, y); const char *digtxt = (char *) 0, *dmgtxt = (char *) 0; - if (gc.context.digging.down) /* not continuing previous dig (w/ pick-axe) */ - (void) memset((genericptr_t) &gc.context.digging, 0, + if (svc.context.digging.down) /* not continuing previous dig (w/ pick-axe) */ + (void) memset((genericptr_t) &svc.context.digging, 0, sizeof (struct dig_info)); if (!boulder @@ -591,18 +591,18 @@ still_chewing(coordxy x, coordxy y) You("are too full to eat the bars."); nomul(0); return 1; - } else if (!gc.context.digging.chew - || gc.context.digging.pos.x != x - || gc.context.digging.pos.y != y - || !on_level(&gc.context.digging.level, &u.uz)) { - gc.context.digging.down = FALSE; - gc.context.digging.chew = TRUE; - gc.context.digging.warned = FALSE; - gc.context.digging.pos.x = x; - gc.context.digging.pos.y = y; - assign_level(&gc.context.digging.level, &u.uz); + } else if (!svc.context.digging.chew + || svc.context.digging.pos.x != x + || svc.context.digging.pos.y != y + || !on_level(&svc.context.digging.level, &u.uz)) { + svc.context.digging.down = FALSE; + svc.context.digging.chew = TRUE; + svc.context.digging.warned = FALSE; + svc.context.digging.pos.x = x; + svc.context.digging.pos.y = y; + assign_level(&svc.context.digging.level, &u.uz); /* solid rock takes more work & time to dig through */ - gc.context.digging.effort = + svc.context.digging.effort = (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc; You("start chewing %s %s.", (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS) @@ -619,10 +619,10 @@ still_chewing(coordxy x, coordxy y) : "door"); watch_dig((struct monst *) 0, x, y, FALSE); return 1; - } else if ((gc.context.digging.effort += (30 + u.udaminc)) <= 100) { + } else if ((svc.context.digging.effort += (30 + u.udaminc)) <= 100) { if (flags.verbose) You("%s chewing on the %s.", - gc.context.digging.chew ? "continue" : "begin", + svc.context.digging.chew ? "continue" : "begin", boulder ? "boulder" : IS_TREE(lev->typ) @@ -632,7 +632,7 @@ still_chewing(coordxy x, coordxy y) : (lev->typ == IRONBARS) ? "bars" : "door"); - gc.context.digging.chew = TRUE; + svc.context.digging.chew = TRUE; watch_dig((struct monst *) 0, x, y, FALSE); return 1; } @@ -663,7 +663,7 @@ still_chewing(coordxy x, coordxy y) || sobj_at(BOULDER, x, y)) { block_point(x, y); /* delobj will unblock the point */ /* reset dig state */ - (void) memset((genericptr_t) &gc.context.digging, 0, + (void) memset((genericptr_t) &svc.context.digging, 0, sizeof (struct dig_info)); return 1; } @@ -674,9 +674,9 @@ still_chewing(coordxy x, coordxy y) dmgtxt = "damage"; } digtxt = "chew a hole in the wall."; - if (gl.level.flags.is_maze_lev) { + if (svl.level.flags.is_maze_lev) { lev->typ = ROOM; - } else if (gl.level.flags.is_cavernous_lev && !in_town(x, y)) { + } else if (svl.level.flags.is_cavernous_lev && !in_town(x, y)) { lev->typ = CORR; } else { lev->typ = DOOR; @@ -735,7 +735,7 @@ still_chewing(coordxy x, coordxy y) You1(digtxt); /* after newsym */ if (dmgtxt) pay_for_damage(dmgtxt, FALSE); - (void) memset((genericptr_t) &gc.context.digging, 0, + (void) memset((genericptr_t) &svc.context.digging, 0, sizeof (struct dig_info)); return 0; } @@ -783,7 +783,7 @@ dosinkfall(void) losehp(Maybe_Half_Phys(dmg), fell_on_sink, NO_KILLER_PREFIX); exercise(A_DEX, FALSE); selftouch("Falling, you"); - for (obj = gl.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) + for (obj = svl.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) { You("fell on %s.", doname(obj)); losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink, @@ -901,7 +901,7 @@ boolean invocation_pos(coordxy x, coordxy y) { return (boolean) (Invocation_lev(&u.uz) - && x == gi.inv_pos.x && y == gi.inv_pos.y); + && x == svi.inv_pos.x && y == svi.inv_pos.y); } /* return TRUE if (dx,dy) is an OK place to move; @@ -917,7 +917,7 @@ test_move( struct rm *tmpr = &levl[x][y]; struct rm *ust; - gc.context.door_opened = FALSE; + svc.context.door_opened = FALSE; /* * Check for physical obstacles. First, the place we are going. */ @@ -951,7 +951,7 @@ test_move( /* Eat the rock. */ if (mode == DO_MOVE && still_chewing(x, y)) return FALSE; - } else if (flags.autodig && !gc.context.run && !gc.context.nopick + } else if (flags.autodig && !svc.context.run && !svc.context.nopick && uwep && is_pick(uwep)) { /* MRKR: Automatic digging when wielding the appropriate tool */ if (mode == DO_MOVE) @@ -1005,10 +1005,10 @@ test_move( if (amorphous(gy.youmonst.data)) You("try to ooze under the door," " but can't squeeze your possessions through."); - if (flags.autoopen && !gc.context.run + if (flags.autoopen && !svc.context.run && !Confusion && !Stunned && !Fumbling) { - gc.context.door_opened - = gc.context.move + svc.context.door_opened + = svc.context.move = (doopen_indir(x, y) == ECMD_TIME ? 1 : 0); } else if (x == ux || y == uy) { if (Blind || Stunned || ACURR(A_DEX) < 10 @@ -1025,7 +1025,7 @@ test_move( we haven't opened a door but we're going to return False and without having 'door_opened' set, 'move' would get reset by caller */ - gc.context.door_opened = gc.context.move = TRUE; + svc.context.door_opened = svc.context.move = TRUE; /* since we've just lied about successfully moving, we need to manually stop running */ nomul(0); @@ -1079,7 +1079,7 @@ test_move( /* Pick travel path that does not require crossing a trap. * Avoid water and lava using the usual running rules. * (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */ - if (gc.context.run == 8 && (mode != DO_MOVE) && !u_at(x, y)) { + if (svc.context.run == 8 && (mode != DO_MOVE) && !u_at(x, y)) { struct trap *t = t_at(x, y); if (t && t->tseen && t->ttyp != VIBRATING_SQUARE) @@ -1115,7 +1115,7 @@ test_move( } if (sobj_at(BOULDER, x, y) && (Sokoban || !Passes_walls)) { - if (mode != TEST_TRAV && gc.context.run >= 2 + if (mode != TEST_TRAV && svc.context.run >= 2 && !(Blind || Hallucination) && !could_move_onto_boulder(x, y)) { if (mode == DO_MOVE && flags.mention_walls) pline_dir(xytod(dx,dy), "A boulder blocks your path."); @@ -1169,7 +1169,7 @@ findtravelpath(int mode) if (!gt.travelmap) gt.travelmap = selection_new(); /* if travel to adjacent, reachable location, use normal movement rules */ - if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && gc.context.travel1 + if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && svc.context.travel1 /* was '&& distmin(u.ux, u.uy, u.tx, u.ty) == 1' */ && next2u(u.tx, u.ty) /* one step away */ /* handle restricted diagonals */ @@ -1185,7 +1185,7 @@ findtravelpath(int mode) return TRUE; } if (mode == TRAVP_TRAVEL) - gc.context.run = 8; + svc.context.run = 8; } if (u.tx != u.ux || u.ty != u.uy) { coordxy travel[COLNO][ROWNO]; @@ -1306,7 +1306,7 @@ findtravelpath(int mode) && ((x == u.tx && y == u.ty) || visited)) { nomul(0); /* reset run so domove run checks work */ - gc.context.run = 8; + svc.context.run = 8; if (visited) You("stop, unsure which way to go."); else @@ -1695,7 +1695,7 @@ disturb_buried_zombies(coordxy x, coordxy y) struct obj *otmp; long t; - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) { + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) { if (otmp->otyp == CORPSE && otmp->timed && otmp->ox >= x - 1 && otmp->ox <= x + 1 && otmp->oy >= y - 1 && otmp->oy <= y + 1 @@ -1744,8 +1744,8 @@ handle_tip(int tip) if (!flags.tips) return; - if (tip >= 0 && tip < NUM_TIPS && !gc.context.tips[tip]) { - gc.context.tips[tip] = TRUE; + if (tip >= 0 && tip < NUM_TIPS && !svc.context.tips[tip]) { + svc.context.tips[tip] = TRUE; switch (tip) { case TIP_ENHANCE: pline("(Use the #enhance command to advance them.)"); @@ -1792,9 +1792,9 @@ swim_move_danger(coordxy x, coordxy y) continue to move over lava if already doing so */ || (is_lava(x, y) && !Known_lwalking && !is_lava(u.ux, u.uy)) || liquid_wall) { - if (gc.context.nopick) { + if (svc.context.nopick) { /* moving with m-prefix */ - gc.context.tips[TIP_SWIM] = TRUE; + svc.context.tips[TIP_SWIM] = TRUE; return FALSE; } else if (ParanoidSwim || liquid_wall) { You("avoid %s into the %s.", @@ -1819,7 +1819,7 @@ domove_bump_mon(struct monst *mtmp, int glyph) * attack_check(), which still wastes a turn, but prints a * different message and makes the player remember the monster. */ - if (gc.context.nopick && !gc.context.travel + if (svc.context.nopick && !svc.context.travel && (canspotmon(mtmp) || glyph_is_invisible(glyph) || glyph_is_warning(glyph))) { if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers @@ -1853,7 +1853,7 @@ domove_attackmon_at( * This is different from ceiling hiders, who aren't handled in * do_attack(). */ - if (gc.context.forcefight || !mtmp->mundetected || sensemon(mtmp) + if (svc.context.forcefight || !mtmp->mundetected || sensemon(mtmp) || ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) && !is_safemon(mtmp))) { /* target monster might decide to switch places with you... */ @@ -1881,7 +1881,7 @@ domove_attackmon_at( staticfn boolean domove_fight_ironbars(coordxy x, coordxy y) { - if (gc.context.forcefight && levl[x][y].typ == IRONBARS && uwep) { + if (svc.context.forcefight && levl[x][y].typ == IRONBARS && uwep) { struct obj *obj = uwep; unsigned breakflags = (BRK_BY_HERO | BRK_FROM_INV | BRK_MELEE); @@ -1908,7 +1908,7 @@ domove_fight_web(coordxy x, coordxy y) { struct trap *trap = t_at(x, y); - if (gc.context.forcefight && trap && trap->ttyp == WEB && trap->tseen) { + if (svc.context.forcefight && trap && trap->ttyp == WEB && trap->tseen) { int wtype = uwep_skill_type(), /* minus_2: restricted or unskilled: -1, basic: 0, skilled: 1, expert: 2, master: 3, grandmaster: 4 */ @@ -2085,7 +2085,7 @@ domove_swap_with_pet(struct monst *mtmp, coordxy x, coordxy y) if (!u.uconduct.killer++) livelog_printf(LL_CONDUCT, "killed for the first time"); mndx = monsndx(mtmp->data); - tmp = experience(mtmp, (int) gm.mvitals[mndx].died); + tmp = experience(mtmp, (int) svm.mvitals[mndx].died); more_experienced(tmp, 0); newexplevel(); /* will decide if you go up */ } @@ -2123,9 +2123,9 @@ domove_fight_empty(coordxy x, coordxy y) * because m_at() might find a vault guard there */ /* specifying 'F' with no monster wastes a turn */ - if (gc.context.forcefight + if (svc.context.forcefight /* remembered an 'I' && didn't use a move command */ - || (glyph_is_invisible(glyph) && !m_at(x, y) && !gc.context.nopick)) { + || (glyph_is_invisible(glyph) && !m_at(x, y) && !svc.context.nopick)) { struct obj *boulder = 0; boolean explo = (Upolyd && attacktype(gy.youmonst.data, AT_EXPL)), solid = (off_edge || (!accessible(x, y) @@ -2149,7 +2149,7 @@ domove_fight_empty(coordxy x, coordxy y) /* force fight at boulder/statue or wall/door while wielding pick: start digging to break the boulder or wall */ - if (gc.context.forcefight + if (svc.context.forcefight /* can we dig? */ && uwep && dig_typ(uwep, x, y) /* should we dig? */ @@ -2349,8 +2349,8 @@ avoid_moving_on_liquid( if ((levl[x][y].typ == levl[u.ux][u.uy].typ /* or you are using shift-dir running and the transition isn't dangerous... */ - || (gc.context.run < 2 && (!is_lava(x, y) || in_air)) - || gc.context.travel) + || (svc.context.run < 2 && (!is_lava(x, y) || in_air)) + || svc.context.travel) /* and you know you won't fall in */ && (in_air || Known_lwalking || (is_pool(x, y) && Known_wwalking)) && !(IS_WATERWALL(levl[x][y].typ) || levl[x][y].typ == LAVAWALL)) { @@ -2373,15 +2373,15 @@ avoid_moving_on_liquid( staticfn boolean avoid_running_into_trap_or_liquid(coordxy x, coordxy y) { - boolean would_stop = (gc.context.run >= 2); - if (!gc.context.run) + boolean would_stop = (svc.context.run >= 2); + if (!svc.context.run) return FALSE; if (avoid_moving_on_trap(x,y, would_stop) || (Blind && avoid_moving_on_liquid(x,y, would_stop))) { nomul(0); if (would_stop) - gc.context.move = 0; + svc.context.move = 0; return would_stop; } return FALSE; @@ -2392,7 +2392,7 @@ staticfn boolean move_out_of_bounds(coordxy x, coordxy y) { if (!isok(x, y)) { - if (gc.context.forcefight) + if (svc.context.forcefight) return domove_fight_empty(x, y); if (flags.mention_walls) { @@ -2411,7 +2411,7 @@ move_out_of_bounds(coordxy x, coordxy y) directionname(xytod(dx, dy))); } nomul(0); - gc.context.move = 0; + svc.context.move = 0; return TRUE; } return FALSE; @@ -2526,10 +2526,10 @@ domove_core(void) boolean cause_delay = FALSE, /* dragging ball will skip a move */ displaceu = FALSE; /* involuntary swap */ - if (gc.context.travel) { + if (svc.context.travel) { if (!findtravelpath(TRAVP_TRAVEL)) (void) findtravelpath(TRAVP_GUESS); - gc.context.travel1 = 0; + svc.context.travel1 = 0; } if (carrying_too_much()) @@ -2570,13 +2570,13 @@ domove_core(void) /* Don't attack if you're running, and can see it */ /* It's fine to displace pets, though */ /* We should never get here if forcefight */ - if (gc.context.run && ((!Blind && mon_visible(mtmp) + if (svc.context.run && ((!Blind && mon_visible(mtmp) && ((M_AP_TYPE(mtmp) != M_AP_FURNITURE && M_AP_TYPE(mtmp) != M_AP_OBJECT) || Protection_from_shape_changers)) || sensemon(mtmp))) { nomul(0); - gc.context.move = 0; + svc.context.move = 0; return; } } @@ -2593,7 +2593,7 @@ domove_core(void) /* don't stop travel when displacing pets; if the displace fails for some reason, do_attack() in uhitm.c will stop travel rather than domove */ - if (!is_safemon(mtmp) || gc.context.forcefight) + if (!is_safemon(mtmp) || svc.context.forcefight) nomul(0); if (domove_bump_mon(mtmp, glyph)) @@ -2625,7 +2625,7 @@ domove_core(void) /* maybe ask player for confirmation before walking into known traps */ if (ParanoidTrap && (trap = t_at(x, y)) != 0 && trap->tseen - && (!gc.context.nopick || gc.context.run) + && (!svc.context.nopick || svc.context.run) && !Stunned && !Confusion && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) && (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE @@ -2658,7 +2658,7 @@ domove_core(void) yes/no if it is */ if (!paranoid_query(ParanoidConfirm, qbuf)) { nomul(0); - gc.context.move = 0; + svc.context.move = 0; return; } } @@ -2676,8 +2676,8 @@ domove_core(void) } if (!test_move(u.ux, u.uy, x - u.ux, y - u.uy, DO_MOVE)) { - if (!gc.context.door_opened) { - gc.context.move = 0; + if (!svc.context.door_opened) { + svc.context.move = 0; nomul(0); } return; @@ -2685,7 +2685,7 @@ domove_core(void) /* Is it dangerous to swim in water or lava? */ if (swim_move_danger(x, y)) { - gc.context.move = 0; + svc.context.move = 0; nomul(0); return; } @@ -2734,10 +2734,10 @@ domove_core(void) map_invisible(u.ux0, u.uy0); /* monster chose to swap places; hero doesn't get any credit or blame if something bad happens to it */ - gc.context.mon_moving = 1; + svc.context.mon_moving = 1; if (!minliquid(mtmp)) (void) mintrap(mtmp, NO_TRAP_FLAGS); - gc.context.mon_moving = 0; + svc.context.mon_moving = 0; /* * If safepet at destination then move the pet to the hero's @@ -2766,8 +2766,8 @@ domove_core(void) u_on_newpos(u.ux, u.uy); reset_occupations(); - if (gc.context.run) { - if (gc.context.run < 8) + if (svc.context.run) { + if (svc.context.run < 8) if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) || IS_FURNITURE(tmpr->typ)) nomul(0); @@ -2827,13 +2827,13 @@ domove_core(void) void runmode_delay_output(void) { - if ((gc.context.run || gm.multi) && flags.runmode != RUN_TPORT) { + if ((svc.context.run || gm.multi) && flags.runmode != RUN_TPORT) { /* for tport mode, don't display anything until we've stopped; for normal (leap) mode, update display every 7th step (relative to turn counter; ought to be to start of running); for walk and crawl (visual debugging) modes, update the display after every step */ - if (flags.runmode != RUN_LEAP || !(gm.moves % 7L)) { + if (flags.runmode != RUN_LEAP || !(svm.moves % 7L)) { /* moveloop() suppresses time_botl when running */ disp.time_botl = flags.time; curs_on_u(); @@ -2886,7 +2886,7 @@ overexertion(void) position, but is now called by do_attack() so that it doesn't execute if you decline to attack a peaceful monster */ gethungry(); - if ((gm.moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) { + if ((svm.moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) { overexert_hp(); } return (boolean) (gm.multi < 0); /* might have fainted (forced to sleep) */ @@ -3218,7 +3218,7 @@ staticfn boolean furniture_present(int furniture, int roomno) { int x, y, lx, ly, hx, hy; - struct mkroom *sroom = &gr.rooms[roomno]; + struct mkroom *sroom = &svr.rooms[roomno]; ly = sroom->ly, hy = sroom->hy; lx = sroom->lx; hx = sroom->hx; @@ -3240,7 +3240,7 @@ in_rooms(coordxy x, coordxy y, int typewanted) #define goodtype(rno) \ (!typewanted \ - || (typefound = gr.rooms[rno - ROOMOFFSET].rtype) == typewanted \ + || (typefound = svr.rooms[rno - ROOMOFFSET].rtype) == typewanted \ || (typewanted == SHOPBASE && typefound > SHOPBASE)) switch (rno = levl[x][y].roomno) { @@ -3302,14 +3302,14 @@ in_town(coordxy x, coordxy y) struct mkroom *sroom; boolean has_subrooms = FALSE; - if (!gl.level.flags.has_town) + if (!svl.level.flags.has_town) return FALSE; /* * See if (x,y) is in a room with subrooms, if so, assume it's the * town. If there are no subrooms, the whole level is in town. */ - for (sroom = &gr.rooms[0]; sroom->hx > 0; sroom++) { + for (sroom = &svr.rooms[0]; sroom->hx > 0; sroom++) { if (sroom->nsubrooms > 0) { has_subrooms = TRUE; if (inside_room(sroom, x, y)) @@ -3381,10 +3381,10 @@ check_special_room(boolean newlev) * TODO: change the minetn variants which don't include any town * boundary to have such. */ - if (gl.level.flags.has_town && !gc.context.achieveo.minetn_reached + if (svl.level.flags.has_town && !svc.context.achieveo.minetn_reached && In_mines(&u.uz) && in_town(u.ux, u.uy)) { record_achievement(ACH_TOWN); - gc.context.achieveo.minetn_reached = TRUE; + svc.context.achieveo.minetn_reached = TRUE; } if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */ @@ -3395,7 +3395,7 @@ check_special_room(boolean newlev) u_entered_shop(u.ushops_entered); for (ptr = &u.uentered[0]; *ptr; ptr++) { - int roomno = *ptr - ROOMOFFSET, rt = gr.rooms[roomno].rtype; + int roomno = *ptr - ROOMOFFSET, rt = svr.rooms[roomno].rtype; boolean msg_given = TRUE; /* Did we just enter some other special room? */ @@ -3450,10 +3450,10 @@ check_special_room(boolean newlev) if (oracle) { SetVoice(oracle, 0, 80, 0); if (!oracle->mpeaceful) - verbalize("You're in Delphi, %s.", gp.plname); + verbalize("You're in Delphi, %s.", svp.plname); else verbalize("%s, %s, welcome to Delphi!", - Hello((struct monst *) 0), gp.plname); + Hello((struct monst *) 0), svp.plname); } else msg_given = FALSE; break; @@ -3470,30 +3470,30 @@ check_special_room(boolean newlev) room_discovered(roomno); if (rt != 0) { - gr.rooms[roomno].rtype = OROOM; + svr.rooms[roomno].rtype = OROOM; if (!search_special(rt)) { /* No more room of that type */ switch (rt) { case COURT: - gl.level.flags.has_court = 0; + svl.level.flags.has_court = 0; break; case SWAMP: - gl.level.flags.has_swamp = 0; + svl.level.flags.has_swamp = 0; break; case MORGUE: - gl.level.flags.has_morgue = 0; + svl.level.flags.has_morgue = 0; break; case ZOO: - gl.level.flags.has_zoo = 0; + svl.level.flags.has_zoo = 0; break; case BARRACKS: - gl.level.flags.has_barracks = 0; + svl.level.flags.has_barracks = 0; break; case TEMPLE: - gl.level.flags.has_temple = 0; + svl.level.flags.has_temple = 0; break; case BEEHIVE: - gl.level.flags.has_beehive = 0; + svl.level.flags.has_beehive = 0; break; } } @@ -3645,7 +3645,7 @@ lookaround(void) return; } - if (Blind || gc.context.run == 0) + if (Blind || svc.context.run == 0) return; for (x = u.ux - 1; x <= u.ux + 1; x++) for (y = u.uy - 1; y <= u.uy + 1; y++) { @@ -3665,8 +3665,8 @@ lookaround(void) && mon_visible(mtmp)) { /* running movement and not a hostile monster */ /* OR it blocks our move direction and we're not traveling */ - if ((gc.context.run != 1 && !is_safemon(mtmp)) - || (infront && !gc.context.travel)) { + if ((svc.context.run != 1 && !is_safemon(mtmp)) + || (infront && !svc.context.travel)) { if (flags.mention_walls) pline_xy(x, y, "%s blocks your path.", upstart(a_monnam(mtmp))); @@ -3682,8 +3682,8 @@ lookaround(void) continue; /* stop for traps, sometimes */ - if (avoid_moving_on_trap(x, y, (infront && gc.context.run > 1))) { - if (gc.context.run == 1) + if (avoid_moving_on_trap(x, y, (infront && svc.context.run > 1))) { + if (svc.context.run == 1) goto bcorr; /* if you must */ if (infront) goto stop; @@ -3698,7 +3698,7 @@ lookaround(void) /* ignore if diagonal */ if (x != u.ux && y != u.uy) continue; - if (gc.context.run != 1 && !gc.context.travel) { + if (svc.context.run != 1 && !svc.context.travel) { if (flags.mention_walls) { set_msg_xy(x, y); You("stop in front of the door."); @@ -3712,8 +3712,8 @@ lookaround(void) bcorr: if (levl[u.ux][u.uy].typ != ROOM) { /* running or traveling */ - if (gc.context.run == 1 || gc.context.run == 3 - || gc.context.run == 8) { + if (svc.context.run == 1 || svc.context.run == 3 + || svc.context.run == 8) { /* distance from x,y to location we're moving to */ i = dist2(x, y, u.ux + u.dx, u.uy + u.dy); /* ignore if not on or directly adjacent to it */ @@ -3741,9 +3741,9 @@ lookaround(void) goto stop; continue; } else { /* e.g. objects or trap or stairs */ - if (gc.context.run == 1) + if (svc.context.run == 1) goto bcorr; - if (gc.context.run == 8) + if (svc.context.run == 8) continue; if (mtmp) continue; /* d */ @@ -3756,12 +3756,12 @@ lookaround(void) return; } /* end for loops */ - if (corrct > 1 && gc.context.run == 2) { + if (corrct > 1 && svc.context.run == 2) { if (flags.mention_walls) pline_The("corridor widens here."); goto stop; } - if ((gc.context.run == 1 || gc.context.run == 3 || gc.context.run == 8) + if ((svc.context.run == 1 || svc.context.run == 3 || svc.context.run == 8) && !noturn && !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) { /* make sure that we do not turn too far */ @@ -3865,13 +3865,13 @@ end_running(boolean and_travel) { /* moveloop() suppresses time_botl when context.run is non-zero; when running stops, update 'time' even if other botl status is unchanged */ - if (flags.time && gc.context.run) + if (flags.time && svc.context.run) disp.time_botl = TRUE; - gc.context.run = 0; + svc.context.run = 0; /* 'context.mv' isn't travel but callers who want to end travel all clear it too */ if (and_travel) - gc.context.travel = gc.context.travel1 = gc.context.mv = 0; + svc.context.travel = svc.context.travel1 = svc.context.mv = 0; if (gt.travelmap) { selection_free(gt.travelmap, TRUE); gt.travelmap = NULL; @@ -3938,10 +3938,10 @@ maybe_wail(void) SHOCK_RES, FIRE_RES, SLEEP_RES, DISINT_RES, TELEPORT_CONTROL, STEALTH, FAST, INVIS }; - if (gm.moves <= gw.wailmsg + 50) + if (svm.moves <= gw.wailmsg + 50) return; - gw.wailmsg = gm.moves; + gw.wailmsg = svm.moves; if (Role_if(PM_WIZARD) || Race_if(PM_ELF) || Role_if(PM_VALKYRIE)) { const char *who; int i, powercnt; @@ -4024,9 +4024,9 @@ losehp(int n, const char *knam, schar k_format) if (u.uhp > u.uhpmax) u.uhpmax = u.uhp; /* perhaps n was negative */ if (u.uhp < 1) { - gk.killer.format = k_format; - if (gk.killer.name != knam) /* the thing that killed you */ - Strcpy(gk.killer.name, knam ? knam : ""); + svk.killer.format = k_format; + if (svk.killer.name != knam) /* the thing that killed you */ + Strcpy(svk.killer.name, knam ? knam : ""); urgent_pline("You die..."); done(DIED); } else if (n > 0 && u.uhp * 10 < u.uhpmax) { diff --git a/src/insight.c b/src/insight.c index 8d44962d3..163855db4 100644 --- a/src/insight.c +++ b/src/insight.c @@ -363,7 +363,7 @@ enlightenment( if (ge.en_via_menu) start_menu(ge.en_win, MENU_BEHAVE_STANDARD); - Strcpy(tmpbuf, gp.plname); + Strcpy(tmpbuf, svp.plname); *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */ /* as in background_enlightenment, when poly'd we need to use the saved gender in u.mfemale rather than the current you-as-monster gender */ @@ -512,7 +512,7 @@ background_enlightenment(int unused_mode UNUSED, int final) way sooner (in other words, didn't start that way) */ ? (!final ? "now " : "belatedly ") /* atheist (ignored in very early game) */ - : (!u.uconduct.gnostic && gm.moves > 1000L) + : (!u.uconduct.gnostic && svm.moves > 1000L) ? "nominally " /* lastly, normal case */ : "", @@ -577,13 +577,13 @@ background_enlightenment(int unused_mode UNUSED, int final) !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf); } else if (Is_knox(&u.uz)) { /* this gives away the fact that the knox branch is only 1 level */ - Sprintf(buf, "on the %s level", gd.dungeons[u.uz.dnum].dname); + Sprintf(buf, "on the %s level", svd.dungeons[u.uz.dnum].dname); /* TODO? maybe phrase it differently when actually inside the fort, if we're able to determine that (not trivial) */ } else { char dgnbuf[QBUFSZ]; - Strcpy(dgnbuf, gd.dungeons[u.uz.dnum].dname); + Strcpy(dgnbuf, svd.dungeons[u.uz.dnum].dname); if (!strncmpi(dgnbuf, "The ", 4)) *dgnbuf = lowc(*dgnbuf); Sprintf(tmpbuf, "level %d", @@ -599,11 +599,11 @@ background_enlightenment(int unused_mode UNUSED, int final) you_are(buf, ""); /* this is shown even if the 'time' option is off */ - if (gm.moves == 1L) { + if (svm.moves == 1L) { you_have("just started your adventure", ""); } else { /* 'turns' grates on the nerves in this context... */ - Sprintf(buf, "the dungeon %ld turn%s ago", gm.moves, plur(gm.moves)); + Sprintf(buf, "the dungeon %ld turn%s ago", svm.moves, plur(svm.moves)); /* same phrasing for current and final: "entered" is unconditional */ enlght_line(You_, "entered ", buf, ""); } @@ -913,7 +913,7 @@ status_enlightenment(int mode, int final) /* if hero dies while dismounting, u.usteed will still be set; we want to ignore steed in that situation */ && !(final == ENL_GAMEOVERDEAD - && !strcmp(gk.killer.name, "riding accident"))); + && !strcmp(svk.killer.name, "riding accident"))); const char *steedname = (!Riding ? (char *) 0 : x_monnam(u.usteed, u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE, @@ -1544,30 +1544,30 @@ attributes_enlightenment( you_are("telepathic", from_what(TELEPAT)); if (Warning) you_are("warned", from_what(WARNING)); - if (Warn_of_mon && gc.context.warntype.obj) { + if (Warn_of_mon && svc.context.warntype.obj) { Sprintf(buf, "aware of the presence of %s", - (gc.context.warntype.obj & M2_ORC) ? "orcs" - : (gc.context.warntype.obj & M2_ELF) ? "elves" - : (gc.context.warntype.obj & M2_DEMON) ? "demons" : something); + (svc.context.warntype.obj & M2_ORC) ? "orcs" + : (svc.context.warntype.obj & M2_ELF) ? "elves" + : (svc.context.warntype.obj & M2_DEMON) ? "demons" : something); you_are(buf, from_what(WARN_OF_MON)); } - if (Warn_of_mon && gc.context.warntype.polyd) { + if (Warn_of_mon && svc.context.warntype.polyd) { Sprintf(buf, "aware of the presence of %s", - ((gc.context.warntype.polyd & (M2_HUMAN | M2_ELF)) + ((svc.context.warntype.polyd & (M2_HUMAN | M2_ELF)) == (M2_HUMAN | M2_ELF)) ? "humans and elves" - : (gc.context.warntype.polyd & M2_HUMAN) + : (svc.context.warntype.polyd & M2_HUMAN) ? "humans" - : (gc.context.warntype.polyd & M2_ELF) + : (svc.context.warntype.polyd & M2_ELF) ? "elves" - : (gc.context.warntype.polyd & M2_ORC) + : (svc.context.warntype.polyd & M2_ORC) ? "orcs" - : (gc.context.warntype.polyd & M2_DEMON) + : (svc.context.warntype.polyd & M2_DEMON) ? "demons" : "certain monsters"); you_are(buf, ""); } - warnspecies = gc.context.warntype.speciesidx; + warnspecies = svc.context.warntype.speciesidx; if (Warn_of_mon && ismnum(warnspecies)) { Sprintf(buf, "aware of the presence of %s", makeplural(mons[warnspecies].pmnames[NEUTRAL])); @@ -1917,7 +1917,7 @@ attributes_enlightenment( Sprintf(buf, "Fruit #%d ", f->fid); enl_msg(buf, "is ", "was ", f->fname, ""); } - enl_msg("The current fruit ", "is ", "was ", gp.pl_fruit, ""); + enl_msg("The current fruit ", "is ", "was ", svp.pl_fruit, ""); Sprintf(buf, "%d", flags.made_fruit); enl_msg("The made fruit flag ", "is ", "was ", buf, ""); } @@ -2005,7 +2005,7 @@ youhiding(boolean via_enlghtmt, /* enlightenment line vs topl message */ if (is_pool(u.ux, u.uy)) Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy)); } else if (hides_under(gy.youmonst.data)) { - struct obj *o = gl.level.objects[u.ux][u.uy]; + struct obj *o = svl.level.objects[u.ux][u.uy]; if (o) Sprintf(bp, " underneath %s", ansimpleoname(o)); @@ -2395,7 +2395,7 @@ record_achievement(schar achidx) /* avoid livelog for achievements recorded during final disclosure: nudist and blind-from-birth; also ascension which is suppressed by this gets logged separately in really_done() */ - if (gp.program_state.gameover) + if (svp.program_state.gameover) return; if (absidx >= ACH_RNK1 && absidx <= ACH_RNK8) { @@ -2408,8 +2408,8 @@ record_achievement(schar achidx) || achidx == ACH_MINE_PRIZE) { /* need to supply extra information for these two */ short otyp = ((achidx == ACH_SOKO_PRIZE) - ? gc.context.achieveo.soko_prize_otyp - : gc.context.achieveo.mines_prize_otyp); + ? svc.context.achieveo.soko_prize_otyp + : svc.context.achieveo.mines_prize_otyp); /* note: OBJ_NAME() works here because both "bag of holding" and "amulet of reflection" are fully named in their objects[] entry @@ -2641,8 +2641,8 @@ vanqsort_cmp( break; case VANQ_COUNT_H_L: case VANQ_COUNT_L_H: - died1 = gm.mvitals[indx1].died; - died2 = gm.mvitals[indx2].died; + died1 = svm.mvitals[indx1].died; + died2 = svm.mvitals[indx2].died; res = died2 - died1; /* dead count high to low */ if (flags.vanq_sortmode == VANQ_COUNT_L_H) res = -res; /* dead count low to high */ @@ -2717,7 +2717,7 @@ dovanquished(void) #define UniqCritterIndx(mndx) \ ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC) -#define done_stopprint gp.program_state.stopprint +#define done_stopprint svp.program_state.stopprint void list_vanquished(char defquery, boolean ask) @@ -2740,7 +2740,7 @@ list_vanquished(char defquery, boolean ask) /* get totals first */ ntypes = 0; for (i = LOW_PM; i < NUMMONS; i++) { - if ((nkilled = (int) gm.mvitals[i].died) == 0) + if ((nkilled = (int) svm.mvitals[i].died) == 0) continue; mindx[ntypes++] = i; total_killed += (long) nkilled; @@ -2779,7 +2779,7 @@ list_vanquished(char defquery, boolean ask) qsort((genericptr_t) mindx, ntypes, sizeof *mindx, vanqsort_cmp); for (ni = 0; ni < ntypes; ni++) { i = mindx[ni]; - nkilled = gm.mvitals[i].died; + nkilled = svm.mvitals[i].died; mlet = mons[i].mlet; if (class_header && mlet != prev_mlet) { Strcpy(buf, def_monsyms[(int) mlet].explain); @@ -2852,7 +2852,7 @@ list_vanquished(char defquery, boolean ask) * still in progress, so use present tense via pline(), or for dumplog * which needs putstr() and past tense. */ - } else if (!gp.program_state.gameover) { + } else if (!svp.program_state.gameover) { /* #vanquished rather than final disclosure, so pline() is ok */ pline("No creatures have been vanquished."); #ifdef DUMPLOG @@ -2869,7 +2869,7 @@ num_genocides(void) int i, n = 0; for (i = LOW_PM; i < NUMMONS; ++i) { - if (gm.mvitals[i].mvflags & G_GENOD) { + if (svm.mvitals[i].mvflags & G_GENOD) { ++n; if (UniqCritterIndx(i)) impossible("unique creature '%d: %s' genocided?", @@ -2888,7 +2888,7 @@ num_extinct(void) for (i = LOW_PM; i < NUMMONS; ++i) { if (UniqCritterIndx(i)) continue; - if ((gm.mvitals[i].mvflags & G_GONE) == G_EXTINCT) + if ((svm.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ++n; } return n; @@ -2909,7 +2909,7 @@ num_gone(int mvflags, int *mindx) if (UniqCritterIndx(i)) continue; - if ((gm.mvitals[i].mvflags & mflg) != 0) + if ((svm.mvitals[i].mvflags & mflg) != 0) mindx[n++] = i; } return n; @@ -2927,7 +2927,7 @@ list_genocided(char defquery, boolean ask) char buf[BUFSZ]; boolean genoing, /* prompting for genocide or class genocide */ dumping; /* for DUMPLOG; doesn't need to be conditional */ - boolean both = (gp.program_state.gameover || wizard || discover); + boolean both = (svp.program_state.gameover || wizard || discover); dumping = (defquery == 'd'); genoing = (defquery == 'g'); @@ -3011,7 +3011,7 @@ list_genocided(char defquery, boolean ask) * clear. During normal play, 'mndx' won't be in the * collected list unless that bit is set. */ - if ((gm.mvitals[mndx].mvflags & G_GONE) == G_EXTINCT) + if ((svm.mvitals[mndx].mvflags & G_GONE) == G_EXTINCT) Strcat(buf, " (extinct)"); putstr(klwin, 0, buf); } @@ -3031,7 +3031,7 @@ list_genocided(char defquery, boolean ask) } /* See the comment for similar code near the end of list_vanquished(). */ - } else if (!gp.program_state.gameover) { + } else if (!svp.program_state.gameover) { /* #genocided rather than final disclosure, so pline() is ok and extinction has been ignored */ pline("No creatures have been genocided%s.", genoing ? " yet" : ""); @@ -3064,18 +3064,18 @@ doborn(void) putstr(datawin, 0, "died born"); for (i = LOW_PM; i < NUMMONS; i++) - if (gm.mvitals[i].born || gm.mvitals[i].died - || (gm.mvitals[i].mvflags & G_GONE) != 0) { + if (svm.mvitals[i].born || svm.mvitals[i].died + || (svm.mvitals[i].mvflags & G_GONE) != 0) { Sprintf(buf, fmt, - gm.mvitals[i].died, gm.mvitals[i].born, - ((gm.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' - : ((gm.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' - : ((gm.mvitals[i].mvflags & G_GONE) != 0) ? 'X' + svm.mvitals[i].died, svm.mvitals[i].born, + ((svm.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' + : ((svm.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' + : ((svm.mvitals[i].mvflags & G_GONE) != 0) ? 'X' : ' ', mons[i].pmnames[NEUTRAL]); putstr(datawin, 0, buf); - nborn += gm.mvitals[i].born; - ndied += gm.mvitals[i].died; + nborn += svm.mvitals[i].born; + ndied += svm.mvitals[i].died; } putstr(datawin, 0, ""); @@ -3376,7 +3376,7 @@ ustatusline(void) Strcat(info, mon_nam(u.ustuck)); } - pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", gp.plname, + pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", svp.plname, piousness(FALSE, align_str(u.ualign.type)), Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp, Upolyd ? u.mhmax : u.uhpmax, u.uac, info); diff --git a/src/invent.c b/src/invent.c index b2020e342..bfac244f6 100644 --- a/src/invent.c +++ b/src/invent.c @@ -355,7 +355,7 @@ loot_xname(struct obj *obj) if (wizard) { /* flags.debug */ /* paranoia: before toggling off wizard mode, guard against a panic in xname() producing a normal mode panic save file */ - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; flags.debug = FALSE; } @@ -363,7 +363,7 @@ loot_xname(struct obj *obj) if (save_debug) { flags.debug = TRUE; - gp.program_state.something_worth_saving = 1; + svp.program_state.something_worth_saving = 1; } /* restore the object */ if (obj->oclass == POTION_CLASS) { @@ -1006,11 +1006,11 @@ addinv_core1(struct obj *obj) dumplog, originally just recorded in XLOGFILE */ if (is_mines_prize(obj)) { record_achievement(ACH_MINE_PRIZE); - gc.context.achieveo.mines_prize_oid = 0; /* done with luckstone o_id */ + svc.context.achieveo.mines_prize_oid = 0; /* done with luckstone o_id */ obj->nomerge = 0; /* was set in create_object(sp_lev.c) */ } else if (is_soko_prize(obj)) { record_achievement(ACH_SOKO_PRIZE); - gc.context.achieveo.soko_prize_oid = 0; /* done with bag/amulet o_id */ + svc.context.achieveo.soko_prize_oid = 0; /* done with bag/amulet o_id */ obj->nomerge = 0; /* (got set in sp_lev.c) */ } } @@ -1384,7 +1384,7 @@ delallobj(coordxy x, coordxy y) { struct obj *otmp, *otmp2; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp2) { if (otmp == uball) unpunish(); /* after unpunish(), or might get deallocated chain */ @@ -1437,7 +1437,7 @@ sobj_at(int otyp, coordxy x, coordxy y) { struct obj *otmp; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (otmp->otyp == otyp) break; @@ -1561,7 +1561,7 @@ obj_here(struct obj *obj, coordxy x, coordxy y) { struct obj *otmp; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (obj == otmp) return TRUE; return FALSE; @@ -1570,7 +1570,7 @@ obj_here(struct obj *obj, coordxy x, coordxy y) struct obj * g_at(coordxy x, coordxy y) { - struct obj *obj = gl.level.objects[x][y]; + struct obj *obj = svl.level.objects[x][y]; while (obj) { if (obj->oclass == COIN_CLASS) @@ -2650,7 +2650,7 @@ update_inventory(void) { int save_suppress_price; - if (!gp.program_state.in_moveloop) /* not covered by suppress_map_output */ + if (!svp.program_state.in_moveloop) /* not covered by suppress_map_output */ return; if (suppress_map_output()) /* despite name, used for perm_invent too */ return; @@ -4347,7 +4347,7 @@ dotypeinv(void) title[0] = '\0'; u_carried = count_unpaid(gi.invent); u_floor = count_unpaid(fobj); - u_buried = count_unpaid(gl.level.buriedobjlist); + u_buried = count_unpaid(svl.level.buriedobjlist); any_unpaid = u_carried + u_floor + u_buried; tally_BUCX(gi.invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt, &jcnt); @@ -4661,7 +4661,7 @@ look_here( if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen) There("is %s here.", an(trapname(trap->ttyp, FALSE))); - otmp = gl.level.objects[u.ux][u.uy]; + otmp = svl.level.objects[u.ux][u.uy]; dfeature = dfeature_at(u.ux, u.uy, fbuf2); if (dfeature && !strcmp(dfeature, "pool of water") && Underwater) dfeature = 0; @@ -4851,7 +4851,7 @@ stackobj(struct obj *obj) { struct obj *otmp; - for (otmp = gl.level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere) if (otmp != obj && merged(&obj, &otmp)) break; return; @@ -5249,7 +5249,7 @@ useupf(struct obj *obj, long numused) otmp = splitobj(obj, numused); else otmp = obj; - if (!gc.context.mon_moving && costly_spot(otmp->ox, otmp->oy)) { + if (!svc.context.mon_moving && costly_spot(otmp->ox, otmp->oy)) { if (strchr(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0))) addtobill(otmp, FALSE, FALSE, FALSE); else @@ -5975,7 +5975,7 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen) should use the normal look_here command instead of probing (caller has already used bhitpile() which will have set dknown on all items) */ if (is_pool_or_lava(x, y) && !Underwater - && (obj = gl.level.objects[x][y]) != 0) { + && (obj = svl.level.objects[x][y]) != 0) { const char *real_liquid = is_pool(x, y) ? "water" : "lava", *seen_liquid = hliquid(real_liquid); @@ -5991,7 +5991,7 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen) underwhat = more_than_1 ? "under them" : "beneath it"; } else { Sprintf(qbuf, "Things that are under the %s here:", seen_liquid); - if (query_objlist(qbuf, &gl.level.objects[x][y], BY_NEXTHERE, + if (query_objlist(qbuf, &svl.level.objects[x][y], BY_NEXTHERE, &selected, PICK_NONE, allow_all) > 0) free((genericptr_t) selected), selected = 0; for (n2 = 0; obj; obj = obj->nexthere) @@ -6001,7 +6001,7 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen) } /* count # of buried objects here */ - for (n = 0, obj = gl.level.buriedobjlist; obj; obj = obj->nobj) + for (n = 0, obj = svl.level.buriedobjlist; obj; obj = obj->nobj) if (obj->ox == x && obj->oy == y) { if (as_if_seen) obj->dknown = 1; @@ -6013,7 +6013,7 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen) go.only.y = y; /* "buried here", but vary if we've already shown underwater items */ Sprintf(qbuf, "Things that are buried %s:", underwhat); - if (query_objlist(qbuf, &gl.level.buriedobjlist, INVORDER_SORT, + if (query_objlist(qbuf, &svl.level.buriedobjlist, INVORDER_SORT, &selected, PICK_NONE, only_here) > 0) free((genericptr_t) selected); go.only.x = go.only.y = 0; @@ -6120,7 +6120,7 @@ sync_perminvent(void) WIN_INVEN = create_nhwindow(NHW_MENU); } - if (WIN_INVEN != WIN_ERR && gp.program_state.beyond_savefile_load) { + if (WIN_INVEN != WIN_ERR && svp.program_state.beyond_savefile_load) { gi.in_sync_perminvent = 1; (void) display_inventory((char *) 0, FALSE); gi.in_sync_perminvent = 0; diff --git a/src/lock.c b/src/lock.c index 3cf20a669..7d7f151cb 100644 --- a/src/lock.c +++ b/src/lock.c @@ -192,7 +192,7 @@ breakchestlock(struct obj *box, boolean destroyit) useup(otmp); } if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) { - otmp->age = gm.moves - otmp->age; /* actual age */ + otmp->age = svm.moves - otmp->age; /* actual age */ start_corpse_timeout(otmp); } place_object(otmp, u.ux, u.uy); @@ -441,7 +441,7 @@ pick_lock( count = 0; c = 'n'; /* in case there are no boxes here */ - for (otmp = gl.level.objects[cc.x][cc.y]; otmp; + for (otmp = svl.level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere) { /* autounlock on boxes: only the one that was just discovered to be locked; don't include any other boxes which might be here */ @@ -575,7 +575,7 @@ pick_lock( /* this is probably only relevant when blind */ feel_location(cc.x, cc.y); if (door->glyph != oldglyph - || gl.lastseentyp[cc.x][cc.y] != oldlastseentyp) + || svl.lastseentyp[cc.x][cc.y] != oldlastseentyp) res = PICKLOCK_LEARNED_SOMETHING; if (is_drawbridge_wall(cc.x, cc.y) >= 0) @@ -639,7 +639,7 @@ pick_lock( gx.xlock.box = 0; } } - gc.context.move = 0; + svc.context.move = 0; gx.xlock.chance = ch; gx.xlock.picktyp = picktyp; gx.xlock.magic_key = is_magic_key(&gy.youmonst, pick); @@ -706,7 +706,7 @@ doforce(void) /* A lock is made only for the honest man, the thief will break it. */ gx.xlock.box = (struct obj *) 0; - for (otmp = gl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) if (Is_box(otmp)) { if (otmp->obroken || !otmp->olocked) { /* force doname() to omit known "broken" or "unlocked" @@ -827,7 +827,7 @@ doopen_indir(coordxy x, coordxy y) newsym(cc.x, cc.y); if (door->glyph != oldglyph - || gl.lastseentyp[cc.x][cc.y] != oldlastseentyp) + || svl.lastseentyp[cc.x][cc.y] != oldlastseentyp) res = ECMD_TIME; /* learned something */ } @@ -989,7 +989,7 @@ doclose(void) schar oldlastseentyp = update_mapseen_for(x, y); feel_location(x, y); - if (door->glyph != oldglyph || gl.lastseentyp[x][y] != oldlastseentyp) + if (door->glyph != oldglyph || svl.lastseentyp[x][y] != oldlastseentyp) res = ECMD_TIME; /* learned something */ } diff --git a/src/mail.c b/src/mail.c index 3c7d64c11..54c8aebff 100644 --- a/src/mail.c +++ b/src/mail.c @@ -406,7 +406,7 @@ newmail(struct mail_info *info) message_seen = TRUE; SetVoice(md, 0, 80, 0); - verbalize("%s, %s! %s.", Hello(md), gp.plname, info->display_txt); + verbalize("%s, %s! %s.", Hello(md), svp.plname, info->display_txt); if (info->message_typ) { struct obj *obj = mksobj(SCR_MAIL, FALSE, FALSE); @@ -447,7 +447,7 @@ ckmailstatus(void) return; if (mustgetmail < 0) { #if defined(AMIGA) || defined(MSDOS) || defined(TOS) - mustgetmail = (gm.moves < 2000) ? (100 + rn2(2000)) : (2000 + rn2(3000)); + mustgetmail = (svm.moves < 2000) ? (100 + rn2(2000)) : (2000 + rn2(3000)); #endif return; } @@ -533,12 +533,12 @@ ckmailstatus(void) if (!mailbox || u.uswallow || !flags.biff #ifdef MAILCKFREQ - || gm.moves < laststattime + MAILCKFREQ + || svm.moves < laststattime + MAILCKFREQ #endif ) return; - laststattime = gm.moves; + laststattime = svm.moves; if (stat(mailbox, &nmstat)) { #ifdef PERMANENT_MAILBOX pline("Cannot get status of MAIL=\"%s\" anymore.", mailbox); @@ -668,8 +668,8 @@ ck_server_admin_msg(void) static struct stat ost,nst; static long lastchk = 0; - if (gm.moves < lastchk + SERVER_ADMIN_MSG_CKFREQ) return; - lastchk = gm.moves; + if (svm.moves < lastchk + SERVER_ADMIN_MSG_CKFREQ) return; + lastchk = svm.moves; if (!stat(SERVER_ADMIN_MSG, &nst)) { if (nst.st_mtime > ost.st_mtime) diff --git a/src/makemon.c b/src/makemon.c index 249cfc6c7..5bb2f203e 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -830,7 +830,7 @@ clone_mon( struct monst *m2; /* may be too weak or have been extinguished for population control */ - if (mon->mhp <= 1 || (gm.mvitals[monsndx(mon->data)].mvflags & G_EXTINCT)) + if (mon->mhp <= 1 || (svm.mvitals[monsndx(mon->data)].mvflags & G_EXTINCT)) return (struct monst *) 0; if (x == 0) { @@ -894,7 +894,7 @@ clone_mon( } /* not all clones caused by player are tame or peaceful */ - if (!gc.context.mon_moving && mon->mpeaceful) { + if (!svc.context.mon_moving && mon->mpeaceful) { if (mon->mtame) m2->mtame = rn2(max(2 + u.uluck, 2)) ? mon->mtame : 0; else if (mon->mpeaceful) @@ -947,23 +947,23 @@ propagate(int mndx, boolean tally, boolean ghostly) boolean gone, result; int lim = mbirth_limit(mndx); - gone = (gm.mvitals[mndx].mvflags & G_GONE) != 0; /* geno'd|extinct */ - result = ((int) gm.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE; + gone = (svm.mvitals[mndx].mvflags & G_GONE) != 0; /* geno'd|extinct */ + result = ((int) svm.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE; /* if it's unique, don't ever make it again */ if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC) - gm.mvitals[mndx].mvflags |= G_EXTINCT; + svm.mvitals[mndx].mvflags |= G_EXTINCT; - if (gm.mvitals[mndx].born < 255 && tally && (!ghostly || result)) - gm.mvitals[mndx].born++; - if ((int) gm.mvitals[mndx].born >= lim + if (svm.mvitals[mndx].born < 255 && tally && (!ghostly || result)) + svm.mvitals[mndx].born++; + if ((int) svm.mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN) - && !(gm.mvitals[mndx].mvflags & G_EXTINCT)) { + && !(svm.mvitals[mndx].mvflags & G_EXTINCT)) { if (wizard) { debugpline1("Automatically extinguished %s.", makeplural(mons[mndx].pmnames[NEUTRAL])); } - gm.mvitals[mndx].mvflags |= G_EXTINCT; + svm.mvitals[mndx].mvflags |= G_EXTINCT; } return result; } @@ -1152,7 +1152,7 @@ makemon( fakemon = cg.zeromonst; cc.x = cc.y = 0; - if (iflags.debug_mongen || (!gl.level.flags.rndmongen && !ptr)) + if (iflags.debug_mongen || (!svl.level.flags.rndmongen && !ptr)) return (struct monst *) 0; /* if caller wants random location, do it here */ @@ -1190,9 +1190,9 @@ makemon( mndx = monsndx(ptr); /* if you are to make a specific monster and it has already been genocided, return */ - if (gm.mvitals[mndx].mvflags & G_GENOD) + if (svm.mvitals[mndx].mvflags & G_GENOD) return (struct monst *) 0; - if (wizard && (gm.mvitals[mndx].mvflags & G_EXTINCT)) { + if (wizard && (svm.mvitals[mndx].mvflags & G_EXTINCT)) { debugpline1("Explicitly creating extinct monster %s.", mons[mndx].pmnames[NEUTRAL]); } @@ -1238,7 +1238,7 @@ makemon( mtmp->m_id = next_ident(); set_mon_data(mtmp, ptr); /* mtmp->data = ptr; */ if (ptr->msound == MS_LEADER && quest_info(MS_LEADER) == mndx) - gq.quest_status.leader_m_id = mtmp->m_id; + svq.quest_status.leader_m_id = mtmp->m_id; mtmp->mnum = mndx; /* set up level and hit points */ @@ -1255,9 +1255,9 @@ makemon( but for ones which can be random, it has already been chosen (in role_init(), for possible use by the quest pager code) */ else if (ptr->msound == MS_LEADER && quest_info(MS_LEADER) == mndx) - mtmp->female = gq.quest_status.ldrgend; + mtmp->female = svq.quest_status.ldrgend; else if (ptr->msound == MS_NEMESIS && quest_info(MS_NEMESIS) == mndx) - mtmp->female = gq.quest_status.nemgend; + mtmp->female = svq.quest_status.nemgend; /* female used to be set randomly here even for neuters on the grounds that it was ignored, but after corpses were changed to @@ -1350,8 +1350,8 @@ makemon( allow_minvent = FALSE; } else if (mndx == PM_WIZARD_OF_YENDOR) { mtmp->iswiz = TRUE; - gc.context.no_of_wizards++; - if (gc.context.no_of_wizards == 1 && Is_earthlevel(&u.uz)) + svc.context.no_of_wizards++; + if (svc.context.no_of_wizards == 1 && Is_earthlevel(&u.uz)) mitem = SPE_DIG; } else if (mndx == PM_GHOST && !(mmflags & MM_NONAME)) { mtmp = christen_monst(mtmp, rndghostname()); @@ -1502,10 +1502,10 @@ unmakemon( that just happened when creating this monster or the threshold had already been reached and further increments were suppressed; assume the latter */ - if (countbirth && gm.mvitals[mndx].born > 0 && gm.mvitals[mndx].born < 255) - gm.mvitals[mndx].born -= 1; + if (countbirth && svm.mvitals[mndx].born > 0 && svm.mvitals[mndx].born < 255) + svm.mvitals[mndx].born -= 1; if ((mon->data->geno & G_UNIQ) != 0) - gm.mvitals[mndx].mvflags &= ~G_EXTINCT; + svm.mvitals[mndx].mvflags &= ~G_EXTINCT; mon->mhp = 0; /* let discard_minvent() know that mon isn't being kept */ /* uncreate any artifact that the monster was provided with; unlike @@ -1573,7 +1573,7 @@ uncommon(int mndx) { if (mons[mndx].geno & (G_NOGEN | G_UNIQ)) return TRUE; - if (gm.mvitals[mndx].mvflags & G_GONE) + if (svm.mvitals[mndx].mvflags & G_GONE) return TRUE; if (Inhell) return (boolean) (mons[mndx].maligntyp > A_NEUTRAL); @@ -1593,11 +1593,11 @@ align_shift(struct permonst *ptr) static NEARDATA s_level *lev; int alshift; - if (oldmoves != gm.moves) { + if (oldmoves != svm.moves) { lev = Is_special(&u.uz); - oldmoves = gm.moves; + oldmoves = svm.moves; } - switch ((lev) ? lev->flags.align : gd.dungeons[u.uz.dnum].flags.align) { + switch ((lev) ? lev->flags.align : svd.dungeons[u.uz.dnum].flags.align) { default: /* just in case */ case AM_NONE: alshift = 0; @@ -1619,8 +1619,8 @@ align_shift(struct permonst *ptr) staticfn int temperature_shift(struct permonst *ptr) { - if (gl.level.flags.temperature - && pm_resistance(ptr, (gl.level.flags.temperature > 0) + if (svl.level.flags.temperature + && pm_resistance(ptr, (svl.level.flags.temperature > 0) ? MR_FIRE : MR_COLD)) return 3; return 0; @@ -1716,7 +1716,7 @@ mk_gen_ok(int mndx, unsigned mvflagsmask, unsigned genomask) { struct permonst *ptr = &mons[mndx]; - if (gm.mvitals[mndx].mvflags & mvflagsmask) + if (svm.mvitals[mndx].mvflags & mvflagsmask) return FALSE; if (ptr->geno & genomask) return FALSE; @@ -1812,7 +1812,7 @@ mkclass_aligned(char class, int spc, /* special mons[].geno handling */ against picking the next demon resulted in incubus being picked nearly twice as often as succubus); we need the '+1' in case the entire set is too high - level (really low gl.level hero) */ + level (really low svl.level hero) */ nums[last] = k + 1 - (adj_lev(&mons[last]) > (u.ulevel * 2)); num += nums[last]; } @@ -1876,7 +1876,7 @@ adj_lev(struct permonst *ptr) /* does not depend on other strengths, but does get stronger * every time he is killed */ - tmp = ptr->mlevel + gm.mvitals[PM_WIZARD_OF_YENDOR].died; + tmp = ptr->mlevel + svm.mvitals[PM_WIZARD_OF_YENDOR].died; if (tmp > 49) tmp = 49; return tmp; @@ -1977,12 +1977,12 @@ grow_up(struct monst *mtmp, struct monst *victim) /* new form might force gender change */ fem = is_male(ptr) ? 0 : is_female(ptr) ? 1 : mtmp->female; - if (gm.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ + if (svm.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ if (canspotmon(mtmp)) pline("As %s grows up into %s, %s %s!", mon_nam(mtmp), an(pmname(ptr, Mgender(mtmp))), mhe(mtmp), nonliving(ptr) ? "expires" : "dies"); - set_mon_data(mtmp, ptr); /* keep gm.mvitals[] accurate */ + set_mon_data(mtmp, ptr); /* keep svm.mvitals[] accurate */ mondied(mtmp); return (struct permonst *) 0; } else if (canspotmon(mtmp)) { @@ -2261,7 +2261,7 @@ set_mimic_sym(struct monst *mtmp) /* only valid for INSIDE of room */ roomno = levl[mx][my].roomno - ROOMOFFSET; if (roomno >= 0) - rt = gr.rooms[roomno].rtype; + rt = svr.rooms[roomno].rtype; #ifdef SPECIALIZATION else if (IS_ROOM(typ)) rt = OROOM, roomno = 0; @@ -2271,7 +2271,7 @@ set_mimic_sym(struct monst *mtmp) if (OBJ_AT(mx, my)) { ap_type = M_AP_OBJECT; - appear = gl.level.objects[mx][my]->otyp; + appear = svl.level.objects[mx][my]->otyp; } else if (IS_DOOR(typ) || IS_WALL(typ) || typ == SDOOR || typ == SCORR) { ap_type = M_AP_FURNITURE; /* @@ -2291,7 +2291,7 @@ set_mimic_sym(struct monst *mtmp) appear = Is_rogue_level(&u.uz) ? S_hwall : S_hcdoor; else appear = Is_rogue_level(&u.uz) ? S_vwall : S_vcdoor; - } else if (gl.level.flags.is_maze_lev + } else if (svl.level.flags.is_maze_lev && !(In_mines(&u.uz) && in_town(u.ux, u.uy)) && !In_sokoban(&u.uz) && rn2(2)) { ap_type = M_AP_OBJECT; @@ -2371,7 +2371,7 @@ set_mimic_sym(struct monst *mtmp) && (appear == STATUE || appear == FIGURINE || appear == CORPSE || appear == EGG || appear == TIN)) { int mndx = rndmonnum(), - nocorpse_ndx = (gm.mvitals[mndx].mvflags & G_NOCORPSE) != 0; + nocorpse_ndx = (svm.mvitals[mndx].mvflags & G_NOCORPSE) != 0; if (appear == CORPSE && nocorpse_ndx) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, PM_ARCHEOLOGIST); @@ -2383,7 +2383,7 @@ set_mimic_sym(struct monst *mtmp) MCORPSENM(mtmp) = mndx; } else if (ap_type == M_AP_OBJECT && appear == SLIME_MOLD) { newmcorpsenm(mtmp); - MCORPSENM(mtmp) = gc.context.current_fruit; + MCORPSENM(mtmp) = svc.context.current_fruit; /* if no objects of this fruit type have been created yet, context.current_fruit is available for re-use when the player assigns a new fruit name; override that--having a mimic as the diff --git a/src/mcastu.c b/src/mcastu.c index afa7a8722..68a8a8119 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -64,7 +64,7 @@ cursetxt(struct monst *mtmp, boolean undirected) point_msg = "at you, then curses"; pline_mon(mtmp, "%s points %s.", Monnam(mtmp), point_msg); - } else if ((!(gm.moves % 4) || !rn2(4))) { + } else if ((!(svm.moves % 4) || !rn2(4))) { if (!Deaf) Norep("You hear a mumbled curse."); /* Deaf-aware */ } @@ -388,14 +388,14 @@ touch_of_death(struct monst *mtmp) u.mh = 0; rehumanize(); /* fatal iff Unchanging */ } else if (drain >= u.uhpmax) { - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, kbuf); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, kbuf); done(DIED); } else { u.uhpmax -= drain; losehp(dmg, kbuf, KILLED_BY); } - gk.killer.name[0] = '\0'; /* not killed if we get here... */ + svk.killer.name[0] = '\0'; /* not killed if we get here... */ } /* give a reason for death by some monster spells */ @@ -468,7 +468,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) dmg = 0; break; case MGC_CLONE_WIZ: - if (mtmp->iswiz && gc.context.no_of_wizards == 1) { + if (mtmp->iswiz && svc.context.no_of_wizards == 1) { pline("Double Trouble..."); clonewiz(); dmg = 0; @@ -544,7 +544,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) losestr(rnd(dmg), death_inflicted_by(kbuf, "strength loss", mtmp), KILLED_BY); - gk.killer.name[0] = '\0'; /* not killed if we get here... */ + svk.killer.name[0] = '\0'; /* not killed if we get here... */ monstunseesu(M_SEEN_MAGR); } dmg = 0; @@ -928,7 +928,7 @@ spell_would_be_useless(struct monst *mtmp, unsigned int adtyp, int spellnum) if (!mcouldseeu && (spellnum == MGC_SUMMON_MONS || (!mtmp->iswiz && spellnum == MGC_CLONE_WIZ))) return TRUE; - if ((!mtmp->iswiz || gc.context.no_of_wizards > 1) + if ((!mtmp->iswiz || svc.context.no_of_wizards > 1) && spellnum == MGC_CLONE_WIZ) return TRUE; /* aggravation (global wakeup) when everyone is already active */ diff --git a/src/mhitm.c b/src/mhitm.c index d74866296..20744c09d 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -28,9 +28,9 @@ noises(struct monst *magr, struct attack *mattk) { boolean farq = (mdistu(magr) > 15); - if (!Deaf && (farq != gf.far_noise || gm.moves - gn.noisetime > 10)) { + if (!Deaf && (farq != gf.far_noise || svm.moves - gn.noisetime > 10)) { gf.far_noise = farq; - gn.noisetime = gm.moves; + gn.noisetime = svm.moves; You_hear("%s%s.", (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises", farq ? " in the distance" : ""); @@ -360,7 +360,7 @@ mattackm( * some cases, in which case this still counts as its move for the round * and it shouldn't move again. */ - magr->mlstmv = gm.moves; + magr->mlstmv = svm.moves; /* controls whether a mind flayer uses all of its tentacle-for-DRIN attacks; when fighting a headless monster, stop after the first diff --git a/src/mhitu.c b/src/mhitu.c index 1a2e59400..56c731425 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -566,7 +566,7 @@ mattacku(struct monst *mtmp) * parallelism to work, we can't rephrase it, so we * zap the "laid by you" momentarily instead. */ - struct obj *obj = gl.level.objects[u.ux][u.uy]; + struct obj *obj = svl.level.objects[u.ux][u.uy]; if (obj || u.umonnum == PM_TRAPPER || (gy.youmonst.data->mlet == S_EEL @@ -585,14 +585,14 @@ mattacku(struct monst *mtmp) pline( "Wait, %s! There's a hidden %s named %s there!", m_monnam(mtmp), - pmname(gy.youmonst.data, Ugender), gp.plname); + pmname(gy.youmonst.data, Ugender), svp.plname); else pline( "Wait, %s! There's a %s named %s hiding under %s!", m_monnam(mtmp), pmname(gy.youmonst.data, Ugender), - gp.plname, - doname(gl.level.objects[u.ux][u.uy])); + svp.plname, + doname(svl.level.objects[u.ux][u.uy])); if (obj) obj->spe = save_spe; } else @@ -614,7 +614,7 @@ mattacku(struct monst *mtmp) pline("It gets stuck on you."); else /* see note about m_monnam() above */ pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp), - pmname(gy.youmonst.data, Ugender), gp.plname); + pmname(gy.youmonst.data, Ugender), svp.plname); if (sticky) set_ustuck(mtmp); gy.youmonst.m_ap_type = M_AP_NOTHING; @@ -635,7 +635,7 @@ mattacku(struct monst *mtmp) else /* see note about m_monnam() above */ pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp), mimic_obj_name(&gy.youmonst), - an(pmname(&mons[u.umonnum], Ugender)), gp.plname); + an(pmname(&mons[u.umonnum], Ugender)), svp.plname); if (gm.multi < 0) { /* this should always be the case */ char buf[BUFSZ]; @@ -870,7 +870,7 @@ mattacku(struct monst *mtmp) bot(); /* give player a chance of waking up before dying -kaa */ if (sum[i] == M_ATTK_HIT) { /* successful attack */ - if (u.usleep && u.usleep < gm.moves && !rn2(10)) { + if (u.usleep && u.usleep < svm.moves && !rn2(10)) { gm.multi = -1; gn.nomovemsg = "The combat suddenly awakens you."; } @@ -1095,7 +1095,7 @@ hitmu(struct monst *mtmp, struct attack *mattk) const char *what; char Amonbuf[BUFSZ]; - if ((obj = gl.level.objects[mtmp->mx][mtmp->my]) != 0) { + if ((obj = svl.level.objects[mtmp->mx][mtmp->my]) != 0) { if (Blind && !obj->dknown) what = something; else if (is_pool(mtmp->mx, mtmp->my) && !Underwater) @@ -1667,8 +1667,8 @@ gazemu(struct monst *mtmp, struct attack *mattk) if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) break; urgent_pline("You turn to stone..."); - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, pmname(mtmp->data, Mgender(mtmp))); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, pmname(mtmp->data, Mgender(mtmp))); done(STONING); } break; @@ -2451,14 +2451,14 @@ cloneu(void) if (u.mh <= 1) return (struct monst *) 0; - if (gm.mvitals[mndx].mvflags & G_EXTINCT) + if (svm.mvitals[mndx].mvflags & G_EXTINCT) return (struct monst *) 0; mon = makemon(gy.youmonst.data, u.ux, u.uy, NO_MINVENT | MM_EDOG | MM_NOMSG); if (!mon) return NULL; mon->mcloned = 1; - mon = christen_monst(mon, gp.plname); + mon = christen_monst(mon, svp.plname); initedog(mon); mon->m_lev = gy.youmonst.data->mlevel; mon->mhpmax = u.mhmax; diff --git a/src/minion.c b/src/minion.c index 1aee993a0..889b28ed7 100644 --- a/src/minion.c +++ b/src/minion.c @@ -133,7 +133,7 @@ msummon(struct monst *mon) * If this daemon is unique and being re-summoned (the only way we * could get this far with an extinct dtype), try another. */ - if ((gm.mvitals[dtype].mvflags & G_GONE) != 0) { + if ((svm.mvitals[dtype].mvflags & G_GONE) != 0) { dtype = ndemon(atyp); if (dtype == NON_PM) return 0; @@ -388,7 +388,7 @@ dprince(aligntyp atyp) for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) { pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS); - if (!(gm.mvitals[pm].mvflags & G_GONE) + if (!(svm.mvitals[pm].mvflags & G_GONE) && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) return pm; } @@ -402,7 +402,7 @@ dlord(aligntyp atyp) for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) { pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX); - if (!(gm.mvitals[pm].mvflags & G_GONE) + if (!(svm.mvitals[pm].mvflags & G_GONE) && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) return pm; } @@ -413,7 +413,7 @@ dlord(aligntyp atyp) int llord(void) { - if (!(gm.mvitals[PM_ARCHON].mvflags & G_GONE)) + if (!(svm.mvitals[PM_ARCHON].mvflags & G_GONE)) return PM_ARCHON; return lminion(); /* approximate */ diff --git a/src/mklev.c b/src/mklev.c index 589d12d60..98dc94e8e 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -82,7 +82,7 @@ door_into_nonjoined(coordxy x, coordxy y) /* Is this connecting to a room that doesn't want joining? */ if (levl[tx][ty].roomno >= ROOMOFFSET - && !gr.rooms[levl[tx][ty].roomno - ROOMOFFSET].needjoining) { + && !svr.rooms[levl[tx][ty].roomno - ROOMOFFSET].needjoining) { return TRUE; } } @@ -124,13 +124,13 @@ void sort_rooms(void) { coordxy x, y; - unsigned i, ri[MAXNROFROOMS + 1] = { 0U }, n = (unsigned) gn.nroom; + unsigned i, ri[MAXNROFROOMS + 1] = { 0U }, n = (unsigned) svn.nroom; - qsort((genericptr_t) gr.rooms, n, sizeof (struct mkroom), mkroom_cmp); + qsort((genericptr_t) svr.rooms, n, sizeof (struct mkroom), mkroom_cmp); /* Update the roomnos on the map */ for (i = 0; i < n; i++) - ri[gr.rooms[i].roomnoidx] = i; + ri[svr.rooms[i].roomnoidx] = i; for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) { @@ -170,7 +170,7 @@ do_room_or_subroom(struct mkroom *croom, } else croom->rlit = 0; - croom->roomnoidx = (croom - gr.rooms); + croom->roomnoidx = (croom - svr.rooms); croom->lx = lowx; croom->hx = hix; croom->ly = lowy; @@ -220,12 +220,12 @@ add_room(int lowx, int lowy, int hix, int hiy, { struct mkroom *croom; - croom = &gr.rooms[gn.nroom]; + croom = &svr.rooms[svn.nroom]; do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, (boolean) TRUE); croom++; croom->hx = -1; - gn.nroom++; + svn.nroom++; } void @@ -254,7 +254,7 @@ free_luathemes(enum lua_theme_group theme_group) * most_themes => entering endgame, free non-endgame themes; * all_themes => end of game, free all themes. */ - for (i = 0; i < gn.n_dgns; ++i) { + for (i = 0; i < svn.n_dgns; ++i) { if ((theme_group == tut_themes && i != tutorial_dnum) || (theme_group == most_themes && i == astral_level.dnum)) continue; @@ -274,7 +274,7 @@ makerooms(void) nhl_sandbox_info sbi = {NHL_SB_SAFE, 1*1024*1024, 0, 1*1024*1024}; lua_State *themes = (lua_State *) gl.luathemes[u.uz.dnum]; - if (!themes && *(fname = gd.dungeons[u.uz.dnum].themerms)) { + if (!themes && *(fname = svd.dungeons[u.uz.dnum].themerms)) { if ((themes = nhl_init(&sbi)) != 0) { if (!nhl_loadlua(themes, fname)) { /* loading lua failed, don't use themed rooms */ @@ -288,7 +288,7 @@ makerooms(void) } } if (!themes) /* don't try again when making next level */ - *fname = '\0'; /* gd.dungeons[u.uz.dnum].themerms */ + *fname = '\0'; /* svd.dungeons[u.uz.dnum].themerms */ } if (themes) { @@ -302,13 +302,13 @@ makerooms(void) /* make rooms until satisfied */ /* rnd_rect() will returns 0 if no more rects are available... */ - while (gn.nroom < (MAXNROFROOMS - 1) && rnd_rect()) { - if (gn.nroom >= (MAXNROFROOMS / 6) && rn2(2) && !tried_vault) { + while (svn.nroom < (MAXNROFROOMS - 1) && rnd_rect()) { + if (svn.nroom >= (MAXNROFROOMS / 6) && rn2(2) && !tried_vault) { tried_vault = TRUE; if (create_vault()) { - gv.vault_x = gr.rooms[gn.nroom].lx; - gv.vault_y = gr.rooms[gn.nroom].ly; - gr.rooms[gn.nroom].hx = -1; + gv.vault_x = svr.rooms[svn.nroom].lx; + gv.vault_y = svr.rooms[svn.nroom].ly; + svr.rooms[svn.nroom].hx = -1; } } else { if (themes) { @@ -319,7 +319,7 @@ makerooms(void) iflags.in_lua = gi.in_mk_themerooms = FALSE; if (gt.themeroom_failed && ((themeroom_tries++ > 10) - || (gn.nroom >= (MAXNROFROOMS / 6)))) + || (svn.nroom >= (MAXNROFROOMS / 6)))) break; } else { if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1)) @@ -345,8 +345,8 @@ join(int a, int b, boolean nxcor) struct mkroom *croom, *troom; int dx, dy; - croom = &gr.rooms[a]; - troom = &gr.rooms[b]; + croom = &svr.rooms[a]; + troom = &svr.rooms[b]; if (!croom->needjoining || !troom->needjoining) return; @@ -408,7 +408,7 @@ join(int a, int b, boolean nxcor) dest.y = ty; if (!dig_corridor(&org, &dest, nxcor, - gl.level.flags.arboreal ? ROOM : CORR, STONE)) + svl.level.flags.arboreal ? ROOM : CORR, STONE)) return; /* we succeeded in digging the corridor */ @@ -428,48 +428,48 @@ makecorridors(void) int a, b, i; boolean any = TRUE; - for (a = 0; a < gn.nroom - 1; a++) { + for (a = 0; a < svn.nroom - 1; a++) { join(a, a + 1, FALSE); if (!rn2(50)) break; /* allow some randomness */ } - for (a = 0; a < gn.nroom - 2; a++) + for (a = 0; a < svn.nroom - 2; a++) if (gs.smeq[a] != gs.smeq[a + 2]) join(a, a + 2, FALSE); - for (a = 0; any && a < gn.nroom; a++) { + for (a = 0; any && a < svn.nroom; a++) { any = FALSE; - for (b = 0; b < gn.nroom; b++) + for (b = 0; b < svn.nroom; b++) if (gs.smeq[a] != gs.smeq[b]) { join(a, b, FALSE); any = TRUE; } } /* add some extra corridors which may be blocked off */ - if (gn.nroom > 2) - for (i = rn2(gn.nroom) + 4; i; i--) { - a = rn2(gn.nroom); - b = rn2(gn.nroom - 2); + if (svn.nroom > 2) + for (i = rn2(svn.nroom) + 4; i; i--) { + a = rn2(svn.nroom); + b = rn2(svn.nroom - 2); if (b >= a) b += 2; join(a, b, TRUE); } } -/* (re)allocate space for gd.doors array */ +/* (re)allocate space for svd.doors array */ staticfn void alloc_doors(void) { - if (!gd.doors || gd.doorindex >= gd.doors_alloc) { - int c = gd.doors_alloc + DOORINC; + if (!svd.doors || gd.doorindex >= svd.doors_alloc) { + int c = svd.doors_alloc + DOORINC; coord *doortmp = (coord *) alloc(c * sizeof(coord)); (void) memset((genericptr_t) doortmp, 0, c * sizeof(coord)); - if (gd.doors) { - (void) memcpy(doortmp, gd.doors, gd.doors_alloc * sizeof(coord)); - free(gd.doors); + if (svd.doors) { + (void) memcpy(doortmp, svd.doors, svd.doors_alloc * sizeof(coord)); + free(svd.doors); } - gd.doors = doortmp; - gd.doors_alloc = c; + svd.doors = doortmp; + svd.doors_alloc = c; } } @@ -485,7 +485,7 @@ add_door(coordxy x, coordxy y, struct mkroom *aroom) if (aroom->doorct) { for (i = 0; i < aroom->doorct; i++) { tmp = aroom->fdoor + i; - if (gd.doors[tmp].x == x && gd.doors[tmp].y == y) + if (svd.doors[tmp].x == x && svd.doors[tmp].y == y) return; } } @@ -496,10 +496,10 @@ add_door(coordxy x, coordxy y, struct mkroom *aroom) aroom->doorct++; for (tmp = gd.doorindex; tmp > aroom->fdoor; tmp--) - gd.doors[tmp] = gd.doors[tmp - 1]; + svd.doors[tmp] = svd.doors[tmp - 1]; - for (i = 0; i < gn.nroom; i++) { - broom = &gr.rooms[i]; + for (i = 0; i < svn.nroom; i++) { + broom = &svr.rooms[i]; if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor) broom->fdoor++; } @@ -510,8 +510,8 @@ add_door(coordxy x, coordxy y, struct mkroom *aroom) } gd.doorindex++; - gd.doors[aroom->fdoor].x = x; - gd.doors[aroom->fdoor].y = y; + svd.doors[aroom->fdoor].x = x; + svd.doors[aroom->fdoor].y = y; } staticfn void @@ -546,7 +546,7 @@ dosdoor(coordxy x, coordxy y, struct mkroom *aroom, int type) } /* also done in roguecorr(); doing it here first prevents - making mimics in place of trapped doors on rogue gl.level */ + making mimics in place of trapped doors on rogue svl.level */ if (Is_rogue_level(&u.uz)) levl[x][y].doormask = D_NODOOR; @@ -554,9 +554,9 @@ dosdoor(coordxy x, coordxy y, struct mkroom *aroom, int type) struct monst *mtmp; if (level_difficulty() >= 9 && !rn2(5) - && !((gm.mvitals[PM_SMALL_MIMIC].mvflags & G_GONE) - && (gm.mvitals[PM_LARGE_MIMIC].mvflags & G_GONE) - && (gm.mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) { + && !((svm.mvitals[PM_SMALL_MIMIC].mvflags & G_GONE) + && (svm.mvitals[PM_LARGE_MIMIC].mvflags & G_GONE) + && (svm.mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) { /* make a mimic instead */ levl[x][y].doormask = D_NODOOR; mtmp = makemon(mkclass(S_MIMIC, 0), x, y, NO_MM_FLAGS); @@ -583,7 +583,7 @@ dosdoor(coordxy x, coordxy y, struct mkroom *aroom, int type) staticfn boolean cardinal_nextto_room(struct mkroom *aroom, coordxy x, coordxy y) { - int rmno = (int) ((aroom - gr.rooms) + ROOMOFFSET); + int rmno = (int) ((aroom - svr.rooms) + ROOMOFFSET); if (isok(x - 1, y) && !levl[x - 1][y].edge && (int) levl[x - 1][y].roomno == rmno) @@ -649,7 +649,7 @@ makeniche(int trap_type) struct trap *ttmp; while (vct--) { - aroom = &gr.rooms[rn2(gn.nroom)]; + aroom = &svr.rooms[rn2(svn.nroom)]; if (aroom->rtype != OROOM) continue; /* not an ordinary room */ if (aroom->doorct == 1 && rn2(5)) @@ -690,7 +690,7 @@ makeniche(int trap_type) mkclass(S_HUMAN, 0), xx, yy + dy, TRUE); } - if (!gl.level.flags.noteleport) + if (!svl.level.flags.noteleport) (void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE, FALSE); if (!rn2(3)) @@ -704,8 +704,8 @@ makeniche(int trap_type) staticfn void make_niches(void) { - int ct = rnd((gn.nroom >> 1) + 1), dep = depth(&u.uz); - boolean ltptr = (!gl.level.flags.noteleport && dep > 15), + int ct = rnd((svn.nroom >> 1) + 1), dep = depth(&u.uz); + boolean ltptr = (!svl.level.flags.noteleport && dep > 15), vamp = (dep > 5 && dep < 25); while (ct--) { @@ -732,15 +732,15 @@ count_level_features(void) { coordxy x, y; - gl.level.flags.nfountains = gl.level.flags.nsinks = 0; + svl.level.flags.nfountains = svl.level.flags.nsinks = 0; for (y = 0; y < ROWNO; y++) for (x = 1; x < COLNO; x++) { int typ = levl[x][y].typ; if (typ == FOUNTAIN) - gl.level.flags.nfountains++; + svl.level.flags.nfountains++; else if (typ == SINK) - gl.level.flags.nsinks++; + svl.level.flags.nsinks++; } } @@ -765,55 +765,55 @@ clear_level_structures(void) lev = &levl[x][0]; for (y = 0; y < ROWNO; y++) { *lev++ = zerorm; - gl.level.objects[x][y] = (struct obj *) 0; - gl.level.monsters[x][y] = (struct monst *) 0; + svl.level.objects[x][y] = (struct obj *) 0; + svl.level.monsters[x][y] = (struct monst *) 0; } } - gl.level.objlist = (struct obj *) 0; - gl.level.buriedobjlist = (struct obj *) 0; - gl.level.monlist = (struct monst *) 0; - gl.level.damagelist = (struct damage *) 0; - gl.level.bonesinfo = (struct cemetery *) 0; + svl.level.objlist = (struct obj *) 0; + svl.level.buriedobjlist = (struct obj *) 0; + svl.level.monlist = (struct monst *) 0; + svl.level.damagelist = (struct damage *) 0; + svl.level.bonesinfo = (struct cemetery *) 0; - gl.level.flags.nfountains = 0; - gl.level.flags.nsinks = 0; - gl.level.flags.has_shop = 0; - gl.level.flags.has_vault = 0; - gl.level.flags.has_zoo = 0; - gl.level.flags.has_court = 0; - gl.level.flags.has_morgue = gl.level.flags.graveyard = 0; - gl.level.flags.has_beehive = 0; - gl.level.flags.has_barracks = 0; - gl.level.flags.has_temple = 0; - gl.level.flags.has_swamp = 0; - gl.level.flags.noteleport = 0; - gl.level.flags.hardfloor = 0; - gl.level.flags.nommap = 0; - gl.level.flags.hero_memory = 1; - gl.level.flags.shortsighted = 0; - gl.level.flags.sokoban_rules = 0; - gl.level.flags.is_maze_lev = 0; - gl.level.flags.is_cavernous_lev = 0; - gl.level.flags.arboreal = 0; - gl.level.flags.has_town = 0; - gl.level.flags.wizard_bones = 0; - gl.level.flags.corrmaze = 0; - gl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0; - gl.level.flags.rndmongen = 1; - gl.level.flags.deathdrops = 1; - gl.level.flags.noautosearch = 0; - gl.level.flags.fumaroles = 0; - gl.level.flags.stormy = 0; + svl.level.flags.nfountains = 0; + svl.level.flags.nsinks = 0; + svl.level.flags.has_shop = 0; + svl.level.flags.has_vault = 0; + svl.level.flags.has_zoo = 0; + svl.level.flags.has_court = 0; + svl.level.flags.has_morgue = svl.level.flags.graveyard = 0; + svl.level.flags.has_beehive = 0; + svl.level.flags.has_barracks = 0; + svl.level.flags.has_temple = 0; + svl.level.flags.has_swamp = 0; + svl.level.flags.noteleport = 0; + svl.level.flags.hardfloor = 0; + svl.level.flags.nommap = 0; + svl.level.flags.hero_memory = 1; + svl.level.flags.shortsighted = 0; + svl.level.flags.sokoban_rules = 0; + svl.level.flags.is_maze_lev = 0; + svl.level.flags.is_cavernous_lev = 0; + svl.level.flags.arboreal = 0; + svl.level.flags.has_town = 0; + svl.level.flags.wizard_bones = 0; + svl.level.flags.corrmaze = 0; + svl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0; + svl.level.flags.rndmongen = 1; + svl.level.flags.deathdrops = 1; + svl.level.flags.noautosearch = 0; + svl.level.flags.fumaroles = 0; + svl.level.flags.stormy = 0; - gn.nroom = 0; - gr.rooms[0].hx = -1; + svn.nroom = 0; + svr.rooms[0].hx = -1; gn.nsubroom = 0; gs.subrooms[0].hx = -1; gd.doorindex = 0; - if (gd.doors_alloc) { - free((genericptr_t) gd.doors); - gd.doors = (coord *) 0; - gd.doors_alloc = 0; + if (svd.doors_alloc) { + free((genericptr_t) svd.doors); + svd.doors = (coord *) 0; + svd.doors_alloc = 0; } init_rect(); init_vault(); @@ -1035,8 +1035,8 @@ fill_ordinary_room( * of rooms; about 5 - 7.5% for 2 boxes, least likely * when few rooms; chance for 3 or more is negligible. */ - /*assert(gn.nroom > 0); // must be true because we're filling a room*/ - if (!skip_chests && !rn2(gn.nroom * 5 / 2) && somexyspace(croom, &pos)) + /*assert(svn.nroom > 0); // must be true because we're filling a room*/ + if (!skip_chests && !rn2(svn.nroom * 5 / 2) && somexyspace(croom, &pos)) (void) mksobj_at(rn2(3) ? LARGE_BOX : CHEST, pos.x, pos.y, TRUE, FALSE); @@ -1113,10 +1113,10 @@ makelevel(void) /* check for special levels */ if (slev && !Is_rogue_level(&u.uz)) { makemaz(slev->proto); - } else if (gd.dungeons[u.uz.dnum].proto[0]) { + } else if (svd.dungeons[u.uz.dnum].proto[0]) { makemaz(""); - } else if (gd.dungeons[u.uz.dnum].fill_lvl[0]) { - makemaz(gd.dungeons[u.uz.dnum].fill_lvl); + } else if (svd.dungeons[u.uz.dnum].fill_lvl[0]) { + makemaz(svd.dungeons[u.uz.dnum].fill_lvl); } else if (In_quest(&u.uz)) { char fillname[9]; s_level *loc_lev; @@ -1142,7 +1142,7 @@ makelevel(void) } else { makerooms(); } - assert(gn.nroom > 0); + assert(svn.nroom > 0); sort_rooms(); generate_stairs(); /* up and down stairs */ @@ -1167,20 +1167,20 @@ makelevel(void) add_room(gv.vault_x, gv.vault_y, gv.vault_x + w, gv.vault_y + h, TRUE, VAULT, FALSE); - gl.level.flags.has_vault = 1; + svl.level.flags.has_vault = 1; ++room_threshold; - gr.rooms[gn.nroom - 1].needfill = FILL_NORMAL; - fill_special_room(&gr.rooms[gn.nroom - 1]); + svr.rooms[svn.nroom - 1].needfill = FILL_NORMAL; + fill_special_room(&svr.rooms[svn.nroom - 1]); mk_knox_portal(gv.vault_x + w, gv.vault_y + h); - if (!gl.level.flags.noteleport && !rn2(3)) + if (!svl.level.flags.noteleport && !rn2(3)) makevtele(); } else if (rnd_rect() && create_vault()) { - gv.vault_x = gr.rooms[gn.nroom].lx; - gv.vault_y = gr.rooms[gn.nroom].ly; + gv.vault_x = svr.rooms[svn.nroom].lx; + gv.vault_y = svr.rooms[svn.nroom].ly; if (check_room(&gv.vault_x, &w, &gv.vault_y, &h, TRUE)) goto fill_vault; else - gr.rooms[gn.nroom].hx = -1; + svr.rooms[svn.nroom].hx = -1; } } @@ -1190,31 +1190,31 @@ makelevel(void) if (wizard && nh_getenv("SHOPTYPE")) do_mkroom(SHOPBASE); else if (u_depth > 1 && u_depth < depth(&medusa_level) - && gn.nroom >= room_threshold && rn2(u_depth) < 3) + && svn.nroom >= room_threshold && rn2(u_depth) < 3) do_mkroom(SHOPBASE); else if (u_depth > 4 && !rn2(6)) do_mkroom(COURT); else if (u_depth > 5 && !rn2(8) - && !(gm.mvitals[PM_LEPRECHAUN].mvflags & G_GONE)) + && !(svm.mvitals[PM_LEPRECHAUN].mvflags & G_GONE)) do_mkroom(LEPREHALL); else if (u_depth > 6 && !rn2(7)) do_mkroom(ZOO); else if (u_depth > 8 && !rn2(5)) do_mkroom(TEMPLE); else if (u_depth > 9 && !rn2(5) - && !(gm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) + && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) do_mkroom(BEEHIVE); else if (u_depth > 11 && !rn2(6)) do_mkroom(MORGUE); else if (u_depth > 12 && !rn2(8) && antholemon()) do_mkroom(ANTHOLE); else if (u_depth > 14 && !rn2(4) - && !(gm.mvitals[PM_SOLDIER].mvflags & G_GONE)) + && !(svm.mvitals[PM_SOLDIER].mvflags & G_GONE)) do_mkroom(BARRACKS); else if (u_depth > 15 && !rn2(6)) do_mkroom(SWAMP); else if (u_depth > 16 && !rn2(8) - && !(gm.mvitals[PM_COCKATRICE].mvflags & G_GONE)) + && !(svm.mvitals[PM_COCKATRICE].mvflags & G_GONE)) do_mkroom(COCKNEST); skip0: @@ -1233,7 +1233,7 @@ makelevel(void) rooms (intended to be indistinguishable from the normally generated items); work out which room these will be placed in */ int fillable_room_count = 0; - for (croom = gr.rooms; croom->hx > 0; croom++) { + for (croom = svr.rooms; croom->hx > 0; croom++) { if (ROOM_IS_FILLABLE(croom)) fillable_room_count++; } @@ -1245,7 +1245,7 @@ makelevel(void) ? rn2(fillable_room_count) : -1; /* for each room: put things inside */ - for (croom = gr.rooms; croom->hx > 0; croom++) { + for (croom = svr.rooms; croom->hx > 0; croom++) { boolean fillable = ROOM_IS_FILLABLE(croom); fill_ordinary_room(croom, @@ -1256,8 +1256,8 @@ makelevel(void) } /* Fill all special rooms now, regardless of whether this is a special * level, proto level, or ordinary level. */ - for (i = 0; i < gn.nroom; ++i) { - fill_special_room(&gr.rooms[i]); + for (i = 0; i < svn.nroom; ++i) { + fill_special_room(&svr.rooms[i]); } themerooms_post_level_generate(); @@ -1303,7 +1303,7 @@ mineralize(int kelp_pool, int kelp_moat, int goldprob, int gemprob, almost all special levels are excluded */ if (!skip_lvl_checks && (In_hell(&u.uz) || In_V_tower(&u.uz) || Is_rogue_level(&u.uz) - || gl.level.flags.arboreal + || svl.level.flags.arboreal || ((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz) && (!In_mines(&u.uz) || sp->flags.town)))) return; @@ -1388,10 +1388,10 @@ level_finalize_topology(void) /* has_morgue gets cleared once morgue is entered; graveyard stays set (graveyard might already be set even when has_morgue is clear [see fixup_special()], so don't update it unconditionally) */ - if (gl.level.flags.has_morgue) - gl.level.flags.graveyard = 1; - if (!gl.level.flags.is_maze_lev) { - for (croom = &gr.rooms[0]; croom != &gr.rooms[gn.nroom]; croom++) + if (svl.level.flags.has_morgue) + svl.level.flags.graveyard = 1; + if (!svl.level.flags.is_maze_lev) { + for (croom = &svr.rooms[0]; croom != &svr.rooms[svn.nroom]; croom++) #ifdef SPECIALIZATION topologize(croom, FALSE); #else @@ -1399,10 +1399,10 @@ level_finalize_topology(void) #endif } set_wall_state(); - /* for many room types, gr.rooms[].rtype is zeroed once the room has been - entered; gr.rooms[].orig_rtype always retains original rtype value */ - for (ridx = 0; ridx < SIZE(gr.rooms); ridx++) - gr.rooms[ridx].orig_rtype = gr.rooms[ridx].rtype; + /* for many room types, svr.rooms[].rtype is zeroed once the room has been + entered; svr.rooms[].orig_rtype always retains original rtype value */ + for (ridx = 0; ridx < SIZE(svr.rooms); ridx++) + svr.rooms[ridx].orig_rtype = svr.rooms[ridx].rtype; } void @@ -1432,7 +1432,7 @@ topologize(struct mkroom *croom) #endif { coordxy x, y; - int roomno = (int) ((croom - gr.rooms) + ROOMOFFSET); + int roomno = (int) ((croom - svr.rooms) + ROOMOFFSET); coordxy lowx = croom->lx, lowy = croom->ly; coordxy hix = croom->hx, hiy = croom->hy; #ifdef SPECIALIZATION @@ -1493,7 +1493,7 @@ find_branch_room(coord *mp) { struct mkroom *croom = 0; - if (gn.nroom == 0) { + if (svn.nroom == 0) { mazexy(mp); /* already verifies location */ } else { croom = generate_stairs_find_room(); @@ -1511,7 +1511,7 @@ pos_to_room(coordxy x, coordxy y) int i; struct mkroom *curr; - for (curr = gr.rooms, i = 0; i < gn.nroom; curr++, i++) + for (curr = svr.rooms, i = 0; i < svn.nroom; curr++, i++) if (inside_room(curr, x, y)) return curr; ; @@ -1790,7 +1790,7 @@ traptype_rnd(unsigned mktrapflags) kind = NO_TRAP; break; case LEVEL_TELEP: - if (lvl < 5 || gl.level.flags.noteleport + if (lvl < 5 || svl.level.flags.noteleport || single_level_branch(&u.uz)) kind = NO_TRAP; break; @@ -1816,7 +1816,7 @@ traptype_rnd(unsigned mktrapflags) kind = NO_TRAP; break; case TELEP_TRAP: - if (gl.level.flags.noteleport) + if (svl.level.flags.noteleport) kind = NO_TRAP; break; case HOLE: @@ -2045,25 +2045,25 @@ generate_stairs_find_room(void) int i, phase, ai; int *rmarr; - if (!gn.nroom) + if (!svn.nroom) return (struct mkroom *) 0; - rmarr = (int *) alloc(sizeof(int) * gn.nroom); + rmarr = (int *) alloc(sizeof(int) * svn.nroom); for (phase = 2; phase > -1; phase--) { ai = 0; - for (i = 0; i < gn.nroom; i++) - if (generate_stairs_room_good(&gr.rooms[i], phase)) + for (i = 0; i < svn.nroom; i++) + if (generate_stairs_room_good(&svr.rooms[i], phase)) rmarr[ai++] = i; if (ai > 0) { i = rmarr[rn2(ai)]; free(rmarr); - return &gr.rooms[i]; + return &svr.rooms[i]; } } free(rmarr); - croom = &gr.rooms[rn2(gn.nroom)]; + croom = &svr.rooms[rn2(svn.nroom)]; return croom; } @@ -2081,7 +2081,7 @@ generate_stairs(void) if (!Is_botlevel(&u.uz)) { if ((croom = generate_stairs_find_room()) == NULL) - panic(gen_stairs_panic, gn.nroom); + panic(gen_stairs_panic, svn.nroom); if (!somexyspace(croom, &pos)) { pos.x = somex(croom); @@ -2094,7 +2094,7 @@ generate_stairs(void) /* if there is only 1 room and we found it above, this will find it again */ if ((croom = generate_stairs_find_room()) == NULL) - panic(gen_stairs_panic, gn.nroom); + panic(gen_stairs_panic, svn.nroom); if (!somexyspace(croom, &pos)) { pos.x = somex(croom); @@ -2119,7 +2119,7 @@ mkfount(struct mkroom *croom) if (!rn2(7)) levl[m.x][m.y].blessedftn = 1; - gl.level.flags.nfountains++; + svl.level.flags.nfountains++; } staticfn boolean @@ -2148,7 +2148,7 @@ mksink(struct mkroom *croom) if (!set_levltyp(m.x, m.y, SINK)) return; - gl.level.flags.nsinks++; + svl.level.flags.nsinks++; } staticfn void @@ -2222,7 +2222,7 @@ mkgrave(struct mkroom *croom) /* * Major level transmutation: add a set of stairs (to the Sanctum) after * an earthquake that leaves behind a new topology, centered at inv_pos. - * Assumes there are no rooms within the invocation area and that gi.inv_pos + * Assumes there are no rooms within the invocation area and that svi.inv_pos * is not too close to the edge of the map. Also assume the hero can see, * which is guaranteed for normal play due to the fact that sight is needed * to read the Book of the Dead. [That assumption is not valid; it is @@ -2240,8 +2240,8 @@ mkinvokearea(void) pline_The("floor shakes violently under you!"); /* decide whether to issue the crumbling walls message */ { - xmin = xmax = gi.inv_pos.x; - ymin = ymax = gi.inv_pos.y; + xmin = xmax = svi.inv_pos.x; + ymin = ymax = svi.inv_pos.y; wallct = mkinvk_check_wall(xmin, ymin); /* this replicates the somewhat convoluted loop below, working out from the stair position, except for stopping early when @@ -2285,8 +2285,8 @@ mkinvokearea(void) reset_utrap(FALSE); } - xmin = xmax = gi.inv_pos.x; /* reset after the check for walls */ - ymin = ymax = gi.inv_pos.y; + xmin = xmax = svi.inv_pos.x; /* reset after the check for walls */ + ymin = ymax = svi.inv_pos.y; mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */ for (dist = 1; dist < 7; dist++) { @@ -2464,7 +2464,7 @@ mk_knox_portal(coordxy x, coordxy y) } /* Already set or 2/3 chance of deferring until a later level. */ - if (source->dnum < gn.n_dgns || (rn2(3) && !wizard)) + if (source->dnum < svn.n_dgns || (rn2(3) && !wizard)) return; if (!(u.uz.dnum == oracle_level.dnum /* in main dungeon */ diff --git a/src/mkmap.c b/src/mkmap.c index 7246e97c4..32c6aef68 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -251,8 +251,8 @@ join_map_cleanup(void) for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) levl[x][y].roomno = NO_ROOM; - gn.nroom = gn.nsubroom = 0; - gr.rooms[gn.nroom].hx = gs.subrooms[gn.nsubroom].hx = -1; + svn.nroom = gn.nsubroom = 0; + svr.rooms[svn.nroom].hx = gs.subrooms[gn.nsubroom].hx = -1; } staticfn void @@ -272,12 +272,12 @@ join_map(schar bg_typ, schar fg_typ) gm.min_rx = gm.max_rx = i; gm.min_ry = gm.max_ry = j; gn.n_loc_filled = 0; - flood_fill_rm(i, j, gn.nroom + ROOMOFFSET, FALSE, FALSE); + flood_fill_rm(i, j, svn.nroom + ROOMOFFSET, FALSE, FALSE); if (gn.n_loc_filled > 3) { add_room(gm.min_rx, gm.min_ry, gm.max_rx, gm.max_ry, FALSE, OROOM, TRUE); - gr.rooms[gn.nroom - 1].irregular = TRUE; - if (gn.nroom >= (MAXNROFROOMS * 2)) + svr.rooms[svn.nroom - 1].irregular = TRUE; + if (svn.nroom >= (MAXNROFROOMS * 2)) goto joinm; } else { /* @@ -287,7 +287,7 @@ join_map(schar bg_typ, schar fg_typ) for (sx = gm.min_rx; sx <= gm.max_rx; sx++) for (sy = gm.min_ry; sy <= gm.max_ry; sy++) if ((int) levl[sx][sy].roomno - == gn.nroom + ROOMOFFSET) { + == svn.nroom + ROOMOFFSET) { levl[sx][sy].typ = bg_typ; levl[sx][sy].roomno = NO_ROOM; } @@ -302,8 +302,8 @@ join_map(schar bg_typ, schar fg_typ) * so don't call sort_rooms(), which can screw up the roomno's * validity in the levl structure. */ - for (croom = &gr.rooms[0], croom2 = croom + 1; - croom2 < &gr.rooms[gn.nroom]; ) { + for (croom = &svr.rooms[0], croom2 = croom + 1; + croom2 < &svr.rooms[svn.nroom]; ) { /* pick random starting and end locations for "corridor" */ if (!somexy(croom, &sm) || !somexy(croom2, &em)) { /* ack! -- the level is going to be busted */ @@ -350,8 +350,8 @@ finish_map( || (bg_typ == TREE && levl[i][j].typ == bg_typ) || (walled && IS_WALL(levl[i][j].typ))) levl[i][j].lit = TRUE; - for (i = 0; i < gn.nroom; i++) - gr.rooms[i].rlit = 1; + for (i = 0; i < svn.nroom; i++) + svr.rooms[i].rlit = 1; } /* light lava even if everything's otherwise unlit; ice might be frozen pool rather than frozen moat */ @@ -383,8 +383,8 @@ remove_rooms(int lx, int ly, int hx, int hy) int i; struct mkroom *croom; - for (i = gn.nroom - 1; i >= 0; --i) { - croom = &gr.rooms[i]; + for (i = svn.nroom - 1; i >= 0; --i) { + croom = &svr.rooms[i]; if (croom->hx < lx || croom->lx >= hx || croom->hy < ly || croom->ly >= hy) continue; /* no overlap */ @@ -413,8 +413,8 @@ remove_rooms(int lx, int ly, int hx, int hy) staticfn void remove_room(unsigned int roomno) { - struct mkroom *croom = &gr.rooms[roomno]; - struct mkroom *maxroom = &gr.rooms[--gn.nroom]; + struct mkroom *croom = &svr.rooms[roomno]; + struct mkroom *maxroom = &svr.rooms[--svn.nroom]; int i, j; unsigned oroomno; @@ -425,7 +425,7 @@ remove_room(unsigned int roomno) *croom = *maxroom; /* since maxroom moved, update affected level roomno values */ - oroomno = gn.nroom + ROOMOFFSET; + oroomno = svn.nroom + ROOMOFFSET; roomno += ROOMOFFSET; for (i = croom->lx; i <= croom->hx; ++i) for (j = croom->ly; j <= croom->hy; ++j) { @@ -481,8 +481,8 @@ mkmap(lev_init *init_lev) init_lev->icedpools); /* a walled, joined level is cavernous, not mazelike -dlc */ if (walled && join) { - gl.level.flags.is_maze_lev = FALSE; - gl.level.flags.is_cavernous_lev = TRUE; + svl.level.flags.is_maze_lev = FALSE; + svl.level.flags.is_cavernous_lev = TRUE; } free(gn.new_locations); } diff --git a/src/mkmaze.c b/src/mkmaze.c index 040d466f3..adc2cd649 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -305,7 +305,7 @@ maze0xy(coord *cc) staticfn boolean is_exclusion_zone(xint16 type, coordxy x, coordxy y) { - struct exclusion_zone *ez = ge.exclusion_zones; + struct exclusion_zone *ez = sve.exclusion_zones; while (ez) { if (((type == LR_DOWNTELE && (ez->zonetype == LR_DOWNTELE || ez->zonetype == LR_TELE)) @@ -332,7 +332,7 @@ bad_location( return (boolean) (occupied(x, y) || within_bounded_area(x, y, nlx, nly, nhx, nhy) || !((levl[x][y].typ == CORR - && gl.level.flags.is_maze_lev) + && svl.level.flags.is_maze_lev) || levl[x][y].typ == ROOM || levl[x][y].typ == AIR)); } @@ -355,7 +355,7 @@ place_lregion( * if there are rooms and this a branch, let place_branch choose * the branch location (to avoid putting branches in corridors). */ - if (rtype == LR_BRANCH && gn.nroom) { + if (rtype == LR_BRANCH && svn.nroom) { place_branch(Is_branchlev(&u.uz), 0, 0); return; } @@ -562,7 +562,7 @@ fixup_special(void) boolean added_branch = FALSE; if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) { - gl.level.flags.hero_memory = 0; + svl.level.flags.hero_memory = 0; /* water level is an odd beast - it has to be set up before calling place_lregions etc. */ setup_waterlevel(); @@ -597,24 +597,24 @@ fixup_special(void) case LR_DOWNTELE: /* save the region outlines for goto_level() */ if (r->rtype == LR_TELE || r->rtype == LR_UPTELE) { - gu.updest.lx = r->inarea.x1; - gu.updest.ly = r->inarea.y1; - gu.updest.hx = r->inarea.x2; - gu.updest.hy = r->inarea.y2; - gu.updest.nlx = r->delarea.x1; - gu.updest.nly = r->delarea.y1; - gu.updest.nhx = r->delarea.x2; - gu.updest.nhy = r->delarea.y2; + svu.updest.lx = r->inarea.x1; + svu.updest.ly = r->inarea.y1; + svu.updest.hx = r->inarea.x2; + svu.updest.hy = r->inarea.y2; + svu.updest.nlx = r->delarea.x1; + svu.updest.nly = r->delarea.y1; + svu.updest.nhx = r->delarea.x2; + svu.updest.nhy = r->delarea.y2; } if (r->rtype == LR_TELE || r->rtype == LR_DOWNTELE) { - gd.dndest.lx = r->inarea.x1; - gd.dndest.ly = r->inarea.y1; - gd.dndest.hx = r->inarea.x2; - gd.dndest.hy = r->inarea.y2; - gd.dndest.nlx = r->delarea.x1; - gd.dndest.nly = r->delarea.y1; - gd.dndest.nhx = r->delarea.x2; - gd.dndest.nhy = r->delarea.y2; + svd.dndest.lx = r->inarea.x1; + svd.dndest.ly = r->inarea.y1; + svd.dndest.hx = r->inarea.x2; + svd.dndest.hy = r->inarea.y2; + svd.dndest.nlx = r->delarea.x1; + svd.dndest.nly = r->delarea.y1; + svd.dndest.nhx = r->delarea.x2; + svd.dndest.nhy = r->delarea.y2; } /* place_lregion gets called from goto_level() */ break; @@ -634,7 +634,7 @@ fixup_special(void) struct obj *otmp; int tryct; - croom = &gr.rooms[0]; /* the first room defined on the medusa level */ + croom = &svr.rooms[0]; /* the first room defined on the medusa level */ for (tryct = rnd(4); tryct; tryct--) { x = somex(croom); y = somey(croom); @@ -669,9 +669,9 @@ fixup_special(void) } } else if (Role_if(PM_CLERIC) && In_quest(&u.uz)) { /* less chance for undead corpses (lured from lower morgues) */ - gl.level.flags.graveyard = 1; + svl.level.flags.graveyard = 1; } else if (Is_stronghold(&u.uz)) { - gl.level.flags.graveyard = 1; + svl.level.flags.graveyard = 1; } else if (on_level(&u.uz, &baalzebub_level)) { /* custom wallify the "beetle" potion of the level */ baalz_fixup(); @@ -680,7 +680,7 @@ fixup_special(void) } if ((sp = Is_special(&u.uz)) != 0 && sp->flags.town) /* Mine Town */ - gl.level.flags.has_town = 1; + svl.level.flags.has_town = 1; if (gl.lregions) free((genericptr_t) gl.lregions), gl.lregions = 0; @@ -705,7 +705,7 @@ migrate_orc(struct monst *mtmp, unsigned long mflags) cur_depth = (int) depth(&u.uz); max_depth = dunlevs_in_dungeon(&u.uz) - + (gd.dungeons[u.uz.dnum].depth_start - 1); + + (svd.dungeons[u.uz.dnum].depth_start - 1); if (mflags == ORC_LEADER) { /* Note that the orc leader will take possession of any * remaining stuff not already delivered to other @@ -961,7 +961,7 @@ create_maze(int corrwid, int wallthick, boolean rmdeadends) rdx = (gx.x_maze_max / scale); rdy = (gy.y_maze_max / scale); - if (gl.level.flags.corrmaze) + if (svl.level.flags.corrmaze) for (x = 2; x < (rdx * 2); x++) for (y = 2; y < (rdy * 2); y++) levl[x][y].typ = STONE; @@ -979,7 +979,7 @@ create_maze(int corrwid, int wallthick, boolean rmdeadends) walkfrom((int) mm.x, (int) mm.y, 0); if (rmdeadends) - maze_remove_deadends((gl.level.flags.corrmaze) ? CORR : ROOM); + maze_remove_deadends((svl.level.flags.corrmaze) ? CORR : ROOM); /* restore bounds */ gx.x_maze_max = tmp_xmax; @@ -1052,10 +1052,10 @@ pick_vibrasquare_location(void) if (x_range <= INVPOS_X_MARGIN || y_range <= INVPOS_Y_MARGIN || (x_range * y_range) <= (INVPOS_DISTANCE * INVPOS_DISTANCE)) { - debugpline2("gi.inv_pos: maze is too small! (%d x %d)", + debugpline2("svi.inv_pos: maze is too small! (%d x %d)", gx.x_maze_max, gy.y_maze_max); } - gi.inv_pos.x = gi.inv_pos.y = 0; /*{occupied() => invocation_pos()}*/ + svi.inv_pos.x = svi.inv_pos.y = 0; /*{occupied() => invocation_pos()}*/ do { x = rn1(x_range, x_maze_min + INVPOS_X_MARGIN + 1); y = rn1(y_range, y_maze_min + INVPOS_Y_MARGIN + 1); @@ -1068,8 +1068,8 @@ pick_vibrasquare_location(void) || abs(x - stway->sx) == abs(y - stway->sy) || distmin(x, y, stway->sx, stway->sy) <= INVPOS_DISTANCE || !SPACE_POS(levl[x][y].typ) || occupied(x, y))); - gi.inv_pos.x = x; - gi.inv_pos.y = y; + svi.inv_pos.x = x; + svi.inv_pos.y = y; #undef INVPOS_X_MARGIN #undef INVPOS_Y_MARGIN #undef INVPOS_DISTANCE @@ -1121,22 +1121,22 @@ makemaz(const char *s) "%s-%d", s, rnd((int) sp->rndlevs)); else Strcpy(protofile, s); - } else if (*(gd.dungeons[u.uz.dnum].proto)) { + } else if (*(svd.dungeons[u.uz.dnum].proto)) { if (dunlevs_in_dungeon(&u.uz) > 1) { if (sp && sp->rndlevs) Snprintf(protofile, sizeof protofile, - "%s%d-%d", gd.dungeons[u.uz.dnum].proto, + "%s%d-%d", svd.dungeons[u.uz.dnum].proto, dunlev(&u.uz), rnd((int) sp->rndlevs)); else Snprintf(protofile, sizeof protofile, - "%s%d", gd.dungeons[u.uz.dnum].proto, + "%s%d", svd.dungeons[u.uz.dnum].proto, dunlev(&u.uz)); } else if (sp && sp->rndlevs) { Snprintf(protofile, sizeof protofile, - "%s-%d", gd.dungeons[u.uz.dnum].proto, + "%s-%d", svd.dungeons[u.uz.dnum].proto, rnd((int) sp->rndlevs)); } else - Strcpy(protofile, gd.dungeons[u.uz.dnum].proto); + Strcpy(protofile, svd.dungeons[u.uz.dnum].proto); } else Strcpy(protofile, ""); @@ -1179,8 +1179,8 @@ makemaz(const char *s) impossible("Couldn't load \"%s\" - making a maze.", protofile); } - gl.level.flags.is_maze_lev = 1; - gl.level.flags.corrmaze = !rn2(3); + svl.level.flags.is_maze_lev = 1; + svl.level.flags.corrmaze = !rn2(3); if (!Invocation_lev(&u.uz) && rn2(2)) { create_maze(-1, -1, !rn2(5)); @@ -1188,7 +1188,7 @@ makemaz(const char *s) create_maze(1, 1, FALSE); } - if (!gl.level.flags.corrmaze) + if (!svl.level.flags.corrmaze) wallification(2, 2, gx.x_maze_max, gy.y_maze_max); mazexy(&mm); @@ -1198,7 +1198,7 @@ makemaz(const char *s) mkstairs(mm.x, mm.y, 0, (struct mkroom *) 0, FALSE); /* down */ } else { /* choose "vibrating square" location */ pick_vibrasquare_location(); - maketrap(gi.inv_pos.x, gi.inv_pos.y, VIBRATING_SQUARE); + maketrap(svi.inv_pos.x, svi.inv_pos.y, VIBRATING_SQUARE); } /* place branch stair or portal */ @@ -1222,7 +1222,7 @@ walkfrom(coordxy x, coordxy y, schar typ) int dirs[4]; if (!typ) { - if (gl.level.flags.corrmaze) + if (svl.level.flags.corrmaze) typ = CORR; else typ = ROOM; @@ -1267,7 +1267,7 @@ walkfrom(coordxy x, coordxy y, schar typ) int dirs[4]; if (!typ) { - if (gl.level.flags.corrmaze) + if (svl.level.flags.corrmaze) typ = CORR; else typ = ROOM; @@ -1301,7 +1301,7 @@ void mazexy(coord *cc) { coordxy x, y; - int allowedtyp = (gl.level.flags.corrmaze ? CORR : ROOM); + int allowedtyp = (svl.level.flags.corrmaze ? CORR : ROOM); int cpt = 0; do { @@ -1357,7 +1357,7 @@ get_level_extends( } } } - xmin -= (nonwall || !gl.level.flags.is_maze_lev) ? 2 : 1; + xmin -= (nonwall || !svl.level.flags.is_maze_lev) ? 2 : 1; if (xmin < 0) xmin = 0; @@ -1373,7 +1373,7 @@ get_level_extends( } } } - xmax += (nonwall || !gl.level.flags.is_maze_lev) ? 2 : 1; + xmax += (nonwall || !svl.level.flags.is_maze_lev) ? 2 : 1; if (xmax >= COLNO) xmax = COLNO - 1; @@ -1389,7 +1389,7 @@ get_level_extends( } } } - ymin -= (nonwall || !gl.level.flags.is_maze_lev) ? 2 : 1; + ymin -= (nonwall || !svl.level.flags.is_maze_lev) ? 2 : 1; found = nonwall = FALSE; for (ymax = ROWNO - 1; !found && ymax >= 0; ymax--) { @@ -1403,7 +1403,7 @@ get_level_extends( } } } - ymax += (nonwall || !gl.level.flags.is_maze_lev) ? 2 : 1; + ymax += (nonwall || !svl.level.flags.is_maze_lev) ? 2 : 1; *left = xmin; *right = xmax; @@ -1450,7 +1450,7 @@ mkportal(coordxy x, coordxy y, xint16 todnum, xint16 todlevel) return; } debugpline4("mkportal: at <%d,%d>, to %s, level %d", x, y, - gd.dungeons[todnum].dname, todlevel); + svd.dungeons[todnum].dname, todlevel); ttmp->dst.dnum = todnum; ttmp->dst.dlevel = todlevel; return; @@ -1467,7 +1467,7 @@ fumaroles(void) nmax++; sizemin += 5; } - if (gl.level.flags.temperature > 0) { + if (svl.level.flags.temperature > 0) { nmax++; sizemin += 5; } @@ -1497,10 +1497,10 @@ fumaroles(void) */ /* bubble movement boundaries */ -#define gbxmin (gx.xmin + 1) -#define gbymin (gy.ymin + 1) -#define gbxmax (gx.xmax - 1) -#define gbymax (gy.ymax - 1) +#define gbxmin (svx.xmin + 1) +#define gbymin (svy.ymin + 1) +#define gbxmax (svx.xmax - 1) +#define gbymax (svy.ymax - 1) /* the bubble hero is in */ static struct bubble *hero_bubble = NULL; @@ -1540,7 +1540,7 @@ movebubbles(void) * Pick up everything inside of a bubble then fill all bubble * locations. */ - for (b = up ? gb.bbubbles : ge.ebubbles; b; + for (b = up ? svb.bbubbles : ge.ebubbles; b; b = up ? b->next : b->prev) { if (b->cons) panic("movebubbles: cons != null"); @@ -1556,7 +1556,7 @@ movebubbles(void) if (OBJ_AT(x, y)) { struct obj *olist = (struct obj *) 0, *otmp; - while ((otmp = gl.level.objects[x][y]) != 0) { + while ((otmp = svl.level.objects[x][y]) != 0) { remove_object(otmp); otmp->ox = otmp->oy = 0; otmp->nexthere = olist; @@ -1644,7 +1644,7 @@ movebubbles(void) * would eventually end up in the last bubble in the chain. */ up = !up; - for (b = up ? gb.bbubbles : ge.ebubbles; b; b = up ? b->next : b->prev) { + for (b = up ? svb.bbubbles : ge.ebubbles; b; b = up ? b->next : b->prev) { int rx = rn2(3), ry = rn2(3); mv_bubble(b, b->dx + 1 - (!b->dx ? rx : (rx ? 1 : 0)), @@ -1697,21 +1697,21 @@ save_waterlevel(NHFILE *nhfp) { struct bubble *b; - if (!gb.bbubbles) + if (!svb.bbubbles) return; if (perform_bwrite(nhfp)) { int n = 0; - for (b = gb.bbubbles; b; b = b->next) + for (b = svb.bbubbles; b; b = b->next) ++n; if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &n, sizeof(int)); - bwrite(nhfp->fd, (genericptr_t) &gx.xmin, sizeof(int)); - bwrite(nhfp->fd, (genericptr_t) &gy.ymin, sizeof(int)); - bwrite(nhfp->fd, (genericptr_t) &gx.xmax, sizeof(int)); - bwrite(nhfp->fd, (genericptr_t) &gy.ymax, sizeof(int)); + bwrite(nhfp->fd, (genericptr_t) &svx.xmin, sizeof(int)); + bwrite(nhfp->fd, (genericptr_t) &svy.ymin, sizeof(int)); + bwrite(nhfp->fd, (genericptr_t) &svx.xmax, sizeof(int)); + bwrite(nhfp->fd, (genericptr_t) &svy.ymax, sizeof(int)); } - for (b = gb.bbubbles; b; b = b->next) { + for (b = svb.bbubbles; b; b = b->next) { if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) b, sizeof(struct bubble)); } @@ -1727,14 +1727,14 @@ restore_waterlevel(NHFILE *nhfp) struct bubble *b = (struct bubble *) 0, *btmp; int i, n = 0; - gb.bbubbles = (struct bubble *) 0; + svb.bbubbles = (struct bubble *) 0; set_wportal(); if (nhfp->structlevel) { mread(nhfp->fd,(genericptr_t) &n, sizeof (int)); - mread(nhfp->fd,(genericptr_t) &gx.xmin, sizeof (int)); - mread(nhfp->fd,(genericptr_t) &gy.ymin, sizeof (int)); - mread(nhfp->fd,(genericptr_t) &gx.xmax, sizeof (int)); - mread(nhfp->fd,(genericptr_t) &gy.ymax, sizeof (int)); + mread(nhfp->fd,(genericptr_t) &svx.xmin, sizeof (int)); + mread(nhfp->fd,(genericptr_t) &svy.ymin, sizeof (int)); + mread(nhfp->fd,(genericptr_t) &svx.xmax, sizeof (int)); + mread(nhfp->fd,(genericptr_t) &svy.ymax, sizeof (int)); } for (i = 0; i < n; i++) { btmp = b; @@ -1745,7 +1745,7 @@ restore_waterlevel(NHFILE *nhfp) btmp->next = b; b->prev = btmp; } else { - gb.bbubbles = b; + svb.bbubbles = b; b->prev = (struct bubble *) 0; } mv_bubble(b, 0, 0, TRUE); @@ -1755,7 +1755,7 @@ restore_waterlevel(NHFILE *nhfp) b->next = (struct bubble *) 0; } else { /* avoid "saving and reloading may fix this" */ - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; /* during restore, information about what level this is might not be available so we're wishy-washy about what we describe */ impossible("No %s to restore?", @@ -1764,7 +1764,7 @@ restore_waterlevel(NHFILE *nhfp) : (Is_airlevel(&u.uz) || Is_airlevel(&gu.uz_save)) ? "clouds" : "air bubbles or clouds"); - gp.program_state.something_worth_saving = 1; + svp.program_state.something_worth_saving = 1; } } @@ -1789,15 +1789,15 @@ setup_waterlevel(void) (int) u.uz.dnum, (int) u.uz.dlevel); /* ouch, hardcoded... (file scope statics and used in bxmin,bymax,&c) */ - gx.xmin = 3; - gy.ymin = 1; + svx.xmin = 3; + svy.ymin = 1; /* use separate statements so that compiler won't complain about min() comparing two constants; the alternative is to do this in the preprocessor: #if (20 > ROWNO-1) ymax=ROWNO-1 #else ymax=20 #endif */ - gx.xmax = 78; - gx.xmax = min(gx.xmax, (COLNO - 1) - 1); - gy.ymax = 20; - gy.ymax = min(gy.ymax, (ROWNO - 1)); + svx.xmax = 78; + svx.xmax = min(svx.xmax, (COLNO - 1) - 1); + svy.ymax = 20; + svy.ymax = min(svy.ymax, (ROWNO - 1)); /* entire level is remembered as one glyph and any unspecified portion should default to level's base element rather than to usual stone */ @@ -1832,11 +1832,11 @@ unsetup_waterlevel(void) struct bubble *b, *bb; /* free bubbles */ - for (b = gb.bbubbles; b; b = bb) { + for (b = svb.bbubbles; b; b = bb) { bb = b->next; free((genericptr_t) b); } - gb.bbubbles = ge.ebubbles = (struct bubble *) 0; + svb.bbubbles = ge.ebubbles = (struct bubble *) 0; } staticfn void @@ -1882,8 +1882,8 @@ mk_bubble(coordxy x, coordxy y, int n) (void) memcpy((genericptr_t) b->bm, (genericptr_t) bmask[n], (bmask[n][1] + 2) * sizeof (b->bm[0])); b->cons = 0; - if (!gb.bbubbles) - gb.bbubbles = b; + if (!svb.bbubbles) + svb.bbubbles = b; if (ge.ebubbles) { ge.ebubbles->next = b; b->prev = ge.ebubbles; diff --git a/src/mkobj.c b/src/mkobj.c index 6b0e518d8..afe335afa 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -177,7 +177,7 @@ staticfn boolean may_generate_eroded(struct obj *otmp) { /* initial hero inventory */ - if (gm.moves <= 1 && !gi.in_mklev) + if (svm.moves <= 1 && !gi.in_mklev) return FALSE; /* already erodeproof or cannot be eroded */ if (otmp->oerodeproof || !erosion_matters(otmp) || !is_damageable(otmp)) @@ -283,18 +283,18 @@ mkobj(int oclass, boolean artif) } if (oclass == SPBOOK_no_NOVEL) { - i = rnd_class(gb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); + i = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); oclass = SPBOOK_CLASS; /* for sanity check below */ } else { prob = rnd(go.oclass_prob_totals[oclass]); - i = gb.bases[oclass]; + i = svb.bases[oclass]; while ((prob -= objects[i].oc_prob) > 0) ++i; } if (objects[i].oc_class != oclass || !OBJ_NAME(objects[i])) { impossible("probtype error, oclass=%d i=%d", (int) oclass, i); - i = gb.bases[oclass]; + i = svb.bases[oclass]; } return mksobj(i, TRUE, artif); @@ -321,7 +321,7 @@ mkbox_cnts(struct obj *box) case SACK: case OILSKIN_SACK: /* initial inventory: sack starts out empty */ - if (gm.moves <= 1 && !gi.in_mklev) { + if (svm.moves <= 1 && !gi.in_mklev) { n = 0; break; } @@ -473,8 +473,8 @@ splitobj(struct obj *obj, long num) otmp->lua_ref_cnt = 0; otmp->pickup_prev = 0; - gc.context.objsplit.parent_oid = obj->o_id; - gc.context.objsplit.child_oid = otmp->o_id; + svc.context.objsplit.parent_oid = obj->o_id; + svc.context.objsplit.child_oid = otmp->o_id; obj->nobj = otmp; /* Only set nexthere when on the floor; nexthere is also used as a back pointer to the container object when contained. @@ -504,7 +504,7 @@ splitobj(struct obj *obj, long num) unsigned next_ident(void) { - unsigned res = gc.context.ident; + unsigned res = svc.context.ident; /* +rnd(2): originally just +1; changed to rnd() to avoid potential exploit of player using #adjust to split an object stack in a manner @@ -514,14 +514,14 @@ next_ident(void) next object to be created was knowable and player could make a wish under controlled circumstances for an item that is affected by the low bits of its obj->o_id [particularly helm of opposite alignment] */ - gc.context.ident += rnd(2); /* ready for next new object or monster */ + svc.context.ident += rnd(2); /* ready for next new object or monster */ /* if ident has wrapped to 0, force it to be non-zero; if/when it ever wraps past 0 (unlikely, but possible on a configuration which uses 16-bit 'int'), just live with that and hope no o_id conflicts between objects or m_id conflicts between monsters arise */ - if (!gc.context.ident) - gc.context.ident = rnd(2); + if (!svc.context.ident) + svc.context.ident = rnd(2); return res; } @@ -532,7 +532,7 @@ staticfn unsigned nextoid(struct obj *oldobj, struct obj *newobj) { int olddif, newdif, trylimit = 256; /* limit of 4 suffices at present */ - unsigned oid = gc.context.ident - 1; /* loop increment will reverse -1 */ + unsigned oid = svc.context.ident - 1; /* loop increment will reverse -1 */ olddif = oid_price_adjustment(oldobj, oldobj->o_id); do { @@ -541,7 +541,7 @@ nextoid(struct obj *oldobj, struct obj *newobj) ++oid; newdif = oid_price_adjustment(newobj, oid); } while (newdif != olddif && --trylimit >= 0); - gc.context.ident = oid; /* update 'last ident used' */ + svc.context.ident = oid; /* update 'last ident used' */ (void) next_ident(); /* increment context.ident for next use */ return oid; /* caller will use this ident */ } @@ -582,17 +582,17 @@ unsplitobj(struct obj *obj) } /* first try the expected case; obj is split from another stack */ - if (obj->o_id == gc.context.objsplit.child_oid) { + if (obj->o_id == svc.context.objsplit.child_oid) { /* parent probably precedes child and will require list traversal */ ochild = obj; - target_oid = gc.context.objsplit.parent_oid; + target_oid = svc.context.objsplit.parent_oid; if (obj->nobj && obj->nobj->o_id == target_oid) oparent = obj->nobj; - } else if (obj->o_id == gc.context.objsplit.parent_oid) { + } else if (obj->o_id == svc.context.objsplit.parent_oid) { /* alternate scenario: another stack was split from obj; child probably follows parent and will be found here */ oparent = obj; - target_oid = gc.context.objsplit.child_oid; + target_oid = svc.context.objsplit.child_oid; if (obj->nobj && obj->nobj->o_id == target_oid) ochild = obj->nobj; } @@ -621,7 +621,7 @@ unsplitobj(struct obj *obj) void clear_splitobjs(void) { - gc.context.objsplit.parent_oid = gc.context.objsplit.child_oid = 0; + svc.context.objsplit.parent_oid = svc.context.objsplit.child_oid = 0; } /* @@ -666,7 +666,7 @@ replace_object(struct obj *obj, struct obj *otmp) obj->nobj = otmp; obj->nexthere = otmp; extract_nobj(obj, &fobj); - extract_nexthere(obj, &gl.level.objects[obj->ox][obj->oy]); + extract_nexthere(obj, &svl.level.objects[obj->ox][obj->oy]); break; default: panic("replace_object: obj position"); @@ -889,11 +889,11 @@ mksobj_init(struct obj *otmp, boolean artif) tryct = 50; do otmp->corpsenm = undead_to_corpse(rndmonnum()); - while ((gm.mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) + while ((svm.mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0)); if (tryct == 0) { /* perhaps rndmonnum() only wants to make G_NOCORPSE - monsters on this gl.level; create an adventurer's + monsters on this svl.level; create an adventurer's corpse instead, then */ otmp->corpsenm = PM_HUMAN; } @@ -919,7 +919,7 @@ mksobj_init(struct obj *otmp, boolean artif) for (tryct = 200; tryct > 0; --tryct) { mndx = undead_to_corpse(rndmonnum()); if (mons[mndx].cnutrit - && !(gm.mvitals[mndx].mvflags & G_NOCORPSE)) { + && !(svm.mvitals[mndx].mvflags & G_NOCORPSE)) { otmp->corpsenm = mndx; set_tin_variety(otmp, RANDOM_TIN); break; @@ -928,7 +928,7 @@ mksobj_init(struct obj *otmp, boolean artif) blessorcurse(otmp, 10); break; case SLIME_MOLD: - otmp->spe = gc.context.current_fruit; + otmp->spe = svc.context.current_fruit; flags.made_fruit = TRUE; break; case KELP_FROND: @@ -1046,7 +1046,7 @@ mksobj_init(struct obj *otmp, boolean artif) break; case AMULET_CLASS: if (otmp->otyp == AMULET_OF_YENDOR) - gc.context.made_amulet = TRUE; + svc.context.made_amulet = TRUE; if (rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || otmp->otyp == AMULET_OF_CHANGE || otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { @@ -1086,7 +1086,7 @@ mksobj_init(struct obj *otmp, boolean artif) otmp = mk_artifact(otmp, (aligntyp) A_NONE); /* simulate lacquered armor for samurai */ if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL - && (gm.moves <= 1 || In_quest(&u.uz))) { + && (svm.moves <= 1 || In_quest(&u.uz))) { #ifdef UNIXPC /* optimizer bitfield bug */ otmp->oerodeproof = 1; @@ -1160,7 +1160,7 @@ mksobj(int otyp, boolean init, boolean artif) otmp = newobj(); *otmp = cg.zeroobj; - otmp->age = gm.moves; + otmp->age = svm.moves; otmp->o_id = next_ident(); otmp->quan = 1L; otmp->oclass = let; @@ -1181,7 +1181,7 @@ mksobj(int otyp, boolean init, boolean artif) case CORPSE: if (otmp->corpsenm == NON_PM) { otmp->corpsenm = undead_to_corpse(rndmonnum()); - if (gm.mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE)) + if (svm.mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE)) otmp->corpsenm = gu.urole.mnum; } /*FALLTHRU*/ @@ -1341,7 +1341,7 @@ start_corpse_timeout(struct obj *body) action = ROT_CORPSE; /* default action: rot away */ rot_adjust = gi.in_mklev ? 25 : 10; /* give some variation */ - age = gm.moves - body->age; + age = svm.moves - body->age; if (age > ROT_AGE) when = rot_adjust; else @@ -1460,9 +1460,9 @@ shrink_glob( /* * If shrinkage occurred while we were on another level, catch up now. */ - if (expire_time < gm.moves && globloc != BURIED_UNDER_ICE) { + if (expire_time < svm.moves && globloc != BURIED_UNDER_ICE) { /* number of units of weight to remove */ - long delta = (gm.moves - expire_time + 24L) / 25L, + long delta = (svm.moves - expire_time + 24L) / 25L, /* leftover amount to use for new timer */ moddelta = 25L - (delta % 25L); @@ -1501,7 +1501,7 @@ shrink_glob( */ if (eating_glob(obj) || globloc == BURIED_UNDER_ICE - || (globloc == SET_ON_ICE && (gm.moves % 3L) == 1L)) { + || (globloc == SET_ON_ICE && (svm.moves % 3L) == 1L)) { /* schedule next shrink attempt; for the being eaten case, the glob and its timer might be deleted before this kicks in */ start_glob_timeout(obj, 0L); @@ -1803,7 +1803,7 @@ set_bknown( { if (obj->bknown != onoff) { obj->bknown = onoff; - if (obj->where == OBJ_INVENT && gm.moves > 1L) + if (obj->where == OBJ_INVENT && svm.moves > 1L) update_inventory(); } } @@ -1964,7 +1964,7 @@ fixup_oil( } else if (source && source->otyp == POT_OIL) { /* potion is no longer oil, being turned into non-oil */ if (potion->age == source->age) - potion->age = gm.moves; + potion->age = svm.moves; /* when source is a partly used oil, mark potion as diluted */ if (source->age < MAX_OIL_IN_FLASK) potion->odiluted = 1; @@ -2246,7 +2246,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y) safe_typename(otmp->otyp), otmp->where); assert(x >= 0 && x < COLNO && y >= 0 && y < ROWNO); - otmp2 = gl.level.objects[x][y]; + otmp2 = svl.level.objects[x][y]; obj_no_longer_held(otmp); if (otmp->otyp == BOULDER) { @@ -2266,7 +2266,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y) } else { /* put on top of current pile */ otmp->nexthere = otmp2; - gl.level.objects[x][y] = otmp; + svl.level.objects[x][y] = otmp; } /* set the object's new location */ @@ -2294,7 +2294,7 @@ recreate_pile_at(coordxy x, coordxy y) struct obj *otmp, *next_obj, *reversed = 0; /* remove all objects at , saving a reversed temporary list */ - for (otmp = gl.level.objects[x][y]; otmp; otmp = next_obj) { + for (otmp = svl.level.objects[x][y]; otmp; otmp = next_obj) { next_obj = otmp->nexthere; remove_object(otmp); /* obj_extract_self() for floor */ otmp->nobj = reversed; @@ -2319,12 +2319,12 @@ obj_ice_effects(coordxy x, coordxy y, boolean do_buried) { struct obj *otmp; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) { + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) { if (otmp->timed) obj_timer_checks(otmp, x, y, 0); } if (do_buried) { - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) { + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) { if (otmp->ox == x && otmp->oy == y) { if (otmp->timed) obj_timer_checks(otmp, x, y, 0); @@ -2347,12 +2347,12 @@ peek_at_iced_corpse_age(struct obj *otmp) if (otmp->otyp == CORPSE && otmp->on_ice) { /* Adjust the age; must be same as obj_timer_checks() for off ice*/ - age = gm.moves - otmp->age; + age = svm.moves - otmp->age; retval += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT; debugpline3( "The %s age has ice modifications: otmp->age = %ld, returning %ld.", s_suffix(doname(otmp)), otmp->age, retval); - debugpline1("Effective age of corpse: %ld.", gm.moves - retval); + debugpline1("Effective age of corpse: %ld.", svm.moves - retval); } return retval; } @@ -2391,8 +2391,8 @@ obj_timer_checks( later calculations behave as if it had been on ice during that time (longwinded way of saying this is the inverse of removing it from the ice and of peeking at its age). */ - age = gm.moves - otmp->age; - otmp->age = gm.moves - (age * ROT_ICE_ADJUSTMENT); + age = svm.moves - otmp->age; + otmp->age = svm.moves - (age * ROT_ICE_ADJUSTMENT); } /* Check for corpses coming off ice */ @@ -2413,7 +2413,7 @@ obj_timer_checks( tleft /= ROT_ICE_ADJUSTMENT; restart_timer = TRUE; /* Adjust the age */ - age = gm.moves - otmp->age; + age = svm.moves - otmp->age; otmp->age += age * (ROT_ICE_ADJUSTMENT - 1) / ROT_ICE_ADJUSTMENT; } } @@ -2433,7 +2433,7 @@ remove_object(struct obj *otmp) if (otmp->where != OBJ_FLOOR) panic("remove_object: obj not on floor"); - extract_nexthere(otmp, &gl.level.objects[x][y]); + extract_nexthere(otmp, &svl.level.objects[x][y]); extract_nobj(otmp, &fobj); /* update vision iff this was the only boulder at its spot */ if (otmp->otyp == BOULDER && !sobj_at(BOULDER, x, y)) @@ -2502,7 +2502,7 @@ obj_extract_self(struct obj *obj) extract_nobj(obj, &gm.migrating_objs); break; case OBJ_BURIED: - extract_nobj(obj, &gl.level.buriedobjlist); + extract_nobj(obj, &svl.level.buriedobjlist); break; case OBJ_ONBILL: extract_nobj(obj, &gb.billobjs); @@ -2645,8 +2645,8 @@ add_to_buried(struct obj *obj) panic("add_to_buried: obj not free"); obj->where = OBJ_BURIED; - obj->nobj = gl.level.buriedobjlist; - gl.level.buriedobjlist = obj; + obj->nobj = svl.level.buriedobjlist; + svl.level.buriedobjlist = obj; } /* recalculate weight of object, which doesn't have to be a container @@ -2706,9 +2706,9 @@ dealloc_obj(struct obj *obj) /* if obj came from the most recent splitobj(), it's no longer eligible for unsplitobj(); perform inline clear_splitobjs() */ - if (obj->o_id == gc.context.objsplit.parent_oid - || obj->o_id == gc.context.objsplit.child_oid) - gc.context.objsplit.parent_oid = gc.context.objsplit.child_oid = 0; + if (obj->o_id == svc.context.objsplit.parent_oid + || obj->o_id == svc.context.objsplit.child_oid) + svc.context.objsplit.parent_oid = svc.context.objsplit.child_oid = 0; if (obj->lua_ref_cnt) { /* obj is referenced from a lua script, let lua gc free it */ @@ -2871,7 +2871,7 @@ obj_sanity_check(void) for (y = 0; y < ROWNO; y++) { char at_fmt[BUFSZ]; - otop = gl.level.objects[x][y]; + otop = svl.level.objects[x][y]; prevo = 0; for (obj = otop; obj; prevo = obj, obj = prevo->nexthere) { /* should match ; <0,*> should always be empty */ @@ -2905,7 +2905,7 @@ obj_sanity_check(void) objlist_sanity(gi.invent, OBJ_INVENT, "invent sanity"); objlist_sanity(gm.migrating_objs, OBJ_MIGRATING, "migrating sanity"); - objlist_sanity(gl.level.buriedobjlist, OBJ_BURIED, "buried sanity"); + objlist_sanity(svl.level.buriedobjlist, OBJ_BURIED, "buried sanity"); objlist_sanity(gb.billobjs, OBJ_ONBILL, "bill sanity"); objlist_sanity(go.objs_deleted, OBJ_DELETED, "deleted object sanity"); @@ -3262,7 +3262,7 @@ init_dummyobj(struct obj *obj, short otyp, long oquan) obj->next_boulder = 0; /* overloads corpsenm, avoid NON_PM */ /* but suppressing fruit details leads to "bad fruit #0" */ if (obj->otyp == SLIME_MOLD) - obj->spe = gc.context.current_fruit; + obj->spe = svc.context.current_fruit; } return obj; } @@ -3621,11 +3621,11 @@ obj_absorb(struct obj **obj1, struct obj **obj2) o2wt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt; /* averaging the relative ages is less likely to overflow than averaging the absolute ages directly */ - agetmp = (((gm.moves - otmp1->age) * o1wt - + (gm.moves - otmp2->age) * o2wt) + agetmp = (((svm.moves - otmp1->age) * o1wt + + (svm.moves - otmp2->age) * o2wt) / (o1wt + o2wt)); /* convert relative age back to absolute age */ - otmp1->age = gm.moves - agetmp; + otmp1->age = svm.moves - agetmp; otmp1->owt += o2wt; if (otmp1->oeaten || otmp2->oeaten) otmp1->oeaten = o1wt + o2wt; diff --git a/src/mkroom.c b/src/mkroom.c index 0d256ab79..3b117dc04 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -150,14 +150,14 @@ mkshop(void) } gottype: - for (sroom = &gr.rooms[0];; sroom++) { + for (sroom = &svr.rooms[0];; sroom++) { /* return from this loop: cannot find any eligible room to be a shop * continue: sroom is ineligible * break: sroom is eligible */ if (sroom->hx < 0) return; - if (sroom - gr.rooms >= gn.nroom) { + if (sroom - svr.rooms >= svn.nroom) { impossible("rooms[] not closed by -1?"); return; } @@ -215,11 +215,11 @@ staticfn struct mkroom * pick_room(boolean strict) { struct mkroom *sroom; - int i = gn.nroom; + int i = svn.nroom; - for (sroom = &gr.rooms[rn2(gn.nroom)]; i--; sroom++) { - if (sroom == &gr.rooms[gn.nroom]) - sroom = &gr.rooms[0]; + for (sroom = &svr.rooms[rn2(svn.nroom)]; i--; sroom++) { + if (sroom == &svr.rooms[svn.nroom]) + sroom = &svr.rooms[0]; if (sroom->hx < 0) return (struct mkroom *) 0; if (sroom->rtype != OROOM) @@ -274,7 +274,7 @@ fill_zoo(struct mkroom *sroom) int sx, sy, i; int sh, goldlim = 0, type = sroom->rtype; coordxy tx = 0, ty = 0; - int rmno = (int) ((sroom - gr.rooms) + ROOMOFFSET); + int rmno = (int) ((sroom - svr.rooms) + ROOMOFFSET); coord mm; /* Note: This doesn't check needfill; it assumes the caller has already @@ -282,7 +282,7 @@ fill_zoo(struct mkroom *sroom) sh = sroom->fdoor; switch (type) { case COURT: - if (gl.level.flags.is_maze_lev) { + if (svl.level.flags.is_maze_lev) { for (tx = sroom->lx; tx <= sroom->hx; tx++) for (ty = sroom->ly; ty <= sroom->hy; ty++) if (IS_THRONE(levl[tx][ty].typ)) @@ -320,15 +320,15 @@ fill_zoo(struct mkroom *sroom) if (sroom->irregular) { if ((int) levl[sx][sy].roomno != rmno || levl[sx][sy].edge || (sroom->doorct - && distmin(sx, sy, gd.doors[sh].x, gd.doors[sh].y) <= 1)) + && distmin(sx, sy, svd.doors[sh].x, svd.doors[sh].y) <= 1)) continue; } else if (!SPACE_POS(levl[sx][sy].typ) || (sroom->doorct - && ((sx == sroom->lx && gd.doors[sh].x == sx - 1) - || (sx == sroom->hx && gd.doors[sh].x == sx + 1) - || (sy == sroom->ly && gd.doors[sh].y == sy - 1) + && ((sx == sroom->lx && svd.doors[sh].x == sx - 1) + || (sx == sroom->hx && svd.doors[sh].x == sx + 1) + || (sy == sroom->ly && svd.doors[sh].y == sy - 1) || (sy == sroom->hy - && gd.doors[sh].y == sy + 1)))) + && svd.doors[sh].y == sy + 1)))) continue; /* don't place monster on explicitly placed throne */ if (type == COURT && IS_THRONE(levl[sx][sy].typ)) @@ -362,7 +362,7 @@ fill_zoo(struct mkroom *sroom) case ZOO: case LEPREHALL: if (sroom->doorct) { - int distval = dist2(sx, sy, gd.doors[sh].x, gd.doors[sh].y); + int distval = dist2(sx, sy, svd.doors[sh].x, svd.doors[sh].y); i = sq(distval); } else i = goldlim; @@ -421,23 +421,23 @@ fill_zoo(struct mkroom *sroom) add_to_container(chest, gold); chest->owt = weight(chest); chest->spe = 2; /* so it can be found later */ - gl.level.flags.has_court = 1; + svl.level.flags.has_court = 1; break; } case BARRACKS: - gl.level.flags.has_barracks = 1; + svl.level.flags.has_barracks = 1; break; case ZOO: - gl.level.flags.has_zoo = 1; + svl.level.flags.has_zoo = 1; break; case MORGUE: - gl.level.flags.has_morgue = 1; + svl.level.flags.has_morgue = 1; break; case SWAMP: - gl.level.flags.has_swamp = 1; + svl.level.flags.has_swamp = 1; break; case BEEHIVE: - gl.level.flags.has_beehive = 1; + svl.level.flags.has_beehive = 1; break; } } @@ -462,7 +462,7 @@ mkundead( || !revive(otmp, FALSE))) (void) makemon(mdat, cc.x, cc.y, mm_flags); } - gl.level.flags.graveyard = TRUE; /* reduced chance for undead corpse */ + svl.level.flags.graveyard = TRUE; /* reduced chance for undead corpse */ } staticfn struct permonst * @@ -511,9 +511,9 @@ antholemon(void) break; } /* try again if chosen type has been genocided or used up */ - } while (++trycnt < 3 && (gm.mvitals[mtyp].mvflags & G_GONE)); + } while (++trycnt < 3 && (svm.mvitals[mtyp].mvflags & G_GONE)); - return ((gm.mvitals[mtyp].mvflags & G_GONE) ? (struct permonst *) 0 + return ((svm.mvitals[mtyp].mvflags & G_GONE) ? (struct permonst *) 0 : &mons[mtyp]); } @@ -526,12 +526,12 @@ mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ int rmno; for (i = 0; i < 5; i++) { /* turn up to 5 rooms swampy */ - sroom = &gr.rooms[rn2(gn.nroom)]; + sroom = &svr.rooms[rn2(svn.nroom)]; if (sroom->hx < 0 || sroom->rtype != OROOM || has_upstairs(sroom) || has_dnstairs(sroom)) continue; - rmno = (int)(sroom - gr.rooms) + ROOMOFFSET; + rmno = (int)(sroom - svr.rooms) + ROOMOFFSET; /* satisfied; make a swamp */ sroom->rtype = SWAMP; @@ -560,7 +560,7 @@ mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ NO_MM_FLAGS); } } - gl.level.flags.has_swamp = 1; + svl.level.flags.has_swamp = 1; } } @@ -569,7 +569,7 @@ shrine_pos(int roomno) { static coord buf; int delta; - struct mkroom *troom = &gr.rooms[roomno - ROOMOFFSET]; + struct mkroom *troom = &svr.rooms[roomno - ROOMOFFSET]; /* if width and height are odd, placement will be the exact center; if either or both are even, center point is a hypothetical spot @@ -601,13 +601,13 @@ mktemple(void) * In temples, shrines are blessed altars * located in the center of the room */ - shrine_spot = shrine_pos((int) ((sroom - gr.rooms) + ROOMOFFSET)); + shrine_spot = shrine_pos((int) ((sroom - svr.rooms) + ROOMOFFSET)); lev = &levl[shrine_spot->x][shrine_spot->y]; lev->typ = ALTAR; lev->altarmask = induced_align(80); priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE); lev->altarmask |= AM_SHRINE; - gl.level.flags.has_temple = 1; + svl.level.flags.has_temple = 1; } boolean @@ -669,7 +669,7 @@ boolean inside_room(struct mkroom *croom, coordxy x, coordxy y) { if (croom->irregular) { - int i = (int) ((croom - gr.rooms) + ROOMOFFSET); + int i = (int) ((croom - svr.rooms) + ROOMOFFSET); return (!levl[x][y].edge && (int) levl[x][y].roomno == i); } @@ -688,7 +688,7 @@ somexy(struct mkroom *croom, coord *c) int i; if (croom->irregular) { - i = (int) ((croom - gr.rooms) + ROOMOFFSET); + i = (int) ((croom - svr.rooms) + ROOMOFFSET); while (try_cnt++ < 100) { c->x = somex(croom); @@ -757,7 +757,7 @@ search_special(schar type) { struct mkroom *croom; - for (croom = &gr.rooms[0]; croom->hx >= 0; croom++) + for (croom = &svr.rooms[0]; croom->hx >= 0; croom++) if ((type == ANY_TYPE && croom->rtype != OROOM) || (type == ANY_SHOP && croom->rtype >= SHOPBASE) || croom->rtype == type) @@ -821,7 +821,7 @@ squadmon(void) } mndx = ROLL_FROM(squadprob).pm; gotone: - if (!(gm.mvitals[mndx].mvflags & G_GONE)) + if (!(svm.mvitals[mndx].mvflags & G_GONE)) return &mons[mndx]; else return (struct permonst *) 0; @@ -858,9 +858,9 @@ save_rooms(NHFILE *nhfp) /* First, write the number of rooms */ if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) &gn.nroom, sizeof(gn.nroom)); - for (i = 0; i < gn.nroom; i++) - save_room(nhfp, &gr.rooms[i]); + bwrite(nhfp->fd, (genericptr_t) &svn.nroom, sizeof(svn.nroom)); + for (i = 0; i < svn.nroom; i++) + save_room(nhfp, &svr.rooms[i]); } staticfn void @@ -888,14 +888,14 @@ rest_rooms(NHFILE *nhfp) short i; if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &gn.nroom, sizeof(gn.nroom)); + mread(nhfp->fd, (genericptr_t) &svn.nroom, sizeof(svn.nroom)); gn.nsubroom = 0; - for (i = 0; i < gn.nroom; i++) { - rest_room(nhfp, &gr.rooms[i]); - gr.rooms[i].resident = (struct monst *) 0; + for (i = 0; i < svn.nroom; i++) { + rest_room(nhfp, &svr.rooms[i]); + svr.rooms[i].resident = (struct monst *) 0; } - gr.rooms[gn.nroom].hx = -1; /* restore ending flags */ + svr.rooms[svn.nroom].hx = -1; /* restore ending flags */ gs.subrooms[gn.nsubroom].hx = -1; } @@ -1043,8 +1043,8 @@ staticfn boolean invalid_shop_shape(struct mkroom *sroom) { coordxy x, y; - coordxy doorx = gd.doors[sroom->fdoor].x; - coordxy doory = gd.doors[sroom->fdoor].y; + coordxy doorx = svd.doors[sroom->fdoor].x; + coordxy doory = svd.doors[sroom->fdoor].y; coordxy insidex = 0, insidey = 0, insidect = 0; /* First, identify squares inside the room and next to the door. */ diff --git a/src/mon.c b/src/mon.c index b7114e9d9..23c7ccde2 100644 --- a/src/mon.c +++ b/src/mon.c @@ -40,8 +40,8 @@ extern const struct shclass shtypes[]; /* defined in shknam.c */ #define LEVEL_SPECIFIC_NOCORPSE(mdat) \ (Is_rogue_level(&u.uz) \ - || !gl.level.flags.deathdrops \ - || (gl.level.flags.graveyard && is_undead(mdat) && rn2(3))) + || !svl.level.flags.deathdrops \ + || (svl.level.flags.graveyard && is_undead(mdat) && rn2(3))) #if 0 @@ -98,7 +98,7 @@ sanity_check_single_mon( #endif return; } - if (chk_geno && (gm.mvitals[mndx].mvflags & G_GENOD) != 0) + if (chk_geno && (svm.mvitals[mndx].mvflags & G_GENOD) != 0) impossible("genocided %s in play (%s)", pmname(mptr, Mgender(mtmp)), msg); if (mtmp->mtame && !mtmp->mpeaceful) @@ -255,7 +255,7 @@ mon_sanity_check(void) if (x != u.ux || y != u.uy) impossible("steed (%s) claims to be at <%d,%d>?", fmt_ptr((genericptr_t) mtmp), x, y); - } else if (gl.level.monsters[x][y] != mtmp) { + } else if (svl.level.monsters[x][y] != mtmp) { impossible("mon (%s) at <%d,%d> is not there!", fmt_ptr((genericptr_t) mtmp), x, y); } else if (mtmp->wormno) { @@ -271,7 +271,7 @@ mon_sanity_check(void) for (x = 1; x < COLNO; x++) for (y = 0; y < ROWNO; y++) - if ((mtmp = gl.level.monsters[x][y]) != 0) { + if ((mtmp = svl.level.monsters[x][y]) != 0) { for (m = fmon; m; m = m->nmon) if (m == mtmp) break; @@ -530,7 +530,7 @@ pm_to_cham(int mndx) || is_reviver((mon)->data) \ /* normally quest leader will be unique, */ \ /* but he or she might have been polymorphed */ \ - || (mon)->m_id == gq.quest_status.leader_m_id \ + || (mon)->m_id == svq.quest_status.leader_m_id \ /* special cancellation handling for these */ \ || (dmgtype((mon)->data, AD_SEDU) || dmgtype((mon)->data, AD_SSEX))) @@ -866,7 +866,7 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags) default: #endif default_1: - if (gm.mvitals[mndx].mvflags & G_NOCORPSE) { + if (svm.mvitals[mndx].mvflags & G_NOCORPSE) { return (struct obj *) 0; } else { corpstatflags |= CORPSTAT_INIT; @@ -890,7 +890,7 @@ default_1: /* if polymorph or undead turning has killed this monster, prevent the same attack beam from hitting its corpse */ - if (gc.context.bypasses) + if (svc.context.bypasses) bypass_obj(obj); if (has_mgivenname(mtmp)) @@ -1010,7 +1010,7 @@ minliquid_core(struct monst *mtmp) hero to create lava beneath a monster, so the !mon_moving case is not expected to happen (and we haven't made a player-against-monster variation of the message above) */ - if (gc.context.mon_moving) + if (svc.context.mon_moving) mondead(mtmp); /* no corpse */ else xkilled(mtmp, XKILL_NOMSG); @@ -1046,7 +1046,7 @@ minliquid_core(struct monst *mtmp) return 0; } if (cansee(mtmp->mx, mtmp->my)) { - if (gc.context.mon_moving) + if (svc.context.mon_moving) pline_mon(mtmp, "%s drowns.", Monnam(mtmp)); else /* hero used fire to melt ice that monster was on */ @@ -1058,7 +1058,7 @@ minliquid_core(struct monst *mtmp) pline("%s sinks as %s rushes in and flushes you out.", Monnam(mtmp), hliquid("water")); } - if (gc.context.mon_moving) + if (svc.context.mon_moving) mondied(mtmp); /* ok to leave corpse despite water */ else xkilled(mtmp, XKILL_NOMSG); @@ -1102,7 +1102,7 @@ mcalcmove( else if (mon->mspeed == MFAST) mmove = (4 * mmove + 2) / 3; - if (mon == u.usteed && u.ugallop && gc.context.mv) { + if (mon == u.usteed && u.ugallop && svc.context.mv) { /* increase movement by a factor of 1.5; also increase variance of movement speed (if it's naturally 24, we don't want it to always become 36) */ @@ -1176,7 +1176,7 @@ movemon_singlemon(struct monst *mtmp) if (u.utotype #ifdef SAFERHANGUP /* or if the program has lost contact with the user */ - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { gs.somebody_can_move = FALSE; @@ -1191,9 +1191,9 @@ movemon_singlemon(struct monst *mtmp) mon->isgd flag so that dmonsfree() will get rid of mon) */ if (mtmp->isgd && !mtmp->mx && !(mtmp->mstate & MON_MIGRATING)) { /* parked at <0,0>; eventually isgd should get set to false */ - if (gm.moves > mtmp->mlstmv) { + if (svm.moves > mtmp->mlstmv) { (void) gd_move(mtmp); - mtmp->mlstmv = gm.moves; + mtmp->mlstmv = svm.moves; } return FALSE; } @@ -1218,7 +1218,7 @@ movemon_singlemon(struct monst *mtmp) vision_recalc(0); /* vision! */ /* reset obj bypasses before next monster moves */ - if (gc.context.bypasses) + if (svc.context.bypasses) clear_bypasses(); clear_splitobjs(); if (minliquid(mtmp)) @@ -1291,7 +1291,7 @@ movemon(void) if (any_light_source()) gv.vision_full_recalc = 1; /* in case a mon moved w/ a light source */ /* reset obj bypasses after last monster has moved */ - if (gc.context.bypasses) + if (svc.context.bypasses) clear_bypasses(); clear_splitobjs(); /* remove dead monsters; dead vault guard will be left at <0,0> @@ -1432,7 +1432,7 @@ meatmetal(struct monst *mtmp) return 0; /* Eats topmost metal object if it is there */ - for (otmp = gl.level.objects[mtmp->mx][mtmp->my]; otmp; + for (otmp = svl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp->nexthere) { /* Don't eat indigestible/choking/inappropriate objects */ if ((mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) @@ -1505,7 +1505,7 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */ /* eat organic objects, including cloth and wood, if present; engulf others, except huge rocks and metal attached to player [despite comment at top, doesn't assume that eater is a g-cube] */ - for (otmp = gl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; /* avoid special items; once hero picks them up, they'll cease @@ -1820,7 +1820,7 @@ mpickstuff(struct monst *mtmp) if (!could_reach_item(mtmp, mtmp->mx, mtmp->my)) return FALSE; - for (otmp = gl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; /* avoid special items; once hero picks them up, they'll cease @@ -2277,7 +2277,7 @@ mfndpos( } /* Note: ALLOW_SANCT only prevents movement, not attack, into a temple. */ - if (gl.level.flags.has_temple && *in_rooms(nx, ny, TEMPLE) + if (svl.level.flags.has_temple && *in_rooms(nx, ny, TEMPLE) && !*in_rooms(x, y, TEMPLE) && in_your_sanctuary((struct monst *) 0, nx, ny)) { if (!(flag & ALLOW_SANCT)) @@ -2457,8 +2457,8 @@ replmon(struct monst *mtmp, struct monst *mtmp2) } mtmp->minvent = 0; /* before relmon(mtmp), because it could clear polearm.hitmon */ - if (gc.context.polearm.hitmon == mtmp) - gc.context.polearm.hitmon = mtmp2; + if (svc.context.polearm.hitmon == mtmp) + svc.context.polearm.hitmon = mtmp2; /* remove the old monster from the map and from `fmon' list */ relmon(mtmp, (struct monst **) 0); @@ -2621,14 +2621,14 @@ staticfn void mon_leaving_level(struct monst *mon) { coordxy mx = mon->mx, my = mon->my; - boolean onmap = (isok(mx, my) && gl.level.monsters[mx][my] == mon); + boolean onmap = (isok(mx, my) && svl.level.monsters[mx][my] == mon); /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ mon->mtrapped = 0; unstuck(mon); /* mon is not swallowing or holding you nor held by you */ /* vault guard might be at <0,0> */ - if (onmap || mon == gl.level.monsters[0][0]) { + if (onmap || mon == svl.level.monsters[0][0]) { if (mon->wormno) remove_worm(mon); else @@ -2650,8 +2650,8 @@ mon_leaving_level(struct monst *mon) newsym(mx, my); } /* if mon is a remembered target, forget it since it isn't here anymore */ - if (mon == gc.context.polearm.hitmon) - gc.context.polearm.hitmon = (struct monst *) 0; + if (mon == svc.context.polearm.hitmon) + svc.context.polearm.hitmon = (struct monst *) 0; } /* 'mtmp' is going away; remove effects of mtmp from other data structures */ @@ -2789,7 +2789,7 @@ lifesaved_monster(struct monst *mtmp) /* equip replacement amulet, if any, on next move */ check_gear_next_turn(mtmp); - surviver = !(gm.mvitals[monsndx(mtmp->data)].mvflags & G_GENOD); + surviver = !(svm.mvitals[monsndx(mtmp->data)].mvflags & G_GENOD); mtmp->mcanmove = 1; mtmp->mfrozen = 0; if (mtmp->mtame && !mtmp->isminion) { @@ -2818,7 +2818,7 @@ vamprises(struct monst *mtmp) int mndx = mtmp->cham; if (ismnum(mndx) && mndx != monsndx(mtmp->data) - && !(gm.mvitals[mndx].mvflags & G_GENOD)) { + && !(svm.mvitals[mndx].mvflags & G_GENOD)) { coord new_xy; char buf[BUFSZ]; /* alternate message phrasing for some monster types */ @@ -2890,7 +2890,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL staticfn void logdeadmon(struct monst *mtmp, int mndx) { - int howmany = gm.mvitals[mndx].died; + int howmany = svm.mvitals[mndx].died; if (mndx == PM_MEDUSA && howmany == 1) { record_achievement(ACH_MEDU); /* also generates a livelog event */ @@ -2899,7 +2899,7 @@ logdeadmon(struct monst *mtmp, int mndx) || (mtmp->isshk && !mtmp->mrevived)) { char shkdetail[QBUFSZ]; const char *mkilled; - boolean herodidit = !gc.context.mon_moving; + boolean herodidit = !svc.context.mon_moving; /* * livelog event; unique_corpstat() includes the Wizard and @@ -3010,7 +3010,7 @@ mondead(struct monst *mtmp) set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT]); /* - * gm.mvitals[].died does double duty as total number of dead monsters + * svm.mvitals[].died does double duty as total number of dead monsters * and as experience factor for the player killing more monsters. * this means that a dragon dying by other means reduces the * experience the player gets for killing a dragon directly; this @@ -3020,16 +3020,16 @@ mondead(struct monst *mtmp) * for rings of conflict and such. */ mndx = monsndx(mtmp->data); - if (gm.mvitals[mndx].died < 255) - gm.mvitals[mndx].died++; + if (svm.mvitals[mndx].died < 255) + svm.mvitals[mndx].died++; /* if it's a (possibly polymorphed) quest leader, mark him as dead */ - if (mtmp->m_id == gq.quest_status.leader_m_id) - gq.quest_status.leader_is_dead = TRUE; + if (mtmp->m_id == svq.quest_status.leader_m_id) + svq.quest_status.leader_is_dead = TRUE; #ifdef MAIL_STRUCTURES /* if the mail daemon dies, no more mail delivery. -3. */ if (mndx == PM_MAIL_DAEMON) - gm.mvitals[mndx].mvflags |= G_GENOD; + svm.mvitals[mndx].mvflags |= G_GENOD; #endif if (mtmp->data->mlet == S_KOP) { @@ -3092,9 +3092,9 @@ corpse_chance( if (was_swallowed && magr) { if (magr == &gy.youmonst) { There("is an explosion in your %s!", body_part(STOMACH)); - Sprintf(gk.killer.name, "%s explosion", + Sprintf(svk.killer.name, "%s explosion", s_suffix(pmname(mdat, Mgender(mon)))); - losehp(Maybe_Half_Phys(tmp), gk.killer.name, KILLED_BY_AN); + losehp(Maybe_Half_Phys(tmp), svk.killer.name, KILLED_BY_AN); } else { You_hear("an explosion."); magr->mhp -= tmp; @@ -3466,7 +3466,7 @@ xkilled( int otyp; /* illogical but traditional "treasure drop" */ - if (!rn2(6) && !(gm.mvitals[mndx].mvflags & G_NOCORPSE) + if (!rn2(6) && !(svm.mvitals[mndx].mvflags & G_NOCORPSE) /* no extra item from swallower or steed */ && (x != u.ux || y != u.uy) /* no extra item from kops--too easy to abuse */ @@ -3551,19 +3551,19 @@ xkilled( } /* give experience points */ - tmp = experience(mtmp, (int) gm.mvitals[mndx].died); + tmp = experience(mtmp, (int) svm.mvitals[mndx].died); more_experienced(tmp, 0); newexplevel(); /* will decide if you go up */ /* adjust alignment points */ - if (mtmp->m_id == gq.quest_status.leader_m_id) { /* REAL BAD! */ + if (mtmp->m_id == svq.quest_status.leader_m_id) { /* REAL BAD! */ adjalign(-(u.ualign.record + (int) ALIGNLIM / 2)); u.ugangr += 7; /* instantly become "extremely" angry */ change_luck(-20); pline("That was %sa bad idea...", u.uevent.qcompleted ? "probably " : ""); } else if (mdat->msound == MS_NEMESIS) { /* Real good! */ - if (!gq.quest_status.killed_leader) + if (!svq.quest_status.killed_leader) adjalign((int) (ALIGNLIM / 4)); } else if (mdat->msound == MS_GUARDIAN) { /* Bad */ adjalign(-(int) (ALIGNLIM / 8)); @@ -3637,7 +3637,7 @@ vamp_stone(struct monst *mtmp) /* this only happens if shapeshifted */ if (mndx >= LOW_PM && mndx != monsndx(mtmp->data) - && !(gm.mvitals[mndx].mvflags & G_GENOD)) { + && !(svm.mvitals[mndx].mvflags & G_GENOD)) { char buf[BUFSZ]; /* construct a format string before transformation */ @@ -3749,10 +3749,10 @@ elemental_clog(struct monst *mon) if (In_endgame(&u.uz)) { m1 = m2 = m3 = m4 = m5 = zm = (struct monst *) 0; - if (!msgmv || (gm.moves - msgmv) > 200L) { + if (!msgmv || (svm.moves - msgmv) > 200L) { if (!msgmv || rn2(2)) You_feel("besieged."); - msgmv = gm.moves; + msgmv = svm.moves; } /* * m1 an elemental from another plane. @@ -4164,7 +4164,7 @@ setmangry(struct monst *mtmp, boolean via_attack) qst_guardians_respond(); /* make other peaceful monsters react */ - if (!gc.context.mon_moving) + if (!svc.context.mon_moving) peacefuls_respond(mtmp); } @@ -4192,7 +4192,7 @@ wakeup(struct monst *mtmp, boolean via_attack) have to lose his disguise */ if (M_AP_TYPE(mtmp) != M_AP_MONSTER) seemimic(mtmp); - } else if (gc.context.forcefight && !gc.context.mon_moving + } else if (svc.context.forcefight && !svc.context.mon_moving && mtmp->mundetected) { mtmp->mundetected = 0; newsym(mtmp->mx, mtmp->my); @@ -4236,11 +4236,11 @@ wake_nearto_core(coordxy x, coordxy y, int distance, boolean petcall) mtmp->msleeping = 0; /* wake indeterminate sleep */ if (!(mtmp->data->geno & G_UNIQ)) mtmp->mstrategy &= ~STRAT_WAITMASK; /* wake 'meditation' */ - if (gc.context.mon_moving || !petcall) + if (svc.context.mon_moving || !petcall) continue; if (mtmp->mtame) { if (!mtmp->isminion) - EDOG(mtmp)->whistletime = gm.moves; + EDOG(mtmp)->whistletime = svm.moves; /* Fix up a pet who is stuck "fleeing" its master */ mon_track_clear(mtmp); } @@ -4520,7 +4520,7 @@ maybe_unhide_at(coordxy x, coordxy y) if (undetected && ((hides_under(mtmp->data) && (!OBJ_AT(x, y) || trapped - || !can_hide_under_obj(gl.level.objects[x][y]))) + || !can_hide_under_obj(svl.level.objects[x][y]))) || (mtmp->data->mlet == S_EEL && !is_pool(x, y)))) (void) hideunder(mtmp); } @@ -4557,7 +4557,7 @@ hideunder(struct monst *mtmp) } } else if (hides_under(mtmp->data) /* hider-underers only hide under objects */ - && (otmp = gl.level.objects[x][y]) != 0 + && (otmp = svl.level.objects[x][y]) != 0 /* most things can be hidden under, but not all */ && can_hide_under_obj(otmp) /* aquatic creatures don't reach here; other swimmers @@ -4767,7 +4767,7 @@ pickvampshape(struct monst *mon) /* return to base form if chosen poly target has been genocided or randomly if already in an alternate form (to prevent always switching back and forth between bat and fog) */ - if ((gm.mvitals[mndx].mvflags & G_GENOD) != 0 + if ((svm.mvitals[mndx].mvflags & G_GENOD) != 0 || (mon->data != &mons[mon->cham] && !rn2(4))) return mon->cham; @@ -4779,7 +4779,7 @@ staticfn boolean isspecmon(struct monst *mon) { return (mon->isshk || mon->ispriest || mon->isgd - || mon->m_id == gq.quest_status.leader_m_id); + || mon->m_id == svq.quest_status.leader_m_id); } /* restrict certain special monsters (shopkeepers, aligned priests, @@ -5028,7 +5028,7 @@ accept_newcham_form(struct monst *mon, int mndx) if (mndx == NON_PM) return 0; mdat = &mons[mndx]; - if ((gm.mvitals[mndx].mvflags & G_GENOD) != 0) + if ((svm.mvitals[mndx].mvflags & G_GENOD) != 0) return 0; if (is_placeholder(mdat)) return 0; @@ -5129,7 +5129,7 @@ newcham( } while (--tryct > 0); if (!tryct) return 0; - } else if (gm.mvitals[monsndx(mdat)].mvflags & G_GENOD) + } else if (svm.mvitals[monsndx(mdat)].mvflags & G_GENOD) return 0; /* passed in mdat is genocided */ if (mdat == olddata) @@ -5275,7 +5275,7 @@ newcham( mon_break_armor(mtmp, polyspot); if (!(mtmp->misc_worn_check & W_ARMG)) mselftouch(mtmp, "No longer petrify-resistant, ", - !gc.context.mon_moving); + !svc.context.mon_moving); check_gear_next_turn(mtmp); /* This ought to re-test can_carry() on each item in the inventory @@ -5309,7 +5309,7 @@ newcham( /* old form might not have been affected by Elbereth but perhaps the new form is */ - if (gc.context.mon_moving) { + if (svc.context.mon_moving) { /* give 'mtmp' a new chance to pinpoint hero's location */ if (!u_at(mtmp->mux, mtmp->muy)) set_apparxy(mtmp); @@ -5390,8 +5390,8 @@ dead_species(int m_idx, boolean egg) */ /* assert(ismnum(m_idx)); */ alt_idx = egg ? big_to_little(m_idx) : m_idx; - return (boolean) ((gm.mvitals[m_idx].mvflags & G_GENOD) != 0 - || (gm.mvitals[alt_idx].mvflags & G_GENOD) != 0); + return (boolean) ((svm.mvitals[m_idx].mvflags & G_GENOD) != 0 + || (svm.mvitals[alt_idx].mvflags & G_GENOD) != 0); } /* kill off any eggs of genocided monsters */ @@ -5449,8 +5449,8 @@ kill_genocided_monsters(void) continue; mndx = monsndx(mtmp->data); kill_cham = (ismnum(mtmp->cham) - && (gm.mvitals[mtmp->cham].mvflags & G_GENOD)); - if ((gm.mvitals[mndx].mvflags & G_GENOD) || kill_cham) { + && (svm.mvitals[mtmp->cham].mvflags & G_GENOD)); + if ((svm.mvitals[mndx].mvflags & G_GENOD) || kill_cham) { if (ismnum(mtmp->cham) && !kill_cham) (void) newcham(mtmp, (struct permonst *) 0, NC_SHOW_MSG); else @@ -5463,7 +5463,7 @@ kill_genocided_monsters(void) kill_eggs(gi.invent); kill_eggs(fobj); kill_eggs(gm.migrating_objs); - kill_eggs(gl.level.buriedobjlist); + kill_eggs(svl.level.buriedobjlist); } void diff --git a/src/mondata.c b/src/mondata.c index 58c29f63f..28da3358a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -81,7 +81,7 @@ poly_when_stoned(struct permonst *ptr) { /* non-stone golems turn into stone golems unless latter is genocided */ return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] - && !(gm.mvitals[PM_STONE_GOLEM].mvflags & G_GENOD)); + && !(svm.mvitals[PM_STONE_GOLEM].mvflags & G_GENOD)); /* allow G_EXTINCT */ } diff --git a/src/monmove.c b/src/monmove.c index 18d573f4a..0c563c3de 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -184,7 +184,7 @@ watch_on_duty(struct monst *mtmp) } } else if (is_digging()) { /* chewing, wand/spell of digging are checked elsewhere */ - watch_dig(mtmp, gc.context.digging.pos.x, gc.context.digging.pos.y, + watch_dig(mtmp, svc.context.digging.pos.x, svc.context.digging.pos.y, FALSE); } } @@ -287,7 +287,7 @@ void mon_regen(struct monst *mon, boolean digest_meal) { if (mon->mhp < mon->mhpmax - && (gm.moves % 20 == 0 || regenerates(mon->data))) + && (svm.moves % 20 == 0 || regenerates(mon->data))) mon->mhp++; if (mon->mspec_used) mon->mspec_used--; @@ -357,7 +357,7 @@ find_pmmonst(int pm) { struct monst *mtmp = 0; - if ((gm.mvitals[pm].mvflags & G_GENOD) == 0) + if ((svm.mvitals[pm].mvflags & G_GENOD) == 0) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; @@ -999,7 +999,7 @@ mon_would_consume_item(struct monst *mtmp, struct obj *otmp) if (mtmp->mtame && has_edog(mtmp) /* has_edog(): not guardian angel */ && (ftyp = dogfood(mtmp, otmp)) < MANFOOD - && (ftyp < ACCFOOD || EDOG(mtmp)->hungrytime <= gm.moves)) + && (ftyp < ACCFOOD || EDOG(mtmp)->hungrytime <= svm.moves)) return TRUE; return FALSE; @@ -1338,7 +1338,7 @@ m_search_items( costly = costly_spot(xx, yy); /* look through the items on this location */ - for (otmp = gl.level.objects[xx][yy]; + for (otmp = svl.level.objects[xx][yy]; otmp; otmp = otmp->nexthere) { /* monsters may pick rocks up, but won't go out of their way to grab them; this might hamper sling wielders, but it cuts @@ -1673,7 +1673,7 @@ m_move(struct monst *mtmp, int after) return MMOVE_DONE; /* still eating */ } if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) - && can_hide_under_obj(gl.level.objects[mtmp->mx][mtmp->my]) && rn2(10)) + && can_hide_under_obj(svl.level.objects[mtmp->mx][mtmp->my]) && rn2(10)) return MMOVE_NOTHING; /* do not leave hiding place */ /* Where does 'mtmp' think you are? Not necessary if m_move() called @@ -1854,7 +1854,7 @@ m_move(struct monst *mtmp, int after) chi = -1; nidist = dist2(nix, niy, ggx, ggy); /* allow monsters be shortsighted on some levels for balance */ - if (!mtmp->mpeaceful && gl.level.flags.shortsighted + if (!mtmp->mpeaceful && svl.level.flags.shortsighted && nidist > (couldsee(nix, niy) ? 144 : 36) && appr == 1) appr = 0; if (is_unicorn(ptr) && noteleport_level(mtmp)) { @@ -2281,7 +2281,7 @@ can_ooze(struct monst *mtmp) boolean can_fog(struct monst *mtmp) { - if (!(gm.mvitals[PM_FOG_CLOUD].mvflags & G_GENOD) && is_vampshifter(mtmp) + if (!(svm.mvitals[PM_FOG_CLOUD].mvflags & G_GENOD) && is_vampshifter(mtmp) && !Protection_from_shape_changers && !stuff_prevents_passage(mtmp)) return TRUE; return FALSE; diff --git a/src/mthrowu.c b/src/mthrowu.c index adf4cfb99..65ceb076d 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -453,7 +453,7 @@ ohitmon( (nonliving(mtmp->data) || is_vampshifter(mtmp) || !canspotmon(mtmp)) ? "destroyed" : "killed"); /* don't blame hero for unknown rolling boulder trap */ - if (!gc.context.mon_moving && (otmp->otyp != BOULDER + if (!svc.context.mon_moving && (otmp->otyp != BOULDER || range >= 0 || otmp->otrapped)) xkilled(mtmp, XKILL_NOMSG); else @@ -484,7 +484,7 @@ ohitmon( mtmp->mblinded = tmp; } - if (!DEADMONSTER(mtmp) && !gc.context.mon_moving) + if (!DEADMONSTER(mtmp) && !svc.context.mon_moving) setmangry(mtmp, TRUE); objgone = drop_throw(otmp, 1, gb.bhitpos.x, gb.bhitpos.y); diff --git a/src/muse.c b/src/muse.c index d26cb4c74..6c3d08abc 100644 --- a/src/muse.c +++ b/src/muse.c @@ -68,8 +68,8 @@ precheck(struct monst *mon, struct obj *obj) struct monst *mtmp; if (objdescr_is(obj, "milky")) { - if (!(gm.mvitals[PM_GHOST].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(gm.mvitals[PM_GHOST].born))) { + if (!(svm.mvitals[PM_GHOST].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(svm.mvitals[PM_GHOST].born))) { if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) return 0; mquaffmsg(mon, obj); @@ -94,8 +94,8 @@ precheck(struct monst *mon, struct obj *obj) } } if (objdescr_is(obj, "smoky") - && !(gm.mvitals[PM_DJINNI].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(gm.mvitals[PM_DJINNI].born))) { + && !(svm.mvitals[PM_DJINNI].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(svm.mvitals[PM_DJINNI].born))) { if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) return 0; mquaffmsg(mon, obj); @@ -598,7 +598,7 @@ find_defensive(struct monst *mtmp, boolean tryescape) or some other monster is there */ if (u_at(xx, yy) || (xx != x && yy != y && !diag_ok) - || (gl.level.monsters[xx][yy] && !(xx == x && yy == y))) + || (svl.level.monsters[xx][yy] && !(xx == x && yy == y))) continue; /* skip if there's no trap or can't/won't move onto trap */ if ((t = t_at(xx, yy)) == 0 @@ -771,7 +771,7 @@ staticfn int mon_escape(struct monst *mtmp, boolean vismon) { if (mon_has_special(mtmp) - || (mtmp->iswiz && gc.context.no_of_wizards < 2)) + || (mtmp->iswiz && svc.context.no_of_wizards < 2)) return 0; if (vismon) pline("%s escapes the dungeon!", Monnam(mtmp)); @@ -1611,7 +1611,7 @@ mbhitm(struct monst *mtmp, struct obj *otmp) /* context.bypasses=True: if resist() happens to be fatal, make_corpse() will set obj->bypass on the new corpse so that mbhito() will skip it instead of reviving it */ - gc.context.bypasses = TRUE; /* for make_corpse() */ + svc.context.bypasses = TRUE; /* for make_corpse() */ (void) resist(mtmp, WAND_CLASS, rnd(8), NOTELL); } if (wake) { @@ -1645,7 +1645,7 @@ fhito_loc(struct obj *obj, if (!fhito || !OBJ_AT(tx, ty)) return FALSE; - for (otmp = gl.level.objects[tx][ty]; otmp; otmp = next_obj) { + for (otmp = svl.level.objects[tx][ty]; otmp; otmp = next_obj) { next_obj = otmp->nexthere; if (otmp->where != OBJ_FLOOR || otmp->ox != tx || otmp->oy != ty) @@ -2038,7 +2038,7 @@ find_misc(struct monst *mtmp) for (yy = y - 1; yy <= y + 1; yy++) if (isok(xx, yy) && !u_at(xx, yy) && (diag_ok || xx == x || yy == y) - && ((xx == x && yy == y) || !gl.level.monsters[xx][yy])) + && ((xx == x && yy == y) || !svl.level.monsters[xx][yy])) if ((t = t_at(xx, yy)) != 0 && (ignore_boulders || !sobj_at(BOULDER, xx, yy)) && !onscary(xx, yy, mtmp)) { @@ -2848,14 +2848,14 @@ mon_consume_unstone( if (mon->mtame && !mon->isminion && nutrit > 0) { struct edog *edog = EDOG(mon); - if (edog->hungrytime < gm.moves) - edog->hungrytime = gm.moves; + if (edog->hungrytime < svm.moves) + edog->hungrytime = svm.moves; edog->hungrytime += nutrit; mon->mconf = 0; } /* use up monster's next move */ mon->movement -= NORMAL_SPEED; - mon->mlstmv = gm.moves; + mon->mlstmv = svm.moves; } /* decide whether obj can cure petrification; also used when picking up */ @@ -3114,7 +3114,7 @@ muse_unslime( } /* use up monster's next move */ mon->movement -= NORMAL_SPEED; - mon->mlstmv = gm.moves; + mon->mlstmv = svm.moves; return res; } diff --git a/src/music.c b/src/music.c index 740b3dc77..d4ebd46e8 100644 --- a/src/music.c +++ b/src/music.c @@ -714,23 +714,23 @@ staticfn char * improvised_notes(boolean *same_as_last_time) { static const char notes[7] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }; - /* target buffer has to be in gc.context, otherwise saving game + /* target buffer has to be in svc.context, otherwise saving game * between improvised recitals would not be able to maintain * the same_as_last_time context. */ /* You can change your tune, usually */ - if (!(Unchanging && gc.context.jingle[0] != '\0')) { - int i, notecount = rnd(SIZE(gc.context.jingle) - 1); /* 1 - 5 */ + if (!(Unchanging && svc.context.jingle[0] != '\0')) { + int i, notecount = rnd(SIZE(svc.context.jingle) - 1); /* 1 - 5 */ for (i = 0; i < notecount; ++i) { - gc.context.jingle[i] = ROLL_FROM(notes); + svc.context.jingle[i] = ROLL_FROM(notes); } - gc.context.jingle[notecount] = '\0'; + svc.context.jingle[notecount] = '\0'; *same_as_last_time = FALSE; } else { *same_as_last_time = TRUE; } - return gc.context.jingle; + return svc.context.jingle; } /* @@ -769,7 +769,7 @@ do_play_instrument(struct obj *instr) if (c == 'q') { goto nevermind; } else if (c == 'y') { - Strcpy(buf, gt.tune); + Strcpy(buf, svt.tune); } else { getlin("What tune are you playing? [5 notes, A-G]", buf); (void) mungspaces(buf); @@ -794,7 +794,7 @@ do_play_instrument(struct obj *instr) */ if (Is_stronghold(&u.uz)) { exercise(A_WIS, TRUE); /* just for trying */ - if (!strcmp(buf, gt.tune)) { + if (!strcmp(buf, svt.tune)) { /* Search for the drawbridge */ for (y = u.uy - 1; y <= u.uy + 1; y++) for (x = u.ux - 1; x <= u.ux + 1; x++) { @@ -834,13 +834,13 @@ do_play_instrument(struct obj *instr) for (x = 0; x < (int) strlen(buf); x++) if (x < 5) { - if (buf[x] == gt.tune[x]) { + if (buf[x] == svt.tune[x]) { gears++; matched[x] = TRUE; } else { for (y = 0; y < 5; y++) - if (!matched[y] && buf[x] == gt.tune[y] - && buf[y] != gt.tune[y]) { + if (!matched[y] && buf[x] == svt.tune[y] + && buf[y] != svt.tune[y]) { tumblers++; matched[y] = TRUE; break; diff --git a/src/nhlobj.c b/src/nhlobj.c index 411219f0a..b89b25e02 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -379,7 +379,7 @@ l_obj_at(lua_State *L) cvt_to_abscoord(&x, &y); lua_pop(L, 2); - (void) l_obj_push(L, gl.level.objects[x][y]); + (void) l_obj_push(L, svl.level.objects[x][y]); return 1; } else nhl_error(L, "l_obj_at: Wrong args"); diff --git a/src/nhlsel.c b/src/nhlsel.c index 544df9d4b..bd0fb6e7c 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -429,7 +429,7 @@ l_selection_room(lua_State *L) if (argc == 1) { int i = luaL_checkinteger(L, -1); - croom = (i >= 0 && i < gn.nroom) ? &gr.rooms[i] : NULL; + croom = (i >= 0 && i < svn.nroom) ? &svr.rooms[i] : NULL; } sel = selection_from_mkroom(croom); diff --git a/src/nhlua.c b/src/nhlua.c index 93816ef83..d285a8a57 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1091,8 +1091,8 @@ nhl_dnum_name(lua_State *L) if (argc == 1) { lua_Integer dnum = luaL_checkinteger(L, 1); - if (dnum >= 0 && dnum < gn.n_dgns) - lua_pushstring(L, gd.dungeons[dnum].dname); + if (dnum >= 0 && dnum < svn.n_dgns) + lua_pushstring(L, svd.dungeons[dnum].dname); else lua_pushstring(L, ""); } else @@ -1584,8 +1584,8 @@ nhl_gamestate(lua_State *L) d_level cur_uz = u.uz, cur_uz0 = u.uz0; /* restore game state */ - gm.moves = gg.gmst_moves; - pline("Resetting time to move #%ld.", gm.moves); + svm.moves = gg.gmst_moves; + pline("Resetting time to move #%ld.", svm.moves); gg.gmst_moves = 0L; gl.lastinvnr = 51; @@ -1602,11 +1602,11 @@ nhl_gamestate(lua_State *L) assert(gg.gmst_ubak != NULL); (void) memcpy((genericptr_t) &u, gg.gmst_ubak, sizeof u); assert(gg.gmst_disco != NULL); - (void) memcpy((genericptr_t) &gd.disco, gg.gmst_disco, - sizeof gd.disco); + (void) memcpy((genericptr_t) &svd.disco, gg.gmst_disco, + sizeof svd.disco); assert(gg.gmst_mvitals != NULL); - (void) memcpy((genericptr_t) &gm.mvitals, gg.gmst_mvitals, - sizeof gm.mvitals); + (void) memcpy((genericptr_t) &svm.mvitals, gg.gmst_mvitals, + sizeof svm.mvitals); /* some restored state would confuse the level change in progress */ u.uz = cur_uz, u.uz0 = cur_uz0; init_uhunger(); @@ -1614,7 +1614,7 @@ nhl_gamestate(lua_State *L) gg.gmst_stored = FALSE; } else if (!reststate && !gg.gmst_stored) { /* store game state */ - gg.gmst_moves = gm.moves; + gg.gmst_moves = svm.moves; while ((otmp = gi.invent) != NULL) { wornmask = otmp->owornmask; setnotworn(otmp); @@ -1626,12 +1626,12 @@ nhl_gamestate(lua_State *L) gl.lastinvnr = 51; /* next inv letter to try to use will be 'a' */ gg.gmst_ubak = (genericptr_t) alloc(sizeof u); (void) memcpy(gg.gmst_ubak, (genericptr_t) &u, sizeof u); - gg.gmst_disco = (genericptr_t) alloc(sizeof gd.disco); - (void) memcpy(gg.gmst_disco, (genericptr_t) &gd.disco, - sizeof gd.disco); - gg.gmst_mvitals = (genericptr_t) alloc(sizeof gm.mvitals); - (void) memcpy(gg.gmst_mvitals, (genericptr_t) &gm.mvitals, - sizeof gm.mvitals); + gg.gmst_disco = (genericptr_t) alloc(sizeof svd.disco); + (void) memcpy(gg.gmst_disco, (genericptr_t) &svd.disco, + sizeof svd.disco); + gg.gmst_mvitals = (genericptr_t) alloc(sizeof svm.mvitals); + (void) memcpy(gg.gmst_mvitals, (genericptr_t) &svm.mvitals, + sizeof svm.mvitals); gg.gmst_stored = TRUE; } else { impossible("nhl_gamestate: inconsistent state (%s vs %s)", @@ -1840,7 +1840,7 @@ nhl_meta_u_index(lua_State *L) lua_pushstring(L, gu.urole.name.m); return 1; } else if (!strcmp(tkey, "moves")) { - lua_pushinteger(L, gm.moves); + lua_pushinteger(L, svm.moves); return 1; } else if (!strcmp(tkey, "uhave_amulet")) { lua_pushinteger(L, u.uhave.amulet); diff --git a/src/o_init.c b/src/o_init.c index 5eb8ec865..23c62cfd6 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -58,7 +58,7 @@ setgemprobs(d_level *dlev) : ledger_no(dlev); else lev = 0; - first = gb.bases[GEM_CLASS]; + first = svb.bases[GEM_CLASS]; for (j = 0; j < 9 - lev / 3; j++) objects[first + j].oc_prob = 0; @@ -73,7 +73,7 @@ setgemprobs(d_level *dlev) objects[j].oc_prob = (171 + j - first) / (LAST_REAL_GEM + 1 - first); /* recompute GEM_CLASS total oc_prob - including rocks/stones */ - for (j = gb.bases[GEM_CLASS]; j < gb.bases[GEM_CLASS + 1]; j++) + for (j = svb.bases[GEM_CLASS]; j < svb.bases[GEM_CLASS + 1]; j++) sum += objects[j].oc_prob; go.oclass_prob_totals[GEM_CLASS] = sum; } @@ -152,7 +152,7 @@ init_objects(void) char oclass; for (i = 0; i <= MAXOCLASSES; i++) { - gb.bases[i] = 0; + svb.bases[i] = 0; if (i > 0 && i < MAXOCLASSES && objects[i].oc_class != i) panic( "init_objects: class for generic object #%d doesn't match (%d)", @@ -180,7 +180,7 @@ init_objects(void) last = first + 1; while (last < NUM_OBJECTS && objects[last].oc_class == oclass) last++; - gb.bases[(int) oclass] = first; + svb.bases[(int) oclass] = first; if (oclass == GEM_CLASS) { setgemprobs((d_level *) 0); @@ -197,13 +197,13 @@ init_objects(void) attempting to process non-existent class MAXOCLASSES; the [MAXOCLASSES+1] element gives that non-class 0 objects when traversing objects[] from bases[X] through bases[X+1]-1 */ - gb.bases[MAXOCLASSES] = gb.bases[MAXOCLASSES + 1] = NUM_OBJECTS; + svb.bases[MAXOCLASSES] = svb.bases[MAXOCLASSES + 1] = NUM_OBJECTS; /* hypothetically someone might remove all objects of some class, or be adding a new class and not populated it yet, leaving gaps in bases[]; guarantee that there are no such gaps */ for (last = MAXOCLASSES - 1; last >= 0; --last) - if (!gb.bases[last]) - gb.bases[last] = gb.bases[last + 1]; + if (!svb.bases[last]) + svb.bases[last] = svb.bases[last + 1]; /* check objects[].oc_name_known */ for (i = MAXOCLASSES; i < NUM_OBJECTS; ++i) { @@ -233,7 +233,7 @@ init_objects(void) } /* Compute the total probability of each object class. - * Assumes gb.bases[] has already been set. */ + * Assumes svb.bases[] has already been set. */ void init_oclass_probs(void) { @@ -245,15 +245,15 @@ init_oclass_probs(void) /* note: for ILLOBJ_CLASS, bases[oclass+1]-1 isn't the last item in the class; but all the generic items have probability 0 so adding them to 'sum' has no impact */ - for (i = gb.bases[oclass]; i < gb.bases[oclass + 1]; ++i) { + for (i = svb.bases[oclass]; i < svb.bases[oclass + 1]; ++i) { sum += objects[i].oc_prob; } if (sum <= 0 && oclass != ILLOBJ_CLASS - && gb.bases[oclass] != gb.bases[oclass + 1]) { + && svb.bases[oclass] != svb.bases[oclass + 1]) { impossible("%s (%d) probability total for oclass %d", !sum ? "zero" : "negative", sum, oclass); /* gracefully fail by setting all members of this class to 1 */ - for (i = gb.bases[oclass]; i < gb.bases[oclass + 1]; ++i) { + for (i = svb.bases[oclass]; i < svb.bases[oclass + 1]; ++i) { objects[i].oc_prob = 1; sum++; } @@ -286,14 +286,14 @@ obj_shuffle_range( break; case POTION_CLASS: /* potion of water has the only fixed description */ - *lo_p = gb.bases[POTION_CLASS]; + *lo_p = svb.bases[POTION_CLASS]; *hi_p = POT_WATER - 1; break; case AMULET_CLASS: case SCROLL_CLASS: case SPBOOK_CLASS: /* exclude non-magic types and also unique ones */ - *lo_p = gb.bases[ocls]; + *lo_p = svb.bases[ocls]; for (i = *lo_p; objects[i].oc_class == ocls; i++) if (objects[i].oc_unique || !objects[i].oc_magic) break; @@ -303,8 +303,8 @@ obj_shuffle_range( case WAND_CLASS: case VENOM_CLASS: /* entire class */ - *lo_p = gb.bases[ocls]; - *hi_p = gb.bases[ocls + 1] - 1; + *lo_p = svb.bases[ocls]; + *hi_p = svb.bases[ocls + 1] - 1; break; } @@ -332,7 +332,7 @@ shuffle_all(void) /* do whole classes (amulets, &c) */ for (idx = 0; idx < SIZE(shuffle_classes); idx++) { - obj_shuffle_range(gb.bases[(int) shuffle_classes[idx]], &first, &last); + obj_shuffle_range(svb.bases[(int) shuffle_classes[idx]], &first, &last); shuffle(first, last, TRUE); } /* do type ranges (helms, &c) */ @@ -376,8 +376,8 @@ savenames(NHFILE *nhfp) if (perform_bwrite(nhfp)) { if (nhfp->structlevel) { - bwrite(nhfp->fd, (genericptr_t) gb.bases, sizeof gb.bases); - bwrite(nhfp->fd, (genericptr_t) gd.disco, sizeof gd.disco); + bwrite(nhfp->fd, (genericptr_t) svb.bases, sizeof svb.bases); + bwrite(nhfp->fd, (genericptr_t) svd.disco, sizeof svd.disco); bwrite(nhfp->fd, (genericptr_t) objects, sizeof(struct objclass) * NUM_OBJECTS); } @@ -408,8 +408,8 @@ restnames(NHFILE *nhfp) unsigned int len = 0; if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t) gb.bases, sizeof gb.bases); - mread(nhfp->fd, (genericptr_t) gd.disco, sizeof gd.disco); + mread(nhfp->fd, (genericptr_t) svb.bases, sizeof svb.bases); + mread(nhfp->fd, (genericptr_t) svd.disco, sizeof svd.disco); mread(nhfp->fd, (genericptr_t) objects, NUM_OBJECTS * sizeof (struct objclass)); } @@ -444,10 +444,10 @@ discover_object( uname'd) or the next open slot; one or the other will be found before we reach the next class... */ - for (dindx = gb.bases[acls]; gd.disco[dindx] != 0; dindx++) - if (gd.disco[dindx] == oindx) + for (dindx = svb.bases[acls]; svd.disco[dindx] != 0; dindx++) + if (svd.disco[dindx] == oindx) break; - gd.disco[dindx] = oindx; + svd.disco[dindx] = oindx; /* if already known, we forced an item with a Japanese name into disco[] but don't want to exercise wisdom or update perminv */ @@ -460,7 +460,7 @@ discover_object( exercise(A_WIS, TRUE); } /* !in_moveloop => initial inventory, gameover => final disclosure */ - if (gp.program_state.in_moveloop && !gp.program_state.gameover) { + if (svp.program_state.in_moveloop && !svp.program_state.gameover) { if (objects[oindx].oc_class == GEM_CLASS) gem_learned(oindx); /* could affect price of unpaid gems */ update_inventory(); @@ -477,18 +477,18 @@ undiscover_object(int oindx) boolean found = FALSE; /* find the object; shift those behind it forward one slot */ - for (dindx = gb.bases[acls]; - dindx < NUM_OBJECTS && gd.disco[dindx] != 0 + for (dindx = svb.bases[acls]; + dindx < NUM_OBJECTS && svd.disco[dindx] != 0 && objects[dindx].oc_class == acls; dindx++) if (found) - gd.disco[dindx - 1] = gd.disco[dindx]; - else if (gd.disco[dindx] == oindx) + svd.disco[dindx - 1] = svd.disco[dindx]; + else if (svd.disco[dindx] == oindx) found = TRUE; /* clear last slot */ if (found) - gd.disco[dindx - 1] = 0; + svd.disco[dindx - 1] = 0; else impossible("named object not in disco"); @@ -549,7 +549,7 @@ sortloot_descr(int otyp, char *outbuf) o.corpsenm = NON_PM; /* suppress statue and figurine details */ /* but suppressing fruit details leads to "bad fruit #0" */ if (otyp == SLIME_MOLD) - o.spe = gc.context.current_fruit; + o.spe = svc.context.current_fruit; (void) memset((genericptr_t) &sl_cookie, 0, sizeof sl_cookie); sl_cookie.obj = (struct obj *) 0; @@ -754,9 +754,9 @@ dodiscovered(void) /* free after Robert Viduya */ for (s = classes; *s; s++) { oclass = *s; prev_class = oclass + 1; /* forced different from oclass */ - for (i = gb.bases[(int) oclass]; + for (i = svb.bases[(int) oclass]; i < NUM_OBJECTS && objects[i].oc_class == oclass; i++) { - if ((dis = gd.disco[i]) != 0 && interesting_to_discover(dis)) { + if ((dis = svd.disco[i]) != 0 && interesting_to_discover(dis)) { ct++; if (oclass != prev_class) { if ((alphabyclass || lootsort) && sorted_ct) { @@ -885,9 +885,9 @@ doclassdisco(void) for (s = allclasses; *s; ++s) { oclass = *s; c = def_oc_syms[(int) oclass].sym; - for (i = gb.bases[(int) oclass]; + for (i = svb.bases[(int) oclass]; i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) - if ((dis = gd.disco[i]) != 0 && interesting_to_discover(dis)) { + if ((dis = svd.disco[i]) != 0 && interesting_to_discover(dis)) { if (!strchr(discosyms, c)) { (void) strkitten(discosyms, c); if (!traditional) { @@ -995,8 +995,8 @@ doclassdisco(void) : "alphabetical order"); putstr(tmpwin, 0, buf); /* skip iflags.menu_headings */ sorted_ct = 0; - for (i = gb.bases[(int) oclass]; i <= gb.bases[oclass + 1] - 1; ++i) { - if ((dis = gd.disco[i]) != 0 && interesting_to_discover(dis)) { + for (i = svb.bases[(int) oclass]; i <= svb.bases[oclass + 1] - 1; ++i) { + if ((dis = svd.disco[i]) != 0 && interesting_to_discover(dis)) { ++ct; Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); if (lootsort) @@ -1058,9 +1058,9 @@ rename_disco(void) for (s = flags.inv_order; *s; s++) { oclass = *s; prev_class = oclass + 1; /* forced different from oclass */ - for (i = gb.bases[(int) oclass]; + for (i = svb.bases[(int) oclass]; i < NUM_OBJECTS && objects[i].oc_class == oclass; i++) { - dis = gd.disco[i]; + dis = svd.disco[i]; if (!dis || !interesting_to_discover(dis)) continue; ct++; diff --git a/src/objnam.c b/src/objnam.c index c1ed38dfb..c9e4efd9b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -325,7 +325,7 @@ obj_is_pname(struct obj *obj) { if (!obj->oartifact || !has_oname(obj)) return FALSE; - if (!gp.program_state.gameover && !iflags.override_ID) { + if (!svp.program_state.gameover && !iflags.override_ID) { if (not_fully_identified(obj)) return FALSE; } @@ -371,7 +371,7 @@ distant_name( against a potential extra chance to browse the map with getpos() during final disclosure (not currently implemented, nor planned) */ save_oid = obj->o_id; - if (gp.program_state.gameover) + if (svp.program_state.gameover) obj->o_id = 0; /* this maybe-nearby part used to be replicated in multiple callers */ @@ -406,12 +406,12 @@ fruitname( boolean juice) /* whether or not to append " juice" to the name */ { char *buf = nextobuf(); - const char *fruit_nam = strstri(gp.pl_fruit, " of "); + const char *fruit_nam = strstri(svp.pl_fruit, " of "); if (fruit_nam) fruit_nam += 4; /* skip past " of " */ else - fruit_nam = gp.pl_fruit; /* use it as is */ + fruit_nam = svp.pl_fruit; /* use it as is */ Sprintf(buf, "%s%s", makesingular(fruit_nam), juice ? " juice" : ""); return buf; @@ -955,7 +955,7 @@ xname_flags( "You were acid resistant because of your alchemy smock \ with text \"Kiss the cook\"." when disclosing attributes anyway */ - if (gp.program_state.gameover && obj->o_id && bufspaceleft > 0) { + if (svp.program_state.gameover && obj->o_id && bufspaceleft > 0) { const char *lbl; char tmpbuf[BUFSZ]; @@ -1444,7 +1444,7 @@ doname_base( the message as it gets added to invent and also if it gets snuffed out immediately (where it will end up as not partly used after all) */ - turns_left += peek_timer(BURN_OBJECT, &timer) - gm.moves; + turns_left += peek_timer(BURN_OBJECT, &timer) - svm.moves; } if (turns_left < full_burn_time) Strcat(prefix, "partly used "); @@ -1503,7 +1503,7 @@ doname_base( Strcat(prefix, "stale "); #endif if (ismnum(omndx) - && (known || (gm.mvitals[omndx].mvflags & MV_KNOWS_EGG))) { + && (known || (svm.mvitals[omndx].mvflags & MV_KNOWS_EGG))) { Strcat(prefix, mons[omndx].pmnames[NEUTRAL]); Strcat(prefix, " "); if (obj->spe == 1) @@ -1625,7 +1625,7 @@ doname_base( bill might not be available yet while restore is in progress (objects won't normally be formatted during that time, but if 'perm_invent' is enabled then they might be [not any more...]) */ - if (iflags.suppress_price || gp.program_state.restoring) { + if (iflags.suppress_price || svp.program_state.restoring) { ; /* don't attempt to obtain any shop pricing, even if 'with_price' */ } else if (is_unpaid(obj)) { /* in inventory or in container in invent */ char pricebuf[40]; @@ -3379,7 +3379,7 @@ rnd_otyp_by_wpnskill(schar skill) int i, n = 0; short otyp = STRANGE_OBJECT; - for (i = gb.bases[WEAPON_CLASS]; + for (i = svb.bases[WEAPON_CLASS]; i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++) if (objects[i].oc_skill == skill) { n++; @@ -3387,7 +3387,7 @@ rnd_otyp_by_wpnskill(schar skill) } if (n > 0) { n = rn2(n); - for (i = gb.bases[WEAPON_CLASS]; + for (i = svb.bases[WEAPON_CLASS]; i < NUM_OBJECTS && objects[i].oc_class == WEAPON_CLASS; i++) if (objects[i].oc_skill == skill) if (--n < 0) @@ -3419,8 +3419,8 @@ rnd_otyp_by_namedesc( (void) memset((genericptr_t) validobjs, 0, sizeof validobjs); if (oclass) { - lo = gb.bases[(uchar) oclass]; - hi = gb.bases[(uchar) oclass + 1] - 1; + lo = svb.bases[(uchar) oclass]; + hi = svb.bases[(uchar) oclass + 1] - 1; } else { lo = MAXOCLASSES; /* STRANGE_OBJECT + 1; */ hi = NUM_OBJECTS - 1; @@ -3521,7 +3521,7 @@ wizterrainwish(struct _readobjnam_data *d) if (!BSTRCMPI(bp, p - 8, "fountain")) { lev->typ = FOUNTAIN; if (oldtyp != FOUNTAIN) - gl.level.flags.nfountains++; + svl.level.flags.nfountains++; lev->looted = d->looted ? F_LOOTED : 0; /* overlays 'flags' */ lev->blessedftn = d->blessed || !strncmpi(bp, "magic ", 6); pline("A %sfountain.", lev->blessedftn ? "magic " : ""); @@ -3534,7 +3534,7 @@ wizterrainwish(struct _readobjnam_data *d) } else if (!BSTRCMPI(bp, p - 4, "sink")) { lev->typ = SINK; if (oldtyp != SINK) - gl.level.flags.nsinks++; + svl.level.flags.nsinks++; lev->looted = d->looted ? (S_LPUDDING | S_LDWASHER | S_LRING) : 0; pline("A sink."); madeterrain = TRUE; @@ -3568,7 +3568,7 @@ wizterrainwish(struct _readobjnam_data *d) } else { dbterrainmesg("Moat", x, y); } - water_damage_chain(gl.level.objects[x][y], TRUE); + water_damage_chain(svl.level.objects[x][y], TRUE); madeterrain = TRUE; /* also matches "molten lava" */ @@ -3592,7 +3592,7 @@ wizterrainwish(struct _readobjnam_data *d) } else { dbterrainmesg("Lava", x, y); } - fire_damage_chain(gl.level.objects[x][y], TRUE, TRUE, x, y); + fire_damage_chain(svl.level.objects[x][y], TRUE, TRUE, x, y); madeterrain = TRUE; } else if (!BSTRCMPI(bp, p - 3, "ice")) { if (!is_dbridge) { @@ -3890,7 +3890,7 @@ readobjnam_init(char *bp, struct _readobjnam_data *d) d->bp = d->origbp = bp; d->p = (char *) 0; d->name = (const char *) 0; - d->ftype = gc.context.current_fruit; + d->ftype = svc.context.current_fruit; (void) memset(d->globbuf, '\0', sizeof d->globbuf); (void) memset(d->fruitbuf, '\0', sizeof d->fruitbuf); } @@ -4651,7 +4651,7 @@ readobjnam_postparse3(struct _readobjnam_data *d) /* check real names of gems first */ if (!d->oclass && d->actualn) { - for (i = gb.bases[GEM_CLASS]; i <= LAST_REAL_GEM; i++) { + for (i = svb.bases[GEM_CLASS]; i <= LAST_REAL_GEM; i++) { const char *zn; if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(d->actualn, zn)) { @@ -4894,7 +4894,7 @@ readobjnam(char *bp, struct obj *no_wish) * Disallow such topology tweaks for WIZKIT startup wishes. */ wiztrap: - if (wizard && !gp.program_state.wizkit_wishing && !d.oclass) { + if (wizard && !svp.program_state.wizkit_wishing && !d.oclass) { /* [inline code moved to separate routine to unclutter readobjnam] */ if ((d.otmp = wizterrainwish(&d)) != 0) return d.otmp; @@ -4982,7 +4982,7 @@ readobjnam(char *bp, struct obj *no_wish) if (rn1cnt > 6 - d.gsize) rn1cnt = 6 - d.gsize; if (d.cnt > rn1cnt - && (!wizard || gp.program_state.wizkit_wishing + && (!wizard || svp.program_state.wizkit_wishing || y_n("Override glob weight limit?") != 'y')) d.cnt = rn1cnt; d.otmp->owt *= (unsigned) d.cnt; @@ -5116,7 +5116,7 @@ readobjnam(char *bp, struct obj *no_wish) corpses and tins, switch to their corresponding human form; for figurines, override the can't-be-human restriction instead */ if (d.typ != FIGURINE && is_were(&mons[d.mntmp]) - && (gm.mvitals[d.mntmp].mvflags & G_NOCORPSE) != 0 + && (svm.mvitals[d.mntmp].mvflags & G_NOCORPSE) != 0 && (humanwere = counter_were(d.mntmp)) != NON_PM) d.mntmp = humanwere; @@ -5125,14 +5125,14 @@ readobjnam(char *bp, struct obj *no_wish) if (dead_species(d.mntmp, FALSE)) { d.otmp->corpsenm = NON_PM; /* it's empty */ } else if ((!(mons[d.mntmp].geno & G_UNIQ) || wizard) - && !(gm.mvitals[d.mntmp].mvflags & G_NOCORPSE) + && !(svm.mvitals[d.mntmp].mvflags & G_NOCORPSE) && mons[d.mntmp].cnutrit != 0) { d.otmp->corpsenm = d.mntmp; } break; case CORPSE: if ((!(mons[d.mntmp].geno & G_UNIQ) || wizard) - && !(gm.mvitals[d.mntmp].mvflags & G_NOCORPSE)) { + && !(svm.mvitals[d.mntmp].mvflags & G_NOCORPSE)) { if (mons[d.mntmp].msound == MS_GUARDIAN) d.mntmp = genus(d.mntmp, 1); set_corpsenm(d.otmp, d.mntmp); diff --git a/src/options.c b/src/options.c index 0c05ae9ad..73c87703d 100644 --- a/src/options.c +++ b/src/options.c @@ -578,7 +578,7 @@ parseoptions( } /* allow optfn's to test whether they were called from parseoptions() */ - gp.program_state.in_parseoptions++; + svp.program_state.in_parseoptions++; if (got_match && matchidx >= 0) { duplicate = duplicate_opt_detection(matchidx); @@ -604,8 +604,8 @@ parseoptions( } } - if (gp.program_state.in_parseoptions > 0) - gp.program_state.in_parseoptions--; + if (svp.program_state.in_parseoptions > 0) + svp.program_state.in_parseoptions--; #if 0 /* This specialization shouldn't be needed any longer because each of @@ -1695,7 +1695,7 @@ optfn_fruit( f = fruit_from_name(op, FALSE, &fnum); if (!f) { if (!flags.made_fruit) - forig = fruit_from_name(gp.pl_fruit, FALSE, (int *) 0); + forig = fruit_from_name(svp.pl_fruit, FALSE, (int *) 0); if (!forig && fnum >= 100) { config_error_add( @@ -1705,19 +1705,19 @@ optfn_fruit( } } goodfruit: - nmcpy(gp.pl_fruit, op, PL_FSIZ); - sanitize_name(gp.pl_fruit); + nmcpy(svp.pl_fruit, op, PL_FSIZ); + sanitize_name(svp.pl_fruit); /* OBJ_NAME(objects[SLIME_MOLD]) won't work for this after initialization; it gets changed to generic "fruit" */ - if (!*gp.pl_fruit) - nmcpy(gp.pl_fruit, "slime mold", PL_FSIZ); + if (!*svp.pl_fruit) + nmcpy(svp.pl_fruit, "slime mold", PL_FSIZ); if (!go.opt_initial) { /* if 'forig' is nonNull, we replace it rather than add a new fruit; it can only be nonNull if no fruits have been created since the previous name was put in place */ - (void) fruitadd(gp.pl_fruit, forig); + (void) fruitadd(svp.pl_fruit, forig); if (give_opt_msg) - pline("Fruit is now \"%s\".", gp.pl_fruit); + pline("Fruit is now \"%s\".", svp.pl_fruit); } /* If initial, then initoptions is allowed to do it instead * of here (initoptions always has to do it even if there's @@ -1727,7 +1727,7 @@ optfn_fruit( return optn_ok; } if (req == get_val || req == get_cnf_val) { - Sprintf(opts, "%s", gp.pl_fruit); + Sprintf(opts, "%s", svp.pl_fruit); return optn_ok; } return optn_ok; @@ -2446,13 +2446,13 @@ optfn_name( if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE)) != empty_optstr) { - nmcpy(gp.plname, op, PL_NSIZ); + nmcpy(svp.plname, op, PL_NSIZ); } else return optn_err; return optn_ok; } if (req == get_val || req == get_cnf_val) { - Sprintf(opts, "%s", gp.plname); + Sprintf(opts, "%s", svp.plname); return optn_ok; } return optn_ok; @@ -3491,7 +3491,7 @@ optfn_role( config_error_add("Unknown %s '%s'", allopt[optidx].name, op); return optn_err; } - nmcpy(gp.pl_character, op, PL_NSIZ); /* Backwards compat */ + nmcpy(svp.pl_character, op, PL_NSIZ); /* Backwards compat */ saveoptstr(optidx, rolestring(flags.initrole, roles, name.m)); } return optn_ok; @@ -7080,7 +7080,7 @@ initoptions_init(void) /* since this is done before init_objects(), do partial init here */ objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD; - nmcpy(gp.pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ); + nmcpy(svp.pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ); } /* @@ -7167,7 +7167,7 @@ initoptions_finish(void) free((genericptr_t) gc.cmdline_rcfile), gc.cmdline_rcfile = 0; /*[end of nethackrc handling]*/ - (void) fruitadd(gp.pl_fruit, (struct fruit *) 0); + (void) fruitadd(svp.pl_fruit, (struct fruit *) 0); /* * Remove "slime mold" from list of object names. This will * prevent it from being wished unless it's actually present @@ -7975,7 +7975,7 @@ fruitadd(char *str, struct fruit *replace_fruit) struct fruit *f; int highest_fruit_id = 0, globpfx; char buf[PL_FSIZ], altname[PL_FSIZ]; - boolean user_specified = (str == gp.pl_fruit); + boolean user_specified = (str == svp.pl_fruit); /* if not user-specified, then it's a fruit name for a fruit on * a bones level or from orctown raider's loot... */ @@ -7991,21 +7991,21 @@ fruitadd(char *str, struct fruit *replace_fruit) they already received it in their original game; str==pl_fruit but makesingular() creates a copy so we need to copy that back into pl_fruit */ - nmcpy(gp.pl_fruit, makesingular(str), PL_FSIZ); + nmcpy(svp.pl_fruit, makesingular(str), PL_FSIZ); /* disallow naming after other foods (since it'd be impossible * to tell the difference); globs might have a size prefix which * needs to be skipped in order to match the object type name */ - globpfx = (!strncmp(gp.pl_fruit, "small ", 6) - || !strncmp(gp.pl_fruit, "large ", 6)) ? 6 - : (!strncmp(gp.pl_fruit, "medium ", 7)) ? 7 - : (!strncmp(gp.pl_fruit, "very large ", 11)) ? 11 + globpfx = (!strncmp(svp.pl_fruit, "small ", 6) + || !strncmp(svp.pl_fruit, "large ", 6)) ? 6 + : (!strncmp(svp.pl_fruit, "medium ", 7)) ? 7 + : (!strncmp(svp.pl_fruit, "very large ", 11)) ? 11 : 0; - for (i = gb.bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) { - if (!strcmp(OBJ_NAME(objects[i]), gp.pl_fruit) + for (i = svb.bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) { + if (!strcmp(OBJ_NAME(objects[i]), svp.pl_fruit) || (globpfx > 0 - && !strcmp(OBJ_NAME(objects[i]), &gp.pl_fruit[globpfx]))) { + && !strcmp(OBJ_NAME(objects[i]), &svp.pl_fruit[globpfx]))) { found = TRUE; break; } @@ -8013,7 +8013,7 @@ fruitadd(char *str, struct fruit *replace_fruit) if (!found) { char *c; - for (c = gp.pl_fruit; *c >= '0' && *c <= '9'; c++) + for (c = svp.pl_fruit; *c >= '0' && *c <= '9'; c++) continue; if (!*c || isspace((uchar) *c)) numeric = TRUE; @@ -8022,22 +8022,22 @@ fruitadd(char *str, struct fruit *replace_fruit) /* these checks for applying food attributes to actual items are case sensitive; "glob of foo" is caught by 'found' if 'foo' is a valid glob; when not valid, allow it as-is */ - || !strncmp(gp.pl_fruit, "cursed ", 7) - || !strncmp(gp.pl_fruit, "uncursed ", 9) - || !strncmp(gp.pl_fruit, "blessed ", 8) - || !strncmp(gp.pl_fruit, "partly eaten ", 13) - || (!strncmp(gp.pl_fruit, "tin of ", 7) - && (!strcmp(gp.pl_fruit + 7, "spinach") - || ismnum(name_to_mon(gp.pl_fruit + 7, (int *) 0)))) - || !strcmp(gp.pl_fruit, "empty tin") - || (!strcmp(gp.pl_fruit, "glob") - || (globpfx > 0 && !strcmp("glob", &gp.pl_fruit[globpfx]))) - || ((str_end_is(gp.pl_fruit, " corpse") - || str_end_is(gp.pl_fruit, " egg")) - && ismnum(name_to_mon(gp.pl_fruit, (int *) 0)))) { - Strcpy(buf, gp.pl_fruit); - Strcpy(gp.pl_fruit, "candied "); - nmcpy(gp.pl_fruit + 8, buf, PL_FSIZ - 8); + || !strncmp(svp.pl_fruit, "cursed ", 7) + || !strncmp(svp.pl_fruit, "uncursed ", 9) + || !strncmp(svp.pl_fruit, "blessed ", 8) + || !strncmp(svp.pl_fruit, "partly eaten ", 13) + || (!strncmp(svp.pl_fruit, "tin of ", 7) + && (!strcmp(svp.pl_fruit + 7, "spinach") + || ismnum(name_to_mon(svp.pl_fruit + 7, (int *) 0)))) + || !strcmp(svp.pl_fruit, "empty tin") + || (!strcmp(svp.pl_fruit, "glob") + || (globpfx > 0 && !strcmp("glob", &svp.pl_fruit[globpfx]))) + || ((str_end_is(svp.pl_fruit, " corpse") + || str_end_is(svp.pl_fruit, " egg")) + && ismnum(name_to_mon(svp.pl_fruit, (int *) 0)))) { + Strcpy(buf, svp.pl_fruit); + Strcpy(svp.pl_fruit, "candied "); + nmcpy(svp.pl_fruit + 8, buf, PL_FSIZ - 8); } *altname = '\0'; /* This flag indicates that a fruit has been made since the @@ -8052,7 +8052,7 @@ fruitadd(char *str, struct fruit *replace_fruit) /* replace_fruit is already part of the fruit chain; update it in place rather than looking it up again */ f = replace_fruit; - copynchars(f->fname, gp.pl_fruit, PL_FSIZ - 1); + copynchars(f->fname, svp.pl_fruit, PL_FSIZ - 1); goto nonew; } } else { @@ -8083,7 +8083,7 @@ fruitadd(char *str, struct fruit *replace_fruit) gf.ffruit = f; nonew: if (user_specified) - gc.context.current_fruit = f->fid; + svc.context.current_fruit = f->fid; return f->fid; } @@ -9885,7 +9885,7 @@ set_playmode(void) { if (wizard) { if (authorize_wizard_mode()) - gp.plnamelen = (int) strlen(strcpy(gp.plname, "wizard")); + gp.plnamelen = (int) strlen(strcpy(svp.plname, "wizard")); else wizard = FALSE; /* not allowed or not available */ /* try explore mode if we didn't make it into wizard mode */ diff --git a/src/pager.c b/src/pager.c index 05078f7a4..96dab253b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -115,7 +115,7 @@ self_lookat(char *outbuf) Sprintf(outbuf, "%s%s%s called %s", /* being blinded may hide invisibility from self */ (Invis && (senseself() || !Blind)) ? "invisible " : "", race, - pmname(&mons[u.umonnum], Ugender), gp.plname); + pmname(&mons[u.umonnum], Ugender), svp.plname); if (u.usteed) Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); if (u.uundetected || (Upolyd && U_AP_TYPE)) @@ -192,7 +192,7 @@ mhidden_description( show_altmon = (mhid_flags & MHID_ALTMON) != 0; boolean fakeobj, isyou = (mon == &gy.youmonst); coordxy x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my; - int glyph = (gl.level.flags.hero_memory && !isyou) ? levl[x][y].glyph + int glyph = (svl.level.flags.hero_memory && !isyou) ? levl[x][y].glyph : glyph_at(x, y); *outbuf = '\0'; @@ -265,7 +265,7 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) *obj_p = (struct obj *) 0; /* TODO: check inside containers in case glyph came from detection */ if ((otmp = sobj_at(glyphotyp, x, y)) == 0) - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) if (otmp->ox == x && otmp->oy == y && otmp->otyp == glyphotyp) break; @@ -286,10 +286,10 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) if (otmp->oclass == COIN_CLASS) otmp->quan = 2L; /* to force pluralization */ else if (otmp->otyp == SLIME_MOLD) - otmp->spe = gc.context.current_fruit; /* give it a type */ + otmp->spe = svc.context.current_fruit; /* give it a type */ if (mtmp && has_mcorpsenm(mtmp)) { /* mimic as corpse/statue */ if (otmp->otyp == SLIME_MOLD) - /* override gc.context.current_fruit to avoid + /* override svc.context.current_fruit to avoid look, use 'O' to make new named fruit, look again giving different results when current_fruit changes */ otmp->spe = MCORPSENM(mtmp); @@ -474,8 +474,8 @@ look_at_monster( if (Hallucination) { Strcat(monbuf, "paranoid delusion"); } else { - unsigned long mW = (gc.context.warntype.obj - | gc.context.warntype.polyd), + unsigned long mW = (svc.context.warntype.obj + | svc.context.warntype.polyd), m2 = mtmp->data->mflags2; const char *whom = ((mW & M2_HUMAN & m2) ? "human" : (mW & M2_ELF & m2) ? "elf" @@ -507,7 +507,7 @@ waterbody_name(coordxy x, coordxy y) { static char pooltype[40]; schar ltyp; - boolean hallucinate = Hallucination && !gp.program_state.gameover; + boolean hallucinate = Hallucination && !svp.program_state.gameover; if (!isok(x, y)) return "drink"; /* should never happen */ @@ -1203,7 +1203,7 @@ do_screen_description( skipped_venom = 0, found = 0; /* count of matching syms found */ boolean hit_trap, need_to_look = FALSE, submerged = (Underwater && !Is_waterlevel(&u.uz)), - hallucinate = (Hallucination && !gp.program_state.gameover); + hallucinate = (Hallucination && !svp.program_state.gameover); const char *x_str; nhsym tmpsym; glyph_info glyphinfo = nul_glyphinfo; @@ -2072,7 +2072,7 @@ look_engrs(boolean nearby) if (!e) continue; glyph = glyph_at(x, y); - sym = ((levl[x][y].typ == GRAVE || gl.lastseentyp[x][y] == GRAVE) + sym = ((levl[x][y].typ == GRAVE || svl.lastseentyp[x][y] == GRAVE) ? S_grave : (levl[x][y].typ == CORR) ? S_engrcorr : S_engroom); diff --git a/src/pickup.c b/src/pickup.c index c228d51b7..4b88e67c6 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -312,7 +312,7 @@ force_decor(boolean via_probing) iflags.prev_decor = STONE; (void) describe_decor(); gd.decor_fumble_override = gd.decor_levitate_override = FALSE; - gl.lastseentyp[u.ux][u.uy] = levl[u.ux][u.uy].typ; + svl.lastseentyp[u.ux][u.uy] = levl[u.ux][u.uy].typ; } void @@ -421,14 +421,14 @@ check_here(boolean picked_some) } /* count the objects here */ - for (obj = gl.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) { + for (obj = svl.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) { if (obj != uchain) ct++; } /* If there are objects here, take a look. */ if (ct) { - if (gc.context.run) + if (svc.context.run) nomul(0); flush_screen(1); (void) look_here(ct, lhflags); @@ -681,7 +681,7 @@ pickup(int what) /* should be a long */ struct trap *t; /* no auto-pick if no-pick move, nothing there, or in a pool */ - if (autopickup && (gc.context.nopick || !OBJ_AT(u.ux, u.uy) + if (autopickup && (svc.context.nopick || !OBJ_AT(u.ux, u.uy) || (is_pool(u.ux, u.uy) && !Underwater) || is_lava(u.ux, u.uy))) { if (flags.mention_decor) @@ -693,16 +693,16 @@ pickup(int what) /* should be a long */ t = t_at(u.ux, u.uy); if (!can_reach_floor(t && is_pit(t->ttyp))) { (void) describe_decor(); /* even when !flags.mention_decor */ - if ((gm.multi && !gc.context.run) || (autopickup && !flags.pickup) + if ((gm.multi && !svc.context.run) || (autopickup && !flags.pickup) || (t && (uteetering_at_seen_pit(t) || uescaped_shaft(t)))) read_engr_at(u.ux, u.uy); return 0; } - /* multi && !gc.context.run means they are in the middle of some other + /* multi && !svc.context.run means they are in the middle of some other * action, or possibly paralyzed, sleeping, etc.... and they just * teleported onto the object. They shouldn't pick it up. */ - if ((gm.multi && !gc.context.run) + if ((gm.multi && !svc.context.run) || (autopickup && !flags.pickup) || notake(gy.youmonst.data)) { check_here(FALSE); @@ -713,14 +713,14 @@ pickup(int what) /* should be a long */ } /* if there's anything here, stop running */ - if (OBJ_AT(u.ux, u.uy) && gc.context.run && gc.context.run != 8 - && !gc.context.nopick) + if (OBJ_AT(u.ux, u.uy) && svc.context.run && svc.context.run != 8 + && !svc.context.nopick) nomul(0); } add_valid_menu_class(0); /* reset */ if (!u.uswallow) { - objchain_p = &gl.level.objects[u.ux][u.uy]; + objchain_p = &svl.level.objects[u.ux][u.uy]; traverse_how = BY_NEXTHERE; } else { objchain_p = &u.ustuck->minvent; @@ -2005,7 +2005,7 @@ container_at(coordxy x, coordxy y, boolean countem) struct obj *cobj, *nobj; int container_count = 0; - for (cobj = gl.level.objects[x][y]; cobj; cobj = nobj) { + for (cobj = svl.level.objects[x][y]; cobj; cobj = nobj) { nobj = cobj->nexthere; if (Is_container(cobj)) { container_count++; @@ -2077,7 +2077,7 @@ do_loot_cont( int res = ECMD_OK; #if 0 - if (ccount < 2 && (gl.level.objects[cobj->ox][cobj->oy] == cobj)) + if (ccount < 2 && (svl.level.objects[cobj->ox][cobj->oy] == cobj)) pline("%s locked.", cobj->lknown ? "It is" : "Hmmm, it turns out to be"); else @@ -2105,7 +2105,7 @@ do_loot_cont( res = ECMD_TIME; /* attempting to untrap or unlock might trigger a trap which destroys 'cobj'; inform caller if that happens */ - for (otmp = gl.level.objects[ox][oy]; otmp; + for (otmp = svl.level.objects[ox][oy]; otmp; otmp = otmp->nexthere) if (otmp == cobj) break; @@ -2223,7 +2223,7 @@ doloot_core(void) win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - for (cobj = gl.level.objects[cc.x][cc.y]; cobj; + for (cobj = svl.level.objects[cc.x][cc.y]; cobj; cobj = cobj->nexthere) if (Is_container(cobj)) { any.a_obj = cobj; @@ -2249,7 +2249,7 @@ doloot_core(void) if (n != 0) c = 'y'; } else { - for (cobj = gl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { + for (cobj = svl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { nobj = cobj->nexthere; if (Is_container(cobj)) { @@ -2619,7 +2619,7 @@ in_container(struct obj *obj) } } if (Icebox && !age_is_relative(obj)) { - obj->age = gm.moves - obj->age; /* actual age */ + obj->age = svm.moves - obj->age; /* actual age */ /* stop any corpse timeouts when frozen */ if (obj->otyp == CORPSE) { if (obj->timed) { @@ -2758,7 +2758,7 @@ void removed_from_icebox(struct obj *obj) { if (!age_is_relative(obj)) { - obj->age = gm.moves - obj->age; /* actual age */ + obj->age = svm.moves - obj->age; /* actual age */ if (obj->otyp == CORPSE) { struct monst *m = get_mtraits(obj, FALSE); boolean iceT = m ? (m->data == &mons[PM_ICE_TROLL]) @@ -2847,7 +2847,7 @@ observe_quantum_cat(struct obj *box, boolean makecat, boolean givemsg) /* set_corpsenm() will start the rot timer that was removed when makemon() created SchroedingersBox; start it from now rather than from when this special corpse got created */ - deadcat->age = gm.moves; + deadcat->age = svm.moves; set_corpsenm(deadcat, PM_HOUSECAT); deadcat = oname(deadcat, sc, ONAME_NO_FLAGS); } @@ -3476,7 +3476,7 @@ choose_tip_container_menu(void) win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - for (otmp = gl.level.objects[u.ux][u.uy], i = 0; otmp; + for (otmp = svl.level.objects[u.ux][u.uy], i = 0; otmp; otmp = otmp->nexthere) if (Is_container(otmp)) { ++i; @@ -3560,7 +3560,7 @@ dotip(void) return res; /* else pick-from-gi.invent below */ } else { - for (cobj = gl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { + for (cobj = svl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { nobj = cobj->nexthere; if (!Is_container(cobj)) continue; diff --git a/src/pline.c b/src/pline.c index 7e22c1a85..e837780dc 100644 --- a/src/pline.c +++ b/src/pline.c @@ -157,10 +157,10 @@ vpline(const char *line, va_list the_args) if (!line || !*line) return; #ifdef HANGUPHANDLING - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) return; #endif - if (gp.program_state.wizkit_wishing) + if (svp.program_state.wizkit_wishing) return; if (a11y.accessiblemsg && isok(a11y.msg_loc.x,a11y.msg_loc.y)) { @@ -509,7 +509,7 @@ livelog_printf(long ll_type, const char *line, ...) (void) vsnprintf(gamelogbuf, sizeof gamelogbuf, line, the_args); va_end(the_args); - gamelog_add(ll_type, gm.moves, gamelogbuf); + gamelog_add(ll_type, svm.moves, gamelogbuf); strNsubst(gamelogbuf, "\t", "_", 0); livelog_add(ll_type, gamelogbuf); } @@ -542,7 +542,7 @@ raw_printf(const char *line, ...) va_start(the_args, line); vraw_printf(line, the_args); va_end(the_args); - if (!gp.program_state.beyond_savefile_load) + if (!svp.program_state.beyond_savefile_load) ge.early_raw_messages++; } @@ -567,7 +567,7 @@ vraw_printf(const char *line, va_list the_args) #if defined(MSGHANDLER) execplinehandler(line); #endif - if (!gp.program_state.beyond_savefile_load) + if (!svp.program_state.beyond_savefile_load) ge.early_raw_messages++; } @@ -579,10 +579,10 @@ impossible(const char *s, ...) char pbuf2[BUFSZ]; va_start(the_args, s); - if (gp.program_state.in_impossible) + if (svp.program_state.in_impossible) panic("impossible called impossible"); - gp.program_state.in_impossible = 1; + svp.program_state.in_impossible = 1; (void) vsnprintf(pbuf, sizeof pbuf, s, the_args); va_end(the_args); pbuf[BUFSZ - 1] = '\0'; /* sanity */ @@ -594,14 +594,14 @@ impossible(const char *s, ...) pline("%s", pbuf); gp.pline_flags = 0; - if (gp.program_state.in_sanity_check) { + if (svp.program_state.in_sanity_check) { /* skip rest of multi-line feedback */ - gp.program_state.in_impossible = 0; + svp.program_state.in_impossible = 0; return; } Strcpy(pbuf2, "Program in disorder!"); - if (gp.program_state.something_worth_saving) + if (svp.program_state.something_worth_saving) Strcat(pbuf2, " (Saving and reloading may fix this problem.)"); pline("%s", pbuf2); pline("Please report these messages to %s.", DEVTEAM_EMAIL); @@ -621,7 +621,7 @@ impossible(const char *s, ...) } #endif - gp.program_state.in_impossible = 0; + svp.program_state.in_impossible = 0; } RESTORE_WARNING_FORMAT_NONLITERAL diff --git a/src/polyself.c b/src/polyself.c index 806192693..2cc1807f0 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -109,7 +109,7 @@ set_uasmon(void) which won't be known during the restore process: but BFlying and BStealth should be set correctly already in that case, so there's nothing to do */ - if (!gp.program_state.restoring) + if (!svp.program_state.restoring) float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ polysense(); @@ -228,11 +228,11 @@ polyman(const char *fmt, const char *arg) struct kinfo *kptr = find_delayed_killer(POLYMORPH); if (kptr != (struct kinfo *) 0 && kptr->name[0]) { - gk.killer.format = kptr->format; - Strcpy(gk.killer.name, kptr->name); + svk.killer.format = kptr->format; + Strcpy(svk.killer.name, kptr->name); } else { - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "self-genocide"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "self-genocide"); } dealloc_killer(kptr); done(GENOCIDED); @@ -275,9 +275,9 @@ change_sex(void) u.mfemale = !u.mfemale; max_rank_sz(); /* [this appears to be superfluous] */ if ((Upolyd ? u.mfemale : flags.female) && gu.urole.name.f) - Strcpy(gp.pl_character, gu.urole.name.f); + Strcpy(svp.pl_character, gu.urole.name.f); else - Strcpy(gp.pl_character, gu.urole.name.m); + Strcpy(svp.pl_character, gu.urole.name.m); if (!Upolyd) { u.umonnum = u.umonster; } else if (u.umonnum == PM_AMOROUS_DEMON) { @@ -413,8 +413,8 @@ newman(void) dead: /* we come directly here if experience level went to 0 or less */ urgent_pline( "Your new form doesn't seem healthy enough to survive."); - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "unsuccessful polymorph"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "unsuccessful polymorph"); done(DIED); /* must have been life-saved to get here */ newuhs(FALSE); @@ -617,7 +617,7 @@ polyself(int psflags) if (draconian) { do_merge: mntmp = armor_to_dragon(uarm->otyp); - if (!(gm.mvitals[mntmp].mvflags & G_GENOD)) { + if (!(svm.mvitals[mntmp].mvflags & G_GENOD)) { unsigned was_lit = uarm->lamplit; int arm_light = artifact_light(uarm) ? arti_light_radius(uarm) : 0; @@ -729,7 +729,7 @@ polymon(int mntmp) was_hiding_under = u.uundetected && hides_under(gy.youmonst.data); int mlvl, newMaxStr; - if (gm.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ + if (svm.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ You_feel("rather %s-ish.", pmname(&mons[mntmp], flags.female ? FEMALE : MALE)); exercise(A_WIS, TRUE); @@ -1346,8 +1346,8 @@ rehumanize(void) /* You can't revert back while unchanging */ if (Unchanging) { if (u.mh < 1) { - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "killed while stuck in creature form"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "killed while stuck in creature form"); done(DIED); /* can get to here if declining to die in explore or wizard mode; since we're wearing an amulet of unchanging we can't @@ -1373,9 +1373,9 @@ rehumanize(void) /* can only happen if some bit of code reduces u.uhp instead of u.mh while poly'd */ Your("old form was not healthy enough to survive."); - Sprintf(gk.killer.name, "reverting to unhealthy %s form", + Sprintf(svk.killer.name, "reverting to unhealthy %s form", gu.urace.adj); - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; done(DIED); } nomul(0); @@ -1732,8 +1732,8 @@ dogaze(void) l_monnam(mtmp)); /* as if gazing at a sleeping anything is fruitful... */ urgent_pline("You turn to stone..."); - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "deliberately meeting Medusa's gaze"); done(STONING); } @@ -1781,7 +1781,7 @@ dohide(void) } if (hides_under(gy.youmonst.data)) { long ct = 0L; - struct obj *otmp, *otop = gl.level.objects[u.ux][u.uy]; + struct obj *otmp, *otop = svl.level.objects[u.ux][u.uy]; if (!otop) { There("is nothing to hide under here."); @@ -2210,9 +2210,9 @@ polysense(void) { short warnidx = NON_PM; - gc.context.warntype.speciesidx = NON_PM; - gc.context.warntype.species = 0; - gc.context.warntype.polyd = 0; + svc.context.warntype.speciesidx = NON_PM; + svc.context.warntype.species = 0; + svc.context.warntype.polyd = 0; HWarn_of_mon &= ~FROMRACE; switch (u.umonnum) { @@ -2222,13 +2222,13 @@ polysense(void) break; case PM_VAMPIRE: case PM_VAMPIRE_LEADER: - gc.context.warntype.polyd = M2_HUMAN | M2_ELF; + svc.context.warntype.polyd = M2_HUMAN | M2_ELF; HWarn_of_mon |= FROMRACE; return; } if (ismnum(warnidx)) { - gc.context.warntype.speciesidx = warnidx; - gc.context.warntype.species = &mons[warnidx]; + svc.context.warntype.speciesidx = warnidx; + svc.context.warntype.species = &mons[warnidx]; HWarn_of_mon |= FROMRACE; } } @@ -2237,8 +2237,8 @@ polysense(void) boolean ugenocided(void) { - return ((gm.mvitals[gu.urole.mnum].mvflags & G_GENOD) - || (gm.mvitals[gu.urace.mnum].mvflags & G_GENOD)); + return ((svm.mvitals[gu.urole.mnum].mvflags & G_GENOD) + || (svm.mvitals[gu.urace.mnum].mvflags & G_GENOD)); } /* how hero feels "inside" after self-genocide of role or race */ diff --git a/src/potion.c b/src/potion.c index 5274e904d..a51be8127 100644 --- a/src/potion.c +++ b/src/potion.c @@ -597,14 +597,14 @@ dodrink(void) otmp->in_use = TRUE; /* you've opened the stopper */ if (objdescr_is(otmp, "milky") - && !(gm.mvitals[PM_GHOST].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(gm.mvitals[PM_GHOST].born))) { + && !(svm.mvitals[PM_GHOST].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(svm.mvitals[PM_GHOST].born))) { ghost_from_bottle(); useup(otmp); return ECMD_TIME; } else if (objdescr_is(otmp, "smoky") - && !(gm.mvitals[PM_DJINNI].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(gm.mvitals[PM_DJINNI].born))) { + && !(svm.mvitals[PM_DJINNI].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(svm.mvitals[PM_DJINNI].born))) { djinni_from_bottle(otmp); useup(otmp); return ECMD_TIME; @@ -1897,7 +1897,7 @@ potionhit(struct monst *mon, struct obj *obj, int how) when inside a tended shop */ if (!shkp) /* if shkp was killed, unpaid ought to cleared already */ obj->unpaid = 0; - else if (gc.context.mon_moving) /* obj thrown by monster */ + else if (svc.context.mon_moving) /* obj thrown by monster */ subfrombill(obj, shkp); else /* obj thrown by hero */ (void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful, diff --git a/src/pray.c b/src/pray.c index 71aed4e26..605b547bf 100644 --- a/src/pray.c +++ b/src/pray.c @@ -690,8 +690,8 @@ fry_by_god(aligntyp resp_god, boolean via_disintegration) { You("%s!", !via_disintegration ? "fry to a crisp" : "disintegrate into a pile of dust"); - gk.killer.format = KILLED_BY; - Sprintf(gk.killer.name, "the wrath of %s", align_gname(resp_god)); + svk.killer.format = KILLED_BY; + Sprintf(svk.killer.name, "the wrath of %s", align_gname(resp_god)); done(DIED); } @@ -1011,7 +1011,7 @@ give_spell(void) || carrying(MAGIC_MARKER)) break; } - otmp->otyp = rnd_class(gb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); + otmp->otyp = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); } /* * 25% chance of learning the spell directly instead of @@ -1220,7 +1220,7 @@ pleased(aligntyp g_align) } else if (u.uevent.uheard_tune < 2) { Soundeffect(se_divine_music, 50); You_hear("a divine music..."); - pline("It sounds like: \"%s\".", gt.tune); + pline("It sounds like: \"%s\".", svt.tune); u.uevent.uheard_tune++; record_achievement(ACH_TUNE); break; @@ -1350,8 +1350,8 @@ pleased(aligntyp g_align) of nutrition will be required. The increase gets throttled if it ever reaches 32K so that configurations using 16-bit ints are still viable. */ - if (gm.moves > 100000L) { - long incr = (gm.moves - 100000L) / 100L, + if (svm.moves > 100000L) { + long incr = (svm.moves - 100000L) / 100L, largest_ublesscnt_incr = (long) (LARGEST_INT - u.ublesscnt); if (incr > largest_ublesscnt_incr) @@ -1372,7 +1372,7 @@ water_prayer(boolean bless_water) long changed = 0; boolean other = FALSE, bc_known = !(Blind || Hallucination); - for (otmp = gl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) { + for (otmp = svl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) { /* turn water into (un)holy water */ if (otmp->otyp == POT_WATER && (bless_water ? !otmp->blessed : !otmp->cursed)) { @@ -1531,8 +1531,8 @@ offer_real_amulet(struct obj *otmp, aligntyp altaralign) /*[apparently shrug/snarl can be sensed without being seen]*/ pline("%s shrugs and retains dominion over %s,", Moloch, u_gname()); pline("then mercilessly snuffs out your life."); - Sprintf(gk.killer.name, "%s indifference", s_suffix(Moloch)); - gk.killer.format = KILLED_BY; + Sprintf(svk.killer.name, "%s indifference", s_suffix(Moloch)); + svk.killer.format = KILLED_BY; done(DIED); /* life-saved (or declined to die in wizard/explore mode) */ pline("%s snarls and tries again...", Moloch); @@ -1871,7 +1871,7 @@ dosacrifice(void) return ECMD_TIME; if (otmp->corpsenm == PM_ACID_BLOB - || (gm.moves <= peek_at_iced_corpse_age(otmp) + 50)) { + || (svm.moves <= peek_at_iced_corpse_age(otmp) + 50)) { value = mons[otmp->corpsenm].difficulty + 1; if (otmp->oeaten) value = eaten_stat(value, otmp); @@ -2096,7 +2096,7 @@ pray_revive(void) { struct obj *otmp; - for (otmp = gl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) if (otmp->otyp == CORPSE && has_omonst(otmp) && OMONST(otmp)->mtame && !OMONST(otmp)->isminion) break; @@ -2586,7 +2586,7 @@ blocked_boulder(int dx, int dy) int nx, ny; long count = 0L; - for (otmp = gl.level.objects[u.ux + dx][u.uy + dy]; otmp; + for (otmp = svl.level.objects[u.ux + dx][u.uy + dy]; otmp; otmp = otmp->nexthere) { if (otmp->otyp == BOULDER) count += otmp->quan; diff --git a/src/priest.c b/src/priest.c index 32ff818e6..d1ab0cdb1 100644 --- a/src/priest.c +++ b/src/priest.c @@ -144,7 +144,7 @@ temple_occupied(char *array) char *ptr; for (ptr = array; *ptr; ptr++) - if (gr.rooms[*ptr - ROOMOFFSET].rtype == TEMPLE) + if (svr.rooms[*ptr - ROOMOFFSET].rtype == TEMPLE) return *ptr; return '\0'; } @@ -244,7 +244,7 @@ priestini( priest = makemon(prim, px, py, MM_EPRI); if (priest) { - EPRI(priest)->shroom = (schar) ((sroom - gr.rooms) + ROOMOFFSET); + EPRI(priest)->shroom = (schar) ((sroom - svr.rooms) + ROOMOFFSET); EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask); EPRI(priest)->shrpos.x = sx; EPRI(priest)->shrpos.y = sy; @@ -365,7 +365,7 @@ priestname( /* same as distant_monnam(), more or less... */ if (do_hallu || !high_priest || reveal_high_priest || !Is_astralevel(&u.uz) - || m_next2u(mon) || gp.program_state.gameover) { + || m_next2u(mon) || svp.program_state.gameover) { Strcat(pname, " of "); Strcat(pname, halu_gname(mon_aligntyp(mon))); } @@ -435,7 +435,7 @@ intemple(int roomno) sanctum = (priest->data == &mons[PM_HIGH_CLERIC] && (Is_sanctum(&u.uz) || In_endgame(&u.uz))); can_speak = !helpless(priest); - if (can_speak && !Deaf && gm.moves >= epri_p->intone_time) { + if (can_speak && !Deaf && svm.moves >= epri_p->intone_time) { unsigned save_priest = priest->ispriest; /* don't reveal the altar's owner upon temple entry in @@ -446,7 +446,7 @@ intemple(int roomno) pline("%s intones:", canseemon(priest) ? Monnam(priest) : "A nearby voice"); priest->ispriest = save_priest; - epri_p->intone_time = gm.moves + (long) d(10, 500); /* ~2505 */ + epri_p->intone_time = svm.moves + (long) d(10, 500); /* ~2505 */ /* make sure that we don't suppress entry message when we've just given its "priest intones" introduction */ epri_p->enter_time = 0L; @@ -464,7 +464,7 @@ intemple(int roomno) /* repeat visit, or attacked priest before entering */ msg1 = "You desecrate this place by your presence!"; } - } else if (gm.moves >= epri_p->enter_time) { + } else if (svm.moves >= epri_p->enter_time) { Sprintf(buf, "Pilgrim, you enter a %s place!", !shrined ? "desecrated" : "sacred"); msg1 = buf; @@ -474,7 +474,7 @@ intemple(int roomno) verbalize1(msg1); if (msg2) verbalize1(msg2); - epri_p->enter_time = gm.moves + (long) d(10, 100); /* ~505 */ + epri_p->enter_time = svm.moves + (long) d(10, 100); /* ~505 */ } if (!sanctum) { if (!shrined || !p_coaligned(priest) @@ -492,9 +492,9 @@ intemple(int roomno) /* give message if we haven't seen it recently or if alignment update has caused it to switch from forbidding to sense-of-peace or vice versa */ - if (gm.moves >= *this_time || *other_time >= *this_time) { + if (svm.moves >= *this_time || *other_time >= *this_time) { You(msg1, msg2); - *this_time = gm.moves + (long) d(10, 20); /* ~55 */ + *this_time = svm.moves + (long) d(10, 20); /* ~55 */ /* avoid being tricked by the RNG: switch might have just happened and previous random threshold could be larger */ if (*this_time <= *other_time) @@ -525,7 +525,7 @@ intemple(int roomno) if (!rn2(5) && (mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NOMSG)) != 0) { - int ngen = gm.mvitals[PM_GHOST].born; + int ngen = svm.mvitals[PM_GHOST].born; if (canspotmon(mtmp)) pline("A%s ghost appears next to you%c", ngen < 5 ? "n enormous" : "", @@ -673,9 +673,9 @@ priest_talk(struct monst *priest) SetVoice(priest, 0, 80, 0); verbalize("Thy selfless generosity is deeply appreciated."); if (money_cnt(gi.invent) < (offer * 2L) && coaligned) { - if (strayed && (gm.moves - u.ucleansed) > 5000L) { + if (strayed && (svm.moves - u.ucleansed) > 5000L) { u.ualign.record = 0; /* cleanse thee */ - u.ucleansed = gm.moves; + u.ucleansed = svm.moves; } else { adjalign(2); } @@ -770,7 +770,7 @@ ghod_hitsu(struct monst *priest) ax = x = EPRI(priest)->shrpos.x; ay = y = EPRI(priest)->shrpos.y; - troom = &gr.rooms[roomno - ROOMOFFSET]; + troom = &svr.rooms[roomno - ROOMOFFSET]; if (u_at(x, y) || !linedup(u.ux, u.uy, x, y, 1)) { if (IS_DOOR(levl[u.ux][u.uy].typ)) { diff --git a/src/quest.c b/src/quest.c index e2c363903..b554a664c 100644 --- a/src/quest.c +++ b/src/quest.c @@ -9,7 +9,7 @@ #include "quest.h" #define Not_firsttime (on_level(&u.uz0, &u.uz)) -#define Qstat(x) (gq.quest_status.x) +#define Qstat(x) (svq.quest_status.x) staticfn void on_start(void); staticfn void on_locate(void); @@ -411,16 +411,16 @@ nemesis_speaks(void) void nemesis_stinks(coordxy mx, coordxy my) { - boolean save_mon_moving = gc.context.mon_moving; + boolean save_mon_moving = svc.context.mon_moving; /* * Some nemeses (determined by caller) release a cloud of noxious * gas when they die. Don't make the hero be responsible for such * a cloud even if hero has just killed nemesis. */ - gc.context.mon_moving = TRUE; + svc.context.mon_moving = TRUE; create_gas_cloud(mx, my, 5, 8); - gc.context.mon_moving = save_mon_moving; + svc.context.mon_moving = save_mon_moving; } staticfn void diff --git a/src/questpgr.c b/src/questpgr.c index bacfbc01d..d7a2ec448 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -114,7 +114,7 @@ find_quest_artifact(unsigned whichchains) qarti = find_qarti(gm.migrating_objs); } if (!qarti && (whichchains & (1 << OBJ_BURIED)) != 0) - qarti = find_qarti(gl.level.buriedobjlist); + qarti = find_qarti(svl.level.buriedobjlist); return qarti; } @@ -217,9 +217,9 @@ qtext_pronoun( : (lwhich == 'i') ? "them" : (lwhich == 'j') ? "their" : "?"; } else { - godgend = (who == 'd') ? gq.quest_status.godgend - : (who == 'l') ? gq.quest_status.ldrgend - : (who == 'n') ? gq.quest_status.nemgend + godgend = (who == 'd') ? svq.quest_status.godgend + : (who == 'l') ? svq.quest_status.ldrgend + : (who == 'n') ? svq.quest_status.nemgend : 2; /* default to neuter */ pnoun = (lwhich == 'h') ? genders[godgend].he : (lwhich == 'i') ? genders[godgend].him @@ -239,7 +239,7 @@ convert_arg(char c) switch (c) { case 'p': - str = gp.plname; + str = svp.plname; break; case 'c': str = (flags.female && gu.urole.name.f) ? gu.urole.name.f @@ -312,7 +312,7 @@ convert_arg(char c) str = Blind ? "sense" : "see"; break; case 'Z': - str = gd.dungeons[0].dname; + str = svd.dungeons[0].dname; break; case '%': str = "%"; @@ -456,7 +456,7 @@ staticfn boolean skip_pager(boolean common UNUSED) { /* WIZKIT: suppress plot feedback if starting with quest artifact */ - if (gp.program_state.wizkit_wishing) + if (svp.program_state.wizkit_wishing) return TRUE; return FALSE; } @@ -637,12 +637,12 @@ qt_montype(void) if (rn2(5)) { qpm = gu.urole.enemy1num; - if (qpm != NON_PM && rn2(5) && !(gm.mvitals[qpm].mvflags & G_GENOD)) + if (qpm != NON_PM && rn2(5) && !(svm.mvitals[qpm].mvflags & G_GENOD)) return &mons[qpm]; return mkclass(gu.urole.enemy1sym, 0); } qpm = gu.urole.enemy2num; - if (qpm != NON_PM && rn2(5) && !(gm.mvitals[qpm].mvflags & G_GENOD)) + if (qpm != NON_PM && rn2(5) && !(svm.mvitals[qpm].mvflags & G_GENOD)) return &mons[qpm]; return mkclass(gu.urole.enemy2sym, 0); } diff --git a/src/read.c b/src/read.c index af36193bb..bb640bd3d 100644 --- a/src/read.c +++ b/src/read.c @@ -1650,7 +1650,7 @@ seffect_light(struct obj **sobjp) } else { int pm = scursed ? PM_BLACK_LIGHT : PM_YELLOW_LIGHT; - if ((gm.mvitals[pm].mvflags & G_GONE)) { + if ((svm.mvitals[pm].mvflags & G_GONE)) { pline("Tiny lights sparkle in the air momentarily."); } else { /* surround with cancelled tame lights which won't explode */ @@ -1730,7 +1730,7 @@ seffect_amnesia(struct obj **sobjp) forget((!sblessed ? ALL_SPELLS : 0)); if (Hallucination) /* Ommmmmm! */ Your("mind releases itself from mundane concerns."); - else if (!strncmpi(gp.plname, "Maud", 4)) + else if (!strncmpi(svp.plname, "Maud", 4)) pline("As your mind turns inward on itself," " you forget everything else."); else if (rn2(2)) @@ -2003,7 +2003,7 @@ seffect_magic_mapping(struct obj **sobjp) int cval; if (is_scroll) { - if (gl.level.flags.nommap) { + if (svl.level.flags.nommap) { Your("mind is filled with crazy lines!"); if (Hallucination) pline("Wow! Modern art."); @@ -2024,7 +2024,7 @@ seffect_magic_mapping(struct obj **sobjp) gk.known = TRUE; } - if (gl.level.flags.nommap) { + if (svl.level.flags.nommap) { Your("%s spins as %s blocks the spell!", body_part(HEAD), something); make_confused(HConfusion + rnd(30), FALSE); @@ -2472,12 +2472,12 @@ litroom( int rx, ry; if (rnum >= 0) { - for (rx = gr.rooms[rnum].lx - 1; rx <= gr.rooms[rnum].hx + 1; rx++) - for (ry = gr.rooms[rnum].ly - 1; - ry <= gr.rooms[rnum].hy + 1; ry++) + for (rx = svr.rooms[rnum].lx - 1; rx <= svr.rooms[rnum].hx + 1; rx++) + for (ry = svr.rooms[rnum].ly - 1; + ry <= svr.rooms[rnum].hy + 1; ry++) set_lit(rx, ry, (genericptr_t) (on ? &is_lit : (char *) 0)); - gr.rooms[rnum].rlit = on; + svr.rooms[rnum].rlit = on; } /* hallways remain dark on the rogue level */ } else if (is_art(obj, ART_SUNSWORD)) { @@ -2577,7 +2577,7 @@ do_class_genocide(void) if (mons[i].mlet == class) { if (!(mons[i].geno & G_GENO)) immunecnt++; - else if (gm.mvitals[i].mvflags & G_GENOD) + else if (svm.mvitals[i].mvflags & G_GENOD) gonecnt++; else goodcnt++; @@ -2618,7 +2618,7 @@ do_class_genocide(void) */ if (Your_Own_Role(i) || Your_Own_Race(i) || ((mons[i].geno & G_GENO) - && !(gm.mvitals[i].mvflags & G_GENOD))) { + && !(svm.mvitals[i].mvflags & G_GENOD))) { /* This check must be first since player monsters might * have G_GENOD or !G_GENO. */ @@ -2632,7 +2632,7 @@ do_class_genocide(void) def_monsyms[class].sym); } - gm.mvitals[i].mvflags |= (G_GENOD | G_NOCORPSE); + svm.mvitals[i].mvflags |= (G_GENOD | G_NOCORPSE); kill_genocided_monsters(); update_inventory(); /* eggs & tins */ pline("Wiped out all %s.", nam); @@ -2665,7 +2665,7 @@ do_class_genocide(void) gameover = TRUE; } } - } else if (gm.mvitals[i].mvflags & G_GENOD) { + } else if (svm.mvitals[i].mvflags & G_GENOD) { if (!gameover) pline("%s are already nonexistent.", upstart(nam)); } else if (!gameover) { @@ -2697,8 +2697,8 @@ do_class_genocide(void) } } if (gameover || u.uhp == -1) { - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "scroll of genocide"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "scroll of genocide"); if (gameover) done(GENOCIDED); } @@ -2774,7 +2774,7 @@ do_genocide( } mndx = name_to_mon(buf, (int *) 0); - if (mndx == NON_PM || (gm.mvitals[mndx].mvflags & G_GENOD)) { + if (mndx == NON_PM || (svm.mvitals[mndx].mvflags & G_GENOD)) { pline("Such creatures %s exist in this world.", (mndx == NON_PM) ? "do not" : "no longer"); continue; @@ -2841,29 +2841,29 @@ do_genocide( livelog_printf(LL_GENOCIDE, "genocided %s", makeplural(buf)); /* setting no-corpse affects wishing and random tin generation */ - gm.mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE); + svm.mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE); pline("Wiped out %s%s.", which, (*which != 'a') ? buf : makeplural(buf)); if (killplayer) { u.uhp = -1; if (how & PLAYER) { - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "genocidal confusion"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "genocidal confusion"); } else if (how & ONTHRONE) { /* player selected while on a throne */ - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "imperious order"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "imperious order"); } else { /* selected player deliberately, not confused */ - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, "scroll of genocide"); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, "scroll of genocide"); } /* Polymorphed characters will die as soon as they're rehumanized. */ /* KMH -- Unchanging prevents rehumanization */ if (Upolyd && ptr != gy.youmonst.data) { - delayed_killer(POLYMORPH, gk.killer.format, gk.killer.name); + delayed_killer(POLYMORPH, svk.killer.format, svk.killer.name); You_feel("%s inside.", udeadinside()); } else done(GENOCIDED); @@ -2876,12 +2876,12 @@ do_genocide( int cnt = 0, census = monster_census(FALSE); if (!(mons[mndx].geno & G_UNIQ) - && !(gm.mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT))) + && !(svm.mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT))) for (i = rn1(3, 4); i > 0; i--) { if (!makemon(ptr, u.ux, u.uy, NO_MINVENT | MM_NOMSG)) break; /* couldn't make one */ ++cnt; - if (gm.mvitals[mndx].mvflags & G_EXTINCT) + if (svm.mvitals[mndx].mvflags & G_EXTINCT) break; /* just made last one */ } if (cnt) { diff --git a/src/region.c b/src/region.c index a3d7b6526..43383ea2f 100644 --- a/src/region.c +++ b/src/region.c @@ -282,7 +282,7 @@ add_region(NhRegion *reg) NhRegion **tmp_reg; int i, j; - if (gm.max_regions <= gn.n_regions) { + if (gm.max_regions <= svn.n_regions) { tmp_reg = gr.regions; gr.regions = (NhRegion **) alloc((gm.max_regions + 10) * sizeof (NhRegion *)); @@ -293,8 +293,8 @@ add_region(NhRegion *reg) } gm.max_regions += 10; } - gr.regions[gn.n_regions] = reg; - gn.n_regions++; + gr.regions[svn.n_regions] = reg; + svn.n_regions++; /* Check for monsters inside the region */ for (i = reg->bounding_box.lx; i <= reg->bounding_box.hx; i++) for (j = reg->bounding_box.ly; j <= reg->bounding_box.hy; j++) { @@ -341,16 +341,16 @@ remove_region(NhRegion *reg) { int i, x, y; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) if (gr.regions[i] == reg) break; - if (i == gn.n_regions) + if (i == svn.n_regions) return; /* remove region before potential newsym() calls, but don't free it yet */ - if (--gn.n_regions != i) - gr.regions[i] = gr.regions[gn.n_regions]; - gr.regions[gn.n_regions] = (NhRegion *) 0; + if (--svn.n_regions != i) + gr.regions[i] = gr.regions[svn.n_regions]; + gr.regions[svn.n_regions] = (NhRegion *) 0; /* Update screen if necessary */ reg->ttl = -2L; /* for visible_region_at */ @@ -386,9 +386,9 @@ clear_regions(void) { int i; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) free_region(gr.regions[i]); - gn.n_regions = 0; + svn.n_regions = 0; if (gm.max_regions > 0) free((genericptr_t) gr.regions); gm.max_regions = 0; @@ -412,7 +412,7 @@ run_regions(void) /* End of life ? */ /* Do it backward because the array will be modified */ - for (i = gn.n_regions - 1; i >= 0; i--) { + for (i = svn.n_regions - 1; i >= 0; i--) { if (gr.regions[i]->ttl == 0L) { if ((f_indx = gr.regions[i]->expire_f) == NO_CALLBACK || (*callbacks[f_indx])(gr.regions[i], (genericptr_t) 0)) @@ -421,7 +421,7 @@ run_regions(void) } /* Process remaining regions */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { /* Make the region age */ if (gr.regions[i]->ttl > 0L) gr.regions[i]->ttl--; @@ -464,7 +464,7 @@ in_out_region(coordxy x, coordxy y) int i, f_indx = 0; /* First check if hero can do the move */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_u) continue; if (inside_region(gr.regions[i], x, y) @@ -478,7 +478,7 @@ in_out_region(coordxy x, coordxy y) } /* Callbacks for the regions hero does leave */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_u) continue; if (hero_inside(gr.regions[i]) @@ -492,7 +492,7 @@ in_out_region(coordxy x, coordxy y) } /* Callbacks for the regions hero does enter */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_u) continue; if (!hero_inside(gr.regions[i]) @@ -517,7 +517,7 @@ m_in_out_region(struct monst *mon, coordxy x, coordxy y) int i, f_indx = 0; /* First check if mon can do the move */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_m == mon->m_id) continue; if (inside_region(gr.regions[i], x, y) @@ -531,7 +531,7 @@ m_in_out_region(struct monst *mon, coordxy x, coordxy y) } /* Callbacks for the regions mon does leave */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_m == mon->m_id) continue; if (mon_in_region(gr.regions[i], mon) @@ -543,7 +543,7 @@ m_in_out_region(struct monst *mon, coordxy x, coordxy y) } /* Callbacks for the regions mon does enter */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (gr.regions[i]->attach_2_m == mon->m_id) continue; if (!mon_in_region(gr.regions[i], mon) @@ -565,7 +565,7 @@ update_player_regions(void) { int i; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) if (!gr.regions[i]->attach_2_u && inside_region(gr.regions[i], u.ux, u.uy)) set_hero_inside(gr.regions[i]); @@ -581,7 +581,7 @@ update_monster_region(struct monst *mon) { int i; - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (inside_region(gr.regions[i], mon->mx, mon->my)) { if (!mon_in_region(gr.regions[i], mon)) add_mon_to_reg(gr.regions[i], mon); @@ -606,7 +606,7 @@ struct monst *monold, *monnew; { int i; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) if (mon_in_region(gr.regions[i], monold)) { remove_mon_from_reg(gr.regions[i], monold); add_mon_to_reg(gr.regions[i], monnew); @@ -621,7 +621,7 @@ remove_mon_from_regions(struct monst *mon) { int i; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) if (mon_in_region(gr.regions[i], mon)) remove_mon_from_reg(gr.regions[i], mon); } @@ -637,7 +637,7 @@ visible_region_at(coordxy x, coordxy y) { int i; - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { if (!gr.regions[i]->visible || gr.regions[i]->ttl == -2L) continue; if (inside_region(gr.regions[i], x, y)) @@ -666,10 +666,10 @@ save_regions(NHFILE *nhfp) goto skip_lots; if (nhfp->structlevel) { /* timestamp */ - bwrite(nhfp->fd, (genericptr_t) &gm.moves, sizeof (gm.moves)); - bwrite(nhfp->fd, (genericptr_t) &gn.n_regions, sizeof (gn.n_regions)); + bwrite(nhfp->fd, (genericptr_t) &svm.moves, sizeof (svm.moves)); + bwrite(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof (svn.n_regions)); } - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { r = gr.regions[i]; if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &r->bounding_box, sizeof (NhRect)); @@ -744,15 +744,15 @@ rest_regions(NHFILE *nhfp) if (ghostly) tmstamp = 0; else - tmstamp = (gm.moves - tmstamp); + tmstamp = (svm.moves - tmstamp); if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &gn.n_regions, sizeof (gn.n_regions)); + mread(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof (svn.n_regions)); - gm.max_regions = gn.n_regions; - if (gn.n_regions > 0) - gr.regions = (NhRegion **) alloc(sizeof (NhRegion *) * gn.n_regions); - for (i = 0; i < gn.n_regions; i++) { + gm.max_regions = svn.n_regions; + if (svn.n_regions > 0) + gr.regions = (NhRegion **) alloc(sizeof (NhRegion *) * svn.n_regions); + for (i = 0; i < svn.n_regions; i++) { r = gr.regions[i] = (NhRegion *) alloc(sizeof (NhRegion)); if (nhfp->structlevel) { mread(nhfp->fd, (genericptr_t) &r->bounding_box, sizeof (NhRect)); @@ -834,7 +834,7 @@ rest_regions(NHFILE *nhfp) } /* remove expired regions, do not trigger the expire_f callback (yet!); also update monster lists if this data is coming from a bones file */ - for (i = gn.n_regions - 1; i >= 0; i--) { + for (i = svn.n_regions - 1; i >= 0; i--) { r = gr.regions[i]; if (r->ttl == 0L) remove_region(r); @@ -858,9 +858,9 @@ region_stats( /* other stats formats take one parameter; this takes two */ Sprintf(hdrbuf, hdrfmt, (long) sizeof (NhRegion), (long) sizeof (NhRect)); - *count = (long) gn.n_regions; /* might be 0 even though max_regions isn't */ + *count = (long) svn.n_regions; /* might be 0 even though max_regions isn't */ *size = (long) gm.max_regions * (long) sizeof (NhRegion); - for (i = 0; i < gn.n_regions; ++i) { + for (i = 0; i < svn.n_regions; ++i) { rg = gr.regions[i]; *size += (long) rg->nrects * (long) sizeof (NhRect); if (rg->enter_msg) @@ -972,7 +972,7 @@ create_force_field(coordxy x, coordxy y, int radius, long ttl) tmprect.hy--; } ff->ttl = ttl; - if (!gi.in_mklev && !gc.context.mon_moving) + if (!gi.in_mklev && !svc.context.mon_moving) set_heros_fault(ff); /* assume player has created it */ /* ff->can_enter_f = enter_force_field; */ /* ff->can_leave_f = enter_force_field; */ @@ -1118,7 +1118,7 @@ is_hero_inside_gas_cloud(void) { int i; - for (i = 0; i < gn.n_regions; i++) + for (i = 0; i < svn.n_regions; i++) if (hero_inside(gr.regions[i]) && gr.regions[i]->inside_f == INSIDE_GAS_CLOUD) return TRUE; @@ -1148,7 +1148,7 @@ create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage) /* a single-point cloud on hero and it deals no damage. probably a natural cause of being polyed. don't message about it */ - if (!gc.context.mon_moving && u_at(x, y) && cloudsize == 1 + if (!svc.context.mon_moving && u_at(x, y) && cloudsize == 1 && (!damage || (damage && m_poisongas_ok(&gy.youmonst) == M_POISONGAS_OK))) inside_cloud = TRUE; @@ -1222,7 +1222,7 @@ create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage) /* If cloud was constrained in small space, give it more time to live. */ cloud->ttl = (cloud->ttl * cloudsize) / newidx; - if (!gi.in_mklev && !gc.context.mon_moving) + if (!gi.in_mklev && !svc.context.mon_moving) set_heros_fault(cloud); /* assume player has created it */ cloud->inside_f = INSIDE_GAS_CLOUD; cloud->expire_f = EXPIRE_GAS_CLOUD; @@ -1262,7 +1262,7 @@ create_gas_cloud_selection(struct selectionvar *sel, int damage) add_rect_to_reg(cloud, &tmprect); } - if (!gi.in_mklev && !gc.context.mon_moving) + if (!gi.in_mklev && !svc.context.mon_moving) set_heros_fault(cloud); /* assume player has created it */ cloud->inside_f = INSIDE_GAS_CLOUD; cloud->expire_f = EXPIRE_GAS_CLOUD; @@ -1285,7 +1285,7 @@ region_danger(void) { int i, f_indx, n = 0; - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { /* only care about regions that hero is in */ if (!hero_inside(gr.regions[i])) continue; @@ -1313,7 +1313,7 @@ region_safety(void) NhRegion *r = 0; int i, f_indx, n = 0; - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { /* only care about regions that hero is in */ if (!hero_inside(gr.regions[i])) continue; diff --git a/src/restore.c b/src/restore.c index 4d587ce9f..31b57d2e3 100644 --- a/src/restore.c +++ b/src/restore.c @@ -67,7 +67,7 @@ extern int amii_numcolors; in an implicit conversion; this macro does it explicitly */ #define Mread(fd,adr,siz) mread((fd), (genericptr_t) (adr), (unsigned) (siz)) -/* Recalculate gl.level.objects[x][y], since this info was not saved. */ +/* Recalculate svl.level.objects[x][y], since this info was not saved. */ staticfn void find_lev_obj(void) { @@ -77,7 +77,7 @@ find_lev_obj(void) for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) - gl.level.objects[x][y] = (struct obj *) 0; + svl.level.objects[x][y] = (struct obj *) 0; /* * Reverse the entire fobj chain, which is necessary so that we can @@ -92,7 +92,7 @@ find_lev_obj(void) } /* fobj should now be empty */ - /* Set gl.level.objects (as well as reversing the chain back again) */ + /* Set svl.level.objects (as well as reversing the chain back again) */ while ((otmp = fobjtmp) != 0) { fobjtmp = otmp->nobj; place_object(otmp, otmp->ox, otmp->oy); @@ -131,7 +131,7 @@ restlevchn(NHFILE *nhfp) int cnt = 0; s_level *tmplev, *x; - gs.sp_levchn = (s_level *) 0; + svs.sp_levchn = (s_level *) 0; if (nhfp->structlevel) Mread(nhfp->fd, &cnt, sizeof cnt); @@ -140,10 +140,10 @@ restlevchn(NHFILE *nhfp) if (nhfp->structlevel) Mread(nhfp->fd, tmplev, sizeof *tmplev); - if (!gs.sp_levchn) - gs.sp_levchn = tmplev; + if (!svs.sp_levchn) + svs.sp_levchn = tmplev; else { - for (x = gs.sp_levchn; x->next; x = x->next) + for (x = svs.sp_levchn; x->next; x = x->next) ; x->next = tmplev; } @@ -171,10 +171,10 @@ restdamage(NHFILE *nhfp) Mread(nhfp->fd, tmp_dam, sizeof *tmp_dam); if (ghostly) - tmp_dam->when += (gm.moves - go.omoves); + tmp_dam->when += (svm.moves - go.omoves); - tmp_dam->next = gl.level.damagelist; - gl.level.damagelist = tmp_dam; + tmp_dam->next = svl.level.damagelist; + svl.level.damagelist = tmp_dam; } while (--counter > 0); } @@ -270,7 +270,7 @@ restobjchn(NHFILE *nhfp, boolean frozen) * immediately after old player died. */ if (ghostly && !frozen && !age_is_relative(otmp)) - otmp->age = gm.moves - go.omoves + otmp->age; + otmp->age = svm.moves - go.omoves + otmp->age; /* get contents of a container or statue */ if (Has_contents(otmp)) { @@ -285,12 +285,12 @@ restobjchn(NHFILE *nhfp, boolean frozen) otmp->bypass = 0; if (!ghostly) { /* fix the pointers */ - if (otmp->o_id == gc.context.victual.o_id) - gc.context.victual.piece = otmp; - if (otmp->o_id == gc.context.tin.o_id) - gc.context.tin.tin = otmp; - if (otmp->o_id == gc.context.spbook.o_id) - gc.context.spbook.book = otmp; + if (otmp->o_id == svc.context.victual.o_id) + svc.context.victual.piece = otmp; + if (otmp->o_id == svc.context.tin.o_id) + svc.context.tin.tin = otmp; + if (otmp->o_id == svc.context.spbook.o_id) + svc.context.spbook.book = otmp; } otmp2 = otmp; } @@ -439,8 +439,8 @@ restmonchn(NHFILE *nhfp) restpriest(mtmp, ghostly); if (!ghostly) { - if (mtmp->m_id == gc.context.polearm.m_id) - gc.context.polearm.hitmon = mtmp; + if (mtmp->m_id == svc.context.polearm.m_id) + svc.context.polearm.hitmon = mtmp; } mtmp2 = mtmp; } @@ -527,13 +527,13 @@ restgamestate(NHFILE *nhfp) return FALSE; } - newgamecontext = gc.context; /* copy statically init'd context */ + newgamecontext = svc.context; /* copy statically init'd context */ if (nhfp->structlevel) - Mread(nhfp->fd, &gc.context, sizeof gc.context); - gc.context.warntype.species = (ismnum(gc.context.warntype.speciesidx)) - ? &mons[gc.context.warntype.speciesidx] + Mread(nhfp->fd, &svc.context, sizeof svc.context); + svc.context.warntype.species = (ismnum(svc.context.warntype.speciesidx)) + ? &mons[svc.context.warntype.speciesidx] : (struct permonst *) 0; - /* gc.context.victual.piece, .tin.tin, .spellbook.book, and .polearm.hitmon + /* svc.context.victual.piece, .tin.tin, .spellbook.book, and .polearm.hitmon are pointers which get set to Null during save and will be recovered via corresponding o_id or m_id while objs or mons are being restored */ @@ -613,7 +613,7 @@ restgamestate(NHFILE *nhfp) iflags.deferred_X = FALSE; iflags.perm_invent = defer_perm_invent; flags = newgameflags; - gc.context = newgamecontext; + svc.context = newgamecontext; gy.youmonst = cg.zeromonst; return FALSE; } @@ -641,7 +641,7 @@ restgamestate(NHFILE *nhfp) gm.migrating_mons = restmonchn(nhfp); if (nhfp->structlevel) { - Mread(nhfp->fd, &gm.mvitals[0], sizeof gm.mvitals); + Mread(nhfp->fd, &svm.mvitals[0], sizeof svm.mvitals); } /* @@ -669,17 +669,17 @@ restgamestate(NHFILE *nhfp) restore_dungeon(nhfp); restlevchn(nhfp); if (nhfp->structlevel) { - Mread(nhfp->fd, &gm.moves, sizeof gm.moves); + Mread(nhfp->fd, &svm.moves, sizeof svm.moves); /* hero_seq isn't saved and restored because it can be recalculated */ - gh.hero_seq = gm.moves << 3; /* normally handled in moveloop() */ - Mread(nhfp->fd, &gq.quest_status, sizeof gq.quest_status); - Mread(nhfp->fd, gs.spl_book, (MAXSPELL + 1) * sizeof (struct spell)); + gh.hero_seq = svm.moves << 3; /* normally handled in moveloop() */ + Mread(nhfp->fd, &svq.quest_status, sizeof svq.quest_status); + Mread(nhfp->fd, svs.spl_book, (MAXSPELL + 1) * sizeof (struct spell)); } restore_artifacts(nhfp); restore_oracles(nhfp); if (nhfp->structlevel) { - Mread(nhfp->fd, gp.pl_character, sizeof gp.pl_character); - Mread(nhfp->fd, gp.pl_fruit, sizeof gp.pl_fruit); + Mread(nhfp->fd, svp.pl_character, sizeof svp.pl_character); + Mread(nhfp->fd, svp.pl_fruit, sizeof svp.pl_fruit); } freefruitchn(gf.ffruit); /* clean up fruit(s) made by initoptions() */ gf.ffruit = loadfruitchn(nhfp); @@ -721,7 +721,7 @@ restlevelfile(xint8 ltmp) nhfp = create_levelfile(ltmp, whynot); if (!nhfp) { /* failed to create a new file; don't attempt to make a panic save */ - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; panic("restlevelfile: %s", whynot); } bufon(nhfp->fd); @@ -738,9 +738,9 @@ dorecover(NHFILE *nhfp) int rtmp; /* suppress map display if some part of the code tries to update that */ - gp.program_state.restoring = REST_GSTATE; + svp.program_state.restoring = REST_GSTATE; - get_plname_from_file(nhfp, gp.plname); + get_plname_from_file(nhfp, svp.plname); getlev(nhfp, 0, (xint8) 0); if (!restgamestate(nhfp)) { NHFILE tnhfp; @@ -755,7 +755,7 @@ dorecover(NHFILE *nhfp) close_nhfile(nhfp); (void) delete_savefile(); u.usteed_mid = u.ustuck_mid = 0; - gp.program_state.restoring = 0; + svp.program_state.restoring = 0; return 0; } /* after restgamestate() -> restnames() so that 'bases[]' is populated */ @@ -769,7 +769,7 @@ dorecover(NHFILE *nhfp) if (rtmp < 2) return rtmp; /* dorecover called recursively */ - gp.program_state.restoring = REST_LEVELS; + svp.program_state.restoring = REST_LEVELS; /* these pointers won't be valid while we're processing the * other levels, but they'll be reset again by restlevelstate() @@ -793,7 +793,7 @@ dorecover(NHFILE *nhfp) #endif clear_nhwindow(WIN_MESSAGE); You("return to level %d in %s%s.", depth(&u.uz), - gd.dungeons[u.uz.dnum].dname, + svd.dungeons[u.uz.dnum].dname, flags.debug ? " while in debug mode" : flags.explore ? " while in explore mode" : ""); curs(WIN_MAP, 1, 1); @@ -828,15 +828,15 @@ dorecover(NHFILE *nhfp) restoreinfo.mread_flags = 0; rewind_nhfile(nhfp); /* return to beginning of file */ (void) validate(nhfp, (char *) 0, FALSE); - get_plname_from_file(nhfp, gp.plname); + get_plname_from_file(nhfp, svp.plname); /* not 0 nor REST_GSTATE nor REST_LEVELS */ - gp.program_state.restoring = REST_CURRENT_LEVEL; + svp.program_state.restoring = REST_CURRENT_LEVEL; getlev(nhfp, 0, (xint8) 0); close_nhfile(nhfp); restlevelstate(); - gp.program_state.something_worth_saving = 1; /* useful data now exists */ + svp.program_state.something_worth_saving = 1; /* useful data now exists */ if (!wizard && !discover) (void) delete_savefile(); @@ -866,9 +866,9 @@ dorecover(NHFILE *nhfp) gv.vision_full_recalc = 1; /* recompute vision (not saved) */ run_timers(); /* expire all timers that have gone off while away */ - gp.program_state.restoring = 0; /* affects bot() so clear before docrt() */ + svp.program_state.restoring = 0; /* affects bot() so clear before docrt() */ - if (ge.early_raw_messages && !gp.program_state.beyond_savefile_load) { + if (ge.early_raw_messages && !svp.program_state.beyond_savefile_load) { /* * We're about to obliterate some potentially important * startup messages, so give the player a chance to see them. @@ -877,7 +877,7 @@ dorecover(NHFILE *nhfp) wait_synch(); } u.usteed_mid = u.ustuck_mid = 0; - gp.program_state.beyond_savefile_load = 1; + svp.program_state.beyond_savefile_load = 1; docrt(); clear_nhwindow(WIN_MESSAGE); @@ -907,7 +907,7 @@ rest_stairs(NHFILE *nhfp) if (nhfp->structlevel) { Mread(nhfp->fd, &stway, sizeof stway); } - if (gp.program_state.restoring != REST_GSTATE + if (svp.program_state.restoring != REST_GSTATE && stway.tolev.dnum == u.uz.dnum) { /* stairway dlevel is relative, make it absolute */ stway.tolev.dlevel += u.uz.dlevel; @@ -993,7 +993,7 @@ trickery(char *reason) pline("Strange, this map is not as I remember it."); pline("Somebody is trying some trickery here..."); pline("This game is void."); - Strcpy(gk.killer.name, reason ? reason : ""); + Strcpy(svk.killer.name, reason ? reason : ""); done(TRICKED); } @@ -1012,7 +1012,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) short tlev; #endif - gp.program_state.in_getlev = TRUE; + svp.program_state.in_getlev = TRUE; if (ghostly) clear_id_mapping(); @@ -1052,34 +1052,34 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) pline1(trickbuf); trickery(trickbuf); } - restcemetery(nhfp, &gl.level.bonesinfo); + restcemetery(nhfp, &svl.level.bonesinfo); rest_levl(nhfp, (boolean) ((sfrestinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); if (nhfp->structlevel) { - Mread(nhfp->fd, gl.lastseentyp, sizeof gl.lastseentyp); + Mread(nhfp->fd, svl.lastseentyp, sizeof svl.lastseentyp); Mread(nhfp->fd, &go.omoves, sizeof go.omoves); } - elapsed = gm.moves - go.omoves; + elapsed = svm.moves - go.omoves; if (nhfp->structlevel) { rest_stairs(nhfp); - Mread(nhfp->fd, &gu.updest, sizeof gu.updest); - Mread(nhfp->fd, &gd.dndest, sizeof gd.dndest); - Mread(nhfp->fd, &gl.level.flags, sizeof gl.level.flags); - if (gd.doors) { - free(gd.doors); - gd.doors = 0; + Mread(nhfp->fd, &svu.updest, sizeof svu.updest); + Mread(nhfp->fd, &svd.dndest, sizeof svd.dndest); + Mread(nhfp->fd, &svl.level.flags, sizeof svl.level.flags); + if (svd.doors) { + free(svd.doors); + svd.doors = 0; } - Mread(nhfp->fd, &gd.doors_alloc, sizeof gd.doors_alloc); - if (gd.doors_alloc) { /* avoid pointless alloc(0) */ - gd.doors = (coord *) alloc(gd.doors_alloc * sizeof (coord)); - Mread(nhfp->fd, gd.doors, gd.doors_alloc * sizeof (coord)); + Mread(nhfp->fd, &svd.doors_alloc, sizeof svd.doors_alloc); + if (svd.doors_alloc) { /* avoid pointless alloc(0) */ + svd.doors = (coord *) alloc(svd.doors_alloc * sizeof (coord)); + Mread(nhfp->fd, svd.doors, svd.doors_alloc * sizeof (coord)); } } rest_rooms(nhfp); /* No joke :-) */ - if (gn.nroom) - gd.doorindex = gr.rooms[gn.nroom - 1].fdoor - + gr.rooms[gn.nroom - 1].doorct; + if (svn.nroom) + gd.doorindex = svr.rooms[svn.nroom - 1].fdoor + + svr.rooms[svn.nroom - 1].doorct; else gd.doorindex = 0; @@ -1096,7 +1096,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (nhfp->structlevel) Mread(nhfp->fd, trap, sizeof *trap); if (trap->tx != 0) { - if (gp.program_state.restoring != REST_GSTATE + if (svp.program_state.restoring != REST_GSTATE && trap->dst.dnum == u.uz.dnum) { /* convert relative destination to absolute */ trap->dst.dlevel += u.uz.dlevel; @@ -1112,14 +1112,14 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) find_lev_obj(); /* restobjchn()'s `frozen' argument probably ought to be a callback routine so that we can check for objects being buried under ice */ - gl.level.buriedobjlist = restobjchn(nhfp, FALSE); + svl.level.buriedobjlist = restobjchn(nhfp, FALSE); gb.billobjs = restobjchn(nhfp, FALSE); rest_engravings(nhfp); /* reset level.monsters for new level */ for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) - gl.level.monsters[x][y] = (struct monst *) 0; + svl.level.monsters[x][y] = (struct monst *) 0; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (mtmp->isshk) set_residency(mtmp, FALSE); @@ -1140,7 +1140,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) } /* regenerate monsters while on another level */ - if (!u.uz.dlevel || gp.program_state.restoring == REST_LEVELS) + if (!u.uz.dlevel || svp.program_state.restoring == REST_LEVELS) continue; if (ghostly) { /* reset peaceful/malign relative to new character; @@ -1242,7 +1242,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly) clear_id_mapping(); - gp.program_state.in_getlev = FALSE; + svp.program_state.in_getlev = FALSE; } void @@ -1410,7 +1410,7 @@ reset_oattached_mids(boolean ghostly) #ifdef SELECTSAVED /* put up a menu listing each character from this player's saved games; - returns 1: use gp.plname[], 0: new game, -1: quit */ + returns 1: use svp.plname[], 0: new game, -1: quit */ int restore_menu( winid bannerwin) /* if not WIN_ERR, clear window and show copyright in menu */ @@ -1422,7 +1422,7 @@ restore_menu( int k, clet, ch = 0; /* ch: 0 => new game */ int clr = NO_COLOR; - *gp.plname = '\0'; + *svp.plname = '\0'; saved = get_saved_games(); /* array of character names */ if (saved && *saved) { tmpwin = create_nhwindow(NHW_MENU); @@ -1455,7 +1455,7 @@ restore_menu( if (select_menu(tmpwin, PICK_ONE, &chosen_game) > 0) { ch = chosen_game->item.a_int; if (ch > 0) - Strcpy(gp.plname, saved[ch - 1]); + Strcpy(svp.plname, saved[ch - 1]); else if (ch < 0) ++ch; /* -1 -> 0 (new game), -2 -> -1 (quit) */ free((genericptr_t) chosen_game); diff --git a/src/rip.c b/src/rip.c index dc237d4b2..8ecc170ef 100644 --- a/src/rip.c +++ b/src/rip.c @@ -96,7 +96,7 @@ genl_outrip(winid tmpwin, int how, time_t when) dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, gp.plname); + Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, svp.plname); center(NAME_LINE, buf); /* Put $ on stone */ diff --git a/src/role.c b/src/role.c index cf1616e52..7707e34c7 100644 --- a/src/role.c +++ b/src/role.c @@ -1664,31 +1664,31 @@ plnamesuffix(void) /* some generic user names will be ignored in favor of prompting */ if (sysopt.genericusers) { if (*sysopt.genericusers == '*') { - gp.plname[0] = '\0'; + svp.plname[0] = '\0'; } else { /* need to ignore appended '-role-race-gender-alignment'; 'plnamelen' is non-zero when dealing with plname[] value that contains a username with dash(es) in it and is usually 0 */ - i = ((eptr = strchr(gp.plname + gp.plnamelen, '-')) != 0) - ? (int) (eptr - gp.plname) - : (int) Strlen(gp.plname); + i = ((eptr = strchr(svp.plname + gp.plnamelen, '-')) != 0) + ? (int) (eptr - svp.plname) + : (int) Strlen(svp.plname); /* look for plname[] in the 'genericusers' space-separated list */ - if (findword(sysopt.genericusers, gp.plname, i, FALSE)) + if (findword(sysopt.genericusers, svp.plname, i, FALSE)) /* it's generic; remove it so that askname() will be called */ - gp.plname[0] = '\0'; + svp.plname[0] = '\0'; } - if (!gp.plname[0]) + if (!svp.plname[0]) gp.plnamelen = 0; } do { - if (!gp.plname[0]) { - askname(); /* fill gp.plname[] if necessary, or set defer_plname */ + if (!svp.plname[0]) { + askname(); /* fill svp.plname[] if necessary, or set defer_plname */ gp.plnamelen = 0; /* plname[] might have -role-race-&c attached */ } /* Look for tokens delimited by '-' */ - sptr = gp.plname + gp.plnamelen; + sptr = svp.plname + gp.plnamelen; if ((eptr = strchr(sptr, '-')) != (char *) 0) *eptr++ = '\0'; while (eptr) { @@ -1707,10 +1707,10 @@ plnamesuffix(void) else if ((i = str2align(sptr)) != ROLE_NONE) flags.initalign = i; } - } while (!gp.plname[0] && !iflags.defer_plname); + } while (!svp.plname[0] && !iflags.defer_plname); - /* commas in the gp.plname confuse the record file, convert to spaces */ - (void) strNsubst(gp.plname, ",", " ", 0); + /* commas in the svp.plname confuse the record file, convert to spaces */ + (void) strNsubst(svp.plname, ",", " ", 0); } /* show current settings for name, role, race, gender, and alignment @@ -1762,7 +1762,7 @@ role_selection_prolog(int which, winid where) Sprintf(buf, "%12s ", "name:"); Strcat(buf, (which == RS_NAME) ? choosing - : !*gp.plname ? not_yet : gp.plname); + : !*svp.plname ? not_yet : svp.plname); putstr(where, 0, buf); Sprintf(buf, "%12s ", "role:"); assert(which == RS_ROLE || r == ROLE_NONE || r == ROLE_RANDOM @@ -1982,15 +1982,15 @@ role_init(void) /* Check for a valid role. Try flags.initrole first. */ if (!validrole(flags.initrole)) { /* Try the player letter second */ - if ((flags.initrole = str2role(gp.pl_character)) < 0) + if ((flags.initrole = str2role(svp.pl_character)) < 0) /* None specified; pick a random role */ flags.initrole = randrole_filtered(); } /* We now have a valid role index. Copy the role name back. */ /* This should become OBSOLETE */ - Strcpy(gp.pl_character, roles[flags.initrole].name.m); - gp.pl_character[PL_CSIZ - 1] = '\0'; + Strcpy(svp.pl_character, roles[flags.initrole].name.m); + svp.pl_character[PL_CSIZ - 1] = '\0'; /* Check for a valid race */ if (!validrace(flags.initrole, flags.initrace)) @@ -2025,7 +2025,7 @@ role_init(void) pm->maligntyp = alignmnt * 3; /* if gender is random, we choose it now instead of waiting until the leader monster is created */ - gq.quest_status.ldrgend = + svq.quest_status.ldrgend = is_neuter(pm) ? 2 : is_female(pm) ? 1 : is_male(pm) ? 0 : (rn2(100) < 50); @@ -2048,7 +2048,7 @@ role_init(void) pm->mflags3 |= M3_WANTSARTI | M3_WAITFORU; /* if gender is random, we choose it now instead of waiting until the nemesis monster is created */ - gq.quest_status.nemgend = is_neuter(pm) ? 2 : is_female(pm) ? 1 + svq.quest_status.nemgend = is_neuter(pm) ? 2 : is_female(pm) ? 1 : is_male(pm) ? 0 : (rn2(100) < 50); } @@ -2074,7 +2074,7 @@ role_init(void) gu.urole.cgod = roles[flags.pantheon].cgod; } /* 0 or 1; no gods are neuter, nor is gender randomized */ - gq.quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess"); + svq.quest_status.godgend = !strcmpi(align_gtitle(alignmnt), "goddess"); #if 0 /* @@ -2204,7 +2204,7 @@ genl_player_setup(int screenheight) char pick4u = 'n'; int result = 0; /* assume failure (player chooses to 'quit') */ - gp.program_state.in_role_selection++; /* affects tty menu cleanup */ + svp.program_state.in_role_selection++; /* affects tty menu cleanup */ /* Used to avoid "Is this ok?" if player has already specified all * four facets of role. * Note that rigid_role_checks might force any unspecified facets to @@ -2681,8 +2681,8 @@ genl_player_setup(int screenheight) /* plnamesuffix() can change any or all of ROLE, RACE, GEND, ALGN; we'll override that and honor only the name */ saveROLE = ROLE, saveRACE = RACE, saveGEND = GEND, saveALGN = ALGN; - gp.plname[0] = '\0'; - plnamesuffix(); /* calls askname() when gp.plname[] is empty */ + svp.plname[0] = '\0'; + plnamesuffix(); /* calls askname() when svp.plname[] is empty */ ROLE = saveROLE, RACE = saveRACE, GEND = saveGEND, ALGN = saveALGN; break; /* getconfirmation is still True */ } @@ -2704,7 +2704,7 @@ genl_player_setup(int screenheight) result = 1; setup_done: - gp.program_state.in_role_selection--; + svp.program_state.in_role_selection--; return result; } @@ -2800,7 +2800,7 @@ plsel_startmenu(int ttyrows, int aspect) rolename = (ROLE < 0) ? "" : (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f : roles[ROLE].name.m; - if (!gp.plname[0] || ROLE < 0 || RACE < 0 || GEND < 0 || ALGN < 0) { + if (!svp.plname[0] || ROLE < 0 || RACE < 0 || GEND < 0 || ALGN < 0) { /* " " */ Sprintf(qbuf, "%.20s %.20s %.20s %.20s", rolename, @@ -2810,7 +2810,7 @@ plsel_startmenu(int ttyrows, int aspect) } else { /* " the " */ Sprintf(qbuf, "%.20s the %.20s %.20s %.20s %.20s", - gp.plname, + svp.plname, aligns[ALGN].adj, genders[GEND].adj, races[RACE].adj, diff --git a/src/rumors.c b/src/rumors.c index 82794b04b..540e6f214 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -582,7 +582,7 @@ init_oracles(dlb *fp) (void) dlb_fgets(line, sizeof line, fp); /* skip "don't edit" comment*/ (void) dlb_fgets(line, sizeof line, fp); if (sscanf(line, "%5d\n", &cnt) == 1 && cnt > 0) { - go.oracle_cnt = (unsigned) cnt; + svo.oracle_cnt = (unsigned) cnt; go.oracle_loc = (unsigned long *) alloc((unsigned) cnt * sizeof(long)); for (i = 0; i < cnt; i++) { (void) dlb_fgets(line, sizeof line, fp); @@ -597,19 +597,19 @@ save_oracles(NHFILE *nhfp) { if (perform_bwrite(nhfp)) { if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) &go.oracle_cnt, - sizeof go.oracle_cnt); - if (go.oracle_cnt) { + bwrite(nhfp->fd, (genericptr_t) &svo.oracle_cnt, + sizeof svo.oracle_cnt); + if (svo.oracle_cnt) { if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) go.oracle_loc, - go.oracle_cnt * sizeof (long)); + svo.oracle_cnt * sizeof (long)); } } } if (release_data(nhfp)) { - if (go.oracle_cnt) { + if (svo.oracle_cnt) { free((genericptr_t) go.oracle_loc); - go.oracle_loc = 0, go.oracle_cnt = 0, go.oracle_flg = 0; + go.oracle_loc = 0, svo.oracle_cnt = 0, go.oracle_flg = 0; } } } @@ -618,13 +618,13 @@ void restore_oracles(NHFILE *nhfp) { if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &go.oracle_cnt, sizeof go.oracle_cnt); + mread(nhfp->fd, (genericptr_t) &svo.oracle_cnt, sizeof svo.oracle_cnt); - if (go.oracle_cnt) { - go.oracle_loc = (unsigned long *) alloc(go.oracle_cnt * sizeof(long)); + if (svo.oracle_cnt) { + go.oracle_loc = (unsigned long *) alloc(svo.oracle_cnt * sizeof(long)); if (nhfp->structlevel) { mread(nhfp->fd, (genericptr_t) go.oracle_loc, - go.oracle_cnt * sizeof (long)); + svo.oracle_cnt * sizeof (long)); } go.oracle_flg = 1; /* no need to call init_oracles() */ } @@ -640,7 +640,7 @@ outoracle(boolean special, boolean delphi) /* early return if we couldn't open ORACLEFILE on previous attempt, or if all the oracularities are already exhausted */ - if (go.oracle_flg < 0 || (go.oracle_flg > 0 && go.oracle_cnt == 0)) + if (go.oracle_flg < 0 || (go.oracle_flg > 0 && svo.oracle_cnt == 0)) return; oracles = dlb_fopen(ORACLEFILE, "r"); @@ -649,17 +649,17 @@ outoracle(boolean special, boolean delphi) if (go.oracle_flg == 0) { /* if this is the first outoracle() */ init_oracles(oracles); go.oracle_flg = 1; - if (go.oracle_cnt == 0) + if (svo.oracle_cnt == 0) goto close_oracles; } /* oracle_loc[0] is the special oracle; oracle_loc[1..oracle_cnt-1] are normal ones */ - if (go.oracle_cnt <= 1 && !special) + if (svo.oracle_cnt <= 1 && !special) goto close_oracles; /*(shouldn't happen)*/ - oracle_idx = special ? 0 : rnd((int) go.oracle_cnt - 1); + oracle_idx = special ? 0 : rnd((int) svo.oracle_cnt - 1); (void) dlb_fseek(oracles, (long) go.oracle_loc[oracle_idx], SEEK_SET); if (!special) /* move offset of very last one into this slot */ - go.oracle_loc[oracle_idx] = go.oracle_loc[--go.oracle_cnt]; + go.oracle_loc[oracle_idx] = go.oracle_loc[--svo.oracle_cnt]; tmpwin = create_nhwindow(NHW_TEXT); if (delphi) @@ -723,7 +723,7 @@ doconsult(struct monst *oracl) break; case 'n': if (umoney <= (long) minor_cost /* don't even ask */ - || (go.oracle_cnt == 1 || go.oracle_flg < 0)) + || (svo.oracle_cnt == 1 || go.oracle_flg < 0)) return ECMD_OK; Sprintf(qbuf, "\"Then dost thou desire a major one?\" (%d %s)", major_cost, currency((long) major_cost)); @@ -763,16 +763,16 @@ doconsult(struct monst *oracl) staticfn void couldnt_open_file(const char *filename) { - int save_something = gp.program_state.something_worth_saving; + int save_something = svp.program_state.something_worth_saving; /* most likely the file is missing, so suppress impossible()'s "saving and restoring might fix this" (unless the fuzzer, which escalates impossible to panic, is running) */ if (!iflags.debug_fuzzer) - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; impossible("Can't open '%s' file.", filename); - gp.program_state.something_worth_saving = save_something; + svp.program_state.something_worth_saving = save_something; } /* is 'word' a capitalized monster name that should be preceded by "the"? diff --git a/src/save.c b/src/save.c index d747db1f3..864f17ead 100644 --- a/src/save.c +++ b/src/save.c @@ -41,7 +41,7 @@ staticfn void zerocomp_bputc(int); #endif #if defined(HANGUPHANDLING) -#define HUP if (!gp.program_state.done_hup) +#define HUP if (!svp.program_state.done_hup) #else #define HUP #endif @@ -59,7 +59,7 @@ dosave(void) clear_nhwindow(WIN_MESSAGE); pline("Saving..."); #if defined(HANGUPHANDLING) - gp.program_state.done_hup = 0; + svp.program_state.done_hup = 0; #endif if (dosave0()) { u.uhp = -1; /* universal game's over indicator */ @@ -86,7 +86,7 @@ dosave0(void) NHFILE *nhfp, *onhfp; int res = 0; - gp.program_state.saving++; /* inhibit status and perm_invent updates */ + svp.program_state.saving++; /* inhibit status and perm_invent updates */ /* we may get here via hangup signal, in which case we want to fix up a few of things before saving so that they won't be restored in an improper state; these will be no-ops for normal save sequence */ @@ -103,7 +103,7 @@ dosave0(void) when punished, make sure ball and chain are placed too */ done_object_cleanup(); /* maybe force some items onto map */ - if (!gp.program_state.something_worth_saving || !gs.SAVEF[0]) + if (!svp.program_state.something_worth_saving || !gs.SAVEF[0]) goto done; fq_save = fqname(gs.SAVEF, SAVEPREFIX, 1); /* level files take 0 */ @@ -190,7 +190,7 @@ dosave0(void) for (ltmp = (xint8) 1; ltmp <= maxledgerno(); ltmp++) { if (ltmp == ledger_no(&gu.uz_save)) continue; - if (!(gl.level_info[ltmp].flags & LFILE_EXISTS)) + if (!(svl.level_info[ltmp].flags & LFILE_EXISTS)) continue; #ifdef MICRO curs(WIN_MAP, 1 + dotcnt++, dotrow); @@ -208,12 +208,12 @@ dosave0(void) HUP pline1(whynot); close_nhfile(nhfp); (void) delete_savefile(); - HUP Strcpy(gk.killer.name, whynot); + HUP Strcpy(svk.killer.name, whynot); HUP done(TRICKED); goto done; } minit(); /* ZEROCOMP */ - getlev(onhfp, gh.hackpid, ltmp); + getlev(onhfp, svh.hackpid, ltmp); close_nhfile(onhfp); if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) <mp, sizeof ltmp); /* lvl no. */ @@ -230,11 +230,11 @@ dosave0(void) delete_levelfile(0); nh_compress(fq_save); /* this should probably come sooner... */ - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; res = 1; done: - gp.program_state.saving--; + svp.program_state.saving--; return res; } @@ -276,11 +276,11 @@ savegamestate(NHFILE *nhfp) { unsigned long uid; - gp.program_state.saving++; /* caller should/did already set this... */ + svp.program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &uid, sizeof uid); - bwrite(nhfp->fd, (genericptr_t) &gc.context, sizeof gc.context); + bwrite(nhfp->fd, (genericptr_t) &svc.context, sizeof svc.context); bwrite(nhfp->fd, (genericptr_t) &flags, sizeof flags); } urealtime.finish_time = getnow(); @@ -313,23 +313,23 @@ savegamestate(NHFILE *nhfp) if (release_data(nhfp)) gm.migrating_mons = (struct monst *) 0; if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) gm.mvitals, sizeof gm.mvitals); + bwrite(nhfp->fd, (genericptr_t) svm.mvitals, sizeof svm.mvitals); save_dungeon(nhfp, (boolean) !!perform_bwrite(nhfp), (boolean) !!release_data(nhfp)); savelevchn(nhfp); if (nhfp->structlevel) { - bwrite(nhfp->fd, (genericptr_t) &gm.moves, sizeof gm.moves); - bwrite(nhfp->fd, (genericptr_t) &gq.quest_status, - sizeof gq.quest_status); - bwrite(nhfp->fd, (genericptr_t) gs.spl_book, + bwrite(nhfp->fd, (genericptr_t) &svm.moves, sizeof svm.moves); + bwrite(nhfp->fd, (genericptr_t) &svq.quest_status, + sizeof svq.quest_status); + bwrite(nhfp->fd, (genericptr_t) svs.spl_book, sizeof (struct spell) * (MAXSPELL + 1)); } save_artifacts(nhfp); save_oracles(nhfp); if (nhfp->structlevel) { - bwrite(nhfp->fd, (genericptr_t) gp.pl_character, - sizeof gp.pl_character); - bwrite(nhfp->fd, (genericptr_t) gp.pl_fruit, sizeof gp.pl_fruit); + bwrite(nhfp->fd, (genericptr_t) svp.pl_character, + sizeof svp.pl_character); + bwrite(nhfp->fd, (genericptr_t) svp.pl_fruit, sizeof svp.pl_fruit); } savefruitchn(nhfp); savenames(nhfp); @@ -338,7 +338,7 @@ savegamestate(NHFILE *nhfp) save_luadata(nhfp); if (nhfp->structlevel) bflush(nhfp->fd); - gp.program_state.saving--; + svp.program_state.saving--; return; } @@ -349,7 +349,7 @@ tricked_fileremoved(NHFILE *nhfp, char *whynot) if (!nhfp) { pline1(whynot); pline("Probably someone removed it."); - Strcpy(gk.killer.name, whynot); + Strcpy(svk.killer.name, whynot); done(TRICKED); return TRUE; } @@ -364,7 +364,7 @@ savestateinlock(void) char whynot[BUFSZ]; NHFILE *nhfp; - gp.program_state.saving++; /* inhibit status and perm_invent updates */ + svp.program_state.saving++; /* inhibit status and perm_invent updates */ /* When checkpointing is on, the full state needs to be written * on each checkpoint. When checkpointing is off, only the pid * needs to be in the level.0 file, so it does not need to be @@ -385,15 +385,15 @@ savestateinlock(void) */ nhfp = open_levelfile(0, whynot); if (tricked_fileremoved(nhfp, whynot)) { - gp.program_state.saving--; + svp.program_state.saving--; return; } if (nhfp->structlevel) (void) read(nhfp->fd, (genericptr_t) &hpid, sizeof hpid); - if (gh.hackpid != hpid) { + if (svh.hackpid != hpid) { Sprintf(whynot, "Level #0 pid (%d) doesn't match ours (%d)!", - hpid, gh.hackpid); + hpid, svh.hackpid); goto giveup; } close_nhfile(nhfp); @@ -402,19 +402,19 @@ savestateinlock(void) if (!nhfp) { pline1(whynot); giveup: - Strcpy(gk.killer.name, whynot); + Strcpy(svk.killer.name, whynot); /* done(TRICKED) will return when running in wizard mode; clear the display-update-suppression flag before rather than after so that screen updating behaves normally; game data shouldn't be inconsistent yet, unlike it would become midway through saving */ - gp.program_state.saving--; + svp.program_state.saving--; done(TRICKED); return; } nhfp->mode = WRITING; if (nhfp->structlevel) - (void) write(nhfp->fd, (genericptr_t) &gh.hackpid, sizeof gh.hackpid); + (void) write(nhfp->fd, (genericptr_t) &svh.hackpid, sizeof svh.hackpid); if (flags.ins_chkpt) { int currlev = ledger_no(&u.uz); @@ -433,7 +433,7 @@ savestateinlock(void) } close_nhfile(nhfp); } - gp.program_state.saving--; + svp.program_state.saving--; gh.havestate = flags.ins_chkpt; return; } @@ -450,7 +450,7 @@ savelev(NHFILE *nhfp, xint8 lev) but we'll be called during run-down */ if (set_uz_save && perform_bwrite(nhfp)) { if (u.uz.dnum == 0 && u.uz.dlevel == 0) { - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; panic("savelev: where are we?"); } gu.uz_save = u.uz; @@ -469,7 +469,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) short tlev; #endif - gp.program_state.saving++; /* even if current mode is FREEING */ + svp.program_state.saving++; /* even if current mode is FREEING */ if (!nhfp) panic("Save on bad file!"); /* impossible */ @@ -500,9 +500,9 @@ savelev_core(NHFILE *nhfp, xint8 lev) dmonsfree(); if (lev >= 0 && lev <= maxledgerno()) - gl.level_info[lev].flags |= VISITED; + svl.level_info[lev].flags |= VISITED; if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) &gh.hackpid, sizeof gh.hackpid); + bwrite(nhfp->fd, (genericptr_t) &svh.hackpid, sizeof svh.hackpid); #ifdef TOS tlev = lev; tlev &= 0x00ff; @@ -520,24 +520,24 @@ savelev_core(NHFILE *nhfp, xint8 lev) the guessing that was needed in 3.4.3 and without having to interpret level data to find where to start; unfortunately it still needs to handle all the data compression schemes */ - savecemetery(nhfp, &gl.level.bonesinfo); + savecemetery(nhfp, &svl.level.bonesinfo); if (nhfp->mode == FREEING) /* see above */ goto skip_lots; savelevl(nhfp, ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); if (nhfp->structlevel) { - bwrite(nhfp->fd, (genericptr_t) gl.lastseentyp, sizeof gl.lastseentyp); - bwrite(nhfp->fd, (genericptr_t) &gm.moves, sizeof gm.moves); + bwrite(nhfp->fd, (genericptr_t) svl.lastseentyp, sizeof svl.lastseentyp); + bwrite(nhfp->fd, (genericptr_t) &svm.moves, sizeof svm.moves); save_stairs(nhfp); - bwrite(nhfp->fd, (genericptr_t) &gu.updest, sizeof (dest_area)); - bwrite(nhfp->fd, (genericptr_t) &gd.dndest, sizeof (dest_area)); - bwrite(nhfp->fd, (genericptr_t) &gl.level.flags, sizeof gl.level.flags); - bwrite(nhfp->fd, (genericptr_t) &gd.doors_alloc, sizeof gd.doors_alloc); + bwrite(nhfp->fd, (genericptr_t) &svu.updest, sizeof (dest_area)); + bwrite(nhfp->fd, (genericptr_t) &svd.dndest, sizeof (dest_area)); + bwrite(nhfp->fd, (genericptr_t) &svl.level.flags, sizeof svl.level.flags); + bwrite(nhfp->fd, (genericptr_t) &svd.doors_alloc, sizeof svd.doors_alloc); /* don't rely on underlying write() behavior to write * nothing if count arg is 0, just skip it */ - if (gd.doors_alloc) - bwrite(nhfp->fd, (genericptr_t) gd.doors, - gd.doors_alloc * sizeof (coord)); + if (svd.doors_alloc) + bwrite(nhfp->fd, (genericptr_t) svd.doors, + svd.doors_alloc * sizeof (coord)); } save_rooms(nhfp); /* no dynamic memory to reclaim */ @@ -551,7 +551,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) save_worm(nhfp); /* save worm information */ savetrapchn(nhfp, gf.ftrap); saveobjchn(nhfp, &fobj); - saveobjchn(nhfp, &gl.level.buriedobjlist); + saveobjchn(nhfp, &svl.level.buriedobjlist); saveobjchn(nhfp, &gb.billobjs); save_engravings(nhfp); savedamage(nhfp); /* pending shop wall and/or floor repair */ @@ -564,12 +564,12 @@ savelev_core(NHFILE *nhfp, xint8 lev) if (nhfp->structlevel) bflush(nhfp->fd); } - gp.program_state.saving--; + svp.program_state.saving--; if (release_data(nhfp)) { clear_level_structures(); gf.ftrap = 0; gb.billobjs = 0; - (void) memset(gr.rooms, 0, sizeof(gr.rooms)); + (void) memset(svr.rooms, 0, sizeof(svr.rooms)); } return; } @@ -688,7 +688,7 @@ savedamage(NHFILE *nhfp) struct damage *damageptr, *tmp_dam; unsigned int xl = 0; - damageptr = gl.level.damagelist; + damageptr = svl.level.damagelist; for (tmp_dam = damageptr; tmp_dam; tmp_dam = tmp_dam->next) xl++; if (perform_bwrite(nhfp)) { @@ -706,7 +706,7 @@ savedamage(NHFILE *nhfp) free((genericptr_t) tmp_dam); } if (release_data(nhfp)) - gl.level.damagelist = 0; + svl.level.damagelist = 0; } staticfn void @@ -717,7 +717,7 @@ save_stairs(NHFILE *nhfp) while (stway) { if (perform_bwrite(nhfp)) { - boolean use_relative = (gp.program_state.restoring != REST_GSTATE + boolean use_relative = (svp.program_state.restoring != REST_GSTATE && stway->tolev.dnum == u.uz.dnum); if (use_relative) { /* make dlevel relative to current level */ @@ -840,17 +840,17 @@ saveobjchn(NHFILE *nhfp, struct obj **obj_p) * Always invalidate the pointer, but ensure that we have * the o_id in order to restore the pointer on reload. */ - if (otmp == gc.context.victual.piece) { - gc.context.victual.o_id = otmp->o_id; - gc.context.victual.piece = (struct obj *) 0; + if (otmp == svc.context.victual.piece) { + svc.context.victual.o_id = otmp->o_id; + svc.context.victual.piece = (struct obj *) 0; } - if (otmp == gc.context.tin.tin) { - gc.context.tin.o_id = otmp->o_id; - gc.context.tin.tin = (struct obj *) 0; + if (otmp == svc.context.tin.tin) { + svc.context.tin.o_id = otmp->o_id; + svc.context.tin.tin = (struct obj *) 0; } - if (otmp == gc.context.spbook.book) { - gc.context.spbook.o_id = otmp->o_id; - gc.context.spbook.book = (struct obj *) 0; + if (otmp == svc.context.spbook.book) { + svc.context.spbook.o_id = otmp->o_id; + svc.context.spbook.book = (struct obj *) 0; } otmp->where = OBJ_FREE; /* set to free so dealloc will work */ otmp->nobj = NULL; /* nobj saved into otmp2 */ @@ -961,9 +961,9 @@ savemonchn(NHFILE *nhfp, struct monst *mtmp) if (mtmp->minvent) saveobjchn(nhfp, &mtmp->minvent); if (release_data(nhfp)) { - if (mtmp == gc.context.polearm.hitmon) { - gc.context.polearm.m_id = mtmp->m_id; - gc.context.polearm.hitmon = NULL; + if (mtmp == svc.context.polearm.hitmon) { + svc.context.polearm.m_id = mtmp->m_id; + svc.context.polearm.hitmon = NULL; } if (mtmp == u.ustuck) u.ustuck_mid = u.ustuck->m_id; @@ -988,7 +988,7 @@ savetrapchn(NHFILE *nhfp, struct trap *trap) struct trap *trap2; while (trap) { - boolean use_relative = (gp.program_state.restoring != REST_GSTATE + boolean use_relative = (svp.program_state.restoring != REST_GSTATE && trap->dst.dnum == u.uz.dnum); trap2 = trap->ntrap; if (use_relative) @@ -1045,13 +1045,13 @@ savelevchn(NHFILE *nhfp) s_level *tmplev, *tmplev2; int cnt = 0; - for (tmplev = gs.sp_levchn; tmplev; tmplev = tmplev->next) + for (tmplev = svs.sp_levchn; tmplev; tmplev = tmplev->next) cnt++; if (perform_bwrite(nhfp)) { if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &cnt, sizeof cnt); } - for (tmplev = gs.sp_levchn; tmplev; tmplev = tmplev2) { + for (tmplev = svs.sp_levchn; tmplev; tmplev = tmplev2) { tmplev2 = tmplev->next; if (perform_bwrite(nhfp)) { if (nhfp->structlevel) @@ -1061,7 +1061,7 @@ savelevchn(NHFILE *nhfp) free((genericptr_t) tmplev); } if (release_data(nhfp)) - gs.sp_levchn = 0; + svs.sp_levchn = 0; } void @@ -1073,7 +1073,7 @@ store_plname_in_file(NHFILE *nhfp) bufoff(nhfp->fd); /* bwrite() before bufon() uses plain write() */ bwrite(nhfp->fd, (genericptr_t) &plsiztmp, sizeof plsiztmp); - bwrite(nhfp->fd, (genericptr_t) gp.plname, plsiztmp); + bwrite(nhfp->fd, (genericptr_t) svp.plname, plsiztmp); bufon(nhfp->fd); } return; diff --git a/src/selvar.c b/src/selvar.c index a746be28b..ca2249a3a 100644 --- a/src/selvar.c +++ b/src/selvar.c @@ -780,7 +780,7 @@ selection_from_mkroom(struct mkroom *croom) if (!croom) return sel; - rmno = (unsigned)((croom - gr.rooms) + ROOMOFFSET); + rmno = (unsigned)((croom - svr.rooms) + ROOMOFFSET); for (y = croom->ly; y <= croom->hy; y++) for (x = croom->lx; x <= croom->hx; x++) if (isok(x, y) && !levl[x][y].edge diff --git a/src/sfstruct.c b/src/sfstruct.c index 5d84583bd..4c19b6403 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -194,7 +194,7 @@ bwrite(int fd, const genericptr_t loc, unsigned num) } if (failed) { #if defined(HANGUPHANDLING) - if (gp.program_state.done_hup) + if (svp.program_state.done_hup) nh_terminate(EXIT_FAILURE); else #endif @@ -230,7 +230,7 @@ mread(int fd, genericptr_t buf, unsigned len) } else { pline("Read %d instead of %u bytes.", (int) rlen, len); display_nhwindow(WIN_MESSAGE, TRUE); /* flush before error() */ - if (gp.program_state.restoring) { + if (svp.program_state.restoring) { (void) nhclose(fd); (void) delete_savefile(); error("Error restoring old game."); diff --git a/src/shk.c b/src/shk.c index 5bd1abe1d..aa2abdb8a 100644 --- a/src/shk.c +++ b/src/shk.c @@ -47,7 +47,7 @@ staticfn void kops_gone(boolean); #define NOTANGRY(mon) ((mon)->mpeaceful) #define ANGRY(mon) (!NOTANGRY(mon)) -#define IS_SHOP(x) (gr.rooms[x].rtype >= SHOPBASE) +#define IS_SHOP(x) (svr.rooms[x].rtype >= SHOPBASE) #define muteshk(shkp) (helpless(shkp) || (shkp)->data->msound <= MS_ANIMAL) @@ -228,7 +228,7 @@ void shkgone(struct monst *mtmp) { struct eshk *eshk = ESHK(mtmp); - struct mkroom *sroom = &gr.rooms[eshk->shoproom - ROOMOFFSET]; + struct mkroom *sroom = &svr.rooms[eshk->shoproom - ROOMOFFSET]; struct obj *otmp; char *p; int sx, sy; @@ -239,12 +239,12 @@ shkgone(struct monst *mtmp) discard_damage_owned_by(mtmp); sroom->resident = (struct monst *) 0; if (!search_special(ANY_SHOP)) - gl.level.flags.has_shop = 0; + svl.level.flags.has_shop = 0; /* items on shop floor revert to ordinary objects */ for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) - for (otmp = gl.level.objects[sx][sy]; otmp; + for (otmp = svl.level.objects[sx][sy]; otmp; otmp = otmp->nexthere) otmp->no_charge = 0; @@ -265,14 +265,14 @@ void set_residency(struct monst *shkp, boolean zero_out) { if (on_level(&(ESHK(shkp)->shoplevel), &u.uz)) - gr.rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident = + svr.rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident = (zero_out) ? (struct monst *) 0 : shkp; } void replshk(struct monst *mtmp, struct monst *mtmp2) { - gr.rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2; + svr.rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2; if (inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) { ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]); } @@ -291,7 +291,7 @@ restshk(struct monst *shkp, boolean ghostly) /* savebones guarantees that non-homed shk's will be gone */ if (ghostly) { assign_level(&eshkp->shoplevel, &u.uz); - if (ANGRY(shkp) && strncmpi(eshkp->customer, gp.plname, PL_NSIZ)) + if (ANGRY(shkp) && strncmpi(eshkp->customer, svp.plname, PL_NSIZ)) pacify_shk(shkp, TRUE); } } @@ -359,7 +359,7 @@ clear_no_charge_obj( || !isok(x, y) || (rno = levl[x][y].roomno) < ROOMOFFSET || !IS_SHOP(rno - ROOMOFFSET) - || (rm_shkp = gr.rooms[rno - ROOMOFFSET].resident) == 0 + || (rm_shkp = svr.rooms[rno - ROOMOFFSET].resident) == 0 || rm_shkp == shkp) otmp->no_charge = 0; } @@ -386,8 +386,8 @@ setpaid(struct monst *shkp) clear_unpaid(shkp, gi.invent); clear_unpaid(shkp, fobj); - if (gl.level.buriedobjlist) - clear_unpaid(shkp, gl.level.buriedobjlist); + if (svl.level.buriedobjlist) + clear_unpaid(shkp, svl.level.buriedobjlist); if (gt.thrownobj) clear_unpaid_obj(shkp, gt.thrownobj); if (gk.kickedobj) @@ -401,7 +401,7 @@ setpaid(struct monst *shkp) /* clear obj->no_charge for all obj in shkp's shop */ clear_no_charge(shkp, fobj); - clear_no_charge(shkp, gl.level.buriedobjlist); + clear_no_charge(shkp, svl.level.buriedobjlist); while ((obj = gb.billobjs) != 0) { obj_extract_self(obj); @@ -442,10 +442,10 @@ call_kops(struct monst *shkp, boolean nearshop) if (!Deaf) pline("An alarm sounds!"); - nokops = ((gm.mvitals[PM_KEYSTONE_KOP].mvflags & G_GONE) - && (gm.mvitals[PM_KOP_SERGEANT].mvflags & G_GONE) - && (gm.mvitals[PM_KOP_LIEUTENANT].mvflags & G_GONE) - && (gm.mvitals[PM_KOP_KAPTAIN].mvflags & G_GONE)); + nokops = ((svm.mvitals[PM_KEYSTONE_KOP].mvflags & G_GONE) + && (svm.mvitals[PM_KOP_SERGEANT].mvflags & G_GONE) + && (svm.mvitals[PM_KOP_LIEUTENANT].mvflags & G_GONE) + && (svm.mvitals[PM_KOP_KAPTAIN].mvflags & G_GONE)); if (!angry_guards(!!Deaf) && nokops) { if (flags.verbose && !Deaf) @@ -532,7 +532,7 @@ u_left_shop(char *leavestring, boolean newlev) SetVoice(shkp, 0, 80, 0); verbalize(not_upset ? "%s! Please pay before leaving." : "%s! Don't you leave without paying!", - gp.plname); + svp.plname); } else { pline("%s %s that you need to pay before leaving%s", Shknam(shkp), @@ -646,7 +646,7 @@ staticfn void deserted_shop(/*const*/ char *enterstring) { struct monst *mtmp; - struct mkroom *r = &gr.rooms[(int) *enterstring - ROOMOFFSET]; + struct mkroom *r = &svr.rooms[(int) *enterstring - ROOMOFFSET]; int x, y, m = 0, n = 0; for (x = r->lx; x <= r->hx; ++x) @@ -708,11 +708,11 @@ u_entered_shop(char *enterstring) eshkp->bill_p = &(eshkp->bill[0]); if ((!eshkp->visitct || *eshkp->customer) - && strncmpi(eshkp->customer, gp.plname, PL_NSIZ)) { + && strncmpi(eshkp->customer, svp.plname, PL_NSIZ)) { /* You seem to be new here */ eshkp->visitct = 0; eshkp->following = 0; - (void) strncpy(eshkp->customer, gp.plname, PL_NSIZ); + (void) strncpy(eshkp->customer, svp.plname, PL_NSIZ); pacify_shk(shkp, TRUE); } @@ -731,12 +731,12 @@ u_entered_shop(char *enterstring) return; } - rt = gr.rooms[*enterstring - ROOMOFFSET].rtype; + rt = svr.rooms[*enterstring - ROOMOFFSET].rtype; if (ANGRY(shkp)) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); - verbalize("So, %s, you dare return to %s %s?!", gp.plname, + verbalize("So, %s, you dare return to %s %s?!", svp.plname, s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); } else { pline("%s seems %s over your return to %s %s!", @@ -747,7 +747,7 @@ u_entered_shop(char *enterstring) if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("Back again, %s? I've got my %s on you.", - gp.plname, mbodypart(shkp, EYE)); + svp.plname, mbodypart(shkp, EYE)); } else { pline_The("atmosphere at %s %s seems unwelcoming.", s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); @@ -764,7 +764,7 @@ u_entered_shop(char *enterstring) } else { if (!Deaf && !muteshk(shkp)) { set_voice(shkp, 0, 80, 0); - verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), gp.plname, + verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), svp.plname, eshkp->visitct++ ? " again" : "", s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); } else { @@ -853,7 +853,7 @@ pick_pick(struct obj *obj) /* if you bring a sack of N picks into a shop to sell, don't repeat this N times when they're taken out */ - if (gm.moves != pickmovetime) { + if (svm.moves != pickmovetime) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("You sneaky %s! Get out of here with that pick!", @@ -865,7 +865,7 @@ pick_pick(struct obj *obj) : "is dismayed because of"); } } - pickmovetime = gm.moves; + pickmovetime = svm.moves; } } @@ -976,7 +976,7 @@ shop_keeper(char rmno) { struct monst *shkp; - shkp = (rmno >= ROOMOFFSET) ? gr.rooms[rmno - ROOMOFFSET].resident : 0; + shkp = (rmno >= ROOMOFFSET) ? svr.rooms[rmno - ROOMOFFSET].resident : 0; if (shkp) { if (has_eshk(shkp)) { if (ANGRY(shkp)) { @@ -989,13 +989,13 @@ shop_keeper(char rmno) shkp->isshk ? "shopkeeper career change" : "shop resident not shopkeeper", (int) rmno, - (int) gr.rooms[rmno - ROOMOFFSET].rtype, + (int) svr.rooms[rmno - ROOMOFFSET].rtype, shkp->mnum, /* [real shopkeeper name is kept in ESHK, not MGIVENNAME] */ has_mgivenname(shkp) ? MGIVENNAME(shkp) : "anonymous"); /* not sure if this is appropriate, because it does nothing to - correct the underlying gr.rooms[].resident issue but... */ + correct the underlying svr.rooms[].resident issue but... */ return (struct monst *) 0; } } @@ -1237,7 +1237,7 @@ home_shk(struct monst *shkp, boolean killkops) coordxy x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y; (void) mnearto(shkp, x, y, TRUE, RLOC_NOMSG); - gl.level.flags.has_shop = 1; + svl.level.flags.has_shop = 1; if (killkops) { kops_gone(TRUE); pacify_guards(); @@ -1370,7 +1370,7 @@ hot_pursuit(struct monst *shkp) return; rile_shk(shkp); - (void) strncpy(ESHK(shkp)->customer, gp.plname, PL_NSIZ); + (void) strncpy(ESHK(shkp)->customer, svp.plname, PL_NSIZ); ESHK(shkp)->following = 1; /* shopkeeper networking: clear obj->no_charge for all obj on the @@ -1846,7 +1846,7 @@ dopay(void) : shkname(shkp), noit_mhim(shkp)); pay(1000L, shkp); - if (strncmp(eshkp->customer, gp.plname, PL_NSIZ) || rn2(3)) + if (strncmp(eshkp->customer, svp.plname, PL_NSIZ) || rn2(3)) make_happy_shk(shkp, FALSE); else pline("But %s is as angry as ever.", shkname(shkp)); @@ -2564,7 +2564,7 @@ inherits( if (!silently) pline("%s %s the %ld %s %sowed %s.", Shknam(shkp), takes, loss, currency(loss), - strncmp(eshkp->customer, gp.plname, PL_NSIZ) ? "" + strncmp(eshkp->customer, svp.plname, PL_NSIZ) ? "" : "you ", noit_mhim(shkp)); /* shopkeeper has now been paid in full */ @@ -2693,7 +2693,7 @@ find_oid(unsigned int id) return obj; if ((obj = o_on(id, fobj)) != 0) return obj; - if ((obj = o_on(id, gl.level.buriedobjlist)) != 0) + if ((obj = o_on(id, svl.level.buriedobjlist)) != 0) return obj; if ((obj = o_on(id, gm.migrating_objs)) != 0) return obj; @@ -3574,7 +3574,7 @@ sub_one_frombill(struct obj *obj, struct monst *shkp) otmp = newobj(); *otmp = *obj; otmp->oextra = (struct oextra *) 0; - bp->bo_id = otmp->o_id = next_ident(); /* gc.context.ident++ */ + bp->bo_id = otmp->o_id = next_ident(); /* svc.context.ident++ */ otmp->where = OBJ_FREE; otmp->quan = (bp->bquan -= obj->quan); otmp->owt = 0; /* superfluous */ @@ -3769,7 +3769,7 @@ stolen_value( if (!silent) { if (canseemon(shkp)) { Norep("%s booms: \"%s, you are a thief!\"", - Shknam(shkp), gp.plname); + Shknam(shkp), svp.plname); } else if (!Deaf) { Norep("You hear a scream, \"Thief!\""); /* Deaf-aware */ } @@ -4320,22 +4320,22 @@ add_damage( if (!*shops) return; } - for (tmp_dam = gl.level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) + for (tmp_dam = svl.level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) if (tmp_dam->place.x == x && tmp_dam->place.y == y) { tmp_dam->cost += cost; - tmp_dam->when = gm.moves; /* needed by pay_for_damage() */ + tmp_dam->when = svm.moves; /* needed by pay_for_damage() */ return; } tmp_dam = (struct damage *) alloc((unsigned) sizeof *tmp_dam); (void) memset((genericptr_t) tmp_dam, 0, sizeof *tmp_dam); - tmp_dam->when = gm.moves; + tmp_dam->when = svm.moves; tmp_dam->place.x = x; tmp_dam->place.y = y; tmp_dam->cost = cost; tmp_dam->typ = levl[x][y].typ; tmp_dam->flags = levl[x][y].flags; - tmp_dam->next = gl.level.damagelist; - gl.level.damagelist = tmp_dam; + tmp_dam->next = svl.level.damagelist; + svl.level.damagelist = tmp_dam; /* If player saw damage, display walls post-repair as walls, not stone */ if (cansee(x, y)) levl[x][y].seenv = SVALL; @@ -4367,7 +4367,7 @@ repairable_damage(struct damage *dam, struct monst *shkp) y = dam->place.y; /* too soon to fix it? */ - if ((gm.moves - dam->when) < REPAIR_DELAY) + if ((svm.moves - dam->when) < REPAIR_DELAY) return FALSE; /* is it a wall? don't fix if anyone is in the way */ if (!IS_ROOM(dam->typ)) { @@ -4395,7 +4395,7 @@ repairable_damage(struct damage *dam, struct monst *shkp) staticfn struct damage * find_damage(struct monst *shkp) { - struct damage *dam = gl.level.damagelist; + struct damage *dam = svl.level.damagelist; if (shk_impaired(shkp)) return NULL; @@ -4416,10 +4416,10 @@ discard_damage_struct(struct damage *dam) if (!dam) return; - if (dam == gl.level.damagelist) { - gl.level.damagelist = dam->next; + if (dam == svl.level.damagelist) { + svl.level.damagelist = dam->next; } else { - struct damage *prev = gl.level.damagelist; + struct damage *prev = svl.level.damagelist; while (prev && prev->next != dam) prev = prev->next; @@ -4434,7 +4434,7 @@ discard_damage_struct(struct damage *dam) staticfn void discard_damage_owned_by(struct monst *shkp) { - struct damage *dam = gl.level.damagelist, *dam2, *prevdam = NULL; + struct damage *dam = svl.level.damagelist, *dam2, *prevdam = NULL; while (dam) { coordxy x = dam->place.x, y = dam->place.y; @@ -4443,8 +4443,8 @@ discard_damage_owned_by(struct monst *shkp) dam2 = dam->next; if (prevdam) prevdam->next = dam2; - if (dam == gl.level.damagelist) - gl.level.damagelist = dam2; + if (dam == svl.level.damagelist) + svl.level.damagelist = dam2; (void) memset(dam, 0, sizeof(struct damage)); free((genericptr_t) dam); dam = dam2; @@ -4504,7 +4504,7 @@ litter_getpos( (void) memset((genericptr_t) litter, 0, 9 * sizeof *litter); - if (gl.level.objects[x][y] && !IS_ROOM(levl[x][y].typ)) { + if (svl.level.objects[x][y] && !IS_ROOM(levl[x][y].typ)) { for (i = 0; i < 9; i++) { ix = x + horiz(i); iy = y + vert(i); @@ -4557,7 +4557,7 @@ litter_scatter( unplacebc(); /* pick 'em up */ placebc(); /* put 'em down */ } - while ((otmp = gl.level.objects[x][y]) != 0) { + while ((otmp = svl.level.objects[x][y]) != 0) { /* Don't mess w/ boulders -- just merge into wall */ if (otmp->otyp == BOULDER || otmp->otyp == ROCK) { obj_extract_self(otmp); @@ -4566,7 +4566,7 @@ litter_scatter( int trylimit = 10; int i = rn2(9), ix, iy; - /* otmp must be moved otherwise gl.level.objects[x][y] will + /* otmp must be moved otherwise svl.level.objects[x][y] will never become Null and while-loop won't terminate */ do { i = (i + 1) % 9; @@ -4759,7 +4759,7 @@ fix_shop_damage(void) struct damage *damg, *nextdamg; /* if this level has no shop damage, there's nothing to do */ - if (!gl.level.damagelist) + if (!svl.level.damagelist) return; /* go through all shopkeepers on the level */ @@ -4771,7 +4771,7 @@ fix_shop_damage(void) /* go through all damage data trying to have this shopkeeper fix it; repair_damage() will only make repairs for damage matching shop controlled by specified shopkeeper */ - for (damg = gl.level.damagelist; damg; damg = nextdamg) { + for (damg = svl.level.damagelist; damg; damg = nextdamg) { nextdamg = damg->next; if (repair_damage(shkp, damg, TRUE)) discard_damage_struct(damg); @@ -4807,26 +4807,26 @@ shk_move(struct monst *shkp) return 0; } if (eshkp->following) { - if (strncmp(eshkp->customer, gp.plname, PL_NSIZ)) { + if (strncmp(eshkp->customer, svp.plname, PL_NSIZ)) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("%s, %s! I was looking for %s.", Hello(shkp), - gp.plname, eshkp->customer); + svp.plname, eshkp->customer); } eshkp->following = 0; return 0; } - if (gm.moves > gf.followmsg + 4) { + if (svm.moves > gf.followmsg + 4) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("%s, %s! Didn't you forget to pay?", - Hello(shkp), gp.plname); + Hello(shkp), svp.plname); } else { pline("%s holds out %s upturned %s.", Shknam(shkp), noit_mhis(shkp), mbodypart(shkp, HAND)); } - gf.followmsg = gm.moves; + gf.followmsg = svm.moves; if (!rn2(9)) { pline("%s doesn't like customers who don't pay.", Shknam(shkp)); @@ -4908,7 +4908,7 @@ after_shk_move(struct monst *shkp) /* reset bill_p, need to re-calc player's occupancy too */ eshkp->bill_p = &eshkp->bill[0]; /* only re-check occupancy if game hasn't just ended */ - if (!gp.program_state.gameover) + if (!svp.program_state.gameover) check_special_room(FALSE); } } @@ -5031,7 +5031,7 @@ makekops(coord *mm) if ((cnt = k_cnt[k]) == 0) break; mndx = k_mndx[k]; - if (gm.mvitals[mndx].mvflags & G_GONE) + if (svm.mvitals[mndx].mvflags & G_GONE) continue; while (cnt--) @@ -5057,10 +5057,10 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) nearest_damage = nearest_shk; int picks = 0; - for (tmp_dam = gl.level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) { + for (tmp_dam = svl.level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) { char *shp; - if (tmp_dam->when != gm.moves || !tmp_dam->cost) + if (tmp_dam->when != svm.moves || !tmp_dam->cost) continue; cost_of_damage += tmp_dam->cost; Strcpy(shops_affected, @@ -5107,7 +5107,7 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) y = appear_here->place.y; /* not the best introduction to the shk... */ - (void) strncpy(ESHK(shkp)->customer, gp.plname, PL_NSIZ); + (void) strncpy(ESHK(shkp)->customer, svp.plname, PL_NSIZ); /* if the shk is already on the war path, be sure it's all out */ if (ANGRY(shkp) || ESHK(shkp)->following) { @@ -5247,7 +5247,7 @@ costly_spot(coordxy x, coordxy y) struct monst *shkp; struct eshk *eshkp; - if (!gl.level.flags.has_shop) + if (!svl.level.flags.has_shop) return FALSE; shkp = shop_keeper(*in_rooms(x, y, SHOPBASE)); if (!shkp || !inhishop(shkp)) @@ -5287,7 +5287,7 @@ shop_object(coordxy x, coordxy y) if (!shkp || !inhishop(shkp)) return (struct obj *) 0; - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (otmp->oclass != COIN_CLASS) break; /* note: otmp might have ->no_charge set, but that's ok */ @@ -5438,18 +5438,18 @@ shk_chat(struct monst *shkp) (!Deaf && !muteshk(shkp)) ? "mentions" : "indicates", noit_mhe(shkp), eshk->robbed ? "non-paying" : "rude"); } else if (eshk->following) { - if (strncmp(eshk->customer, gp.plname, PL_NSIZ)) { + if (strncmp(eshk->customer, svp.plname, PL_NSIZ)) { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("%s %s! I was looking for %s.", - Hello(shkp), gp.plname, eshk->customer); + Hello(shkp), svp.plname, eshk->customer); } eshk->following = 0; } else { if (!Deaf && !muteshk(shkp)) { SetVoice(shkp, 0, 80, 0); verbalize("%s %s! Didn't you forget to pay?", - Hello(shkp), gp.plname); + Hello(shkp), svp.plname); } else { pline("%s taps you on the %s.", Shknam(shkp), body_part(ARM)); diff --git a/src/shknam.c b/src/shknam.c index e1b5bd861..994e6238d 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -413,7 +413,7 @@ shkveg(void) j = maxprob = 0; ok[0] = 0; /* lint suppression */ - for (i = gb.bases[(int) oclass]; i < NUM_OBJECTS; ++i) { + for (i = svb.bases[(int) oclass]; i < NUM_OBJECTS; ++i) { if (objects[i].oc_class != oclass) break; @@ -463,7 +463,7 @@ mkshobj_at(const struct shclass *shp, int sx, int sy, boolean mkspecl) struct obj *novel = mksobj_at(SPE_NOVEL, sx, sy, FALSE, FALSE); if (novel) - gc.context.tribute.bookstock = TRUE; + svc.context.tribute.bookstock = TRUE; return; } @@ -575,7 +575,7 @@ free_eshk(struct monst *mtmp) } /* find a door in room sroom which is good for shop entrance. - returns -1 if no good door found, or the gd.doors index + returns -1 if no good door found, or the svd.doors index and the door coordinates in sx, sy */ staticfn int good_shopdoor(struct mkroom *sroom, coordxy *sx, coordxy *sy) @@ -585,12 +585,12 @@ good_shopdoor(struct mkroom *sroom, coordxy *sx, coordxy *sy) for (i = 0; i < sroom->doorct; i++) { int di = sroom->fdoor + i; - *sx = gd.doors[di].x; - *sy = gd.doors[di].y; + *sx = svd.doors[di].x; + *sy = svd.doors[di].y; /* check that the shopkeeper placement is sane */ if (sroom->irregular) { - int rmno = (int) ((sroom - gr.rooms) + ROOMOFFSET); + int rmno = (int) ((sroom - svr.rooms) + ROOMOFFSET); if (isok(*sx - 1, *sy) && !levl[*sx - 1][*sy].edge && (int) levl[*sx - 1][*sy].roomno == rmno) @@ -646,7 +646,7 @@ shkinit(const struct shclass *shp, struct mkroom *sroom) pline("doormax=%d doorct=%d fdoor=%d", gd.doorindex, sroom->doorct, sh); while (j--) { - pline("door [%d,%d]", gd.doors[sh].x, gd.doors[sh].y); + pline("door [%d,%d]", svd.doors[sh].x, svd.doors[sh].y); sh++; } display_nhwindow(WIN_MESSAGE, FALSE); @@ -666,11 +666,11 @@ shkinit(const struct shclass *shp, struct mkroom *sroom) set_malign(shk); shk->msleeping = 0; mon_learns_traps(shk, ALL_TRAPS); /* we know all the traps already */ - eshkp->shoproom = (schar) ((sroom - gr.rooms) + ROOMOFFSET); + eshkp->shoproom = (schar) ((sroom - svr.rooms) + ROOMOFFSET); sroom->resident = shk; eshkp->shoptype = sroom->rtype; assign_level(&eshkp->shoplevel, &u.uz); - eshkp->shd = gd.doors[sh]; + eshkp->shd = svd.doors[sh]; eshkp->shk.x = sx; eshkp->shk.y = sy; eshkp->robbed = eshkp->credit = eshkp->debit = eshkp->loan = 0L; @@ -692,12 +692,12 @@ stock_room_goodpos(struct mkroom *sroom, int rmno, int sh, int sx, int sy) if (sroom->irregular) { if (levl[sx][sy].edge || (int) levl[sx][sy].roomno != rmno - || distmin(sx, sy, gd.doors[sh].x, gd.doors[sh].y) <= 1) + || distmin(sx, sy, svd.doors[sh].x, svd.doors[sh].y) <= 1) return FALSE; - } else if ((sx == sroom->lx && gd.doors[sh].x == sx - 1) - || (sx == sroom->hx && gd.doors[sh].x == sx + 1) - || (sy == sroom->ly && gd.doors[sh].y == sy - 1) - || (sy == sroom->hy && gd.doors[sh].y == sy + 1)) + } else if ((sx == sroom->lx && svd.doors[sh].x == sx - 1) + || (sx == sroom->hx && svd.doors[sh].x == sx + 1) + || (sy == sroom->ly && svd.doors[sh].y == sy - 1) + || (sy == sroom->hy && svd.doors[sh].y == sy + 1)) return FALSE; /* only generate items on solid floor squares */ @@ -721,7 +721,7 @@ stock_room(int shp_indx, struct mkroom *sroom) int sx, sy, sh; int stockcount = 0, specialspot = 0; char buf[BUFSZ]; - int rmno = (int) ((sroom - gr.rooms) + ROOMOFFSET); + int rmno = (int) ((sroom - svr.rooms) + ROOMOFFSET); const struct shclass *shp = &shtypes[shp_indx]; /* first, try to place a shopkeeper in the room */ @@ -729,8 +729,8 @@ stock_room(int shp_indx, struct mkroom *sroom) return; /* make sure no doorways without doors, and no trapped doors, in shops */ - sx = gd.doors[sroom->fdoor].x; - sy = gd.doors[sroom->fdoor].y; + sx = svd.doors[sroom->fdoor].x; + sy = svd.doors[sroom->fdoor].y; if (levl[sx][sy].doormask == D_NODOOR) { levl[sx][sy].doormask = D_ISOPEN; newsym(sx, sy); @@ -760,7 +760,7 @@ stock_room(int shp_indx, struct mkroom *sroom) || *in_rooms(m, n, 0)) ? ROOM : CORR; } - if (gc.context.tribute.enabled && !gc.context.tribute.bookstock) { + if (svc.context.tribute.enabled && !svc.context.tribute.bookstock) { /* * Out of the number of spots where we're actually * going to put stuff, randomly single out one in particular. @@ -792,7 +792,7 @@ stock_room(int shp_indx, struct mkroom *sroom) mongone(mtmp); } - gl.level.flags.has_shop = TRUE; + svl.level.flags.has_shop = TRUE; } /* does shkp's shop stock this item type? */ @@ -865,7 +865,7 @@ shkname(struct monst *mtmp) } else { const char *shknm = ESHK(mtmp)->shknam; - if (Hallucination && !gp.program_state.gameover) { + if (Hallucination && !svp.program_state.gameover) { const char *const *nlp; int num; diff --git a/src/sit.c b/src/sit.c index 1edd4f4c9..0d55d7470 100644 --- a/src/sit.c +++ b/src/sit.c @@ -135,7 +135,7 @@ throne_sit_effect(void) break; case 10: if (Luck < 0 || (HSee_invisible & INTRINSIC)) { - if (gl.level.flags.nommap) { + if (svl.level.flags.nommap) { pline("A terrible drone fills your head!"); make_confused((HConfusion & TIMEOUT) + (long) rnd(30), FALSE); @@ -303,7 +303,7 @@ dosit(void) && !(uteetering_at_seen_pit(trap) || uescaped_shaft(trap))) { struct obj *obj; - obj = gl.level.objects[u.ux][u.uy]; + obj = svl.level.objects[u.ux][u.uy]; if (gy.youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) { You("coil up around your %shoard.", (obj->quan + money_cnt(gi.invent) < u.ulevel * 1000) diff --git a/src/sounds.c b/src/sounds.c index a6b078d7e..adb8d94c8 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -22,7 +22,7 @@ mon_in_room(struct monst *mon, int rmtyp) { int rno = levl[mon->mx][mon->my].roomno; if (rno >= ROOMOFFSET) - return gr.rooms[rno - ROOMOFFSET].rtype == rmtyp; + return svr.rooms[rno - ROOMOFFSET].rtype == rmtyp; return FALSE; } @@ -211,24 +211,24 @@ dosounds(void) hallu = Hallucination ? 1 : 0; - if (gl.level.flags.nfountains && !rn2(400)) { + if (svl.level.flags.nfountains && !rn2(400)) { static const char *const fountain_msg[4] = { "bubbling water.", "water falling on coins.", "the splashing of a naiad.", "a soda fountain!", }; You_hear1(fountain_msg[rn2(3) + hallu]); } - if (gl.level.flags.nsinks && !rn2(300)) { + if (svl.level.flags.nsinks && !rn2(300)) { static const char *const sink_msg[3] = { "a slow drip.", "a gurgling noise.", "dishes being washed!", }; You_hear1(sink_msg[rn2(2) + hallu]); } - if (gl.level.flags.has_court && !rn2(200)) { + if (svl.level.flags.has_court && !rn2(200)) { if (get_iter_mons(throne_mon_sound)) return; } - if (gl.level.flags.has_swamp && !rn2(200)) { + if (svl.level.flags.has_swamp && !rn2(200)) { static const char *const swamp_msg[3] = { "hear mosquitoes!", "smell marsh gas!", /* so it's a smell...*/ "hear Donald Duck!", @@ -236,10 +236,10 @@ dosounds(void) You1(swamp_msg[rn2(2) + hallu]); return; } - if (gl.level.flags.has_vault && !rn2(200)) { + if (svl.level.flags.has_vault && !rn2(200)) { if (!(sroom = search_special(VAULT))) { /* strange ... */ - gl.level.flags.has_vault = 0; + svl.level.flags.has_vault = 0; return; } if (gd_sound()) @@ -275,15 +275,15 @@ dosounds(void) } return; } - if (gl.level.flags.has_beehive && !rn2(200)) { + if (svl.level.flags.has_beehive && !rn2(200)) { if (get_iter_mons(beehive_mon_sound)) return; } - if (gl.level.flags.has_morgue && !rn2(200)) { + if (svl.level.flags.has_morgue && !rn2(200)) { if (get_iter_mons(morgue_mon_sound)) return; } - if (gl.level.flags.has_barracks && !rn2(200)) { + if (svl.level.flags.has_barracks && !rn2(200)) { static const char *const barracks_msg[4] = { "blades being honed.", "loud snoring.", "dice being thrown.", "General MacArthur!", @@ -306,14 +306,14 @@ dosounds(void) } } } - if (gl.level.flags.has_zoo && !rn2(200)) { + if (svl.level.flags.has_zoo && !rn2(200)) { if (get_iter_mons(zoo_mon_sound)) return; } - if (gl.level.flags.has_shop && !rn2(200)) { + if (svl.level.flags.has_shop && !rn2(200)) { if (!(sroom = search_special(ANY_SHOP))) { /* strange... */ - gl.level.flags.has_shop = 0; + svl.level.flags.has_shop = 0; return; } if (tended_shop(sroom) @@ -326,7 +326,7 @@ dosounds(void) } return; } - if (gl.level.flags.has_temple && !rn2(200) + if (svl.level.flags.has_temple && !rn2(200) && !(Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) { if (get_iter_mons(temple_priest_sound)) return; @@ -414,7 +414,7 @@ growl(struct monst *mtmp) if (canseemon(mtmp) || !Deaf) { pline("%s %s!", Monnam(mtmp), vtense((char *) 0, growl_verb)); iflags.last_msg = PLNMSG_GROWL; - if (gc.context.run) + if (svc.context.run) nomul(0); } wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 18); @@ -464,7 +464,7 @@ yelp(struct monst *mtmp) if (yelp_verb) { Soundeffect(se, 70); /* Soundeffect() handles Deaf or not Deaf */ pline("%s %s!", Monnam(mtmp), vtense((char *) 0, yelp_verb)); - if (gc.context.run) + if (svc.context.run) nomul(0); wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 12); } @@ -504,7 +504,7 @@ whimper(struct monst *mtmp) Soundeffect(se, 50); } pline("%s %s.", Monnam(mtmp), vtense((char *) 0, whimper_verb)); - if (gc.context.run) + if (svc.context.run) nomul(0); wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 6); } @@ -693,7 +693,7 @@ domonnoise(struct monst *mtmp) return ECMD_OK; /* leader might be poly'd; if he can still speak, give leader speech */ - if (mtmp->m_id == gq.quest_status.leader_m_id && msound > MS_ANIMAL) + if (mtmp->m_id == svq.quest_status.leader_m_id && msound > MS_ANIMAL) msound = MS_LEADER; /* make sure it's your role's quest guardian; adjust if not */ else if (msound == MS_GUARDIAN && ptr != &mons[gu.urole.guardnum]) @@ -839,9 +839,9 @@ domonnoise(struct monst *mtmp) } else if (mtmp->mpeaceful) { if (mtmp->mtame && (mtmp->mconf || mtmp->mflee || mtmp->mtrapped - || gm.moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5)) + || svm.moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5)) pline_msg = "whines."; - else if (mtmp->mtame && EDOG(mtmp)->hungrytime > gm.moves + 1000) + else if (mtmp->mtame && EDOG(mtmp)->hungrytime > svm.moves + 1000) pline_msg = "yips."; else { if (ptr != &mons[PM_DINGO]) /* dingos do not actually bark */ @@ -857,10 +857,10 @@ domonnoise(struct monst *mtmp) || mtmp->mtame < 5) { Soundeffect(se_feline_yowl, 80); pline_msg = "yowls."; - } else if (gm.moves > EDOG(mtmp)->hungrytime) { + } else if (svm.moves > EDOG(mtmp)->hungrytime) { Soundeffect(se_feline_meow, 80); pline_msg = "meows."; - } else if (EDOG(mtmp)->hungrytime > gm.moves + 1000) { + } else if (EDOG(mtmp)->hungrytime > svm.moves + 1000) { Soundeffect(se_feline_purr, 40); pline_msg = "purrs."; } else { @@ -910,7 +910,7 @@ domonnoise(struct monst *mtmp) if (mtmp->mtame < 5) { Soundeffect(se_equine_neigh, 60); pline_msg = "neighs."; - } else if (gm.moves > EDOG(mtmp)->hungrytime) { + } else if (svm.moves > EDOG(mtmp)->hungrytime) { Soundeffect(se_equine_whinny, 60); pline_msg = "whinnies."; } else { @@ -1045,7 +1045,7 @@ domonnoise(struct monst *mtmp) } else if (mtmp->mhp < mtmp->mhpmax / 2) pline_msg = "asks for a potion of healing."; else if (mtmp->mtame && !mtmp->isminion - && gm.moves > EDOG(mtmp)->hungrytime) + && svm.moves > EDOG(mtmp)->hungrytime) verbl_msg = "I'm hungry."; /* Specific monsters' interests */ else if (is_elf(ptr)) @@ -1191,7 +1191,7 @@ domonnoise(struct monst *mtmp) boolean ms_Death = (ptr == &mons[PM_DEATH]); /* 3.6 tribute */ - if (ms_Death && !gc.context.tribute.Deathnotice + if (ms_Death && !svc.context.tribute.Deathnotice && (book = u_have_novel()) != 0) { if ((tribtitle = noveltitle(&book->novelidx)) != 0) { Sprintf(verbuf, "Ah, so you have a copy of /%s/.", tribtitle); @@ -1201,7 +1201,7 @@ domonnoise(struct monst *mtmp) Strcat(verbuf, " I may have been misquoted there."); verbl_msg = verbuf; } - gc.context.tribute.Deathnotice = 1; + svc.context.tribute.Deathnotice = 1; } else if (ms_Death && rn2(3) && Death_quote(verbuf, sizeof verbuf)) { verbl_msg = verbuf; /* end of tribute addition */ @@ -1338,7 +1338,7 @@ dochat(void) /* Talking to a wall; secret door remains hidden by behaving like a wall; IS_WALL() test excludes solid rock even when that serves as a wall bordering a corridor */ - if (Blind && !IS_WALL(gl.lastseentyp[tx][ty])) { + if (Blind && !IS_WALL(svl.lastseentyp[tx][ty])) { /* when blind, you can only talk to a wall if it has already been mapped as a wall */ ; diff --git a/src/sp_lev.c b/src/sp_lev.c index 817623089..d71e5266b 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -362,7 +362,7 @@ lvlfill_maze_grid(int x1, int y1, int x2, int y2, schar filling) for (x = x1; x <= x2; x++) for (y = y1; y <= y2; y++) { - if (gl.level.flags.corrmaze) + if (svl.level.flags.corrmaze) levl[x][y].typ = STONE; else levl[x][y].typ = (y < 2 || ((x % 2) && (y % 2))) ? STONE @@ -625,7 +625,7 @@ flip_level( } /* buried objects */ - for (otmp = gl.level.buriedobjlist; otmp; otmp = otmp->nobj) { + for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) { if (!inFlipArea(otmp->ox, otmp->oy)) continue; if (flp & 1) @@ -730,7 +730,7 @@ flip_level( } /* regions (poison clouds, etc) */ - for (i = 0; i < gn.n_regions; i++) { + for (i = 0; i < svn.n_regions; i++) { int j, tmp1, tmp2; if (flp & 1) { tmp1 = FlipY(gr.regions[i]->bounding_box.ly); @@ -759,7 +759,7 @@ flip_level( } /* rooms */ - for (sroom = &gr.rooms[0]; ; sroom++) { + for (sroom = &svr.rooms[0]; ; sroom++) { if (sroom->hx < 0) break; @@ -809,7 +809,7 @@ flip_level( /* doors */ for (i = 0; i < gd.doorindex; i++) { - Flip_coord(gd.doors[i]); + Flip_coord(svd.doors[i]); } /* the map */ @@ -825,13 +825,13 @@ flip_level( levl[x][y] = levl[x][ny]; levl[x][ny] = trm; - otmp = gl.level.objects[x][y]; - gl.level.objects[x][y] = gl.level.objects[x][ny]; - gl.level.objects[x][ny] = otmp; + otmp = svl.level.objects[x][y]; + svl.level.objects[x][y] = svl.level.objects[x][ny]; + svl.level.objects[x][ny] = otmp; - mtmp = gl.level.monsters[x][y]; - gl.level.monsters[x][y] = gl.level.monsters[x][ny]; - gl.level.monsters[x][ny] = mtmp; + mtmp = svl.level.monsters[x][y]; + svl.level.monsters[x][y] = svl.level.monsters[x][ny]; + svl.level.monsters[x][ny] = mtmp; } } if (flp & 2) { @@ -846,13 +846,13 @@ flip_level( levl[x][y] = levl[nx][y]; levl[nx][y] = trm; - otmp = gl.level.objects[x][y]; - gl.level.objects[x][y] = gl.level.objects[nx][y]; - gl.level.objects[nx][y] = otmp; + otmp = svl.level.objects[x][y]; + svl.level.objects[x][y] = svl.level.objects[nx][y]; + svl.level.objects[nx][y] = otmp; - mtmp = gl.level.monsters[x][y]; - gl.level.monsters[x][y] = gl.level.monsters[nx][y]; - gl.level.monsters[nx][y] = mtmp; + mtmp = svl.level.monsters[x][y]; + svl.level.monsters[x][y] = svl.level.monsters[nx][y]; + svl.level.monsters[nx][y] = mtmp; } } @@ -884,7 +884,7 @@ flip_level( if (ball_active && !ball_fliparea) placebc(); Flip_coord(iflags.travelcc); - Flip_coord(gc.context.digging.pos); + Flip_coord(svc.context.digging.pos); } fix_wall_spines(1, 0, COLNO - 1, ROWNO - 1); @@ -1063,7 +1063,7 @@ set_door_orientation(int x, int y) staticfn boolean shared_with_room(int x, int y, struct mkroom *droom) { - int rmno = (droom - gr.rooms) + ROOMOFFSET; + int rmno = (droom - svr.rooms) + ROOMOFFSET; if (!isok(x,y)) return FALSE; @@ -1086,7 +1086,7 @@ maybe_add_door(int x, int y, struct mkroom *droom) { if (droom->hx >= 0 && ((!droom->irregular && inside_room(droom, x, y)) - || (int) levl[x][y].roomno == (droom - gr.rooms) + ROOMOFFSET + || (int) levl[x][y].roomno == (droom - svr.rooms) + ROOMOFFSET || shared_with_room(x, y, droom))) { add_door(x, y, droom); } @@ -1107,10 +1107,10 @@ link_doors_rooms(void) directive, set/clear levl[][].horizontal for it */ set_door_orientation(x, y); - for (tmpi = 0; tmpi < gn.nroom; tmpi++) { - maybe_add_door(x, y, &gr.rooms[tmpi]); - for (m = 0; m < gr.rooms[tmpi].nsubrooms; m++) { - maybe_add_door(x, y, gr.rooms[tmpi].sbrooms[m]); + for (tmpi = 0; tmpi < svn.nroom; tmpi++) { + maybe_add_door(x, y, &svr.rooms[tmpi]); + for (m = 0; m < svr.rooms[tmpi].nsubrooms; m++) { + maybe_add_door(x, y, svr.rooms[tmpi].sbrooms[m]); } } } @@ -1149,7 +1149,7 @@ rndtrap(void) break; case LEVEL_TELEP: case TELEP_TRAP: - if (gl.level.flags.noteleport) + if (svl.level.flags.noteleport) rtrap = NO_TRAP; break; case ROLLING_BOULDER_TRAP: @@ -1168,7 +1168,7 @@ rndtrap(void) * * If x or y is negative, we generate a random coordinate within the area. If * not negative, they are interpreted as relative to the last defined map or - * room, and are output as absolute gl.level.locations coordinates. + * room, and are output as absolute svl.level.locations coordinates. * * The "humidity" flag is used to ensure that engravings aren't created * underwater, or eels on dry land. @@ -1535,10 +1535,10 @@ create_room( + rn2(hx - (lx > 0 ? lx : 3) - dx - xborder + 1); yabs = ly + (ly > 0 ? ylim : 2) + rn2(hy - (ly > 0 ? ly : 2) - dy - yborder + 1); - if (ly == 0 && hy >= (ROWNO - 1) && (!gn.nroom || !rn2(gn.nroom)) + if (ly == 0 && hy >= (ROWNO - 1) && (!svn.nroom || !rn2(svn.nroom)) && (yabs + dy > ROWNO / 2)) { yabs = rn1(3, 2); - if (gn.nroom < 4 && dy > 1) + if (svn.nroom < 4 && dy > 1) dy--; } if (!check_room(&xabs, &dx, &yabs, &dy, vault)) { @@ -1624,12 +1624,12 @@ create_room( split_rects(r1, &r2); if (!vault) { - gs.smeq[gn.nroom] = gn.nroom; + gs.smeq[svn.nroom] = svn.nroom; add_room(xabs, yabs, xabs + wtmp - 1, yabs + htmp - 1, rlit, rtype, FALSE); } else { - gr.rooms[gn.nroom].lx = xabs; - gr.rooms[gn.nroom].ly = yabs; + svr.rooms[svn.nroom].lx = xabs; + svr.rooms[svn.nroom].ly = yabs; } return TRUE; } @@ -1791,7 +1791,7 @@ create_trap(spltrap *t, struct mkroom *croom) if (t->type == VIBRATING_SQUARE) { pick_vibrasquare_location(); - maketrap(gi.inv_pos.x, gi.inv_pos.y, VIBRATING_SQUARE); + maketrap(svi.inv_pos.x, svi.inv_pos.y, VIBRATING_SQUARE); return; } else if (croom) { get_free_room_loc(&x, &y, croom, t->coord); @@ -1920,7 +1920,7 @@ create_monster(monster *m, struct mkroom *croom) pm = (struct permonst *) 0; } else if (m->id != NON_PM) { pm = &mons[m->id]; - g_mvflags = (unsigned) gm.mvitals[monsndx(pm)].mvflags; + g_mvflags = (unsigned) svm.mvitals[monsndx(pm)].mvflags; if ((pm->geno & G_UNIQ) && (g_mvflags & G_EXTINCT)) return; if (g_mvflags & G_GONE) /* genocided or extinct */ @@ -2350,9 +2350,9 @@ create_object(object *o, struct mkroom *croom) static const char prize_warning[] = "multiple prizes on %s level"; if (Is_mineend_level(&u.uz)) { - if (!gc.context.achieveo.mines_prize_oid) { - gc.context.achieveo.mines_prize_oid = otmp->o_id; - gc.context.achieveo.mines_prize_otyp = otmp->otyp; + if (!svc.context.achieveo.mines_prize_oid) { + svc.context.achieveo.mines_prize_oid = otmp->o_id; + svc.context.achieveo.mines_prize_otyp = otmp->otyp; /* prevent stacking; cleared when achievement is recorded; will be reset in addinv_core1() */ otmp->nomerge = 1; @@ -2360,9 +2360,9 @@ create_object(object *o, struct mkroom *croom) impossible(prize_warning, "mines end"); } } else if (Is_sokoend_level(&u.uz)) { - if (!gc.context.achieveo.soko_prize_oid) { - gc.context.achieveo.soko_prize_oid = otmp->o_id; - gc.context.achieveo.soko_prize_otyp = otmp->otyp; + if (!svc.context.achieveo.soko_prize_oid) { + svc.context.achieveo.soko_prize_oid = otmp->o_id; + svc.context.achieveo.soko_prize_otyp = otmp->otyp; otmp->nomerge = 1; /* redundant; Sokoban prizes don't stack; * will be reset in addinv_core1() */ } else { @@ -2415,7 +2415,7 @@ create_altar(altar *a, struct mkroom *croom) } else { get_location_coord(&x, &y, DRY, croom, a->coord); if ((sproom = (schar) *in_rooms(x, y, TEMPLE)) != 0) - croom = &gr.rooms[sproom - ROOMOFFSET]; + croom = &svr.rooms[sproom - ROOMOFFSET]; else croom_is_temple = FALSE; } @@ -2439,7 +2439,7 @@ create_altar(altar *a, struct mkroom *croom) levl[x][y].altarmask |= AM_SHRINE; if (a->shrine == 2) /* high altar or sanctum */ levl[x][y].altarmask |= AM_SANCTUM; - gl.level.flags.has_temple = TRUE; + svl.level.flags.has_temple = TRUE; } } @@ -2636,11 +2636,11 @@ create_corridor(corridor *c) impossible("create_corridor to/from a random wall"); return; } - if (!search_door(&gr.rooms[c->src.room], &org.x, &org.y, c->src.wall, + if (!search_door(&svr.rooms[c->src.room], &org.x, &org.y, c->src.wall, c->src.door)) return; if (c->dest.room != -1) { - if (!search_door(&gr.rooms[c->dest.room], + if (!search_door(&svr.rooms[c->dest.room], &dest.x, &dest.y, c->dest.wall, c->dest.door)) return; switch (c->src.wall) { @@ -2703,7 +2703,7 @@ fill_special_room(struct mkroom *croom) /* Shop ? */ if (croom->rtype >= SHOPBASE) { stock_room(croom->rtype - SHOPBASE, croom); - gl.level.flags.has_shop = TRUE; + svl.level.flags.has_shop = TRUE; return; } @@ -2728,28 +2728,28 @@ fill_special_room(struct mkroom *croom) } switch (croom->rtype) { case VAULT: - gl.level.flags.has_vault = TRUE; + svl.level.flags.has_vault = TRUE; break; case ZOO: - gl.level.flags.has_zoo = TRUE; + svl.level.flags.has_zoo = TRUE; break; case COURT: - gl.level.flags.has_court = TRUE; + svl.level.flags.has_court = TRUE; break; case MORGUE: - gl.level.flags.has_morgue = TRUE; + svl.level.flags.has_morgue = TRUE; break; case BEEHIVE: - gl.level.flags.has_beehive = TRUE; + svl.level.flags.has_beehive = TRUE; break; case BARRACKS: - gl.level.flags.has_barracks = TRUE; + svl.level.flags.has_barracks = TRUE; break; case TEMPLE: - gl.level.flags.has_temple = TRUE; + svl.level.flags.has_temple = TRUE; break; case SWAMP: - gl.level.flags.has_swamp = TRUE; + svl.level.flags.has_swamp = TRUE; break; } } @@ -2765,7 +2765,7 @@ build_room(room *r, struct mkroom *mkr) aroom = &gs.subrooms[gn.nsubroom]; okroom = create_subroom(mkr, r->x, r->y, r->w, r->h, rtype, r->rlit); } else { - aroom = &gr.rooms[gn.nroom]; + aroom = &svr.rooms[svn.nroom]; okroom = create_room(r->x, r->y, r->w, r->h, r->xalign, r->yalign, rtype, r->rlit); } @@ -3692,31 +3692,31 @@ lspo_level_flags(lua_State *L) const char *s = luaL_checkstring(L, i); if (!strcmpi(s, "noteleport")) - gl.level.flags.noteleport = 1; + svl.level.flags.noteleport = 1; else if (!strcmpi(s, "hardfloor")) - gl.level.flags.hardfloor = 1; + svl.level.flags.hardfloor = 1; else if (!strcmpi(s, "nommap")) - gl.level.flags.nommap = 1; + svl.level.flags.nommap = 1; else if (!strcmpi(s, "shortsighted")) - gl.level.flags.shortsighted = 1; + svl.level.flags.shortsighted = 1; else if (!strcmpi(s, "arboreal")) - gl.level.flags.arboreal = 1; + svl.level.flags.arboreal = 1; else if (!strcmpi(s, "mazelevel")) - gl.level.flags.is_maze_lev = 1; + svl.level.flags.is_maze_lev = 1; else if (!strcmpi(s, "shroud")) - gl.level.flags.hero_memory = 1; + svl.level.flags.hero_memory = 1; else if (!strcmpi(s, "graveyard")) - gl.level.flags.graveyard = 1; + svl.level.flags.graveyard = 1; else if (!strcmpi(s, "icedpools")) icedpools = 1; else if (!strcmpi(s, "corrmaze")) - gl.level.flags.corrmaze = 1; + svl.level.flags.corrmaze = 1; else if (!strcmpi(s, "premapped")) gc.coder->premapped = 1; else if (!strcmpi(s, "solidify")) gc.coder->solidify = 1; else if (!strcmpi(s, "sokoban")) - Sokoban = 1; /* gl.level.flags.sokoban_rules */ + Sokoban = 1; /* svl.level.flags.sokoban_rules */ else if (!strcmpi(s, "inaccessibles")) gc.coder->check_inaccessibles = 1; else if (!strcmpi(s, "noflipx")) @@ -3726,21 +3726,21 @@ lspo_level_flags(lua_State *L) else if (!strcmpi(s, "noflip")) gc.coder->allow_flips = 0; else if (!strcmpi(s, "temperate")) - gl.level.flags.temperature = 0; + svl.level.flags.temperature = 0; else if (!strcmpi(s, "hot")) - gl.level.flags.temperature = 1; + svl.level.flags.temperature = 1; else if (!strcmpi(s, "cold")) - gl.level.flags.temperature = -1; + svl.level.flags.temperature = -1; else if (!strcmpi(s, "nomongen")) - gl.level.flags.rndmongen = 0; + svl.level.flags.rndmongen = 0; else if (!strcmpi(s, "nodeathdrops")) - gl.level.flags.deathdrops = 0; + svl.level.flags.deathdrops = 0; else if (!strcmpi(s, "noautosearch")) - gl.level.flags.noautosearch = 1; + svl.level.flags.noautosearch = 1; else if (!strcmpi(s, "fumaroles")) - gl.level.flags.fumaroles = 1; + svl.level.flags.fumaroles = 1; else if (!strcmpi(s, "stormy")) - gl.level.flags.stormy = 1; + svl.level.flags.stormy = 1; else { char buf[BUFSZ]; @@ -4676,7 +4676,7 @@ l_table_getset_feature_flag( } /* guts of nhl_abs_coord; convert a coordinate relative to a map or room - * into an absolute coordinate in gl.level.locations. + * into an absolute coordinate in svl.level.locations. * * If there is no enclosing map or room, the coordinates are assumed to be * absolute already. @@ -4708,7 +4708,7 @@ cvt_to_abscoord(coordxy *x, coordxy *y) } } -/* inverse of cvt_to_abscoord; turn an absolute gl.level.locations coordinate +/* inverse of cvt_to_abscoord; turn an absolute svl.level.locations coordinate * into one relative to the current map or room. */ void cvt_to_relcoord(coordxy *x, coordxy *y) @@ -5438,8 +5438,8 @@ lspo_exclusion(lua_State *L) ez->hy = y2; cvt_to_abscoord(&ez->lx, &ez->ly); cvt_to_abscoord(&ez->hx, &ez->hy); - ez->next = ge.exclusion_zones; - ge.exclusion_zones = ez; + ez->next = sve.exclusion_zones; + sve.exclusion_zones = ez; return 0; } @@ -5563,7 +5563,7 @@ lspo_region(lua_State *L) */ room_not_needed = (rtype == OROOM && !irregular && !do_arrival_room && !gi.in_mk_themerooms); - if (room_not_needed || gn.nroom >= MAXNROFROOMS) { + if (room_not_needed || svn.nroom >= MAXNROFROOMS) { region tmpregion; if (!room_not_needed) impossible("Too many rooms on new level!"); @@ -5577,7 +5577,7 @@ lspo_region(lua_State *L) return 0; } - troom = &gr.rooms[gn.nroom]; + troom = &svr.rooms[svn.nroom]; /* mark rooms that must be filled, but do it later */ troom->needfill = needfill; @@ -5587,8 +5587,8 @@ lspo_region(lua_State *L) if (irregular) { gm.min_rx = gm.max_rx = dx1; gm.min_ry = gm.max_ry = dy1; - gs.smeq[gn.nroom] = gn.nroom; - flood_fill_rm(dx1, dy1, gn.nroom + ROOMOFFSET, rlit, TRUE); + gs.smeq[svn.nroom] = svn.nroom; + flood_fill_rm(dx1, dy1, svn.nroom + ROOMOFFSET, rlit, TRUE); add_room(gm.min_rx, gm.min_ry, gm.max_rx, gm.max_ry, FALSE, rtype, TRUE); troom->rlit = rlit; @@ -5721,7 +5721,7 @@ lspo_mazewalk(lua_State *L) } if (ftyp < 1) { - ftyp = gl.level.flags.corrmaze ? CORR : ROOM; + ftyp = svl.level.flags.corrmaze ? CORR : ROOM; } if (dir == W_RANDOM) @@ -5941,7 +5941,7 @@ lspo_finalize_level(lua_State *L) * is currently not possible, we overload the corrmaze flag for this * purpose. */ - if (!gl.level.flags.corrmaze) + if (!svl.level.flags.corrmaze) wallification(1, 0, COLNO - 1, ROWNO - 1); if (L) @@ -5961,8 +5961,8 @@ lspo_finalize_level(lua_State *L) level_finalize_topology(); - for (i = 0; i < gn.nroom; ++i) { - fill_special_room(&gr.rooms[i]); + for (i = 0; i < svn.nroom; ++i) { + fill_special_room(&svr.rooms[i]); } makemap_prepost(FALSE, wtower); @@ -6272,10 +6272,10 @@ sp_level_coder_init(void) (void) memset((genericptr_t) SpLev_Map, 0, sizeof SpLev_Map); - gl.level.flags.is_maze_lev = 0; - gl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0; - gl.level.flags.rndmongen = 1; - gl.level.flags.deathdrops = 1; + svl.level.flags.is_maze_lev = 0; + svl.level.flags.temperature = In_hell(&u.uz) ? 1 : 0; + svl.level.flags.rndmongen = 1; + svl.level.flags.deathdrops = 1; reset_xystart_size(); @@ -6383,7 +6383,7 @@ load_special(const char *name) * is currently not possible, we overload the corrmaze flag for this * purpose. */ - if (!gl.level.flags.corrmaze) + if (!svl.level.flags.corrmaze) wallification(1, 0, COLNO - 1, ROWNO - 1); flip_level_rnd(gc.coder->allow_flips, FALSE); diff --git a/src/spell.c b/src/spell.c index f4c356e31..eb2354382 100644 --- a/src/spell.c +++ b/src/spell.c @@ -4,7 +4,7 @@ #include "hack.h" -/* spellmenu arguments; 0 thru n-1 used as gs.spl_book[] index when swapping */ +/* spellmenu arguments; 0 thru n-1 used as svs.spl_book[] index when swapping */ #define SPELLMENU_CAST (-2) #define SPELLMENU_VIEW (-1) #define SPELLMENU_SORT (MAXSPELL) /* special menu entry */ @@ -18,9 +18,9 @@ initialization; spell memory is decremented at the end of each turn, including the turn on which the spellbook is read; without the extra increment, the hero used to get cheated out of 1 turn of retention */ -#define incrnknow(spell, x) (gs.spl_book[spell].sp_know = KEEN + (x)) +#define incrnknow(spell, x) (svs.spl_book[spell].sp_know = KEEN + (x)) -#define spellev(spell) gs.spl_book[spell].sp_lev +#define spellev(spell) svs.spl_book[spell].sp_lev #define spellname(spell) OBJ_NAME(objects[spellid(spell)]) #define spellet(spell) \ ((char) ((spell < 26) ? ('a' + spell) : ('A' + spell - 26))) @@ -200,7 +200,7 @@ confused_book(struct obj *spellbook) gone = TRUE; } else { You("find yourself reading the %s line over and over again.", - spellbook == gc.context.spbook.book ? "next" : "first"); + spellbook == svc.context.spbook.book ? "next" : "first"); } return gone; } @@ -269,7 +269,7 @@ deadbook(struct obj *book2) arti_cursed = TRUE; } if (otmp->otyp == BELL_OF_OPENING - && (gm.moves - otmp->age) < 5L) { /* you rang it recently */ + && (svm.moves - otmp->age) < 5L) { /* you rang it recently */ if (!otmp->cursed) arti2_primed = TRUE; else @@ -342,7 +342,7 @@ void book_cursed(struct obj *book) { if (book->cursed && gm.multi >= 0 - && go.occupation == learn && gc.context.spbook.book == book) { + && go.occupation == learn && svc.context.spbook.book == book) { pline("%s shut!", Tobjnam(book, "slam")); set_bknown(book, 1); stop_occupation(); @@ -358,25 +358,25 @@ learn(void) short booktype; char splname[BUFSZ]; boolean costly = TRUE, faded_to_blank = FALSE; - struct obj *book = gc.context.spbook.book; + struct obj *book = svc.context.spbook.book; /* JDS: lenses give 50% faster reading; 33% smaller read time */ - if (gc.context.spbook.delay && ublindf + if (svc.context.spbook.delay && ublindf && ublindf->otyp == LENSES && rn2(2)) - gc.context.spbook.delay++; + svc.context.spbook.delay++; if (Confusion) { /* became confused while learning */ (void) confused_book(book); - gc.context.spbook.book = 0; /* no longer studying */ - gc.context.spbook.o_id = 0; - nomul(gc.context.spbook.delay); /* remaining delay is uninterrupted */ + svc.context.spbook.book = 0; /* no longer studying */ + svc.context.spbook.o_id = 0; + nomul(svc.context.spbook.delay); /* remaining delay is uninterrupted */ gm.multi_reason = "reading a book"; gn.nomovemsg = 0; - gc.context.spbook.delay = 0; + svc.context.spbook.delay = 0; return 0; } - if (gc.context.spbook.delay) { - /* not if (gc.context.spbook.delay++), so at end delay == 0 */ - gc.context.spbook.delay++; + if (svc.context.spbook.delay) { + /* not if (svc.context.spbook.delay++), so at end delay == 0 */ + svc.context.spbook.delay++; return 1; /* still busy */ } exercise(A_WIS, TRUE); /* you're studying. */ @@ -422,8 +422,8 @@ learn(void) /* reset spestudied as if polymorph had taken place */ book->spestudied = rn2(book->spestudied); } else { - gs.spl_book[i].sp_id = booktype; - gs.spl_book[i].sp_lev = objects[booktype].oc_level; + svs.spl_book[i].sp_id = booktype; + svs.spl_book[i].sp_lev = objects[booktype].oc_level; incrnknow(i, 1); book->spestudied++; if (!i) @@ -449,15 +449,15 @@ learn(void) if (book->cursed) { /* maybe a demon cursed it */ if (cursed_book(book)) { useup(book); - gc.context.spbook.book = 0; - gc.context.spbook.o_id = 0; + svc.context.spbook.book = 0; + svc.context.spbook.o_id = 0; return 0; } } if (costly) check_unpaid(book); - gc.context.spbook.book = 0; - gc.context.spbook.o_id = 0; + svc.context.spbook.book = 0; + svc.context.spbook.o_id = 0; return 0; } @@ -477,7 +477,7 @@ study_book(struct obj *spellbook) int dullbook = rnd(25) - ACURR(A_WIS); /* adjust chance if hero stayed awake, got interrupted, retries */ - if (gc.context.spbook.delay && spellbook == gc.context.spbook.book) + if (svc.context.spbook.delay && spellbook == svc.context.spbook.book) dullbook -= rnd(objects[booktype].oc_level); if (dullbook > 0) { @@ -492,10 +492,10 @@ study_book(struct obj *spellbook) } } - if (gc.context.spbook.delay && !confused - && spellbook == gc.context.spbook.book + if (svc.context.spbook.delay && !confused + && spellbook == svc.context.spbook.book /* handle the sequence: start reading, get interrupted, have - gc.context.spbook.book become erased somehow, resume reading it */ + svc.context.spbook.book become erased somehow, resume reading it */ && booktype != SPE_BLANK_PAPER) { You("continue your efforts to %s.", (booktype == SPE_NOVEL) ? "read the novel" : "memorize the spell"); @@ -534,20 +534,20 @@ study_book(struct obj *spellbook) switch (objects[booktype].oc_level) { case 1: case 2: - gc.context.spbook.delay = -objects[booktype].oc_delay; + svc.context.spbook.delay = -objects[booktype].oc_delay; break; case 3: case 4: - gc.context.spbook.delay = -(objects[booktype].oc_level - 1) + svc.context.spbook.delay = -(objects[booktype].oc_level - 1) * objects[booktype].oc_delay; break; case 5: case 6: - gc.context.spbook.delay = + svc.context.spbook.delay = -objects[booktype].oc_level * objects[booktype].oc_delay; break; case 7: - gc.context.spbook.delay = -8 * objects[booktype].oc_delay; + svc.context.spbook.delay = -8 * objects[booktype].oc_delay; break; default: impossible("Unknown spellbook level %d, book %d;", @@ -602,10 +602,10 @@ study_book(struct obj *spellbook) if (too_hard) { boolean gone = cursed_book(spellbook); - nomul(gc.context.spbook.delay); /* study time */ + nomul(svc.context.spbook.delay); /* study time */ gm.multi_reason = "reading a book"; gn.nomovemsg = 0; - gc.context.spbook.delay = 0; + svc.context.spbook.delay = 0; if (gone || !rn2(3)) { if (!gone) pline_The("spellbook crumbles to dust!"); @@ -618,10 +618,10 @@ study_book(struct obj *spellbook) if (!confused_book(spellbook)) { spellbook->in_use = FALSE; } - nomul(gc.context.spbook.delay); + nomul(svc.context.spbook.delay); gm.multi_reason = "reading a book"; gn.nomovemsg = 0; - gc.context.spbook.delay = 0; + svc.context.spbook.delay = 0; return 1; } spellbook->in_use = FALSE; @@ -630,9 +630,9 @@ study_book(struct obj *spellbook) spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "recite" : "memorize"); } - gc.context.spbook.book = spellbook; - if (gc.context.spbook.book) - gc.context.spbook.o_id = gc.context.spbook.book->o_id; + svc.context.spbook.book = spellbook; + if (svc.context.spbook.book) + svc.context.spbook.o_id = svc.context.spbook.book->o_id; set_occupation(learn, "studying", 0); return 1; } @@ -642,9 +642,9 @@ study_book(struct obj *spellbook) void book_disappears(struct obj *obj) { - if (obj == gc.context.spbook.book) { - gc.context.spbook.book = (struct obj *) 0; - gc.context.spbook.o_id = 0; + if (obj == svc.context.spbook.book) { + svc.context.spbook.book = (struct obj *) 0; + svc.context.spbook.o_id = 0; } } @@ -654,10 +654,10 @@ book_disappears(struct obj *obj) void book_substitution(struct obj *old_obj, struct obj *new_obj) { - if (old_obj == gc.context.spbook.book) { - gc.context.spbook.book = new_obj; - if (gc.context.spbook.book) - gc.context.spbook.o_id = gc.context.spbook.book->o_id; + if (old_obj == svc.context.spbook.book) { + svc.context.spbook.book = new_obj; + if (svc.context.spbook.book) + svc.context.spbook.o_id = svc.context.spbook.book->o_id; } } @@ -814,7 +814,7 @@ docast(void) if (getspell(&spell_no)) { cmdq_add_key(CQ_REPEAT, spellet(spell_no)); - return spelleffects(gs.spl_book[spell_no].sp_id, FALSE, FALSE); + return spelleffects(svs.spl_book[spell_no].sp_id, FALSE, FALSE); } return ECMD_FAIL; } @@ -860,8 +860,8 @@ skill_based_spellbook_id(void) int booktype; const uchar spbook_class = (uchar) SPBOOK_CLASS; - for (booktype = gb.bases[spbook_class]; - booktype < gb.bases[spbook_class + 1]; + for (booktype = svb.bases[spbook_class]; + booktype < svb.bases[spbook_class + 1]; booktype++) { int known_up_to_level; int skill = spell_skilltype(booktype); @@ -1051,9 +1051,9 @@ cast_chain_lightning(void) otherwise other monsters witnessing this would treat it as seeing hero attack a peaceful; mimic will be exposed; forcefight makes hider unhide */ - gc.context.forcefight++; + svc.context.forcefight++; wakeup(mon, FALSE); - gc.context.forcefight--; + svc.context.forcefight--; } } @@ -1701,14 +1701,14 @@ tport_spell(int what) save_tport.tport_indx = MAXSPELL; } else if (what == UNHIDESPELL) { /*assert( save_tport.savespell.sp_id == SPE_TELEPORT_AWAY );*/ - gs.spl_book[save_tport.tport_indx] = save_tport.savespell; + svs.spl_book[save_tport.tport_indx] = save_tport.savespell; save_tport.tport_indx = MAXSPELL; /* burn bridge... */ } else if (what == ADD_SPELL) { - save_tport.savespell = gs.spl_book[i]; + save_tport.savespell = svs.spl_book[i]; save_tport.tport_indx = i; - gs.spl_book[i].sp_id = SPE_TELEPORT_AWAY; - gs.spl_book[i].sp_lev = objects[SPE_TELEPORT_AWAY].oc_level; - gs.spl_book[i].sp_know = KEEN; + svs.spl_book[i].sp_id = SPE_TELEPORT_AWAY; + svs.spl_book[i].sp_lev = objects[SPE_TELEPORT_AWAY].oc_level; + svs.spl_book[i].sp_know = KEEN; return REMOVESPELL; /* operation needed to reverse */ } } else { /* spellid(i) == SPE_TELEPORT_AWAY */ @@ -1716,12 +1716,12 @@ tport_spell(int what) save_tport.tport_indx = MAXSPELL; } else if (what == REMOVESPELL) { /*assert( i == save_tport.tport_indx );*/ - gs.spl_book[i] = save_tport.savespell; + svs.spl_book[i] = save_tport.savespell; save_tport.tport_indx = MAXSPELL; } else if (what == HIDE_SPELL) { - save_tport.savespell = gs.spl_book[i]; + save_tport.savespell = svs.spl_book[i]; save_tport.tport_indx = i; - gs.spl_book[i].sp_id = NO_SPELL; + svs.spl_book[i].sp_id = NO_SPELL; return UNHIDESPELL; /* operation needed to reverse */ } } @@ -1737,8 +1737,8 @@ losespells(void) int n, nzap, i; /* in case reading has been interrupted earlier, discard context */ - gc.context.spbook.book = 0; - gc.context.spbook.o_id = 0; + svc.context.spbook.book = 0; + svc.context.spbook.o_id = 0; /* count the number of known spells */ for (n = 0; n < MAXSPELL; ++n) if (spellid(n) == NO_SPELL) @@ -1844,13 +1844,13 @@ spell_cmp(const genericptr vptr1, const genericptr vptr2) /* * gather up all of the possible parameters except spell name * in advance, even though some might not be needed: - * indx. = spl_orderindx[] index into gs.spl_book[]; - * otyp. = gs.spl_book[] index into objects[]; + * indx. = spl_orderindx[] index into svs.spl_book[]; + * otyp. = svs.spl_book[] index into objects[]; * levl. = spell level; * skil. = skill group aka spell class. */ int indx1 = *(int *) vptr1, indx2 = *(int *) vptr2, - otyp1 = gs.spl_book[indx1].sp_id, otyp2 = gs.spl_book[indx2].sp_id, + otyp1 = svs.spl_book[indx1].sp_id, otyp2 = svs.spl_book[indx2].sp_id, levl1 = objects[otyp1].oc_level, levl2 = objects[otyp2].oc_level, skil1 = objects[otyp1].oc_skill, skil2 = objects[otyp2].oc_skill; @@ -1926,13 +1926,13 @@ sortspells(void) if (gs.spl_sortmode == SORTRETAINORDER) { struct spell tmp_book[MAXSPELL]; - /* sort gs.spl_book[] rather than spl_orderindx[]; + /* sort svs.spl_book[] rather than spl_orderindx[]; this also updates the index to reflect the new ordering (we could just free it since that ordering becomes the default) */ for (i = 0; i < MAXSPELL; i++) - tmp_book[i] = gs.spl_book[gs.spl_orderindx[i]]; + tmp_book[i] = svs.spl_book[gs.spl_orderindx[i]]; for (i = 0; i < MAXSPELL; i++) - gs.spl_book[i] = tmp_book[i], gs.spl_orderindx[i] = i; + svs.spl_book[i] = tmp_book[i], gs.spl_orderindx[i] = i; gs.spl_sortmode = SORTBY_LETTER; /* reset */ return; } @@ -2010,9 +2010,9 @@ dovspell(void) if (!dospellmenu(qbuf, splnum, &othnum)) break; - spl_tmp = gs.spl_book[splnum]; - gs.spl_book[splnum] = gs.spl_book[othnum]; - gs.spl_book[othnum] = spl_tmp; + spl_tmp = svs.spl_book[splnum]; + svs.spl_book[splnum] = svs.spl_book[othnum]; + svs.spl_book[othnum] = spl_tmp; } } } @@ -2032,7 +2032,7 @@ DISABLE_WARNING_FORMAT_NONLITERAL staticfn boolean dospellmenu( const char *prompt, - int splaction, /* SPELLMENU_CAST, SPELLMENU_VIEW, or gs.spl_book[] index */ + int splaction, /* SPELLMENU_CAST, SPELLMENU_VIEW, or svs.spl_book[] index */ int *spell_no) { winid tmpwin; @@ -2304,8 +2304,8 @@ initialspell(struct obj *obj) /* initial inventory shouldn't contain duplicate spellbooks */ impossible("Spell %s already known.", OBJ_NAME(objects[otyp])); } else { - gs.spl_book[i].sp_id = otyp; - gs.spl_book[i].sp_lev = objects[otyp].oc_level; + svs.spl_book[i].sp_id = otyp; + svs.spl_book[i].sp_lev = objects[otyp].oc_level; incrnknow(i, 0); } return; @@ -2358,8 +2358,8 @@ force_learn_spell(short otyp) } /* for a going-stale or forgotten spell the sp_id and sp_lev assignments are redundant but harmless; for an unknown spell, they're essential */ - gs.spl_book[i].sp_id = otyp; - gs.spl_book[i].sp_lev = objects[otyp].oc_level; + svs.spl_book[i].sp_id = otyp; + svs.spl_book[i].sp_lev = objects[otyp].oc_level; incrnknow(i, 0); /* set spl_book[i].sp_know to KEEN; unlike when learning * a spell by reading its book, we don't need to add 1 */ return spellet(i); diff --git a/src/stairs.c b/src/stairs.c index 27007c53b..89b9ff3e8 100644 --- a/src/stairs.c +++ b/src/stairs.c @@ -227,7 +227,7 @@ stairs_description( } else { /* known branch stairs; tacking on destination level is too verbose */ Sprintf(outbuf, "branch %s %s to %s", - stairs, updown, gd.dungeons[tolev.dnum].dname); + stairs, updown, svd.dungeons[tolev.dnum].dname); /* dungeons[].dname is capitalized; undo that for "The " */ (void) strsubst(outbuf, "The ", "the "); } diff --git a/src/steed.c b/src/steed.c index 0fae5a4ca..2c7be9c2e 100644 --- a/src/steed.c +++ b/src/steed.c @@ -906,7 +906,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y) mon->mstate, buf); return; } - if ((othermon = gl.level.monsters[x][y]) != 0) { + if ((othermon = svl.level.monsters[x][y]) != 0) { describe_level(buf, 0); monnm = minimal_monnam(mon, FALSE); othnm = (mon != othermon) ? minimal_monnam(othermon, TRUE) : "itself"; @@ -914,7 +914,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y) monnm, othnm, x, y, othermon->mstate, mon->mstate, buf); } mon->mx = x, mon->my = y; - gl.level.monsters[x][y] = mon; + svl.level.monsters[x][y] = mon; mon->mstate = MON_FLOOR; } diff --git a/src/teleport.c b/src/teleport.c index 51fb281e7..151889cb8 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -35,7 +35,7 @@ noteleport_level(struct monst *mon) return TRUE; /* natural no-teleport level */ - if (gl.level.flags.noteleport) + if (svl.level.flags.noteleport) return TRUE; return FALSE; @@ -368,30 +368,30 @@ tele_jump_ok(coordxy x1, coordxy y1, coordxy x2, coordxy y2) { if (!isok(x2, y2)) return FALSE; - if (gd.dndest.nlx > 0) { + if (svd.dndest.nlx > 0) { /* if inside a restricted region, can't teleport outside */ - if (within_bounded_area(x1, y1, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy) - && !within_bounded_area(x2, y2, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy)) + if (within_bounded_area(x1, y1, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy) + && !within_bounded_area(x2, y2, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy)) return FALSE; /* and if outside, can't teleport inside */ - if (!within_bounded_area(x1, y1, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy) - && within_bounded_area(x2, y2, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy)) + if (!within_bounded_area(x1, y1, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy) + && within_bounded_area(x2, y2, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy)) return FALSE; } - if (gu.updest.nlx > 0) { /* ditto */ - if (within_bounded_area(x1, y1, gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy) - && !within_bounded_area(x2, y2, gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy)) + if (svu.updest.nlx > 0) { /* ditto */ + if (within_bounded_area(x1, y1, svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy) + && !within_bounded_area(x2, y2, svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy)) return FALSE; - if (!within_bounded_area(x1, y1, gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy) - && within_bounded_area(x2, y2, gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy)) + if (!within_bounded_area(x1, y1, svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy) + && within_bounded_area(x2, y2, svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy)) return FALSE; } return TRUE; @@ -1124,10 +1124,10 @@ level_tele(void) if (iflags.debug_fuzzer) { do { - newlevel.dnum = rn2(gn.n_dgns); + newlevel.dnum = rn2(svn.n_dgns); } while (newlevel.dnum == astral_level.dnum - || gd.dungeons[newlevel.dnum].flags.unconnected - || !gd.dungeons[newlevel.dnum].num_dunlevs); + || svd.dungeons[newlevel.dnum].flags.unconnected + || !svd.dungeons[newlevel.dnum].num_dunlevs); newlevel.dlevel = 1 + rn2(dunlevs_in_dungeon(&newlevel)); assign_level(&u.ucamefrom, &u.uz); schedule_goto(&newlevel, UTOTYPE_NONE, (char *) 0, (char *) 0); @@ -1214,8 +1214,8 @@ level_tele(void) if (gi.invent) Your("possessions land on the %s with a thud.", surface(u.ux, u.uy)); - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "committed suicide"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "committed suicide"); done(DIED); pline("An energized cloud of dust begins to coalesce."); Your("body rematerializes%s.", @@ -1239,7 +1239,7 @@ level_tele(void) * we let negative values requests fall into the "heaven" handling. */ if (In_quest(&u.uz) && newlev > 0) - newlev = newlev + gd.dungeons[u.uz.dnum].depth_start - 1; + newlev = newlev + svd.dungeons[u.uz.dnum].depth_start - 1; } else { /* involuntary level tele */ random_levtport: newlev = random_teleport_level(); @@ -1269,7 +1269,7 @@ level_tele(void) return; } - gk.killer.name[0] = 0; /* still alive, so far... */ + svk.killer.name[0] = 0; /* still alive, so far... */ if (iflags.debug_fuzzer && newlev < 0) goto random_levtport; @@ -1286,8 +1286,8 @@ level_tele(void) You("arrive in heaven."); SetVoice((struct monst *) 0, 0, 80, voice_deity); verbalize("Thou art early, but we'll admit thee."); - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "went to heaven prematurely"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "went to heaven prematurely"); } else if (newlev == -9) { You_feel("deliriously happy."); pline("(In fact, you're on Cloud 9!)"); @@ -1295,7 +1295,7 @@ level_tele(void) } else You("are now high above the clouds..."); - if (gk.killer.name[0]) { + if (svk.killer.name[0]) { ; /* arrival in heaven is pending */ } else if (Levitation) { escape_by_flying = "float gently down to earth"; @@ -1304,14 +1304,14 @@ level_tele(void) } else { pline("Unfortunately, you don't know how to fly."); You("plummet a few thousand feet to your death."); - Sprintf(gk.killer.name, + Sprintf(svk.killer.name, "teleported out of the dungeon and fell to %s death", uhis()); - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; } } - if (gk.killer.name[0]) { /* the chosen destination was not survivable */ + if (svk.killer.name[0]) { /* the chosen destination was not survivable */ d_level lsav; /* set specific death location; this also suppresses bones */ @@ -1337,7 +1337,7 @@ level_tele(void) /* wizard mode menu; no further validation needed */ ; } else if (u.uz.dnum == medusa_level.dnum - && newlev >= gd.dungeons[u.uz.dnum].depth_start + && newlev >= svd.dungeons[u.uz.dnum].depth_start + dunlevs_in_dungeon(&u.uz)) { find_hell(&newlevel); } else { @@ -1348,7 +1348,7 @@ level_tele(void) d_level *qbranch = In_quest(&u.uz) ? &qstart_level : In_mines(&u.uz) ? &mineend_level : &sanctum_level; - int deepest = gd.dungeons[qbranch->dnum].depth_start + int deepest = svd.dungeons[qbranch->dnum].depth_start + dunlevs_in_dungeon(qbranch) - 1; /* if invocation did not yet occur, teleporting into @@ -1386,7 +1386,7 @@ level_tele(void) /* in case player just read a scroll and is about to be asked to call it something, we can't defer until the end of the turn */ - if (u.utotype && !gc.context.mon_moving) + if (u.utotype && !svc.context.mon_moving) deferred_goto(); #endif } @@ -1528,25 +1528,25 @@ rloc_pos_ok( yy = mtmp->my; if (!xx) { /* no current location (migrating monster arrival) */ - if (gd.dndest.nlx && On_W_tower_level(&u.uz)) + if (svd.dndest.nlx && On_W_tower_level(&u.uz)) return (((yy & 2) != 0) /* inside xor not within */ - ^ !within_bounded_area(x, y, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy)); - if (gu.updest.lx && (yy & 1) != 0) /* moving up */ - return (within_bounded_area(x, y, gu.updest.lx, gu.updest.ly, - gu.updest.hx, gu.updest.hy) - && (!gu.updest.nlx + ^ !within_bounded_area(x, y, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy)); + if (svu.updest.lx && (yy & 1) != 0) /* moving up */ + return (within_bounded_area(x, y, svu.updest.lx, svu.updest.ly, + svu.updest.hx, svu.updest.hy) + && (!svu.updest.nlx || !within_bounded_area(x, y, - gu.updest.nlx, gu.updest.nly, - gu.updest.nhx, gu.updest.nhy))); - if (gd.dndest.lx && (yy & 1) == 0) /* moving down */ - return (within_bounded_area(x, y, gd.dndest.lx, gd.dndest.ly, - gd.dndest.hx, gd.dndest.hy) - && (!gd.dndest.nlx + svu.updest.nlx, svu.updest.nly, + svu.updest.nhx, svu.updest.nhy))); + if (svd.dndest.lx && (yy & 1) == 0) /* moving down */ + return (within_bounded_area(x, y, svd.dndest.lx, svd.dndest.ly, + svd.dndest.hx, svd.dndest.hy) + && (!svd.dndest.nlx || !within_bounded_area(x, y, - gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy))); + svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy))); } else { /* [try to] prevent a shopkeeper or temple priest from being sent out of his room (caller might resort to goodpos() if @@ -2033,7 +2033,7 @@ rloco(struct obj *obj) obj_extract_self(obj); otx = obj->ox; oty = obj->oy; - restricted_fall = (otx == 0 && gd.dndest.lx); + restricted_fall = (otx == 0 && svd.dndest.lx); do { tx = rn1(COLNO - 3, 2); ty = rn2(ROWNO); @@ -2041,20 +2041,20 @@ rloco(struct obj *obj) break; } while (!goodpos(tx, ty, (struct monst *) 0, 0) || (restricted_fall - && (!within_bounded_area(tx, ty, gd.dndest.lx, gd.dndest.ly, - gd.dndest.hx, gd.dndest.hy) - || (gd.dndest.nlx + && (!within_bounded_area(tx, ty, svd.dndest.lx, svd.dndest.ly, + svd.dndest.hx, svd.dndest.hy) + || (svd.dndest.nlx && within_bounded_area(tx, ty, - gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy)))) + svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy)))) /* on the Wizard Tower levels, objects inside should stay inside and objects outside should stay outside */ - || (gd.dndest.nlx && On_W_tower_level(&u.uz) - && within_bounded_area(tx, ty, gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy) + || (svd.dndest.nlx && On_W_tower_level(&u.uz) + && within_bounded_area(tx, ty, svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy) != within_bounded_area(otx, oty, - gd.dndest.nlx, gd.dndest.nly, - gd.dndest.nhx, gd.dndest.nhy))); + svd.dndest.nlx, svd.dndest.nly, + svd.dndest.nhx, svd.dndest.nhy))); if (flooreffects(obj, tx, ty, "fall")) { /* update old location since flooreffects() couldn't; @@ -2140,12 +2140,12 @@ random_teleport_level(void) no one can randomly teleport past it */ if (dunlev_reached(&u.uz) < qlocate_depth) bottom = qlocate_depth; - min_depth = gd.dungeons[u.uz.dnum].depth_start; - max_depth = bottom + (gd.dungeons[u.uz.dnum].depth_start - 1); + min_depth = svd.dungeons[u.uz.dnum].depth_start; + max_depth = bottom + (svd.dungeons[u.uz.dnum].depth_start - 1); } else { min_depth = 1; max_depth = dunlevs_in_dungeon(&u.uz) - + (gd.dungeons[u.uz.dnum].depth_start - 1); + + (svd.dungeons[u.uz.dnum].depth_start - 1); /* can't reach Sanctum if the invocation hasn't been performed */ if (Inhell && !u.uevent.invoked) max_depth -= 1; diff --git a/src/timeout.c b/src/timeout.c index a3ce09ea0..cee1e927e 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -460,11 +460,11 @@ slimed_to_death(struct kinfo *kptr) } /* more sure killer reason is set up */ if (kptr && kptr->name[0]) { - gk.killer.format = kptr->format; - Strcpy(gk.killer.name, kptr->name); + svk.killer.format = kptr->format; + Strcpy(svk.killer.name, kptr->name); } else { - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "turned into green slime"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "turned into green slime"); } dealloc_killer(kptr); @@ -482,20 +482,20 @@ slimed_to_death(struct kinfo *kptr) */ if (emits_light(gy.youmonst.data)) del_light_source(LS_MONSTER, monst_to_any(&gy.youmonst)); - save_mvflags = gm.mvitals[PM_GREEN_SLIME].mvflags; - gm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD; + save_mvflags = svm.mvitals[PM_GREEN_SLIME].mvflags; + svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD; /* become a green slime; also resets youmonst.m_ap_type+.mappearance */ (void) polymon(PM_GREEN_SLIME); - gm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags; + svm.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags; done_timeout(TURNED_SLIME, SLIMED); /* life-saved; even so, hero still has turned into green slime; player may have genocided green slimes after being infected */ - if ((gm.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) { + if ((svm.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) { char slimebuf[BUFSZ]; - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "slimicide"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "slimicide"); /* vary the message depending upon whether life-save was due to amulet or due to declining to die in explore or wizard mode */ Strcpy(slimebuf, "green slime has been genocided..."); @@ -566,11 +566,11 @@ nh_timeout(void) if (flags.friday13) baseluck -= 1; - if (gq.quest_status.killed_leader) + if (svq.quest_status.killed_leader) baseluck -= 4; if (u.uluck != baseluck - && gm.moves % ((u.uhave.amulet || u.ugangr) ? 300 : 600) == 0) { + && svm.moves % ((u.uhave.amulet || u.ugangr) ? 300 : 600) == 0) { /* Cursed luckstones stop bad luck from timing out; blessed luckstones * stop good luck from timing out; normal luckstones stop both; * neither is stopped if you don't have a luckstone. @@ -637,11 +637,11 @@ nh_timeout(void) switch (upp - u.uprops) { case STONED: if (kptr && kptr->name[0]) { - gk.killer.format = kptr->format; - Strcpy(gk.killer.name, kptr->name); + svk.killer.format = kptr->format; + Strcpy(svk.killer.name, kptr->name); } else { - gk.killer.format = NO_KILLER_PREFIX; - Strcpy(gk.killer.name, "killed by petrification"); + svk.killer.format = NO_KILLER_PREFIX; + Strcpy(svk.killer.name, "killed by petrification"); } dealloc_killer(kptr); /* (unlike sliming, you aren't changing form here) */ @@ -666,21 +666,21 @@ nh_timeout(void) } urgent_pline("You die from your illness."); if (kptr && kptr->name[0]) { - gk.killer.format = kptr->format; - Strcpy(gk.killer.name, kptr->name); + svk.killer.format = kptr->format; + Strcpy(svk.killer.name, kptr->name); } else { - gk.killer.format = KILLED_BY_AN; - gk.killer.name[0] = 0; /* take the default */ + svk.killer.format = KILLED_BY_AN; + svk.killer.name[0] = 0; /* take the default */ } dealloc_killer(kptr); - if ((m_idx = name_to_mon(gk.killer.name, + if ((m_idx = name_to_mon(svk.killer.name, (int *) 0)) >= LOW_PM) { if (type_is_pname(&mons[m_idx])) { - gk.killer.format = KILLED_BY; + svk.killer.format = KILLED_BY; } else if (mons[m_idx].geno & G_UNIQ) { - Strcpy(gk.killer.name, the(gk.killer.name)); - gk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, the(svk.killer.name)); + svk.killer.format = KILLED_BY; } } done_timeout(POISONING, SICK); @@ -826,10 +826,10 @@ nh_timeout(void) case WARN_OF_MON: /* timed Warn_of_mon is via #wizintrinsic only */ if (!Warn_of_mon) { - struct permonst *wptr = gc.context.warntype.species; + struct permonst *wptr = svc.context.warntype.species; - gc.context.warntype.species = (struct permonst *) 0; - gc.context.warntype.speciesidx = NON_PM; + svc.context.warntype.species = (struct permonst *) 0; + svc.context.warntype.speciesidx = NON_PM; if (wptr) You("are no longer warned about %s.", makeplural(wptr->pmnames[NEUTRAL])); @@ -845,8 +845,8 @@ nh_timeout(void) } break; case STRANGLED: - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, (u.uburied) ? "suffocation" : "strangulation"); done_timeout(DIED, STRANGLED); /* must be declining to die in explore|wizard mode; @@ -920,7 +920,7 @@ fall_asleep(int how_long, boolean wakeup_msg) } #endif /* early wakeup from combat won't be possible until next monster turn */ - u.usleep = gm.moves; + u.usleep = svm.moves; gn.nomovemsg = wakeup_msg ? "You wake up." : You_can_move_again; } @@ -984,7 +984,7 @@ hatch_egg(anything *arg, long timeout) mnum = big_to_little(egg->corpsenm); /* The identity of one's father is learned, not innate */ yours = (egg->spe || (!flags.female && carried(egg) && !rn2(2))); - silent = (timeout != gm.moves); /* hatched while away */ + silent = (timeout != svm.moves); /* hatched while away */ /* only can hatch when in INVENT, FLOOR, MINVENT; get_obj_location() will fail for MIGRATING, also for CONTAINED @@ -993,7 +993,7 @@ hatch_egg(anything *arg, long timeout) hatchcount = rnd((int) egg->quan); cansee_hatchspot = cansee(x, y) && !silent; if (!(mons[mnum].geno & G_UNIQ) - && !(gm.mvitals[mnum].mvflags & (G_GENOD | G_EXTINCT))) { + && !(svm.mvitals[mnum].mvflags & (G_GENOD | G_EXTINCT))) { for (i = hatchcount; i > 0; i--) { if (!enexto(&cc, x, y, &mons[mnum]) || !(mon = makemon(&mons[mnum], cc.x, cc.y, @@ -1009,7 +1009,7 @@ hatch_egg(anything *arg, long timeout) mon->mtame = 20; } } - if (gm.mvitals[mnum].mvflags & G_EXTINCT) + if (svm.mvitals[mnum].mvflags & G_EXTINCT) break; /* just made last one */ mon2 = mon; /* in case makemon() fails on 2nd egg */ } @@ -1145,7 +1145,7 @@ learn_egg_type(int mnum) { /* baby monsters hatch from grown-up eggs */ mnum = little_to_big(mnum); - gm.mvitals[mnum].mvflags |= MV_KNOWS_EGG; + svm.mvitals[mnum].mvflags |= MV_KNOWS_EGG; /* we might have just learned about other eggs being carried */ update_inventory(); } @@ -1206,9 +1206,9 @@ slip_or_trip(void) } if (!uarmf && otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && !Stone_resistance) { - Sprintf(gk.killer.name, "tripping over %s corpse", + Sprintf(svk.killer.name, "tripping over %s corpse", an(mons[otmp->corpsenm].pmnames[NEUTRAL])); - instapetrify(gk.killer.name); + instapetrify(svk.killer.name); } } else if ((HFumbling & FROMOUTSIDE) || (is_ice(u.ux, u.uy) && !rn2(3))) { /* is fumbling from ice alone? */ @@ -1342,8 +1342,8 @@ burn_object(anything *arg, long timeout) many = menorah ? obj->spe > 1 : obj->quan > 1L; /* timeout while away */ - if (timeout != gm.moves) { - long how_long = gm.moves - timeout; + if (timeout != svm.moves) { + long how_long = svm.moves - timeout; if (how_long >= obj->age) { obj->age = 0; @@ -1783,7 +1783,7 @@ cleanup_burn(anything *arg, long expire_time) del_light_source(LS_OBJECT, obj_to_any(obj)); /* restore unused time */ - obj->age += expire_time - gm.moves; + obj->age += expire_time - svm.moves; obj->lamplit = 0; if (obj->where == OBJ_INVENT) @@ -1799,7 +1799,7 @@ do_storms(void) int count; /* no lightning if not stormy level or too often, even then */ - if (!gl.level.flags.stormy || rn2(8)) + if (!svl.level.flags.stormy || rn2(8)) return; /* the number of strikes is 8-log2(nstrike) */ @@ -1849,7 +1849,7 @@ do_storms(void) * boolean start_timer(long timeout,short kind,short func_index, * anything *arg) * Start a timer of kind 'kind' that will expire at time - * gm.moves+'timeout'. Call the function at 'func_index' + * svm.moves+'timeout'. Call the function at 'func_index' * in the timeout table using argument 'arg'. Return TRUE if * a timer was started. This places the timer on a list ordered * "sooner" to "later". If an object, increment the object's @@ -1997,7 +1997,7 @@ wiz_timeout_queue(void) if (win == WIN_ERR) return ECMD_OK; - Sprintf(buf, "Current time = %ld.", gm.moves); + Sprintf(buf, "Current time = %ld.", svm.moves); putstr(win, 0, buf); putstr(win, 0, ""); putstr(win, 0, "Active timeout queue:"); @@ -2158,7 +2158,7 @@ run_timers(void) * any time. The list is ordered, we are done when the first element * is in the future. */ - while (gt.timer_base && gt.timer_base->timeout <= gm.moves) { + while (gt.timer_base && gt.timer_base->timeout <= svm.moves) { curr = gt.timer_base; gt.timer_base = curr->next; @@ -2207,8 +2207,8 @@ start_timer( gnu = (timer_element *) alloc(sizeof *gnu); (void) memset((genericptr_t) gnu, 0, sizeof *gnu); gnu->next = 0; - gnu->tid = gt.timer_id++; - gnu->timeout = gm.moves + when; + gnu->tid = svt.timer_id++; + gnu->timeout = svm.moves + when; gnu->kind = kind; gnu->needs_fixup = 0; gnu->func_index = func_index; @@ -2242,7 +2242,7 @@ stop_timer(short func_index, anything *arg) (*cleanup_func)(arg, timeout); (void) memset((genericptr_t) doomed, 0, sizeof(timer_element)); free((genericptr_t) doomed); - return (timeout - gm.moves); + return (timeout - svm.moves); } return 0L; } @@ -2293,7 +2293,7 @@ obj_split_timers(struct obj *src, struct obj *dest) for (curr = gt.timer_base; curr; curr = next_timer) { next_timer = curr->next; /* things may be inserted */ if (curr->kind == TIMER_OBJECT && curr->arg.a_obj == src) { - (void) start_timer(curr->timeout - gm.moves, TIMER_OBJECT, + (void) start_timer(curr->timeout - svm.moves, TIMER_OBJECT, curr->func_index, obj_to_any(dest)); } } @@ -2389,7 +2389,7 @@ long spot_time_left(coordxy x, coordxy y, short func_index) { long expires = spot_time_expires(x, y, func_index); - return (expires > 0L) ? expires - gm.moves : 0L; + return (expires > 0L) ? expires - svm.moves : 0L; } /* Insert timer into the global queue */ @@ -2608,7 +2608,7 @@ save_timers(NHFILE *nhfp, int range) if (perform_bwrite(nhfp)) { if (range == RANGE_GLOBAL) { if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) >.timer_id, sizeof(gt.timer_id)); + bwrite(nhfp->fd, (genericptr_t) &svt.timer_id, sizeof(svt.timer_id)); } count = maybe_write_timer(nhfp, range, FALSE); if (nhfp->structlevel) @@ -2648,7 +2648,7 @@ restore_timers(NHFILE *nhfp, int range, long adjust) if (range == RANGE_GLOBAL) { if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) >.timer_id, sizeof gt.timer_id); + mread(nhfp->fd, (genericptr_t) &svt.timer_id, sizeof svt.timer_id); } /* restore elements */ diff --git a/src/topten.c b/src/topten.c index 92f8388da..7bd993ca0 100644 --- a/src/topten.c +++ b/src/topten.c @@ -24,7 +24,7 @@ static long final_fpos; /* [note: do not move this to the 'g' struct] */ #endif -#define done_stopprint gp.program_state.stopprint +#define done_stopprint svp.program_state.stopprint #define newttentry() (struct toptenentry *) alloc(sizeof (struct toptenentry)) #define dealloc_ttentry(ttent) free((genericptr_t) (ttent)) @@ -85,7 +85,7 @@ staticfn void nsb_mung_line(char *); staticfn void nsb_unmung_line(char *); #endif -/* "killed by",&c ["an"] 'gk.killer.name' */ +/* "killed by",&c ["an"] 'svk.killer.name' */ void formatkiller( char *buf, @@ -104,12 +104,12 @@ formatkiller( "", "", "", "", "" }; unsigned l; - char c, *kname = gk.killer.name; + char c, *kname = svk.killer.name; buf[0] = '\0'; /* lint suppression */ - switch (gk.killer.format) { + switch (svk.killer.format) { default: - impossible("bad killer format? (%d)", gk.killer.format); + impossible("bad killer format? (%d)", svk.killer.format); /*FALLTHRU*/ case NO_KILLER_PREFIX: break; @@ -333,7 +333,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL #ifdef XLOGFILE -/* as tab is never used in eg. gp.plname or death, no need to mangle those. */ +/* as tab is never used in eg. svp.plname or death, no need to mangle those. */ staticfn void writexlentry(FILE *rfile, struct toptenentry *tt, int how) { @@ -359,12 +359,12 @@ writexlentry(FILE *rfile, struct toptenentry *tt, int how) formatkiller(tmpbuf, sizeof tmpbuf, how, FALSE); Fprintf(rfile, "%s%cname=%s%cdeath=%s", buf, /* (already includes separator) */ - XLOG_SEP, gp.plname, XLOG_SEP, tmpbuf); + XLOG_SEP, svp.plname, XLOG_SEP, tmpbuf); if (gm.multi < 0) Fprintf(rfile, "%cwhile=%s", XLOG_SEP, gm.multi_reason ? gm.multi_reason : "helpless"); Fprintf(rfile, "%cconduct=0x%lx%cturns=%ld%cachieve=0x%lx", XLOG_SEP, - encodeconduct(), XLOG_SEP, gm.moves, XLOG_SEP, + encodeconduct(), XLOG_SEP, svm.moves, XLOG_SEP, encodeachieve(FALSE)); Fprintf(rfile, "%cachieveX=%s", XLOG_SEP, encode_extended_achievements(achbuf)); @@ -642,7 +642,7 @@ topten(int how, time_t when) * topten uses alloc() several times, which will lead to * problems if the panic was the result of an alloc() failure. */ - if (gp.program_state.panicking) + if (svp.program_state.panicking) return; if (iflags.toptenwin) { @@ -650,7 +650,7 @@ topten(int how, time_t when) } #if defined(HANGUPHANDLING) -#define HUP if (!gp.program_state.done_hup) +#define HUP if (!svp.program_state.done_hup) #else #define HUP #endif @@ -683,7 +683,7 @@ topten(int how, time_t when) copynchars(t0->plrace, gu.urace.filecode, ROLESZ); copynchars(t0->plgend, genders[flags.female].filecode, ROLESZ); copynchars(t0->plalign, aligns[1 - u.ualign.type].filecode, ROLESZ); - copynchars(t0->name, gp.plname, NAMSZ); + copynchars(t0->name, svp.plname, NAMSZ); formatkiller(t0->death, sizeof t0->death, how, TRUE); t0->birthdate = yyyymmdd(ubirthday); t0->deathdate = yyyymmdd(when); @@ -1020,7 +1020,7 @@ outentry(int rank, struct toptenentry *t1, boolean so) } Sprintf(eos(linebuf), fmt, arg); } else { - Sprintf(eos(linebuf), " in %s", gd.dungeons[t1->deathdnum].dname); + Sprintf(eos(linebuf), " in %s", svd.dungeons[t1->deathdnum].dname); if (t1->deathdnum != knox_level.dnum) Sprintf(eos(linebuf), " on level %d", t1->deathlev); if (t1->deathlev != t1->maxlvl) @@ -1251,7 +1251,7 @@ prscore(int argc, char **argv) playerct = 0; players = (const char **) 0; } else { - player0 = gp.plname; + player0 = svp.plname; if (!*player0) player0 = "all"; /* if no plname[], show all scores * (possibly filtered by '-v') */ diff --git a/src/trap.c b/src/trap.c index 5aaaee0de..33145d6e2 100644 --- a/src/trap.c +++ b/src/trap.c @@ -522,7 +522,7 @@ maketrap(coordxy x, coordxy y, int typ) && (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ))) add_damage(x, y, /* schedule repair */ ((IS_DOOR(lev->typ) || IS_WALL(lev->typ)) - && !gc.context.mon_moving) + && !svc.context.mon_moving) ? SHOP_HOLE_COST : 0L); lev->doormask = 0; /* subsumes altarmask, icedpool... */ @@ -535,8 +535,8 @@ maketrap(coordxy x, coordxy y, int typ) else if (lev->typ == STONE || lev->typ == SCORR) (void) set_levltyp(x, y, CORR); else if (IS_WALL(lev->typ) || lev->typ == SDOOR) - (void) set_levltyp(x, y, gl.level.flags.is_maze_lev ? ROOM - : gl.level.flags.is_cavernous_lev ? CORR + (void) set_levltyp(x, y, svl.level.flags.is_maze_lev ? ROOM + : svl.level.flags.is_cavernous_lev ? CORR : DOOR); unearth_objs(x, y); @@ -824,7 +824,7 @@ animate_statue( /* if this isn't caused by a monster using a wand of striking, there might be consequences for the hero */ - if (!gc.context.mon_moving) { + if (!svc.context.mon_moving) { /* if statue is owned by a shop, hero will have to pay for it; stolen_value gives a message (about debt or use of credit) which refers to "it" so needs to follow a message describing @@ -3192,9 +3192,9 @@ launch_obj( launched (perhaps a monster triggered it), destroy context so that next dig attempt never thinks you're resuming previous effort */ if ((otyp == BOULDER || otyp == STATUE) - && singleobj->ox == gc.context.digging.pos.x - && singleobj->oy == gc.context.digging.pos.y) - (void) memset((genericptr_t) &gc.context.digging, 0, + && singleobj->ox == svc.context.digging.pos.x + && singleobj->oy == svc.context.digging.pos.y) + (void) memset((genericptr_t) &svc.context.digging, 0, sizeof(struct dig_info)); dist = distmin(x1, y1, x2, y2); @@ -3711,9 +3711,9 @@ instapetrify(const char *str) if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) return; urgent_pline("You turn to stone..."); - gk.killer.format = KILLED_BY; - if (str != gk.killer.name) - Strcpy(gk.killer.name, str ? str : ""); + svk.killer.format = KILLED_BY; + if (str != svk.killer.name) + Strcpy(svk.killer.name, str ? str : ""); done(STONING); } @@ -4911,7 +4911,7 @@ rescued_from_terrain(int how) iflags.last_msg = PLNMSG_BACK_ON_GROUND; /* for describe_decor() */ /* feedback just disclosed this */ update_lastseentyp(u.ux, u.uy); - iflags.prev_decor = gl.lastseentyp[u.ux][u.uy]; + iflags.prev_decor = svl.lastseentyp[u.ux][u.uy]; } /* return TRUE iff player relocated */ @@ -5036,14 +5036,14 @@ drown(void) /* killer format and name are reconstructed every iteration because lifesaving resets them */ pool_of_water = waterbody_name(u.ux, u.uy); - gk.killer.format = KILLED_BY_AN; + svk.killer.format = KILLED_BY_AN; /* avoid "drowned in [a] water" */ if (!strcmp(pool_of_water, "water")) - pool_of_water = "deep water", gk.killer.format = KILLED_BY; + pool_of_water = "deep water", svk.killer.format = KILLED_BY; /* avoid "drowned in _a_ limitless water" on Plane of Water */ else if (!strcmp(pool_of_water, "limitless water")) - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, pool_of_water); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, pool_of_water); done(DROWNING); /* oops, we're still alive. better get out of the water. */ if (safe_teleds(TELEDS_ALLOW_DRAG | TELEDS_TELEPORT)) @@ -5715,7 +5715,7 @@ untrap( here = u_at(x, y); /* !u.dx && !u.dy */ if (here) /* are there are one or more containers here? */ - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (Is_box(otmp)) { if (++boxcnt > 1) break; @@ -5818,7 +5818,7 @@ untrap( whether any had been found but not attempted to untrap; now at most one per move may be checked and we only continue on to door handling if they are all declined */ - for (otmp = gl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) if (Is_box(otmp)) { (void) safe_qbuf(qbuf, "There is ", " here. Check it for traps?", otmp, @@ -6183,7 +6183,7 @@ chest_trap( unpunish(); /* destroy everything at the spot (the Amulet, the invocation tools, and Rider corpses will remain intact) */ - for (otmp = gl.level.objects[ox][oy]; otmp; otmp = otmp2) { + for (otmp = svl.level.objects[ox][oy]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; if (costly) loss += stolen_value(otmp, otmp->ox, otmp->oy, @@ -6716,8 +6716,8 @@ lava_effects(void) u.uhp = -1; /* killer format and name are reconstructed every iteration because lifesaving resets them */ - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, lava_killer); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, lava_killer); urgent_pline("You %s...", boil_away ? "boil away" : "burn to a crisp"); done(BURNING); @@ -6796,8 +6796,8 @@ sink_into_lava(void) u.utrap -= (1 << 8); if (u.utrap < (1 << 8)) { - gk.killer.format = KILLED_BY; - Strcpy(gk.killer.name, "molten lava"); + svk.killer.format = KILLED_BY; + Strcpy(svk.killer.name, "molten lava"); urgent_pline("You sink below the surface and die."); burn_away_slime(); /* add insult to injury? */ done(DISSOLVED); @@ -6860,13 +6860,13 @@ maybe_finish_sokoban(void) if (!t) { /* for livelog to report the sokoban depth in the way that players tend to think about it: 1 for entry level, 4 for top */ - int sokonum = gd.dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1; + int sokonum = svd.dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1; /* we've passed the last trap without finding a pit or hole; clear the sokoban_rules flag so that luck penalties for things like breaking boulders or jumping will no longer be given, and restrictions on diagonal moves are lifted */ - Sokoban = 0; /* clear gl.level.flags.sokoban_rules */ + Sokoban = 0; /* clear svl.level.flags.sokoban_rules */ /* * TODO: give some feedback about solving the sokoban puzzle * (perhaps say "congratulations" in Japanese?). diff --git a/src/u_init.c b/src/u_init.c index 443587c47..f7356cb56 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -582,7 +582,7 @@ knows_class(char sym) * arrow, and spear limitation below. */ - for (ct = gb.bases[(uchar) sym]; ct < gb.bases[(uchar) sym + 1]; ct++) { + for (ct = svb.bases[(uchar) sym]; ct < svb.bases[(uchar) sym + 1]; ct++) { /* not flagged as magic but shouldn't be pre-discovered */ if (ct == CORNUTHAUM || ct == DUNCE_CAP) continue; @@ -911,7 +911,7 @@ u_init(void) init_uhunger(); for (i = 0; i <= MAXSPELL; i++) - gs.spl_book[i].sp_id = NO_SPELL; + svs.spl_book[i].sp_id = NO_SPELL; u.ublesscnt = 300; /* no prayers just yet */ u.ualignbase[A_CURRENT] = u.ualignbase[A_ORIGINAL] = u.ualign.type = aligns[flags.initalign].value; diff --git a/src/uhitm.c b/src/uhitm.c index e9062acb9..307883235 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -195,7 +195,7 @@ attack_checks( if (engulfing_u(mtmp)) return FALSE; - if (gc.context.forcefight) { + if (svc.context.forcefight) { /* Do this in the caller, after we checked that the monster * didn't die from the blow. Reason: putting the 'I' there * causes the hero to forget the square's contents since @@ -285,7 +285,7 @@ attack_checks( notseen ? "is present" : "appears"); else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater)) pline("Wait! There's a hidden monster there!"); - else if ((obj = gl.level.objects[mtmp->mx][mtmp->my]) != 0) + else if ((obj = svl.level.objects[mtmp->mx][mtmp->my]) != 0) pline("Wait! There's %s hiding under %s!", notseen ? something : (const char *) an(lmonbuf), doname(obj)); @@ -314,7 +314,7 @@ attack_checks( Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); if (!paranoid_query(ParanoidHit, qbuf)) { - gc.context.move = 0; + svc.context.move = 0; return TRUE; } } @@ -429,12 +429,12 @@ force_attack(struct monst *mtmp, boolean pets_too) { boolean attacked, save_Forcefight; - save_Forcefight = gc.context.forcefight; + save_Forcefight = svc.context.forcefight; /* always set forcefight On for hostiles and peacefuls, maybe for pets */ if (pets_too || !mtmp->mtame) - gc.context.forcefight = TRUE; + svc.context.forcefight = TRUE; attacked = do_attack(mtmp); - gc.context.forcefight = save_Forcefight; + svc.context.forcefight = save_Forcefight; return attacked; } @@ -455,7 +455,7 @@ do_attack(struct monst *mtmp) * you'll usually just swap places if this is a movement command */ /* Intelligent chaotic weapons (Stormbringer) want blood */ - if (is_safemon(mtmp) && !gc.context.forcefight) { + if (is_safemon(mtmp) && !svc.context.forcefight) { if (!u_wield_art(ART_STORMBRINGER)) { /* There are some additional considerations: this won't work * if in a shop or Punished or you miss a random roll or @@ -477,7 +477,7 @@ do_attack(struct monst *mtmp) /* only check for in-shop if don't already have reason to stop */ if (!foo) { for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) - if (tended_shop(&gr.rooms[*p - ROOMOFFSET])) { + if (tended_shop(&svr.rooms[*p - ROOMOFFSET])) { inshop = TRUE; break; } @@ -485,7 +485,7 @@ do_attack(struct monst *mtmp) if (inshop || foo) { char buf[BUFSZ]; - if (!gc.context.travel && !gc.context.run) + if (!svc.context.travel && !svc.context.run) if (canspotmon(mtmp) && mtmp->isshk) return ECMD_TIME | dopay(); @@ -570,7 +570,7 @@ do_attack(struct monst *mtmp) * and it returned 0 (it's okay to attack), and the monster didn't * evade. */ - if (gc.context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp) + if (svc.context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp) && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph) && !engulfing_u(mtmp)) map_invisible(u.ux + u.dx, u.uy + u.dy); @@ -3306,8 +3306,8 @@ mhitm_ad_wrap( && !Is_waterlevel(&u.uz); urgent_pline("%s drowns you...", Monnam(magr)); - gk.killer.format = KILLED_BY_AN; - Sprintf(gk.killer.name, "%s by %s", + svk.killer.format = KILLED_BY_AN; + Sprintf(svk.killer.name, "%s by %s", moat ? "moat" : "pool of water", an(pmname(magr->data, Mgender(magr)))); done(DROWNING); @@ -4246,7 +4246,7 @@ mhitm_ad_heal( mhm->damage = 0; } else { if (Role_if(PM_HEALER)) { - if (!Deaf && !(gm.moves % 5)) { + if (!Deaf && !(svm.moves % 5)) { SetVoice(magr, 0, 80, 0); verbalize("Doc, I can't help you unless you cooperate."); } @@ -4426,7 +4426,7 @@ mhitm_ad_dgst( */ num = monsndx(pd); if (magr->mtame && !magr->isminion - && !(gm.mvitals[num].mvflags & G_NOCORPSE)) { + && !(svm.mvitals[num].mvflags & G_NOCORPSE)) { struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); int nutrit; @@ -4914,9 +4914,9 @@ gulpum(struct monst *mdef, struct attack *mattk) if (is_rider(pd)) { pline("Unfortunately, digesting any of it is fatal."); end_engulf(); - Sprintf(gk.killer.name, "unwisely tried to eat %s", + Sprintf(svk.killer.name, "unwisely tried to eat %s", pmname(pd, Mgender(mdef))); - gk.killer.format = NO_KILLER_PREFIX; + svk.killer.format = NO_KILLER_PREFIX; done(DIED); return M_ATTK_MISS; /* lifesaved */ } @@ -4944,7 +4944,7 @@ gulpum(struct monst *mdef, struct attack *mattk) } else { tmp = 1 + (pd->cwt >> 8); if (corpse_chance(mdef, &gy.youmonst, TRUE) - && !(gm.mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) { + && !(svm.mvitals[monsndx(pd)].mvflags & G_NOCORPSE)) { /* nutrition only if there can be a corpse */ u.uhunger += (pd->cnutrit + 1) / 2; } else { @@ -6154,7 +6154,7 @@ flash_hits_mon( light_hits_gremlin(mtmp, amt); } if (!DEADMONSTER(mtmp)) { - if (!gc.context.mon_moving) + if (!svc.context.mon_moving) setmangry(mtmp, TRUE); if (tmp < 9 && !mtmp->isshk && rn2(4)) monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE); @@ -6189,7 +6189,7 @@ light_hits_gremlin(struct monst *mon, int dmg) mon->mhp -= dmg; wake_nearto(mon->mx, mon->my, 30); if (DEADMONSTER(mon)) { - if (gc.context.mon_moving) + if (svc.context.mon_moving) monkilled(mon, (char *) 0, AD_BLND); else killed(mon); diff --git a/src/vault.c b/src/vault.c index 63591948a..a30a3406d 100644 --- a/src/vault.c +++ b/src/vault.c @@ -49,7 +49,7 @@ clear_fcorr(struct monst *grd, boolean forceshow) coordxy fcx, fcy, fcbeg; struct monst *mtmp; boolean sawcorridor = FALSE, - silently = gp.program_state.stopprint ? TRUE : FALSE; + silently = svp.program_state.stopprint ? TRUE : FALSE; struct egd *egrd = EGD(grd); struct trap *trap; struct rm *lev; @@ -156,8 +156,8 @@ parkguard(struct monst *grd) { /* either guard is dead or will now be treated as if so; monster traversal loops should skip it */ - if (grd == gc.context.polearm.hitmon) - gc.context.polearm.hitmon = 0; + if (grd == svc.context.polearm.hitmon) + svc.context.polearm.hitmon = 0; if (grd->mx) { remove_monster(grd->mx, grd->my); newsym(grd->mx, grd->my); @@ -246,7 +246,7 @@ vault_occupied(char *array) char *ptr; for (ptr = array; *ptr; ptr++) - if (gr.rooms[*ptr - ROOMOFFSET].rtype == VAULT) + if (svr.rooms[*ptr - ROOMOFFSET].rtype == VAULT) return *ptr; return '\0'; } @@ -495,13 +495,13 @@ invault(void) if (u.ualign.type == A_LAWFUL /* ignore trailing text, in case player includes rank */ - && strncmpi(buf, gp.plname, (int) strlen(gp.plname)) != 0) { + && strncmpi(buf, svp.plname, (int) strlen(svp.plname)) != 0) { adjalign(-1); /* Liar! */ } if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos") || !strcmpi(buf, "Creosote")) { /* Discworld */ - if (!gm.mvitals[PM_CROESUS].died) { + if (!svm.mvitals[PM_CROESUS].died) { if (Deaf) { if (!Blind) pline("%s waves goodbye.", noit_Monnam(guard)); @@ -583,8 +583,8 @@ invault(void) dug into an empty doorway (which could subsequently have been plugged with an intact door by use of locking magic) */ int vlt = EGD(guard)->vroom; - coordxy lowx = gr.rooms[vlt].lx, hix = gr.rooms[vlt].hx; - coordxy lowy = gr.rooms[vlt].ly, hiy = gr.rooms[vlt].hy; + coordxy lowx = svr.rooms[vlt].lx, hix = svr.rooms[vlt].hx; + coordxy lowy = svr.rooms[vlt].ly, hiy = svr.rooms[vlt].hy; if (x == lowx - 1 && y == lowy - 1) typ = TLCORNER; @@ -623,8 +623,8 @@ move_gold(struct obj *gold, int vroom) remove_object(gold); newsym(gold->ox, gold->oy); - nx = gr.rooms[vroom].lx + rn2(2); - ny = gr.rooms[vroom].ly + rn2(2); + nx = svr.rooms[vroom].lx + rn2(2); + ny = svr.rooms[vroom].ly + rn2(2); place_object(gold, nx, ny); stackobj(gold); newsym(nx, ny); @@ -637,8 +637,8 @@ wallify_vault(struct monst *grd) coordxy x, y; int vlt = EGD(grd)->vroom; char tmp_viz; - coordxy lox = gr.rooms[vlt].lx - 1, hix = gr.rooms[vlt].hx + 1, - loy = gr.rooms[vlt].ly - 1, hiy = gr.rooms[vlt].hy + 1; + coordxy lox = svr.rooms[vlt].lx - 1, hix = svr.rooms[vlt].hx + 1, + loy = svr.rooms[vlt].ly - 1, hiy = svr.rooms[vlt].hy + 1; struct monst *mon; struct obj *gold, *rocks; struct trap *trap; @@ -1210,10 +1210,10 @@ paygd(boolean silently) mnexto(grd, RLOC_NOMSG); if (!silently) pline("%s remits your gold to the vault.", Monnam(grd)); - gdx = gr.rooms[EGD(grd)->vroom].lx + rn2(2); - gdy = gr.rooms[EGD(grd)->vroom].ly + rn2(2); + gdx = svr.rooms[EGD(grd)->vroom].lx + rn2(2); + gdy = svr.rooms[EGD(grd)->vroom].ly + rn2(2); Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.", - gp.plname, + svp.plname, pmname(&mons[u.umonster], flags.female ? FEMALE : MALE)); make_grave(gdx, gdy, buf); } diff --git a/src/vision.c b/src/vision.c index 997a88715..ff80a29bf 100644 --- a/src/vision.c +++ b/src/vision.c @@ -170,7 +170,7 @@ does_block(int x, int y, struct rm *lev) #endif /* Boulders block light. */ - for (obj = gl.level.objects[x][y]; obj; obj = obj->nexthere) + for (obj = svl.level.objects[x][y]; obj; obj = obj->nexthere) if (obj->otyp == BOULDER) return 1; @@ -311,12 +311,12 @@ rogue_vision(seenV **next, coordxy *rmin, coordxy *rmax) /* If in a lit room, we are able to see to its boundaries. */ /* If dark, set COULD_SEE so various spells work -dlc */ if (rnum >= 0) { - for (zy = gr.rooms[rnum].ly - 1; zy <= gr.rooms[rnum].hy + 1; zy++) { - rmin[zy] = start = gr.rooms[rnum].lx - 1; - rmax[zy] = stop = gr.rooms[rnum].hx + 1; + for (zy = svr.rooms[rnum].ly - 1; zy <= svr.rooms[rnum].hy + 1; zy++) { + rmin[zy] = start = svr.rooms[rnum].lx - 1; + rmax[zy] = stop = svr.rooms[rnum].hx + 1; for (zx = start; zx <= stop; zx++) { - if (gr.rooms[rnum].rlit) { + if (svr.rooms[rnum].rlit) { next[zy][zx] = COULD_SEE | IN_SIGHT; levl[zx][zy].seenv = SVALL; /* see the walls */ } else @@ -521,7 +521,7 @@ vision_recalc(int control) int oldseenv; /* previous seenv value */ gv.vision_full_recalc = 0; /* reset flag */ - if (gi.in_mklev || gp.program_state.in_getlev || !iflags.vision_inited) + if (gi.in_mklev || svp.program_state.in_getlev || !iflags.vision_inited) return; /* @@ -825,9 +825,9 @@ vision_recalc(int control) /* This newsym() caused a crash delivering msg about failure to open * dungeon file init_dungeons() -> panic() -> done(11) -> * vision_recalc(2) -> newsym() -> crash! u.ux and u.uy are 0 and - * gp.program_state.panicking == 1 under those circumstances + * svp.program_state.panicking == 1 under those circumstances */ - if (!gp.program_state.panicking) + if (!svp.program_state.panicking) newsym(u.ux, u.uy); /* Make sure the hero shows up! */ /* Set the new min and max pointers. */ diff --git a/src/weapon.c b/src/weapon.c index 01d6f63e4..e4442420d 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1179,7 +1179,7 @@ enhance_weapon_skill(void) int clr = NO_COLOR; /* player knows about #enhance, don't show tip anymore */ - gc.context.tips[TIP_ENHANCE] = TRUE; + svc.context.tips[TIP_ENHANCE] = TRUE; if (wizard && y_n("Advance skills without practice?") == 'y') speedy = TRUE; diff --git a/src/were.c b/src/were.c index e78215ebf..0832555f1 100644 --- a/src/were.c +++ b/src/were.c @@ -130,7 +130,7 @@ new_were(struct monst *mon) /* vision capability isn't changing so we don't call set_apparxy() to update mon's idea of where hero is; peaceful check is redundant */ - if (gc.context.mon_moving && !mon->mpeaceful + if (svc.context.mon_moving && !mon->mpeaceful && onscary(mon->mux, mon->muy, mon) && monnear(mon, mon->mux, mon->muy)) monflee(mon, rn1(9, 2), TRUE, TRUE); /* 2..10 turns */ diff --git a/src/wield.c b/src/wield.c index 6bb329367..b07952ed1 100644 --- a/src/wield.c +++ b/src/wield.c @@ -371,14 +371,14 @@ dowield(void) /* previously interrupted armor removal mustn't be resumed */ reset_remarm(); /* if player chose a partial stack but can't wield it, undo split */ - if (wep->o_id && wep->o_id == gc.context.objsplit.child_oid) + if (wep->o_id && wep->o_id == svc.context.objsplit.child_oid) unsplitobj(wep); return ECMD_FAIL; - } else if (wep->o_id && wep->o_id == gc.context.objsplit.child_oid) { + } else if (wep->o_id && wep->o_id == svc.context.objsplit.child_oid) { /* if wep is the result of supplying a count to getobj() we don't want to split something already wielded; for any other item, we need to give it its own inventory slot */ - if (uwep && uwep->o_id == gc.context.objsplit.parent_oid) { + if (uwep && uwep->o_id == svc.context.objsplit.parent_oid) { unsplitobj(wep); /* wep was merged back to uwep, already_wielded uses wep */ wep = uwep; @@ -538,11 +538,11 @@ doquiver_core(const char *verb) /* "ready" or "fire" */ You("already have no ammunition readied!"); } return ECMD_OK; - } else if (newquiver->o_id == gc.context.objsplit.child_oid) { + } else if (newquiver->o_id == svc.context.objsplit.child_oid) { /* if newquiver is the result of supplying a count to getobj() we don't want to split something already in the quiver; for any other item, we need to give it its own inventory slot */ - if (uquiver && uquiver->o_id == gc.context.objsplit.parent_oid) { + if (uquiver && uquiver->o_id == svc.context.objsplit.parent_oid) { unsplitobj(newquiver); goto already_quivered; } else if (newquiver->oclass == COIN_CLASS) { diff --git a/src/windows.c b/src/windows.c index e7f1351f7..8d4c7e6ff 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1196,13 +1196,13 @@ dump_fmtstr( break; case 'n': /* player name */ if (fullsubs) - Sprintf(tmpbuf, "%s", *gp.plname ? gp.plname : "unknown"); + Sprintf(tmpbuf, "%s", *svp.plname ? svp.plname : "unknown"); else Strcpy(tmpbuf, "{hero name}"); break; case 'N': /* first character of player name */ if (fullsubs) - Sprintf(tmpbuf, "%c", *gp.plname ? *gp.plname : 'u'); + Sprintf(tmpbuf, "%c", *svp.plname ? *svp.plname : 'u'); else Strcpy(tmpbuf, "{hero initial}"); break; @@ -1430,7 +1430,7 @@ encglyph(int glyph) { static char encbuf[20]; /* 10+1 would suffice */ - Sprintf(encbuf, "\\G%04X%04X", gc.context.rndencode, glyph); + Sprintf(encbuf, "\\G%04X%04X", svc.context.rndencode, glyph); return encbuf; } @@ -1449,7 +1449,7 @@ decode_glyph(const char *str, int *glyph_ptr) } else break; } - if (rndchk == gc.context.rndencode) { + if (rndchk == svc.context.rndencode) { *glyph_ptr = dcount = 0; for (; *str && ++dcount <= 4; ++str) { if ((dp = strchr(hexdd, *str)) != 0) { @@ -1814,7 +1814,7 @@ add_menu_heading(winid tmpwin, const char *buf) color = iflags.menu_headings.color; /* suppress highlighting during end-of-game disclosure */ - if (gp.program_state.gameover) + if (svp.program_state.gameover) attr = ATR_NONE, color = NO_COLOR; add_menu(tmpwin, &nul_glyphinfo, &any, '\0', '\0', attr, color, @@ -1862,10 +1862,10 @@ getlin(const char *query, char *bufp) { boolean old_bot_disabled = gb.bot_disabled; - gp.program_state.in_getlin = 1; + svp.program_state.in_getlin = 1; gb.bot_disabled = TRUE; (*windowprocs.win_getlin)(query, bufp); gb.bot_disabled = old_bot_disabled; - gp.program_state.in_getlin = 0; + svp.program_state.in_getlin = 0; } /*windows.c*/ diff --git a/src/wizard.c b/src/wizard.c index 0989f9b20..aefba556d 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -86,7 +86,7 @@ amulet(void) } } - if (!gc.context.no_of_wizards) + if (!svc.context.no_of_wizards) return; /* find Wizard, and wake him if necessary */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { @@ -295,7 +295,7 @@ strategy(struct monst *mtmp) break; } - if (gc.context.made_amulet) + if (svc.context.made_amulet) if ((strat = target_on(M3_WANTSAMUL, mtmp)) != STRAT_NONE) return strat; @@ -544,7 +544,7 @@ pick_nasty( master mind flayer -> mind flayer, but the substitutes are likely to be genocided too */ alt = res; - if ((gm.mvitals[res].mvflags & G_GENOD) != 0 + if ((svm.mvitals[res].mvflags & G_GENOD) != 0 || (difcap > 0 && mons[res].difficulty >= difcap) /* note: nasty() -> makemon() ignores G_HELL|G_NOHELL; arch-lich and master lich are both flagged as hell-only; @@ -552,7 +552,7 @@ pick_nasty( outside of Gehennom (unless the latter has been genocided) */ || (mons[res].geno & (Inhell ? G_NOHELL : G_HELL)) != 0) alt = big_to_little(res); - if (alt != res && (gm.mvitals[alt].mvflags & G_GENOD) == 0) { + if (alt != res && (svm.mvitals[alt].mvflags & G_GENOD) == 0) { const char *mnam = mons[alt].pmnames[NEUTRAL], *lastspace = strrchr(mnam, ' '); @@ -702,7 +702,7 @@ resurrect(void) long elapsed; const char *verb; - if (!gc.context.no_of_wizards) { + if (!svc.context.no_of_wizards) { /* make a new Wizard */ verb = "kill"; mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy, MM_NOWAIT); @@ -718,7 +718,7 @@ resurrect(void) if (mtmp->iswiz /* if he has the Amulet, he won't bring it to you */ && !mon_has_amulet(mtmp) - && (elapsed = gm.moves - mtmp->mlstmv) > 0L) { + && (elapsed = svm.moves - mtmp->mlstmv) > 0L) { mon_catchup_elapsed_time(mtmp, elapsed); if (elapsed >= LARGEST_INT) elapsed = LARGEST_INT - 1; @@ -798,7 +798,7 @@ intervene(void) void wizdeadorgone(void) { - gc.context.no_of_wizards--; + svc.context.no_of_wizards--; if (!u.uevent.udemigod) { u.uevent.udemigod = TRUE; u.udg_cnt = rn1(250, 50); diff --git a/src/wizcmds.c b/src/wizcmds.c index 6d1585ce9..abab4313a 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -76,9 +76,9 @@ makemap_unmakemon(struct monst *mtmp, boolean migratory) /* uncreate any unique monster so that it is eligible to be remade on the new incarnation of the level; ignores DEADMONSTER() [why?] */ if (mtmp->data->geno & G_UNIQ) - gm.mvitals[ndx].mvflags &= ~G_EXTINCT; - if (gm.mvitals[ndx].born) - gm.mvitals[ndx].born--; + svm.mvitals[ndx].mvflags &= ~G_EXTINCT; + if (svm.mvitals[ndx].born) + svm.mvitals[ndx].born--; /* vault is going away; get rid of guard who might be in play or be parked at <0,0>; for the latter, might already be flagged as @@ -276,8 +276,8 @@ wiz_kill(void) Sprintf(qbuf, "%s?", Role_if(PM_SAMURAI) ? "Perform seppuku" : "Commit suicide"); if (paranoid_query(TRUE, qbuf)) { - Sprintf(gk.killer.name, "%s own player", uhis()); - gk.killer.format = KILLED_BY; + Sprintf(svk.killer.name, "%s own player", uhis()); + svk.killer.format = KILLED_BY; done(DIED); } break; @@ -318,12 +318,12 @@ wiz_kill(void) gas spore whose explosion kills any other monsters we need to have the mon_moving flag be True in order to avoid blaming or crediting hero for their deaths */ - gc.context.mon_moving = TRUE; + svc.context.mon_moving = TRUE; pline("%s is %s.", upstart(Mn), nonliving(mtmp->data) ? "destroyed" : "killed"); /* Null second arg suppresses the usual message */ monkilled(mtmp, (char *) 0, AD_PHYS); - gc.context.mon_moving = FALSE; + svc.context.mon_moving = FALSE; } /* end targetting loop if an engulfer dropped hero onto a level- changing trap */ @@ -736,48 +736,48 @@ wiz_map_levltyp(void) /* alignment currently omitted to save space */ } /* level features */ - if (gl.level.flags.nfountains) + if (svl.level.flags.nfountains) Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym, - (int) gl.level.flags.nfountains); - if (gl.level.flags.nsinks) + (int) svl.level.flags.nfountains); + if (svl.level.flags.nsinks) Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym, - (int) gl.level.flags.nsinks); - if (gl.level.flags.has_vault) + (int) svl.level.flags.nsinks); + if (svl.level.flags.has_vault) Strcat(dsc, " vault"); - if (gl.level.flags.has_shop) + if (svl.level.flags.has_shop) Strcat(dsc, " shop"); - if (gl.level.flags.has_temple) + if (svl.level.flags.has_temple) Strcat(dsc, " temple"); - if (gl.level.flags.has_court) + if (svl.level.flags.has_court) Strcat(dsc, " throne"); - if (gl.level.flags.has_zoo) + if (svl.level.flags.has_zoo) Strcat(dsc, " zoo"); - if (gl.level.flags.has_morgue) + if (svl.level.flags.has_morgue) Strcat(dsc, " morgue"); - if (gl.level.flags.has_barracks) + if (svl.level.flags.has_barracks) Strcat(dsc, " barracks"); - if (gl.level.flags.has_beehive) + if (svl.level.flags.has_beehive) Strcat(dsc, " hive"); - if (gl.level.flags.has_swamp) + if (svl.level.flags.has_swamp) Strcat(dsc, " swamp"); /* level flags */ - if (gl.level.flags.noteleport) + if (svl.level.flags.noteleport) Strcat(dsc, " noTport"); - if (gl.level.flags.hardfloor) + if (svl.level.flags.hardfloor) Strcat(dsc, " noDig"); - if (gl.level.flags.nommap) + if (svl.level.flags.nommap) Strcat(dsc, " noMMap"); - if (!gl.level.flags.hero_memory) + if (!svl.level.flags.hero_memory) Strcat(dsc, " noMem"); - if (gl.level.flags.shortsighted) + if (svl.level.flags.shortsighted) Strcat(dsc, " shortsight"); - if (gl.level.flags.graveyard) + if (svl.level.flags.graveyard) Strcat(dsc, " graveyard"); - if (gl.level.flags.is_maze_lev) + if (svl.level.flags.is_maze_lev) Strcat(dsc, " maze"); - if (gl.level.flags.is_cavernous_lev) + if (svl.level.flags.is_cavernous_lev) Strcat(dsc, " cave"); - if (gl.level.flags.arboreal) + if (svl.level.flags.arboreal) Strcat(dsc, " tree"); if (Sokoban) Strcat(dsc, " sokoban-rules"); @@ -806,7 +806,7 @@ wiz_map_levltyp(void) Strcat(dsc, " endgame"); else { /* somebody's added a dungeon branch we're not expecting */ - const char *brname = gd.dungeons[u.uz.dnum].dname; + const char *brname = svd.dungeons[u.uz.dnum].dname; if (!brname || !*brname) brname = "unknown"; @@ -1047,9 +1047,9 @@ wiz_intrinsic(void) break; case WARN_OF_MON: if (!Warn_of_mon) { - gc.context.warntype.speciesidx = PM_GRID_BUG; - gc.context.warntype.species - = &mons[gc.context.warntype.speciesidx]; + svc.context.warntype.speciesidx = PM_GRID_BUG; + svc.context.warntype.species + = &mons[svc.context.warntype.speciesidx]; } goto def_feedback; case GLIB: @@ -1193,7 +1193,7 @@ contained_stats( count_obj(gi.invent, &count, &size, FALSE, TRUE); count_obj(fobj, &count, &size, FALSE, TRUE); - count_obj(gl.level.buriedobjlist, &count, &size, FALSE, TRUE); + count_obj(svl.level.buriedobjlist, &count, &size, FALSE, TRUE); count_obj(gm.migrating_objs, &count, &size, FALSE, TRUE); /* DEADMONSTER check not required in this loop since they have no * inventory */ @@ -1317,7 +1317,7 @@ misc_stats( } count = size = 0L; - for (sd = gl.level.damagelist; sd; sd = sd->next) { + for (sd = svl.level.damagelist; sd; sd = sd->next) { ++count; size += (long) sizeof *sd; } @@ -1340,7 +1340,7 @@ misc_stats( } count = size = 0L; - for (k = gk.killer.next; k; k = k->next) { + for (k = svk.killer.next; k; k = k->next) { ++count; size += (long) sizeof *k; } @@ -1354,7 +1354,7 @@ misc_stats( } count = size = 0L; - for (bi = gl.level.bonesinfo; bi; bi = bi->next) { + for (bi = svl.level.bonesinfo; bi; bi = bi->next) { ++count; size += (long) sizeof *bi; } @@ -1435,7 +1435,7 @@ sanity_check(void) iflags.sanity_no_check = FALSE; return; } - gp.program_state.in_sanity_check++; + svp.program_state.in_sanity_check++; you_sanity_check(); obj_sanity_check(); timer_sanity_check(); @@ -1444,7 +1444,7 @@ sanity_check(void) bc_sanity_check(); trap_sanity_check(); engraving_sanity_check(); - gp.program_state.in_sanity_check--; + svp.program_state.in_sanity_check--; } /* qsort() comparison routine for use in list_migrating_mons() */ @@ -1599,7 +1599,7 @@ wiz_show_stats(void) obj_chain(win, "invent", gi.invent, TRUE, &total_obj_count, &total_obj_size); obj_chain(win, "fobj", fobj, TRUE, &total_obj_count, &total_obj_size); - obj_chain(win, "buried", gl.level.buriedobjlist, FALSE, + obj_chain(win, "buried", svl.level.buriedobjlist, FALSE, &total_obj_count, &total_obj_size); obj_chain(win, "migrating obj", gm.migrating_objs, FALSE, &total_obj_count, &total_obj_size); diff --git a/src/worm.c b/src/worm.c index 479c9d75e..bb95dc4d5 100644 --- a/src/worm.c +++ b/src/worm.c @@ -211,13 +211,13 @@ worm_move(struct monst *worm) seg->nseg = new_seg; /* attach it to the end of the list */ wheads[wnum] = new_seg; /* move the end pointer */ - if (wgrowtime[wnum] <= gm.moves) { + if (wgrowtime[wnum] <= svm.moves) { int whplimit, whpcap, prev_mhp, wsegs = count_wsegs(worm); /* first set up for the next time to grow */ if (!wgrowtime[wnum]) { /* new worm; usually grow a tail segment on its next turn */ - wgrowtime[wnum] = gm.moves + rnd(5); + wgrowtime[wnum] = svm.moves + rnd(5); } else { int mmove = mcalcmove(worm, FALSE), /* prior to 3.7.0, next-grow increment was 3..17 but since @@ -230,7 +230,7 @@ worm_move(struct monst *worm) * speed of 3, effective value is 8..48 */ incr = (incr * NORMAL_SPEED) / max(mmove, 1); - wgrowtime[wnum] = gm.moves + incr; + wgrowtime[wnum] = svm.moves + incr; } /* increase HP based on number of segments; if it has shrunk, it @@ -432,7 +432,7 @@ cutworm(struct monst *worm, coordxy x, coordxy y, /* Sometimes the tail end dies. */ if (!new_worm) { place_worm_seg(worm, x, y); /* place the "head" segment back */ - if (gc.context.mon_moving) { + if (svc.context.mon_moving) { if (canspotmon(worm)) pline("Part of %s tail has been cut off.", s_suffix(mon_nam(worm))); @@ -466,7 +466,7 @@ cutworm(struct monst *worm, coordxy x, coordxy y, /* Place the new monster at all the segment locations. */ place_wsegs(new_worm, worm); - if (gc.context.mon_moving) + if (svc.context.mon_moving) pline("%s is cut in half.", Monnam(worm)); else You("cut %s in half.", mon_nam(worm)); @@ -670,9 +670,9 @@ sanity_check_worm(struct monst *worm) x = curr->wx, y = curr->wy; if (!isok(x, y)) impossible("worm seg not isok <%d,%d>", x, y); - else if (gl.level.monsters[x][y] != worm) + else if (svl.level.monsters[x][y] != worm) impossible("mon (%s) at seg location is not worm (%s)", - fmt_ptr((genericptr_t) gl.level.monsters[x][y]), + fmt_ptr((genericptr_t) svl.level.monsters[x][y]), fmt_ptr((genericptr_t) worm)); curr = curr->nseg; diff --git a/src/worn.c b/src/worn.c index b8593b214..90266fb78 100644 --- a/src/worn.c +++ b/src/worn.c @@ -971,7 +971,7 @@ clear_bypass(struct obj *objchn) /* all objects with their bypass bit set should now be reset to normal; this can be a relatively expensive operation so is only called if - gc.context.bypasses is set */ + svc.context.bypasses is set */ void clear_bypasses(void) { @@ -980,14 +980,14 @@ clear_bypasses(void) /* * 'Object' bypass is also used for one monster function: * polymorph control of long worms. Activated via setting - * gc.context.bypasses even if no specific object has been + * svc.context.bypasses even if no specific object has been * bypassed. */ clear_bypass(fobj); clear_bypass(gi.invent); clear_bypass(gm.migrating_objs); - clear_bypass(gl.level.buriedobjlist); + clear_bypass(svl.level.buriedobjlist); clear_bypass(gb.billobjs); clear_bypass(go.objs_deleted); for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { @@ -1018,14 +1018,14 @@ clear_bypasses(void) if (uchain) uchain->bypass = 0; - gc.context.bypasses = FALSE; + svc.context.bypasses = FALSE; } void bypass_obj(struct obj *obj) { obj->bypass = 1; - gc.context.bypasses = TRUE; + svc.context.bypasses = TRUE; } /* set or clear the bypass bit in a list of objects */ @@ -1035,7 +1035,7 @@ bypass_objlist( boolean on) /* TRUE => set, FALSE => clear */ { if (on && objchain) - gc.context.bypasses = TRUE; + svc.context.bypasses = TRUE; while (objchain) { objchain->bypass = on ? 1 : 0; objchain = objchain->nobj; diff --git a/src/write.c b/src/write.c index 4536b864e..fd967685e 100644 --- a/src/write.c +++ b/src/write.c @@ -171,8 +171,8 @@ dowrite(struct obj *pen) deferred = real = 0; /* not any scroll or book */ deferralchance = 0; /* incremented for each oc_uname match */ - first = gb.bases[(int) paper->oclass]; - last = gb.bases[(int) paper->oclass + 1] - 1; + first = svb.bases[(int) paper->oclass]; + last = svb.bases[(int) paper->oclass + 1] - 1; /* first loop: look for match with name/description */ for (i = first; i <= last; i++) { /* extra shufflable descr not representing a real object */ @@ -363,7 +363,7 @@ dowrite(struct obj *pen) Strcpy(namebuf, OBJ_DESCR(objects[new_obj->otyp])); wipeout_text(namebuf, (6 + MAXULEV - u.ulevel) / 6, 0); } else - Sprintf(namebuf, "%s was here!", gp.plname); + Sprintf(namebuf, "%s was here!", svp.plname); You("write \"%s\" and the scroll disappears.", namebuf); useup(paper); } diff --git a/src/zap.c b/src/zap.c index 4d2ae0036..0bdc7baf2 100644 --- a/src/zap.c +++ b/src/zap.c @@ -234,7 +234,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) dmg *= 2; if (otyp == SPE_TURN_UNDEAD) dmg = spell_damage_bonus(dmg); - gc.context.bypasses = TRUE; /* for make_corpse() */ + svc.context.bypasses = TRUE; /* for make_corpse() */ if (!resist(mtmp, otmp->oclass, dmg, NOTELL)) { if (!DEADMONSTER(mtmp)) monflee(mtmp, 0, FALSE, TRUE); @@ -273,7 +273,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) pline("%s shudders!", Monnam(mtmp)); learn_it = TRUE; } - /* gc.context.bypasses = TRUE; ## for make_corpse() */ + /* svc.context.bypasses = TRUE; ## for make_corpse() */ /* no corpse after system shock */ xkilled(mtmp, XKILL_GIVEMSG | XKILL_NOCORPSE); } else { @@ -309,7 +309,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) /* flag to indicate that cleanup is needed; object bypass cleanup also clears mon->mextra->mcorpsenm for all long worms on the level */ - gc.context.bypasses = TRUE; + svc.context.bypasses = TRUE; } } break; @@ -724,10 +724,10 @@ montraits( if (mtmp->m_id) { mtmp2->m_id = mtmp->m_id; /* might be bringing quest leader back to life */ - if (gq.quest_status.leader_is_dead + if (svq.quest_status.leader_is_dead /* leader_is_dead implies leader_m_id is valid */ - && mtmp2->m_id == gq.quest_status.leader_m_id) - gq.quest_status.leader_is_dead = FALSE; + && mtmp2->m_id == svq.quest_status.leader_m_id) + svq.quest_status.leader_is_dead = FALSE; } mtmp2->mx = mtmp->mx; mtmp2->my = mtmp->my; @@ -1144,7 +1144,7 @@ unturn_dead(struct monst *mon) save_norevive = otmp->norevive; otmp->norevive = 0; - if ((mtmp2 = revive(otmp, !gc.context.mon_moving)) != 0) { + if ((mtmp2 = revive(otmp, !svc.context.mon_moving)) != 0) { ++res; /* might get revived as a zombie rather than corpse's monster */ different_type = (mtmp2->data != &mons[corpsenm]); @@ -1432,7 +1432,7 @@ obj_shudders(struct obj *obj) { int zap_odds; - if (gc.context.bypasses && obj->bypass) + if (svc.context.bypasses && obj->bypass) return FALSE; if (obj->oclass == WAND_CLASS) @@ -1463,7 +1463,7 @@ polyuse(struct obj *objhdr, int mat, int minwt) for (otmp = objhdr; minwt > 0 && otmp; otmp = otmp2) { otmp2 = otmp->nexthere; - if (gc.context.bypasses && otmp->bypass) + if (svc.context.bypasses && otmp->bypass) continue; if (otmp == uball || otmp == uchain) continue; @@ -1505,7 +1505,7 @@ create_polymon(struct obj *obj, int okind) const char *material; int pm_index; - if (gc.context.bypasses) { + if (svc.context.bypasses) { /* this is approximate because the "no golems" !obj->nexthere check below doesn't understand bypassed objects; but it should suffice since bypassed objects always end up as a @@ -1575,7 +1575,7 @@ create_polymon(struct obj *obj, int okind) break; } - if (!(gm.mvitals[pm_index].mvflags & G_GENOD)) + if (!(svm.mvitals[pm_index].mvflags & G_GENOD)) mdat = &mons[pm_index]; mtmp = makemon(mdat, obj->ox, obj->oy, MM_NOMSG); @@ -1819,7 +1819,7 @@ poly_obj(struct obj *obj, int id) case SPBOOK_CLASS: while (otmp->otyp == SPE_POLYMORPH) - otmp->otyp = rnd_class(gb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); + otmp->otyp = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); /* reduce spellbook abuse; non-blank books degrade; 3.7: novels don't use spestudied so shouldn't degrade to blank (but don't force spestudied to zero for them since a non-zero @@ -2110,13 +2110,13 @@ bhito(struct obj *obj, struct obj *otmp) * the invent or mon->minvent chain, possibly recursively. * * The bypass bit on all objects is reset each turn, whenever - * gc.context.bypasses is set. + * svc.context.bypasses is set. * - * We check the obj->bypass bit above AND gc.context.bypasses + * We check the obj->bypass bit above AND svc.context.bypasses * as a safeguard against any stray occurrence left in an obj * struct someplace, although that should never happen. */ - if (gc.context.bypasses) { + if (svc.context.bypasses) { return 0; } else { debugpline1("%s for a moment.", Tobjnam(obj, "pulsate")); @@ -2158,7 +2158,7 @@ bhito(struct obj *obj, struct obj *otmp) (void) boxlock(obj, otmp); if (obj_shudders(obj)) { - boolean cover = ((obj == gl.level.objects[u.ux][u.uy]) + boolean cover = ((obj == svl.level.objects[u.ux][u.uy]) && u.uundetected && hides_under(gy.youmonst.data)); @@ -2247,7 +2247,7 @@ bhito(struct obj *obj, struct obj *otmp) } else { int oox = obj->ox, ooy = obj->oy; - if (gc.context.mon_moving ? !breaks(obj, oox, ooy) + if (svc.context.mon_moving ? !breaks(obj, oox, ooy) : !hero_breaks(obj, oox, ooy, 0)) maybelearnit = FALSE; /* nothing broke */ else @@ -2287,7 +2287,7 @@ bhito(struct obj *obj, struct obj *otmp) struct monst *mtmp; coordxy ox, oy; unsigned save_norevive; - boolean by_u = !gc.context.mon_moving; + boolean by_u = !svc.context.mon_moving; int corpsenm = corpse_revive_type(obj); char *corpsname = cxname_singular(obj); @@ -2385,7 +2385,7 @@ bhitpile( boolean hidingunder, first; int prevotyp, hitanything = 0; - if (!gl.level.objects[tx][ty]) + if (!svl.level.objects[tx][ty]) return 0; /* if hiding underneath an object and zapping up or down, the top item @@ -2395,7 +2395,7 @@ bhitpile( if (obj->otyp == SPE_FORCE_BOLT || obj->otyp == WAN_STRIKING) { struct trap *t = t_at(tx, ty); - struct obj *topofpile = gl.level.objects[tx][ty]; + struct obj *topofpile = svl.level.objects[tx][ty]; /* We can't settle for the default calling sequence of bhito(otmp) -> break_statue(otmp) -> activate_statue_trap(ox,oy) @@ -2408,12 +2408,12 @@ bhitpile( /* assume zapping up or down while hiding under the top item can still activate the trap even if it's below (when zapping up) or above (when zapping down) */ - if (gl.level.objects[tx][ty] != topofpile) + if (svl.level.objects[tx][ty] != topofpile) first = FALSE; /* top item was statue which activated */ } gp.poly_zapped = -1; - for (otmp = gl.level.objects[tx][ty]; otmp; otmp = next_obj) { + for (otmp = svl.level.objects[tx][ty]; otmp; otmp = next_obj) { next_obj = otmp->nexthere; if (hidingunder) { if (first) { @@ -2432,14 +2432,14 @@ bhitpile( } if (gp.poly_zapped >= 0) - create_polymon(gl.level.objects[tx][ty], gp.poly_zapped); + create_polymon(svl.level.objects[tx][ty], gp.poly_zapped); /* when boulders are present they're expected to be on top; with multiple boulders it's possible for some to have been changed into non-boulders (polymorph, stone-to-flesh) while ones beneath resist, so re-stack pile if there are any non-boulders above boulders */ prevotyp = BOULDER; - for (otmp = gl.level.objects[tx][ty]; otmp; otmp = otmp->nexthere) { + for (otmp = svl.level.objects[tx][ty]; otmp; otmp = otmp->nexthere) { if (otmp->otyp == BOULDER && prevotyp != BOULDER) { recreate_pile_at(tx, ty); break; @@ -2820,8 +2820,8 @@ zapyourself(struct obj *obj, boolean ordinary) break; } learn_it = TRUE; - Sprintf(gk.killer.name, "shot %sself with a death ray", uhim()); - gk.killer.format = NO_KILLER_PREFIX; + Sprintf(svk.killer.name, "shot %sself with a death ray", uhim()); + svk.killer.format = NO_KILLER_PREFIX; /* probably don't need these to be urgent; player just gave input without subsequent opportunity to dismiss --More-- with ESC */ urgent_pline("You irradiate yourself with pure energy!"); @@ -3177,7 +3177,7 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ map_zapped = TRUE; if (ltyp == ICE || IS_FURNITURE(ltyp)) { surf = "it"; - if (gl.lastseentyp[x][y] != rememberedltyp) + if (svl.lastseentyp[x][y] != rememberedltyp) ptmp += 1; } else { surf = the(surface(x, y)); @@ -3323,7 +3323,7 @@ zap_updown(struct obj *obj) /* wand or spell, nonnull */ */ if (u.uundetected && hides_under(gy.youmonst.data)) { int hitit = 0; - otmp = gl.level.objects[u.ux][u.uy]; + otmp = svl.level.objects[u.ux][u.uy]; if (otmp) hitit = bhito(otmp, obj); @@ -3581,7 +3581,7 @@ zap_map( case WAN_POLYMORPH: case SPE_POLYMORPH: del_engr(e); - make_engr_at(x, y, random_engraving(ebuf), gm.moves, 0); + make_engr_at(x, y, random_engraving(ebuf), svm.moves, 0); break; case WAN_CANCELLATION: case SPE_CANCELLATION: @@ -3654,10 +3654,10 @@ zap_map( /* map terrain; might reveal a special room which is already within view that hasn't been entered yet */ - oldtyp = gl.lastseentyp[x][y]; + oldtyp = svl.lastseentyp[x][y]; oldglyph = glyph_at(x, y); show_map_spot(x, y, FALSE); - if (oldtyp != gl.lastseentyp[x][y] || oldglyph != glyph_at(x, y)) { + if (oldtyp != svl.lastseentyp[x][y] || oldglyph != glyph_at(x, y)) { /* TODO: ought to give some message */ learn_it = TRUE; } @@ -4409,8 +4409,8 @@ zhitu( break; } monstunseesu(M_SEEN_MAGR); - gk.killer.format = KILLED_BY_AN; - Strcpy(gk.killer.name, fltxt ? fltxt : ""); + svk.killer.format = KILLED_BY_AN; + Strcpy(svk.killer.name, fltxt ? fltxt : ""); /* when killed by disintegration breath, don't leave corpse */ u.ugrave_arise = (type == -ZT_BREATH(ZT_DEATH)) ? -3 : NON_PM; done(DIED); @@ -4513,7 +4513,7 @@ burn_floor_objects( char buf1[BUFSZ], buf2[BUFSZ]; int cnt = 0; - for (obj = gl.level.objects[x][y]; obj; obj = obj2) { + for (obj = svl.level.objects[x][y]; obj; obj = obj2) { obj2 = obj->nexthere; if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS || (obj->oclass == FOOD_CLASS @@ -4559,7 +4559,7 @@ burn_floor_objects( } /* This also ignites floor items, but does not change cnt because they weren't consumed. */ - ignite_items(gl.level.objects[x][y]); + ignite_items(svl.level.objects[x][y]); return cnt; } @@ -5009,15 +5009,15 @@ melt_ice_away(anything *arg, long timeout UNUSED) { coordxy x, y; long where = arg->a_long; - boolean save_mon_moving = gc.context.mon_moving; /* will be False */ + boolean save_mon_moving = svc.context.mon_moving; /* will be False */ /* melt_ice -> minliquid -> mondead|xkilled shouldn't credit/blame hero */ - gc.context.mon_moving = TRUE; /* hero isn't causing this ice to melt */ + svc.context.mon_moving = TRUE; /* hero isn't causing this ice to melt */ y = (coordxy) (where & 0xFFFF); x = (coordxy) ((where >> 16) & 0xFFFF); /* melt_ice does newsym when appropriate */ melt_ice(x, y, "Some ice melts away."); - gc.context.mon_moving = save_mon_moving; + svc.context.mon_moving = save_mon_moving; } /* Burn floor scrolls, evaporate pools, etc... in a single square. @@ -5128,7 +5128,7 @@ zap_over_floor( if (is_pool(x, y) || is_lava(x, y) || lavawall) { boolean lava = (is_lava(x, y) || lavawall), moat = is_moat(x, y); - int chance = max(2, 5 + gl.level.flags.temperature * 10); + int chance = max(2, 5 + svl.level.flags.temperature * 10); if (IS_WATERWALL(lev->typ) || (lavawall && rn2(chance))) { /* For now, don't let WATER freeze. */ @@ -5421,7 +5421,7 @@ void fracture_rock(struct obj *obj) /* no texts here! */ { coordxy x, y; - boolean by_you = !gc.context.mon_moving; + boolean by_you = !svc.context.mon_moving; if (by_you && get_obj_location(obj, &x, &y, 0) && costly_spot(x, y)) { struct monst *shkp = 0; @@ -5468,7 +5468,7 @@ break_statue(struct obj *obj) /* [obj is assumed to be on floor, so no get_obj_location() needed] */ struct trap *trap = t_at(obj->ox, obj->oy); struct obj *item; - boolean by_you = !gc.context.mon_moving; + boolean by_you = !svc.context.mon_moving; if (trap && trap->ttyp == STATUE_TRAP && activate_statue_trap(trap, obj->ox, obj->oy, TRUE)) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 421ad62b9..48a6c17f6 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -81,7 +81,7 @@ nhmain(int argc, char *argv[]) early_init(argc, argv); gh.hname = argv[0]; - gh.hackpid = getpid(); + svh.hackpid = getpid(); (void) umask(0777 & ~FCMASK); choose_windows(DEFAULT_WINDOW_SYS); @@ -193,7 +193,7 @@ nhmain(int argc, char *argv[]) * It seems you really want to play. */ u.uhp = 1; /* prevent RIP on early quits */ - gp.program_state.preserve_locks = 1; + svp.program_state.preserve_locks = 1; #ifndef NO_SIGNAL sethanguphandler((SIG_RET_TYPE) hangup); #endif @@ -227,7 +227,7 @@ nhmain(int argc, char *argv[]) /* wizard mode access is deferred until here */ set_playmode(); /* sets plname to "wizard" for wizard mode */ /* hide any hyphens from plnamesuffix() */ - gp.plnamelen = exact_username ? (int) strlen(gp.plname) : 0; + svp.plnamelen = exact_username ? (int) strlen(svp.plname) : 0; /* strip role,race,&c suffix; calls askname() if plname[] is empty or holds a generic user name like "player" or "games" */ plnamesuffix(); @@ -270,12 +270,12 @@ nhmain(int argc, char *argv[]) * clock, &c not currently in use in the playground directory * (for gl.locknum > 0). */ - if (*gp.plname) { + if (*svp.plname) { getlock(); - gp.program_state.preserve_locks = 0; /* after getlock() */ + svp.program_state.preserve_locks = 0; /* after getlock() */ } - if (*gp.plname && (nhfp = restore_saved_game()) != 0) { + if (*svp.plname && (nhfp = restore_saved_game()) != 0) { const char *fq_save = fqname(gs.SAVEF, SAVEPREFIX, 1); (void) chmod(fq_save, 0); /* disallow parallel restores */ @@ -306,7 +306,7 @@ nhmain(int argc, char *argv[]) } if (!resuming) { - boolean neednewlock = (!*gp.plname); + boolean neednewlock = (!*svp.plname); /* new game: start by choosing role, race, etc; player might change the hero's name while doing that, in which case we try to restore under the new name @@ -315,7 +315,7 @@ nhmain(int argc, char *argv[]) if (!plsel_once) player_selection(); plsel_once = TRUE; - if (neednewlock && *gp.plname) + if (neednewlock && *svp.plname) goto attempt_restore; if (iflags.renameinprogress) { /* player has renamed the hero while selecting role; @@ -381,13 +381,13 @@ process_options(int argc, char *argv[]) #endif case 'u': if (argv[0][2]) { - (void) strncpy(gp.plname, argv[0] + 2, sizeof gp.plname - 1); - gp.plnamelen = 0; /* plname[] might have -role-race attached */ + (void) strncpy(svp.plname, argv[0] + 2, sizeof svp.plname - 1); + svp.plnamelen = 0; /* plname[] might have -role-race attached */ } else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof gp.plname - 1); - gp.plnamelen = 0; + (void) strncpy(svp.plname, argv[0], sizeof svp.plname - 1); + svp.plnamelen = 0; } else { raw_print("Player name expected after -u"); } @@ -534,7 +534,7 @@ whoami(void) * Note that we trust the user here; it is possible to play under * somebody else's name. */ - if (!*gp.plname) { + if (!*svp.plname) { const char *s; s = nh_getenv("USER"); @@ -544,8 +544,8 @@ whoami(void) s = getlogin(); if (s && *s) { - (void) strncpy(gp.plname, s, sizeof gp.plname - 1); - if (strchr(gp.plname, '-')) + (void) strncpy(svp.plname, s, sizeof svp.plname - 1); + if (strchr(svp.plname, '-')) return TRUE; } } @@ -672,7 +672,7 @@ check_user_string(const char *optstr) if (optstr[0] == '*') return TRUE; /* allow any user */ if (sysopt.check_plname) - pwname = gp.plname; + pwname = svp.plname; else if ((pw = get_unix_pw()) != 0) pwname = pw->pw_name; if (!pwname || !*pwname) @@ -1066,7 +1066,7 @@ void js_globals_init() { }); /* globals */ - CREATE_GLOBAL(gp.plname, "s"); + CREATE_GLOBAL(svp.plname, "s"); /* window globals */ CREATE_GLOBAL(WIN_MAP, "i"); diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 3c66cb6b7..5e5c1ee69 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -36,7 +36,7 @@ pckeys(unsigned char scancode, unsigned char shift) { boolean opening_dialog; - opening_dialog = gp.pl_character[0] ? FALSE : TRUE; + opening_dialog = svp.pl_character[0] ? FALSE : TRUE; switch (scancode) { #ifdef SIMULATE_CURSOR case 0x3d: /* F3 = toggle cursor type */ diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 205c9d619..db7f05bf3 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -794,7 +794,7 @@ vesa_cliparound(int x, int y) clipymax = ROWNO - 1; } if (clipx != oldx || clipy != oldy) { - if (on_level(&u.uz0, &u.uz) && !gp.program_state.restoring) + if (on_level(&u.uz0, &u.uz) && !svp.program_state.restoring) /* (void) doredraw(); */ vesa_redrawmap(); } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 8e50ccca8..035343cad 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -472,7 +472,7 @@ vga_cliparound(int x, int y UNUSED) clipx = clipxmax - (viewport_size - 1); } if (clipx != oldx) { - if (on_level(&u.uz0, &u.uz) && !gp.program_state.restoring) + if (on_level(&u.uz0, &u.uz) && !svp.program_state.restoring) /* (void) doredraw(); */ vga_redrawmap(1); } diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index ec8ff0c70..3e0a4c355 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -411,19 +411,19 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ * overwritten without confirmation when a user starts up * another game with the same player name. */ - Strcpy(gl.lock, gp.plname); + Strcpy(gl.lock, svp.plname); regularize(gl.lock); getlock(); #else /* What follows is !PC_LOCKING */ #ifdef AMIGA /* We'll put the bones & levels in the user specified directory \ -jhsa */ - Strcat(gl.lock, gp.plname); + Strcat(gl.lock, svp.plname); Strcat(gl.lock, ".99"); #else /* I'm not sure what, if anything, is left here, but old MFLOPPY had * conflicts with set_lock_and_bones() in files.c. */ - Strcpy(gl.lock, gp.plname); + Strcpy(gl.lock, svp.plname); Strcat(gl.lock, ".99"); regularize(gl.lock); /* is this necessary? */ /* not compatible with full path a la AMIGA */ @@ -436,9 +436,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ if (!nhfp) { raw_print("Cannot create lock file"); } else { - gh.hackpid = 1; + svh.hackpid = 1; if (nhfp->structlevel) - write(nhfp->fd, (genericptr_t) &gh.hackpid, sizeof(gh.hackpid)); + write(nhfp->fd, (genericptr_t) &svh.hackpid, sizeof(svh.hackpid)); close_nhfile(nhfp); } @@ -549,11 +549,11 @@ process_options(int argc, char *argv[]) #endif case 'u': if (argv[0][2]) - (void) strncpy(gp.plname, argv[0] + 2, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0] + 2, sizeof(svp.plname) - 1); else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0], sizeof(svp.plname) - 1); } else raw_print("Player name expected after -u"); break; @@ -715,7 +715,7 @@ port_help(void) boolean authorize_wizard_mode(void) { - if (!strcmp(gp.plname, WIZARD_NAME)) + if (!strcmp(svp.plname, WIZARD_NAME)) return TRUE; return FALSE; } diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index 115134548..f95a26a79 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -179,8 +179,8 @@ gotlock: #endif error("cannot creat file (%s.)", fq_lock); } else { - if (write(fd, (char *) &gh.hackpid, sizeof(gh.hackpid)) - != sizeof(gh.hackpid)) { + if (write(fd, (char *) &svh.hackpid, sizeof(svh.hackpid)) + != sizeof(svh.hackpid)) { #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdirx(orgdir, 0); #endif diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 1a22fd96a..d81748e80 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -99,7 +99,7 @@ main(int argc, char *argv[]) #endif gh.hname = argv[0]; - gh.hackpid = getpid(); + svh.hackpid = getpid(); (void) umask(0777 & ~FCMASK); choose_windows(DEFAULT_WINDOW_SYS); @@ -164,7 +164,7 @@ main(int argc, char *argv[]) */ u.uhp = 1; /* prevent RIP on early quits */ #if defined(HANGUPHANDLING) - gp.program_state.preserve_locks = 1; + svp.program_state.preserve_locks = 1; #ifndef NO_SIGNAL sethanguphandler((SIG_RET_TYPE) hangup); #endif @@ -195,7 +195,7 @@ main(int argc, char *argv[]) /* wizard mode access is deferred until here */ set_playmode(); /* sets plname to "wizard" for wizard mode */ /* hide any hyphens from plnamesuffix() */ - gp.plnamelen = exact_username ? (int) strlen(gp.plname) : 0; + gp.plnamelen = exact_username ? (int) strlen(svp.plname) : 0; /* strip role,race,&c suffix; calls askname() if plname[] is empty or holds a generic user name like "player" or "games" */ plnamesuffix(); @@ -236,14 +236,14 @@ main(int argc, char *argv[]) * clock, &c not currently in use in the playground directory * (for gl.locknum > 0). */ - if (*gp.plname) { + if (*svp.plname) { getlock(); #if defined(HANGUPHANDLING) - gp.program_state.preserve_locks = 0; /* after getlock() */ + svp.program_state.preserve_locks = 0; /* after getlock() */ #endif } - if (*gp.plname && (nhfp = restore_saved_game()) != 0) { + if (*svp.plname && (nhfp = restore_saved_game()) != 0) { const char *fq_save = fqname(gs.SAVEF, SAVEPREFIX, 1); (void) chmod(fq_save, 0); /* disallow parallel restores */ @@ -276,13 +276,13 @@ main(int argc, char *argv[]) } } } - if (gp.program_state.in_self_recover) { - gp.program_state.in_self_recover = FALSE; + if (svp.program_state.in_self_recover) { + svp.program_state.in_self_recover = FALSE; } } if (!resuming) { - boolean neednewlock = (!*gp.plname); + boolean neednewlock = (!*svp.plname); /* new game: start by choosing role, race, etc; player might change the hero's name while doing that, in which case we try to restore under the new name @@ -291,7 +291,7 @@ main(int argc, char *argv[]) if (!plsel_once) player_selection(); plsel_once = TRUE; - if (neednewlock && *gp.plname) + if (neednewlock && *svp.plname) goto attempt_restore; if (iflags.renameinprogress) { /* player has renamed the hero while selecting role; @@ -474,12 +474,12 @@ process_options(int argc, char *argv[]) break; case 'u': if (arg[2]) { - (void) strncpy(gp.plname, arg + 2, sizeof gp.plname - 1); + (void) strncpy(svp.plname, arg + 2, sizeof svp.plname - 1); gp.plnamelen = 0; /* plname[] might have -role-race attached */ } else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof gp.plname - 1); + (void) strncpy(svp.plname, argv[0], sizeof svp.plname - 1); gp.plnamelen = 0; } else { config_error_add("Character name expected after -u"); @@ -916,7 +916,7 @@ whoami(void) * Note that we trust the user here; it is possible to play under * somebody else's name. */ - if (!*gp.plname) { + if (!*svp.plname) { register const char *s; s = nh_getenv("USER"); @@ -926,8 +926,8 @@ whoami(void) s = getlogin(); if (s && *s) { - (void) strncpy(gp.plname, s, sizeof gp.plname - 1); - if (strchr(gp.plname, '-')) + (void) strncpy(svp.plname, s, sizeof svp.plname - 1); + if (strchr(svp.plname, '-')) return TRUE; } } @@ -1052,7 +1052,7 @@ check_user_string(const char *optstr) if (optstr[0] == '*') return TRUE; /* allow any user */ if (sysopt.check_plname) - pwname = gp.plname; + pwname = svp.plname; else if ((pw = get_unix_pw()) != 0) pwname = pw->pw_name; if (!pwname || !*pwname) diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index de465f9b1..725c790c3 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -82,7 +82,7 @@ eraseoldlocks(void) int i; #if defined(HANGUPHANDLING) - gp.program_state.preserve_locks = 0; /* not required but shows intent */ + svp.program_state.preserve_locks = 0; /* not required but shows intent */ /* cannot use maxledgerno() here, because we need to find a lock name * before starting everything (including the dungeon initialization * that sets astral_level, needed for maxledgerno()) up @@ -132,7 +132,7 @@ getlock(void) 'a','b',&c below; override the default and use if we aren't restricting the number of simultaneous games */ if (!gl.locknum) - Sprintf(gl.lock, "%u%s", (unsigned) getuid(), gp.plname); + Sprintf(gl.lock, "%u%s", (unsigned) getuid(), svp.plname); regularize(gl.lock); set_levelfile_name(gl.lock, 0); @@ -216,7 +216,7 @@ getlock(void) } #ifdef SELF_RECOVER if (c == 'r' || c == 'R') { - if (recover_savefile() && gp.program_state.in_self_recover) { + if (recover_savefile() && svp.program_state.in_self_recover) { set_levelfile_name(gl.lock, 0); fq_lock = fqname(gl.lock, LEVELPREFIX, 0); goto gotlock; @@ -246,8 +246,8 @@ getlock(void) error("cannot creat lock file (%s).", fq_lock); /*NOTREACHED*/ } else { - if (write(fd, (genericptr_t) &gh.hackpid, sizeof gh.hackpid) - != sizeof gh.hackpid) { + if (write(fd, (genericptr_t) &svh.hackpid, sizeof svh.hackpid) + != sizeof svh.hackpid) { error("cannot write lock (%s)", fq_lock); /*NOTREACHED*/ } diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index 91f9817ff..0c5045ab9 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -58,7 +58,7 @@ main(int argc, char *argv[]) isn't at risk of getting clobbered by core's handling of DEBUGFILES */ progname = dupstr(vms_basename(argv[0], FALSE)); gh.hname = progname; - gh.hackpid = getpid(); + svh.hackpid = getpid(); (void) umask(0); choose_windows(DEFAULT_WINDOW_SYS); @@ -281,11 +281,11 @@ process_options(int argc, char *argv[]) #endif case 'u': if (argv[0][2]) - (void) strncpy(gp.plname, argv[0] + 2, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0] + 2, sizeof(svp.plname) - 1); else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0], sizeof(svp.plname) - 1); } else raw_print("Player name expected after -u"); break; @@ -390,8 +390,8 @@ whoami(void) */ char *s; - if (!*gp.plname && (s = nh_getenv("USER"))) - (void) lcase(strncpy(gp.plname, s, sizeof(gp.plname) - 1)); + if (!*svp.plname && (s = nh_getenv("USER"))) + (void) lcase(strncpy(svp.plname, s, sizeof(svp.plname) - 1)); } static void @@ -412,7 +412,7 @@ byebye(void) (void) sys$delprc(&mail_pid, (genericptr_t) 0), mail_pid = 0; #endif #ifdef FREE_ALL_MEMORY - if (progname && !gp.program_state.panicking) { + if (progname && !svp.program_state.panicking) { if (gh.hname == progname) gh.hname = (char *) 0; free((genericptr_t) progname), progname = (char *) 0; @@ -421,7 +421,7 @@ byebye(void) /* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */ hup = (void (*)(int)) signal(SIGHUP, SIG_IGN); - if (!gp.program_state.exiting++ + if (!svp.program_state.exiting++ && hup != (void (*)(int)) SIG_DFL && hup != (void (*)(int)) SIG_IGN) { (*hup)(SIGHUP); @@ -446,7 +446,7 @@ genericptr_t mechargs) /* [0] is argc, [1..argc] are the real args */ if (condition == SS$_ACCVIO /* access violation */ || (condition >= SS$_ASTFLT && condition <= SS$_TBIT) || (condition >= SS$_ARTRES && condition <= SS$_INHCHME)) { - gp.program_state.done_hup = TRUE; /* pretend hangup has been attempted */ + svp.program_state.done_hup = TRUE; /* pretend hangup has been attempted */ #if (NH_DEVEL_STATUS == NH_STATUS_RELEASED) if (wizard) #endif diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 8dc0dfe4f..5ff2f8ce4 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -158,7 +158,7 @@ vms_getchar(void) static volatile int recurse = 0; /* SMG is not AST re-entrant! */ #endif - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { /* hangup has occurred; do not attempt to get further user input */ return ESC; } diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index de147bf96..69e5a3929 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -120,7 +120,7 @@ getlock(void) 'a','b',&c below; override the default and use if we aren't restricting the number of simultaneous games */ if (!gl.locknum) - Sprintf(gl.lock, "_%u%s", (unsigned) getuid(), gp.plname); + Sprintf(gl.lock, "_%u%s", (unsigned) getuid(), svp.plname); regularize(gl.lock); set_levelfile_name(gl.lock, 0); @@ -154,8 +154,8 @@ getlock(void) if (fd == -1) { error("cannot creat lock file."); } else { - if (write(fd, (char *) &gh.hackpid, sizeof(gh.hackpid)) - != sizeof(gh.hackpid)) { + if (write(fd, (char *) &svh.hackpid, sizeof(svh.hackpid)) + != sizeof(svh.hackpid)) { error("cannot write lock"); } if (close(fd) == -1) { diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index e430033ce..c38a4b36a 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -936,7 +936,7 @@ void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y) while (dst != sentinel) *dst++ = *fill; - if ((iflags.debug.immediateflips || !gp.program_state.in_moveloop) + if ((iflags.debug.immediateflips || !svp.program_state.in_moveloop) && buffer == console.back_buffer) back_buffer_flip(); } @@ -952,7 +952,7 @@ static void buffer_clear_to_end_of_line(cell_t * buffer, int x, int y) while (dst != sentinel) *dst++ = clear_cell; - if (iflags.debug.immediateflips || !gp.program_state.in_moveloop) + if (iflags.debug.immediateflips || !svp.program_state.in_moveloop) back_buffer_flip(); } @@ -964,7 +964,7 @@ void buffer_write(cell_t * buffer, cell_t * cell, COORD pos) cell_t * dst = buffer + (console.width * pos.Y) + pos.X; *dst = *cell; - if ((iflags.debug.immediateflips || !gp.program_state.in_moveloop) + if ((iflags.debug.immediateflips || !svp.program_state.in_moveloop) && buffer == console.back_buffer) back_buffer_flip(); } @@ -1149,7 +1149,7 @@ tgetch(void) numpad |= 0x10; #endif - return (gp.program_state.done_hup) + return (svp.program_state.done_hup) ? '\033' : keyboard_handling.pCheckInput( console.hConIn, &ir, &count, numpad, 0, &mod, &cc); @@ -1177,7 +1177,7 @@ console_poskey(coordxy *x, coordxy *y, int *mod) if (gc.Cmd.swap_yz) numpad |= 0x10; #endif - ch = (gp.program_state.done_hup) + ch = (svp.program_state.done_hup) ? '\033' : keyboard_handling.pCheckInput( console.hConIn, &ir, &count, numpad, 1, mod, &cc); diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 5c928db86..7f3868560 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -704,17 +704,17 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ (*utf8graphics_mode_callback)(); #endif - /* strip role,race,&c suffix; calls askname() if gp.plname[] is empty + /* strip role,race,&c suffix; calls askname() if svp.plname[] is empty or holds a generic user name like "player" or "games" */ plnamesuffix(); - set_playmode(); /* sets gp.plname to "wizard" for wizard mode */ + set_playmode(); /* sets svp.plname to "wizard" for wizard mode */ /* until the getlock code is resolved, override askname()'s setting of renameallowed; when False, player_selection() won't resent renaming as an option */ iflags.renameallowed = FALSE; /* Obtain the name of the logged on user and incorporate * it into the name. */ - Sprintf(fnamebuf, "%s", gp.plname); + Sprintf(fnamebuf, "%s", svp.plname); (void) fname_encode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%', fnamebuf, encodedfnamebuf, BUFSZ); @@ -732,8 +732,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ if (!nhfp) { raw_print("Cannot create lock file"); } else { - gh.hackpid = GetCurrentProcessId(); - (void) write(nhfp->fd, (genericptr_t) &gh.hackpid, sizeof(gh.hackpid)); + svh.hackpid = GetCurrentProcessId(); + (void) write(nhfp->fd, (genericptr_t) &svh.hackpid, sizeof(svh.hackpid)); close_nhfile(nhfp); } /* @@ -771,8 +771,8 @@ attempt_restore: } } } - if (gp.program_state.in_self_recover) { - gp.program_state.in_self_recover = FALSE; + if (svp.program_state.in_self_recover) { + svp.program_state.in_self_recover = FALSE; set_savefile_name(TRUE); } } @@ -923,11 +923,11 @@ process_options(int argc, char * argv[]) #endif case 'u': if (argv[0][2]) - (void) strncpy(gp.plname, argv[0] + 2, sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0] + 2, sizeof(svp.plname) - 1); else if (argc > 1) { argc--; argv++; - (void) strncpy(gp.plname, argv[0], sizeof(gp.plname) - 1); + (void) strncpy(svp.plname, argv[0], sizeof(svp.plname) - 1); } else raw_print("Player name expected after -u"); break; @@ -1052,7 +1052,7 @@ port_help(void) boolean authorize_wizard_mode(void) { - if (!strcmp(gp.plname, WIZARD_NAME)) + if (!strcmp(svp.plname, WIZARD_NAME)) return TRUE; return FALSE; } @@ -1417,8 +1417,8 @@ gotlock: gf.fqn_prefix[LEVELPREFIX]); raw_print(oops); } else { - if (write(fd, (char *) &gh.hackpid, sizeof(gh.hackpid)) - != sizeof(gh.hackpid)) { + if (write(fd, (char *) &svh.hackpid, sizeof(svh.hackpid)) + != sizeof(svh.hackpid)) { #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) chdirx(orgdir, 0); #endif diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index e1d5324b6..6cfd17e58 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -237,7 +237,7 @@ void NetHackQtBind::qt_askname() int ch = -1; // -1 => new game have_asked = true; - str_copy(default_plname, gp.plname, PL_NSIZ); + str_copy(default_plname, svp.plname, PL_NSIZ); // We do it all here (plus qt_plsel.cpp and qt_svsel.cpp), // nothing in player_selection(). @@ -252,7 +252,7 @@ void NetHackQtBind::qt_askname() NetHackQtSavedGameSelector sgsel((const char **) saved); ch = sgsel.choose(); if (ch >= 0) - str_copy(gp.plname, saved[ch], SIZE(gp.plname)); + str_copy(svp.plname, saved[ch], SIZE(svp.plname)); // caller needs new lock name even if plname[] hasn't changed // because successful get_saved_games() clobbers gs.SAVEF[] ::iflags.renameinprogress = TRUE; @@ -282,10 +282,10 @@ void NetHackQtBind::qt_askname() break; } - if (!*gp.plname) + if (!*svp.plname) // in case Choose() returns with plname[] empty - Strcpy(gp.plname, default_plname); - else if (strcmp(gp.plname, default_plname) != 0) + Strcpy(svp.plname, default_plname); + else if (strcmp(svp.plname, default_plname) != 0) // caller needs to set new lock file name ::iflags.renameinprogress = TRUE; return; @@ -498,7 +498,7 @@ void NetHackQtBind::qt_update_inventory(int arg UNUSED) main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet - if (gp.program_state.something_worth_saving && iflags.perm_invent) + if (svp.program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, false); */ } @@ -667,7 +667,7 @@ char NetHackQtBind::qt_more() // ^C comment in that routine] when the core triggers --More-- via // done2() -> really_done() -> display_nhwindow(WIN_MESSAGE, TRUE) // (get rid of this if the exec() loop issue gets properly fixed) - if (::gp.program_state.gameover) + if (::svp.program_state.gameover) return ch; // bypass --More-- and just continue with program exit NetHackQtMessageWindow *mesgwin = main ? main->GetMessageWindow() : NULL; diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 394b8ec5e..eb22d36d7 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1015,7 +1015,7 @@ bool NetHackQtMainWindow::ok_for_command() * FIXME: it would be much better to gray-out inapplicable entries * when popping up a command menu instead of needing this. */ - if (::gp.program_state.input_state != commandInp) { + if (::svp.program_state.input_state != commandInp) { NetHackQtBind::qt_nhbell(); // possibly call doKeys("\033"); here? return false; @@ -1059,7 +1059,7 @@ void NetHackQtMainWindow::doQuit(bool) // in case someone wants to change that #ifdef MACOS QString info = nh_qsprintf("This will end your NetHack session.%s", - !gp.program_state.something_worth_saving ? "" + !svp.program_state.something_worth_saving ? "" : "\n(Cancel quitting and use the Save command" "\nto save your current game.)"); /* this is similar to closeEvent but the details are different; @@ -1077,7 +1077,7 @@ void NetHackQtMainWindow::doQuit(bool) break; // return to game case 1: // quit -- bypass the prompting preformed by done2() - gp.program_state.stopprint++; + svp.program_state.stopprint++; ::done(QUIT); /*NOTREACHED*/ break; @@ -1406,7 +1406,7 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) { int ok = 0; - if ( gp.program_state.something_worth_saving ) { + if ( svp.program_state.something_worth_saving ) { /* this used to offer "Save" and "Cancel" but cancel (ignoring the close attempt) won't work if user has clicked on the window's Close button */ @@ -1421,7 +1421,7 @@ void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) case 1: // quit -- bypass the prompting preformed by done2() ok = 1; - gp.program_state.stopprint++; + svp.program_state.stopprint++; ::done(QUIT); /*NOTREACHED*/ break; diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index f7480ecbc..6a0e7a524 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -1071,7 +1071,7 @@ void NetHackQtTextWindow::UseRIP(int how, time_t when) /* Put name on stone */ (void) snprintf(rip_line[NAME_LINE], STONE_LINE_LEN + 1, - "%.*s", STONE_LINE_LEN, gp.plname); + "%.*s", STONE_LINE_LEN, svp.plname); /* Put $ on stone; to keep things safe and relatively simple, impose an arbitrary diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index ecc81023b..a280f07fc 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -40,17 +40,17 @@ extern "C" { /* check whether plname[] is among the list of generic user names */ static bool generic_plname() { - if (*gp.plname) { + if (*svp.plname) { const char *sptr, *p; const char *genericusers = sysopt.genericusers; - int ln = (int) strlen(gp.plname); + int ln = (int) strlen(svp.plname); if (!genericusers || !*genericusers) genericusers = "player games"; else if (!strcmp(genericusers, "*")) /* "*" => always ask for name */ return true; - while ((sptr = strstri(genericusers, gp.plname)) != NULL) { + while ((sptr = strstri(genericusers, svp.plname)) != NULL) { /* check for full word: start of list or following a space */ if ((sptr == genericusers || sptr[-1] == ' ') /* and also preceding a space or at end of list */ @@ -263,8 +263,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector( // if plname[] contains a generic user name, clear it if (generic_plname()) - *gp.plname = '\0'; - name->setText(gp.plname); + *svp.plname = '\0'; + name->setText(svp.plname); connect(name, SIGNAL(textChanged(const QString&)), this, SLOT(selectName(const QString&))); name->setFocus(); @@ -545,7 +545,7 @@ void NetHackQtPlayerSelector::Randomize() // if plname[] is empty, disable [Play], otherwise [Play] is the default void NetHackQtPlayerSelector::plnamePlayVsQuit() { - if (*gp.plname) { + if (*svp.plname) { play_btn->setEnabled(true); play_btn->setDefault(true); //quit_btn->setDefault(false); @@ -564,7 +564,7 @@ void NetHackQtPlayerSelector::selectName(const QString& n) // (it would be better to set up a validator that rejects leading spaces) while (*name_str == ' ') ++name_str; - str_copy(gp.plname, name_str, PL_NSIZ); + str_copy(svp.plname, name_str, PL_NSIZ); // possibly enable or disable the [Play] button plnamePlayVsQuit(); } diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 34dc3e2d1..13aae4108 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -858,17 +858,17 @@ void NetHackQtStatusWindow::updateStats() buf = nh_capitalize_words(pmname(&mons[u.umonnum], ::flags.female ? FEMALE : MALE)); } else { - buf = rank_of(u.ulevel, gp.pl_character[0], ::flags.female); + buf = rank_of(u.ulevel, svp.pl_character[0], ::flags.female); } QString buf2; char buf3[BUFSZ]; - buf2 = nh_qsprintf("%s the %s", upstart(strcpy(buf3, gp.plname)), + buf2 = nh_qsprintf("%s the %s", upstart(strcpy(buf3, svp.plname)), buf.toLatin1().constData()); name.setLabel(buf2, NetHackQtLabelledIcon::NoNum, u.ulevel); if (!describe_level(buf3, 0)) { Sprintf(buf3, "%s, level %d", - gd.dungeons[u.uz.dnum].dname, ::depth(&u.uz)); + svd.dungeons[u.uz.dnum].dname, ::depth(&u.uz)); } dlevel.setLabel(buf3); @@ -966,7 +966,7 @@ void NetHackQtStatusWindow::updateStats() if (::flags.time) { // hypothetically Time could grow to enough digits to have trouble // fitting, but it's not worth worrying about - time.setLabel("Time:", (long) gm.moves); + time.setLabel("Time:", (long) svm.moves); } else { time.setLabel(""); } diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 4dc355cbc..a23d9e616 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -220,7 +220,7 @@ char NetHackQtYnDialog::Exec() // for "ynaq" (where "all" is a choice) it's "stop" // and for end of game disclosure it really is "quit" if (question.left(10) == QString("Dump core?") - || (::gp.program_state.gameover + || (::svp.program_state.gameover && question.left(11) == QString("Do you want"))) button_name = "Quit"; else if (is_ynaq) diff --git a/win/X11/winX.c b/win/X11/winX.c index 8daf610ef..b70bee5ea 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1282,7 +1282,7 @@ X11_update_inventory(int arg) if (iflags.perm_invent) { /* skip any calls to update_inventory() before in_moveloop starts */ - if (gp.program_state.in_moveloop || gp.program_state.gameover) { + if (svp.program_state.in_moveloop || svp.program_state.gameover) { updated_inventory = 1; /* hack to avoid mapping&raising window */ if (!arg) { (void) display_inventory((char *) 0, FALSE); @@ -1798,7 +1798,7 @@ X11_hangup(Widget w, XEvent *event, String *params, Cardinal *num_params) static void X11_bail(const char *mesg) { - gp.program_state.something_worth_saving = 0; + svp.program_state.something_worth_saving = 0; clearlocks(); X11_exit_nhwindows(mesg); nh_terminate(EXIT_SUCCESS); @@ -1815,7 +1815,7 @@ askname_delete(Widget w, XEvent *event, String *params, Cardinal *num_params) nhUse(num_params); nh_XtPopdown(w); - (void) strcpy(gp.plname, "Mumbles"); /* give them a name... ;-) */ + (void) strcpy(svp.plname, "Mumbles"); /* give them a name... ;-) */ exit_x_event = TRUE; } @@ -1840,11 +1840,11 @@ askname_done(Widget w, XtPointer client_data, XtPointer call_data) } /* Truncate name if necessary */ - if (len >= sizeof gp.plname - 1) - len = sizeof gp.plname - 1; + if (len >= sizeof svp.plname - 1) + len = sizeof svp.plname - 1; - (void) strncpy(gp.plname, s, len); - gp.plname[len] = '\0'; + (void) strncpy(svp.plname, s, len); + svp.plname[len] = '\0'; XtFree(s); nh_XtPopdown(XtParent(dialog)); @@ -1892,7 +1892,7 @@ X11_askname(void) (XtCallbackProc) 0); SetDialogPrompt(dialog, nhStr("What is your name?")); /* set prompt */ - SetDialogResponse(dialog, gp.plname, PL_NSIZ); /* set default answer */ + SetDialogResponse(dialog, svp.plname, PL_NSIZ); /* set default answer */ XtRealizeWidget(popup); positionpopup(popup, TRUE); /* center,bottom */ @@ -2041,7 +2041,7 @@ X11_getlin( /* we get here after the popup has exited; put prompt and response into the message window (and into core's dumplog history) unless play hasn't started yet */ - if (gp.program_state.in_moveloop || gp.program_state.gameover) { + if (svp.program_state.in_moveloop || svp.program_state.gameover) { /* single space has meaning (to remove a previously applied name) so show it clearly; don't care about legibility of multiple spaces */ const char *visanswer = !input[0] ? "" diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 110cc8953..62e1f44a3 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1988,7 +1988,7 @@ x_event(int exit_condition) /* pkey(retval); */ keep_going = FALSE; #if defined(HANGUPHANDLING) - } else if (gp.program_state.done_hup) { + } else if (svp.program_state.done_hup) { retval = '\033'; inptr = (inptr + 1) % INBUF_SIZE; keep_going = FALSE; @@ -2009,7 +2009,7 @@ x_event(int exit_condition) } keep_going = FALSE; #if defined(HANGUPHANDLING) - } else if (gp.program_state.done_hup) { + } else if (svp.program_state.done_hup) { retval = '\033'; inptr = (inptr + 1) % INBUF_SIZE; keep_going = FALSE; diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 33f790e04..a6a421e57 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -352,11 +352,11 @@ plsel_dialog_acceptvalues(void) XtSetArg(args[0], nhStr(XtNstring), &s); XtGetValues(plsel_name_input, args, ONE); - (void) strncpy(gp.plname, (char *) s, sizeof gp.plname - 1); - gp.plname[sizeof gp.plname - 1] = '\0'; - (void) mungspaces(gp.plname); - if (strlen(gp.plname) < 1) - (void) strcpy(gp.plname, "Mumbles"); + (void) strncpy(svp.plname, (char *) s, sizeof svp.plname - 1); + svp.plname[sizeof svp.plname - 1] = '\0'; + (void) mungspaces(svp.plname); + if (strlen(svp.plname) < 1) + (void) strcpy(svp.plname, "Mumbles"); iflags.renameinprogress = FALSE; } @@ -779,8 +779,8 @@ X11_create_player_selection_name(Widget form) XtSetArg(args[num_args], nhStr(XtNeditType), !plsel_ask_name ? XawtextRead : XawtextEdit); num_args++; XtSetArg(args[num_args], nhStr(XtNresize), XawtextResizeWidth); num_args++; - XtSetArg(args[num_args], nhStr(XtNstring), gp.plname); num_args++; - XtSetArg(args[num_args], XtNinsertPosition, strlen(gp.plname)); num_args++; + XtSetArg(args[num_args], nhStr(XtNstring), svp.plname); num_args++; + XtSetArg(args[num_args], XtNinsertPosition, strlen(svp.plname)); num_args++; XtSetArg(args[num_args], nhStr(XtNaccelerators), XtParseAcceleratorTable(plsel_input_accelerators)); num_args++; plsel_name_input = XtCreateManagedWidget("name_input", @@ -1222,7 +1222,7 @@ X11_player_selection_dialog(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { clearlocks(); @@ -1300,7 +1300,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { clearlocks(); @@ -1373,7 +1373,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { clearlocks(); @@ -1445,7 +1445,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { clearlocks(); @@ -1515,7 +1515,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || gp.program_state.done_hup + || svp.program_state.done_hup #endif ) { clearlocks(); @@ -1539,15 +1539,15 @@ void X11_player_selection(void) { if (iflags.wc_player_selection == VIA_DIALOG) { - if (!*gp.plname) { + if (!*svp.plname) { #ifdef UNIX char *defplname = get_login_name(); #else char *defplname = (char *)0; #endif - (void) strncpy(gp.plname, defplname ? defplname : "Mumbles", - sizeof gp.plname - 1); - gp.plname[sizeof gp.plname - 1] = '\0'; + (void) strncpy(svp.plname, defplname ? defplname : "Mumbles", + sizeof svp.plname - 1); + svp.plname[sizeof svp.plname - 1] = '\0'; iflags.renameinprogress = TRUE; } X11_player_selection_dialog(); diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 63c536910..4e520203c 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1535,7 +1535,7 @@ update_val(struct X_status_value *attr_rec, long new_value) if (attr_rec->type == SV_LABEL) { if (attr_rec == &shown_stats[F_NAME]) { - Strcpy(buf, gp.plname); + Strcpy(buf, svp.plname); buf[0] = highc(buf[0]); Strcat(buf, " the "); if (Upolyd) { @@ -1550,12 +1550,12 @@ update_val(struct X_status_value *attr_rec, long new_value) Strcat(buf, mnam); } else { Strcat(buf, - rank_of(u.ulevel, gp.pl_character[0], flags.female)); + rank_of(u.ulevel, svp.pl_character[0], flags.female)); } } else if (attr_rec == &shown_stats[F_DLEVEL]) { if (!describe_level(buf, 0)) { - Strcpy(buf, gd.dungeons[u.uz.dnum].dname); + Strcpy(buf, svd.dungeons[u.uz.dnum].dname); Sprintf(eos(buf), ", level %d", depth(&u.uz)); } } else if (attr_rec == &shown_stats[F_VERS]) { @@ -1987,7 +1987,7 @@ update_fancy_status_field(int i, int color, int attributes) val = (long) u.ualign.type; break; case F_TIME: - val = flags.time ? (long) gm.moves : 0L; + val = flags.time ? (long) svm.moves : 0L; break; case F_SCORE: #ifdef SCORE_ON_BOTL diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 6f2f6f4ff..e401b7018 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -296,7 +296,7 @@ create_text_window(struct xwindow *wp) XtParseTranslationTable(text_translations)); num_args++; - wp->w = XtCreateManagedWidget(gk.killer.name[0] && WIN_MAP == WIN_ERR + wp->w = XtCreateManagedWidget(svk.killer.name[0] && WIN_MAP == WIN_ERR ? "tombstone" : "text_text", /* name */ asciiTextWidgetClass, @@ -467,7 +467,7 @@ calculate_rip_text(int how, time_t when) long cash; /* Put name on stone */ - Sprintf(rip_line[NAME_LINE], "%.16s", gp.plname); /* STONE_LINE_LEN */ + Sprintf(rip_line[NAME_LINE], "%.16s", svp.plname); /* STONE_LINE_LEN */ /* Put $ on stone */ cash = max(gd.done_money, 0L); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 021d89e15..c1c9c1534 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -227,7 +227,7 @@ curses_character_input_dialog( re-activate them now that input is being requested */ curses_got_input(); - if (gi.invent || (gm.moves > 1)) { + if (gi.invent || (svm.moves > 1)) { curses_get_window_size(MAP_WIN, &map_height, &map_width); } else { map_height = term_rows; @@ -789,7 +789,7 @@ curses_display_nhmenu( menu_determine_pages(current_menu); /* Display pre and post-game menus centered */ - if ((gm.moves <= 1 && !gi.invent) || gp.program_state.gameover) { + if ((svm.moves <= 1 && !gi.invent) || svp.program_state.gameover) { win = curses_create_window(wid, current_menu->width, current_menu->height, CENTER); } else { /* Display during-game menus on the right out of the way */ @@ -1033,7 +1033,7 @@ menu_win_size(nhmenu *menu) int maxheaderwidth = menu->prompt ? (int) strlen(menu->prompt) : 0; nhmenu_item *menu_item_ptr, *last_item_ptr = NULL; - if (gp.program_state.gameover) { + if (svp.program_state.gameover) { /* for final inventory disclosure, use full width */ maxwidth = term_cols - 2; /* +2: borders assumed */ } else { diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 39cb32729..2fd1947ec 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -326,9 +326,9 @@ curses_askname(void) } #endif /* SELECTSAVED */ - curses_line_input_dialog("Who are you?", gp.plname, PL_NSIZ); - (void) mungspaces(gp.plname); - if (!gp.plname[0] || gp.plname[0] == '\033') + curses_line_input_dialog("Who are you?", svp.plname, PL_NSIZ); + (void) mungspaces(svp.plname); + if (!svp.plname[0] || svp.plname[0] == '\033') goto bail; iflags.renameallowed = TRUE; /* tty uses this, we don't [yet?] */ @@ -782,7 +782,7 @@ curses_update_inventory(int arg) } /* skip inventory updating during character initialization */ - if (!gp.program_state.in_moveloop && !gp.program_state.gameover) + if (!svp.program_state.in_moveloop && !svp.program_state.gameover) return; if (!arg) { diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 40585e448..886233e94 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -776,7 +776,7 @@ Currently this is limited to arrow keys, but this may be expanded. */ int curses_convert_keys(int key) { - boolean reject = (gp.program_state.input_state == otherInp), + boolean reject = (svp.program_state.input_state == otherInp), as_is = FALSE, numpad_esc = FALSE; int ret = key; diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index d99e473b2..310ba7820 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -1886,7 +1886,7 @@ draw_horizontal(int x, int y, int hp, int hpmax) wmove(win, y, x); get_playerrank(rank); - sprintf(buf, "%s the %s", gp.plname, rank); + sprintf(buf, "%s the %s", svp.plname, rank); /* Use the title as HP bar (similar to hitpointbar) */ draw_bar(TRUE, hp, hpmax, buf); @@ -1954,7 +1954,7 @@ draw_horizontal(int x, int y, int hp, int hpmax) print_statdiff(" Exp:", &prevlevel, u.ulevel, STAT_OTHER); if (flags.time) - print_statdiff(" T:", &prevtime, gm.moves, STAT_TIME); + print_statdiff(" T:", &prevtime, svm.moves, STAT_TIME); curses_add_statuses(win, FALSE, FALSE, NULL, NULL); } @@ -1973,7 +1973,7 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) char race[BUFSZ]; Strcpy(race, gu.urace.adj); race[0] = highc(race[0]); - wprintw(win, "%s the %s %s%s%s", gp.plname, + wprintw(win, "%s the %s %s%s%s", svp.plname, (u.ualign.type == A_CHAOTIC ? "Chaotic" : u.ualign.type == A_NEUTRAL ? "Neutral" : "Lawful"), Upolyd ? "" : race, Upolyd ? "" : " ", @@ -2035,7 +2035,7 @@ draw_horizontal_new(int x, int y, int hp, int hpmax) #endif /* SCORE_ON_BOTL */ if (flags.time) - print_statdiff(" T:", &prevtime, gm.moves, STAT_TIME); + print_statdiff(" T:", &prevtime, svm.moves, STAT_TIME); curses_add_statuses(win, TRUE, FALSE, &x, &y); @@ -2092,7 +2092,7 @@ draw_vertical(int x, int y, int hp, int hpmax) get_playerrank(rank); int ranklen = strlen(rank); - int namelen = strlen(gp.plname); + int namelen = strlen(svp.plname); int maxlen = 19; #ifdef STATUS_COLORS if (!iflags.hitpointbar) @@ -2109,7 +2109,7 @@ draw_vertical(int x, int y, int hp, int hpmax) while ((ranklen + namelen) > maxlen) ranklen--; /* Still doesn't fit, strip rank */ } - sprintf(buf, "%-*s the %-*s", namelen, gp.plname, ranklen, rank); + sprintf(buf, "%-*s the %-*s", namelen, svp.plname, ranklen, rank); draw_bar(TRUE, hp, hpmax, buf); wmove(win, y++, x); wprintw(win, "%s", dungeons[u.uz.dnum].dname); @@ -2188,7 +2188,7 @@ draw_vertical(int x, int y, int hp, int hpmax) wmove(win, y++, x); if (flags.time) { - print_statdiff("Time: ", &prevtime, gm.moves, STAT_TIME); + print_statdiff("Time: ", &prevtime, svm.moves, STAT_TIME); wmove(win, y++, x); } diff --git a/win/curses/curswins.c b/win/curses/curswins.c index d2168ec35..a9a1b7829 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -69,7 +69,7 @@ curses_create_window(int wid, int width, int height, orient orientation) if ((orientation == UP) || (orientation == DOWN) || (orientation == LEFT) || (orientation == RIGHT)) { - if (gi.invent || (gm.moves > 1)) { + if (gi.invent || (svm.moves > 1)) { map_border = curses_window_has_border(MAP_WIN); curses_get_window_xy(MAP_WIN, &mapx, &mapy); curses_get_window_size(MAP_WIN, &maph, &mapw); @@ -104,7 +104,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = (term_rows / 2) - (height / 2); break; case UP: - if (gi.invent || (gm.moves > 1)) { + if (gi.invent || (svm.moves > 1)) { startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; } else { startx = 0; @@ -113,7 +113,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = mapy + mapb_offset; break; case DOWN: - if (gi.invent || (gm.moves > 1)) { + if (gi.invent || (svm.moves > 1)) { startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; } else { startx = 0; @@ -129,7 +129,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = term_rows - height; break; case RIGHT: - if (gi.invent || (gm.moves > 1)) { + if (gi.invent || (svm.moves > 1)) { startx = (mapw + mapx + (mapb_offset * 2)) - width; } else { startx = term_cols - width; @@ -222,7 +222,7 @@ curses_refresh_nethack_windows(void) return; } - if ((gm.moves <= 1) && !gi.invent) { + if ((svm.moves <= 1) && !gi.invent) { /* Main windows not yet displayed; refresh base window instead */ touchwin(stdscr); refresh(); diff --git a/win/tty/getline.c b/win/tty/getline.c index 53a1465bd..8a648c27d 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -232,7 +232,7 @@ xwaitforspace(const char *s) /* chars allowed besides return */ morc = 0; while ( #ifdef HANGUPHANDLING - !gp.program_state.done_hup && + !svp.program_state.done_hup && #endif (c = tty_nhgetch()) != EOF) { if (c == '\n' || c == '\r') diff --git a/win/tty/topl.c b/win/tty/topl.c index e9f70e420..89de9e6a6 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -184,7 +184,7 @@ remember_topl(void) cw->datlen[idx] = (short) len; } Strcpy(cw->data[idx], gt.toplines); - if (!gp.program_state.in_checkpoint) { + if (!svp.program_state.in_checkpoint) { *gt.toplines = '\0'; cw->maxcol = cw->maxrow = (idx + 1) % cw->rows; } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index d6cdf6200..5ca2d5c45 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -84,7 +84,7 @@ extern void msmsg(const char *, ...); */ #define HUPSKIP() \ do { \ - if (gp.program_state.done_hup) { \ + if (svp.program_state.done_hup) { \ morc = '\033'; \ return; \ } \ @@ -92,7 +92,7 @@ extern void msmsg(const char *, ...); /* morc=ESC - in case we bypass xwaitforspace() which sets that */ #define HUPSKIP_RESULT(RES) \ do { \ - if (gp.program_state.done_hup) \ + if (svp.program_state.done_hup) \ return (RES); \ } while (0) #else /* !HANGUPHANDLING */ @@ -376,11 +376,11 @@ winch_handler(int sig_unused UNUSED) } #endif - gp.program_state.resize_pending++; /* resize_tty() will reset it */ + svp.program_state.resize_pending++; /* resize_tty() will reset it */ /* if nethack is waiting for input, which is the most likely scenario, we will go ahead and respond to the resize immediately; otherwise, tty_nhgetch() will do so the next time it's called */ - if (gp.program_state.getting_char) { + if (svp.program_state.getting_char) { resize_tty(); #if 0 /* [this doesn't work as intended and seems to be unnecessary] */ if (resize_mesg) { @@ -402,7 +402,7 @@ resize_tty(void) struct WinDesc *cw; /* reset to 0 rather than just decrement */ - gp.program_state.resize_pending = 0; + svp.program_state.resize_pending = 0; resize_mesg = 0; getwindowsz(); /* update LI and CO */ @@ -647,7 +647,7 @@ tty_player_selection(void) } /* - * gp.plname is filled either by an option (-u Player or -uPlayer) or + * svp.plname is filled either by an option (-u Player or -uPlayer) or * explicitly (by being the wizard) or by askname. * It may still contain a suffix denoting the role, etc. * Always called after init_nhwindows() and before @@ -668,7 +668,7 @@ tty_askname(void) case 0: break; /* no game chosen; start new game */ case 1: - return; /* gp.plname[] has been set */ + return; /* svp.plname[] has been set */ } #endif /* SELECTSAVED */ @@ -731,7 +731,7 @@ tty_askname(void) && !(c >= '0' && c <= '9' && ct > 0)) c = '_'; #endif - if (ct < (int) (sizeof gp.plname) - 1) { + if (ct < (int) (sizeof svp.plname) - 1) { #if defined(MICRO) #if defined(MSDOS) if (iflags.grmode) { @@ -742,13 +742,13 @@ tty_askname(void) #else (void) putchar(c); #endif - gp.plname[ct++] = c; + svp.plname[ct++] = c; #ifdef WIN32CON ttyDisplay->curx++; #endif } } - gp.plname[ct] = 0; + svp.plname[ct] = 0; } while (ct == 0); /* move to next line to simulate echo of user's */ @@ -1978,7 +1978,7 @@ tty_dismiss_nhwindow(winid window) can't refresh--force the screen to be cleared instead (affects dismissal of 'reset role filtering' menu if screen height forces that to need a second page) */ - if (gp.program_state.in_role_selection) + if (svp.program_state.in_role_selection) clearscreen = TRUE; erase_menu_or_text(window, cw, clearscreen); @@ -3041,7 +3041,7 @@ ttyinv_add_menu( : !show_gold ? 26 : 27); - if (!gp.program_state.in_moveloop) + if (!svp.program_state.in_moveloop) return; slot = selector_to_slot(ch, ttyinvmode, &ignore); if (inuse_only && slot > 2 * rows_per_side) @@ -3216,7 +3216,7 @@ ttyinv_end_menu(int window, struct WinDesc *cw) { if (iflags.perm_invent || gp.perm_invent_toggling_direction == toggling_on) { - if (gp.program_state.in_moveloop) { + if (svp.program_state.in_moveloop) { boolean inuse_only = ((ttyinvmode & InvInUse) != 0); int rows_per_side = inuse_only ? cw->maxrow - 2 : 0; int old_slots_used = ttyinv_slots_used; /* value before render */ @@ -3245,7 +3245,7 @@ ttyinv_render(winid window, struct WinDesc *cw) uint32 current_row_color = NO_COLOR; struct tty_perminvent_cell *cell; char invbuf[BUFSZ]; - boolean force_redraw = gp.program_state.in_docrt ? TRUE : FALSE, + boolean force_redraw = svp.program_state.in_docrt ? TRUE : FALSE, inuse_only = (ttyinvmode & InvInUse) != 0, show_gold = (ttyinvmode & InvShowGold) != 0 && !inuse_only, sparse = (ttyinvmode & InvSparse) != 0 && !inuse_only; @@ -3603,7 +3603,7 @@ tty_wait_synch(void) if (ttyDisplay->inmore) { addtopl("--More--"); (void) fflush(stdout); - } else if (ttyDisplay->inread > gp.program_state.gameover) { + } else if (ttyDisplay->inread > svp.program_state.gameover) { /* this can only happen if we were reading and got interrupted */ ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; /* do this twice; 1st time gets the Quit? message again */ @@ -4036,19 +4036,19 @@ tty_nhgetch(void) i = randomkey(); } else { #ifdef RESIZABLE - if (gp.program_state.resize_pending) + if (svp.program_state.resize_pending) resize_tty(); #endif - gp.program_state.getting_char++; + svp.program_state.getting_char++; #ifdef UNIX - i = (gp.program_state.getting_char == 1) + i = (svp.program_state.getting_char == 1) ? tgetch() : ((read(fileno(stdin), (genericptr_t) &nestbuf, 1) == 1) ? (int) nestbuf : EOF); #else i = tgetch(); #endif - gp.program_state.getting_char--; + svp.program_state.getting_char--; #ifdef RESIZABLE if (resize_mesg) { resize_mesg = 0; diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index 491aa270d..afa55c1c9 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -648,7 +648,7 @@ plselInitDialog(struct plsel_data * data) /* set player name */ control_t * name_box = &data->controls[psc_name_box]; - SetDlgItemText(data->dialog, name_box->id, NH_A2W(gp.plname, wbuf, sizeof(wbuf))); + SetDlgItemText(data->dialog, name_box->id, NH_A2W(svp.plname, wbuf, sizeof(wbuf))); plselRandomize(data); diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index e2317870f..c96aa168d 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -39,7 +39,7 @@ mswin_have_input(void) return #ifdef SAFERHANGUP /* we always have input (ESC) if hangup was requested */ - gp.program_state.done_hup || + svp.program_state.done_hup || #endif (nhi_read_pos != nhi_write_pos); } @@ -69,7 +69,7 @@ mswin_input_pop(void) #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.ei.kbd.ch = '\033'; @@ -98,7 +98,7 @@ mswin_input_peek(void) #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (gp.program_state.done_hup) { + if (svp.program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.ei.kbd.ch = '\033'; diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 231d829a1..1bfa7fdb6 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -457,16 +457,16 @@ MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: { /* exit gracefully */ - if (gp.program_state.gameover) { + if (svp.program_state.gameover) { /* assume the user really meant this, as the game is already * over... */ /* to make sure we still save bones, just set stop printing flag */ - gp.program_state.stopprint++; + svp.program_state.stopprint++; NHEVENT_KBD( '\033'); /* and send keyboard input as if user pressed ESC */ /* additional code for this is done in menu and rip windows */ - } else if (!gp.program_state.something_worth_saving) { + } else if (!svp.program_state.something_worth_saving) { /* User exited before the game started, e.g. during splash display */ /* Just get out. */ @@ -842,7 +842,7 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case IDM_SAVE: if (iflags.debug_fuzzer) break; - if (!gp.program_state.gameover && !gp.program_state.done_hup) + if (!svp.program_state.gameover && !svp.program_state.done_hup) dosave(); else MessageBeep(0); diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index dfb864f61..a65bf9823 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -351,10 +351,10 @@ MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; case WM_CLOSE: - if (gp.program_state.gameover) { + if (svp.program_state.gameover) { data->result = -1; data->done = 1; - gp.program_state.stopprint++; + svp.program_state.stopprint++; return TRUE; } else return FALSE; diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 22d22fd6f..0f951ece5 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -227,7 +227,7 @@ NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) GetNHApp()->hMainWnd = NULL; DestroyWindow(hWnd); SetFocus(GetNHApp()->hMainWnd); - gp.program_state.stopprint++; + svp.program_state.stopprint++; return TRUE; case WM_DESTROY: diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index d64aa0734..9cdb7c2ec 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -696,7 +696,7 @@ mswin_askname(void) { logDebug("mswin_askname()\n"); - if (mswin_getlin_window("Who are you?", gp.plname, PL_NSIZ) == IDCANCEL) { + if (mswin_getlin_window("Who are you?", svp.plname, PL_NSIZ) == IDCANCEL) { bail("bye-bye"); /* not reached */ } @@ -1251,7 +1251,7 @@ void mswin_update_inventory(int arg) { logDebug("mswin_update_inventory(%d)\n", arg); - if (iflags.perm_invent && gp.program_state.something_worth_saving + if (iflags.perm_invent && svp.program_state.something_worth_saving && iflags.window_inited && WIN_INVEN != WIN_ERR) display_inventory(NULL, FALSE); } @@ -1963,7 +1963,7 @@ mswin_outrip(winid wid, int how, time_t when) } /* Put name on stone */ - Sprintf(buf, "%s", gp.plname); + Sprintf(buf, "%s", svp.plname); buf[STONE_LINE_LEN] = 0; putstr(wid, 0, buf); @@ -2862,7 +2862,7 @@ int NHMessageBox(HWND hWnd, LPCTSTR text, UINT type) { TCHAR title[MAX_LOADSTRING]; - if (gp.program_state.exiting && !strcmp(text, "\n")) + if (svp.program_state.exiting && !strcmp(text, "\n")) text = "Press Enter to exit"; LoadString(GetNHApp()->hApp, IDS_APP_TITLE_SHORT, title, MAX_LOADSTRING); From 72d2b0414ca957349c529a2ebf4a1748f0cf9285 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 13 Jul 2024 12:30:59 -0700 Subject: [PATCH 031/121] fix github issue #1257 - nymph theft while blind Issue reported by Meklon2007: some theft feedback during nymph attacks refers to the attacker as "she" and others as "it" if hero is blind. The "she" references are intentional. However, mixing them with "it" references when a series of messages occurs is jarring. This changes "it" to "someone", which is still different from "she" but hopefully enough less so to be tolerable. That resulted in monkeys also being referred to as "someone" because they're classified as humanoid. Change x_monnam()'s AUGMENT_IT handling, which chooses between "someone" and "something" when the monster is not seen, to override humanoid for animals (affects 'Y' class) and for mindless (affects zombies, mummies, and golems). So an unseen monkey will be "it" again. The final message for current item was relying on a cached monster name value. If an unseen nymph or monkey stole a worn blindfold so that hero's vision was restored: "It item" before the changes and "Someone|Something item" after. So update the cached name if sight gets regained, to give " stole ." (If the item is worn armor and the thief is a nymph, it was and still is "She stole ".) The message for having any worn item be stolen, which got split into two parts within the past year, was giving " takes off ". When not dual-wielded, the alternate weapon isn't really worn. Rather than suppress it outright, change the message for uwep/uswapwep/uquiver to say "disarms" instead of "takes off". For accessories, change "takes off" to "removes". Those are more or less interchangeable these days but "removes" matches R instead of T. While testing, my pet evidently killed a nymph (I was blinded and couldn't see it happen) while she stole my gloves and the next message I got was "You finish taking off your suit." The gloves weren't worn anymore so equipname() defaulted to suit. Get rid of equipname() altogether and switch to armor_simple_name() which doesn't rely on the worn-armor pointers. Fixes #1257 --- doc/fixes3-7-0.txt | 8 ++++++- src/do_name.c | 7 ++++-- src/do_wear.c | 5 ++-- src/steal.c | 59 ++++++++++++++++++++++------------------------ 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 0db220b28..f34db3b58 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1450 $ $NHDT-Date: 1720074479 2024/07/04 06:27:59 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1455 $ $NHDT-Date: 1720895738 2024/07/13 18:35:38 $ General Fixes and Modified Features ----------------------------------- @@ -1439,6 +1439,12 @@ using #loot -> 'i'n to put multiple items into a shop-owned container would don't-sell state was being reset for each item so 'a' and 'q' didn't stick beyond the current one join wall "spines" with walls of water and lava +some theft messages by nymphs force "she", others use default monster naming + which yields "it" when unseen; change the latter to "someone" which + still differs from "she" in a series of messages but isn't as jarring +if a nymph stole worn armor and got killed (perhaps by pet) before hero's next + turn, feedback would be "You finish taking off your suit." regardless + of the type of armor being taken off Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/do_name.c b/src/do_name.c index a30e65073..f52ea3425 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1720128164 2024/07/04 21:22:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.319 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1720895738 2024/07/13 18:35:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.320 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -870,8 +870,11 @@ x_monnam( /* unseen monsters, etc.; usually "it" but sometimes more specific; when hallucinating, the more specific values might be inverted */ if (do_it) { + /* !is_animal excludes all Y; !mindless excludes Z, M, \' */ + boolean s_one = humanoid(mdat) && !is_animal(mdat) && !mindless(mdat); + Strcpy(buf, !augment_it ? "it" - : (!do_hallu ? humanoid(mdat) : !rn2(2)) ? "someone" + : (!do_hallu ? s_one : !rn2(2)) ? "someone" : "something"); return buf; } diff --git a/src/do_wear.c b/src/do_wear.c index 0d49b2c1d..21f32504e 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_wear.c $NHDT-Date: 1702017586 2023/12/08 06:39:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.175 $ */ +/* NetHack 3.7 do_wear.c $NHDT-Date: 1720895740 2024/07/13 18:35:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1853,7 +1853,8 @@ armoroff(struct obj *otmp) } if (what) { /* sizeof offdelaybuf == 60; increase it if this becomes longer */ - Sprintf(offdelaybuf, "You finish taking off your %s.", what); + Snprintf(offdelaybuf, sizeof offdelaybuf, + "You finish taking off your %s.", what); gn.nomovemsg = offdelaybuf; } } else { diff --git a/src/steal.c b/src/steal.c index 203edb46f..b26e5484b 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,27 +1,14 @@ -/* NetHack 3.7 steal.c $NHDT-Date: 1707122967 2024/02/05 08:49:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 3.7 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" -staticfn const char *equipname(struct obj *); staticfn int unstolenarm(void); staticfn int stealarm(void); staticfn void worn_item_removal(struct monst *, struct obj *); -staticfn const char * -equipname(struct obj *otmp) -{ - return ((otmp == uarmu) ? shirt_simple_name(otmp) - : (otmp == uarmf) ? boots_simple_name(otmp) - : (otmp == uarms) ? shield_simple_name(otmp) - : (otmp == uarmg) ? gloves_simple_name(otmp) - : (otmp == uarmc) ? cloak_simple_name(otmp) - : (otmp == uarmh) ? helm_simple_name(otmp) - : suit_simple_name(otmp)); -} - /* proportional subset of gold; return value actually fits in an int */ long somegold(long lmoney) @@ -168,7 +155,7 @@ unstolenarm(void) break; gs.stealoid = 0; if (obj) { - You("finish taking off your %s.", equipname(obj)); + You("finish taking off your %s.", armor_simple_name(obj)); } return 0; } @@ -319,6 +306,7 @@ worn_item_removal( struct obj *obj) { char objbuf[BUFSZ], article[20], *p; + const char *verb; int strip_art; Strcpy(objbuf, doname(obj)); @@ -342,7 +330,13 @@ worn_item_removal( && (!strncmp(p + 5, "left ", 5) || !strncmp(p + 5, "right ", 6))) (void) strsubst(p + 2, "on", "from"); - pline("%s takes off %s.", Monnam(mon), objbuf); + /* slightly iffy for alternate weapon that isn't actively dual-wielded, + but it's better to alert the player to the change in equipment than + to suppress the message for that case */ + verb = ((obj->owornmask & W_WEAPONS) != 0L) ? "disarms" + : ((obj->owornmask & W_ACCESSORY) != 0L) ? "removes" + : "takes off"; + pline("%s %s %s.", Some_Monnam(mon), verb, objbuf); iflags.last_msg = PLNMSG_MON_TAKES_OFF_ITEM; /* removal might trigger more messages (due to loss of Lev|Fly; descending happens before the theft in progress finishes) */ @@ -363,6 +357,7 @@ steal(struct monst *mtmp, char *objnambuf) int tmp, could_petrify, armordelay, olddelay, icnt, named = 0, retrycnt = 0; boolean monkey_business = is_animal(mtmp->data), + seen = canspotmon(mtmp), was_doffing, was_punished = Punished; if (objnambuf) @@ -375,10 +370,9 @@ steal(struct monst *mtmp, char *objnambuf) teleporting to safety could result in a previously visible thief no longer being visible; it could also be a case of a blinded hero being able to see via wearing the Eyes of the Overworld and - having those stolen; remember the name in order to avoid "It" - in the eventual " stole " message; (the name might - already be "It"; if so, that's ok) */ - Strcpy(Monnambuf, Monnam(mtmp)); + having those stolen; remember the name as it is now; if unseen, + monkeys will be "It" and nymphs will be "Someone" */ + Strcpy(Monnambuf, Some_Monnam(mtmp)); /* food being eaten might already be used up but will not have been removed from inventory yet; we don't want to steal that, @@ -496,7 +490,7 @@ steal(struct monst *mtmp, char *objnambuf) pline("%s tries to %s %s%s but gives up.", Monnambuf, ROLL_FROM(how), (otmp->owornmask & W_ARMOR) ? "your " : "", - (otmp->owornmask & W_ARMOR) ? equipname(otmp) + (otmp->owornmask & W_ARMOR) ? armor_simple_name(otmp) : yname(otmp)); /* the fewer items you have, the less likely the thief is going to stick around to try again (0) instead of @@ -541,7 +535,6 @@ steal(struct monst *mtmp, char *objnambuf) } else { int curssv = otmp->cursed; int slowly; - boolean seen = canspotmon(mtmp); otmp->cursed = 0; slowly = (armordelay >= 1 || gm.multi < 0); @@ -552,7 +545,7 @@ steal(struct monst *mtmp, char *objnambuf) : !slowly ? "hand over" : was_doffing ? "continue removing" : "start removing", - equipname(otmp)); + armor_simple_name(otmp)); else urgent_pline("%s seduces you and %s off your %s.", !seen ? "She" : Adjmonnam(mtmp, "beautiful"), @@ -560,7 +553,7 @@ steal(struct monst *mtmp, char *objnambuf) : !slowly ? "you take" : was_doffing ? "you continue taking" : "you start taking", - equipname(otmp)); + armor_simple_name(otmp)); named++; /* the following is to set multi for later on */ nomul(-armordelay); @@ -580,6 +573,10 @@ steal(struct monst *mtmp, char *objnambuf) impossible("Tried to steal a strange worn thing. [%d]", otmp->oclass); } + /* hero's blindfold might have just been stolen; if so, replace + cached "It" or "Someone" with Monnam */ + if (!seen && canspotmon(mtmp)) + Strcpy(Monnambuf, Monnam(mtmp)); } else if (otmp->owornmask) { /* weapon or ball&chain */ struct obj *item = otmp; @@ -750,29 +747,29 @@ stealamulet(struct monst *mtmp) /* take off outer gear if we're targeting [hypothetical] quest artifact suit, shirt, gloves, or rings */ if ((otmp == uarm || otmp == uarmu) && uarmc) - remove_worn_item(uarmc, FALSE); + worn_item_removal(mtmp, uarmc); if (otmp == uarmu && uarm) - remove_worn_item(uarm, FALSE); + worn_item_removal(mtmp, uarm); if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg)) && uwep) { /* gloves are about to be unworn; unwield weapon(s) first */ if (u.twoweap) /* remove_worn_item(uswapwep) indirectly */ - remove_worn_item(uswapwep, FALSE); /* clears u.twoweap */ - remove_worn_item(uwep, FALSE); + worn_item_removal(mtmp, uswapwep); /* clears u.twoweap */ + worn_item_removal(mtmp, uwep); } if ((otmp == uright || otmp == uleft) && uarmg) /* calls Gloves_off() to handle wielded cockatrice corpse */ - remove_worn_item(uarmg, FALSE); + worn_item_removal(mtmp, uarmg); /* finally, steal the target item */ if (otmp->owornmask) - remove_worn_item(otmp, TRUE); + worn_item_removal(mtmp, otmp); if (otmp->unpaid) subfrombill(otmp, shop_keeper(*u.ushops)); freeinv(otmp); Strcpy(buf, doname(otmp)); (void) mpickobj(mtmp, otmp); /* could merge and free otmp but won't */ - pline("%s steals %s!", Monnam(mtmp), buf); + pline("%s steals %s!", Some_Monnam(mtmp), buf); if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) (void) rloc(mtmp, RLOC_MSG); (void) encumber_msg(); From 0eb7f109e04355876a26a7d78c33fcf9d60ae7af Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 13 Jul 2024 16:31:35 -0400 Subject: [PATCH 032/121] follow-up, program_state --- include/decl.h | 2 +- outdated/sys/wince/mhinput.c | 6 +++--- outdated/sys/wince/mhmenu.c | 2 +- outdated/sys/wince/mhtext.c | 2 +- outdated/win/Qt3/qt3_win.cpp | 14 ++++++------- outdated/win/gnome/gnbind.c | 4 ++-- src/allmain.c | 8 ++++---- src/artifact.c | 2 +- src/attrib.c | 2 +- src/cmd.c | 38 +++++++++++++++++----------------- src/decl.c | 5 ++++- src/display.c | 16 +++++++-------- src/do.c | 6 +++--- src/do_name.c | 6 +++--- src/do_wear.c | 2 +- src/end.c | 40 ++++++++++++++++++------------------ src/files.c | 32 ++++++++++++++--------------- src/insight.c | 10 ++++----- src/invent.c | 8 ++++---- src/mkmaze.c | 4 ++-- src/mon.c | 2 +- src/o_init.c | 2 +- src/objnam.c | 12 +++++------ src/options.c | 6 +++--- src/pager.c | 4 ++-- src/pline.c | 20 +++++++++--------- src/polyself.c | 2 +- src/priest.c | 2 +- src/questpgr.c | 2 +- src/restore.c | 28 ++++++++++++------------- src/role.c | 4 ++-- src/rumors.c | 6 +++--- src/save.c | 34 +++++++++++++++--------------- src/sfstruct.c | 4 ++-- src/shk.c | 2 +- src/shknam.c | 2 +- src/topten.c | 6 +++--- src/vault.c | 2 +- src/vision.c | 6 +++--- src/windows.c | 6 +++--- src/wizcmds.c | 4 ++-- sys/libnh/libnhmain.c | 4 ++-- sys/msdos/vidvesa.c | 2 +- sys/msdos/vidvga.c | 2 +- sys/unix/unixmain.c | 8 ++++---- sys/unix/unixunix.c | 4 ++-- sys/vms/vmsmain.c | 6 +++--- sys/vms/vmstty.c | 2 +- sys/windows/consoletty.c | 10 ++++----- sys/windows/windmain.c | 4 ++-- win/Qt/qt_bind.cpp | 4 ++-- win/Qt/qt_main.cpp | 10 ++++----- win/Qt/qt_yndlg.cpp | 2 +- win/X11/winX.c | 6 +++--- win/X11/winmap.c | 4 ++-- win/X11/winmisc.c | 10 ++++----- win/curses/cursdial.c | 4 ++-- win/curses/cursmain.c | 2 +- win/curses/cursmisc.c | 2 +- win/tty/getline.c | 2 +- win/tty/topl.c | 2 +- win/tty/wintty.c | 28 ++++++++++++------------- win/win32/mhinput.c | 6 +++--- win/win32/mhmain.c | 8 ++++---- win/win32/mhmenu.c | 4 ++-- win/win32/mhrip.c | 2 +- win/win32/mswproc.c | 4 ++-- 67 files changed, 255 insertions(+), 252 deletions(-) diff --git a/include/decl.h b/include/decl.h index f4c8abbe9..1a63ea1a6 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1194,7 +1194,6 @@ struct instance_globals_saved_p { char plname[PL_NSIZ]; /* player name */ char pl_character[PL_CSIZ]; char pl_fruit[PL_FSIZ]; - struct sinfo program_state; /* flags describing game's current state */ }; struct instance_globals_saved_q { @@ -1280,6 +1279,7 @@ extern struct instance_globals_saved_t svt; extern struct instance_globals_saved_u svu; extern struct instance_globals_saved_x svx; extern struct instance_globals_saved_y svy; +extern struct sinfo program_state; /* flags describing game's current state */ struct const_globals { const struct obj zeroobj; /* used to zero out a struct obj */ diff --git a/outdated/sys/wince/mhinput.c b/outdated/sys/wince/mhinput.c index 4d0f8db47..a7b169342 100644 --- a/outdated/sys/wince/mhinput.c +++ b/outdated/sys/wince/mhinput.c @@ -39,7 +39,7 @@ mswin_have_input() return #ifdef SAFERHANGUP /* we always have input (ESC) if hangup was requested */ - svp.program_state.done_hup || + program_state.done_hup || #endif (nhi_read_pos != nhi_write_pos); } @@ -69,7 +69,7 @@ mswin_input_pop() #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (svp.program_state.done_hup) { + if (program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.kbd.ch = '\033'; @@ -98,7 +98,7 @@ mswin_input_peek() #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (svp.program_state.done_hup) { + if (program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.kbd.ch = '\033'; diff --git a/outdated/sys/wince/mhmenu.c b/outdated/sys/wince/mhmenu.c index e69ddeb62..4aa5f19f4 100644 --- a/outdated/sys/wince/mhmenu.c +++ b/outdated/sys/wince/mhmenu.c @@ -533,7 +533,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) if (!data->text.text) { data->text.text = mswin_init_text_buffer( - svp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); + program_state.gameover ? FALSE : GetNHApp()->bWrapText); if (!data->text.text) break; } diff --git a/outdated/sys/wince/mhtext.c b/outdated/sys/wince/mhtext.c index e99b900ba..a6b813507 100644 --- a/outdated/sys/wince/mhtext.c +++ b/outdated/sys/wince/mhtext.c @@ -39,7 +39,7 @@ mswin_init_text_window() ZeroMemory(data, sizeof(NHTextWindow)); data->window_text = mswin_init_text_buffer( - svp.program_state.gameover ? FALSE : GetNHApp()->bWrapText); + program_state.gameover ? FALSE : GetNHApp()->bWrapText); SetWindowLong(ret, GWL_USERDATA, (LONG) data); return ret; } diff --git a/outdated/win/Qt3/qt3_win.cpp b/outdated/win/Qt3/qt3_win.cpp index 0f9b028cd..483761cfd 100644 --- a/outdated/win/Qt3/qt3_win.cpp +++ b/outdated/win/Qt3/qt3_win.cpp @@ -4037,7 +4037,7 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) void NetHackQtMainWindow::closeEvent(QCloseEvent* e) { - if ( svp.program_state.something_worth_saving ) { + if ( program_state.something_worth_saving ) { switch ( QMessageBox::information( this, "NetHack", "This will end your NetHack session", "&Save", "&Cancel", 0, 1 ) ) @@ -4849,7 +4849,7 @@ void NetHackQtBind::qt_update_inventory() if (main) main->updateInventory(); /* doesn't work yet - if (svp.program_state.something_worth_saving && iflags.perm_invent) + if (program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, FALSE); */ } @@ -4903,14 +4903,14 @@ int NetHackQtBind::qt_nhgetch() // while (keybuffer.Empty() #ifdef SAFERHANGUP - && !svp.program_state.done_hup + && !program_state.done_hup #endif ) { qApp->enter_loop(); } #ifdef SAFERHANGUP - if (svp.program_state.done_hup && keybuffer.Empty()) return '\033'; + if (program_state.done_hup && keybuffer.Empty()) return '\033'; #endif return keybuffer.GetAscii(); } @@ -4924,13 +4924,13 @@ int NetHackQtBind::qt_nh_poskey(int *x, int *y, int *mod) // while (keybuffer.Empty() && clickbuffer.Empty() #ifdef SAFERHANGUP - && !svp.program_state.done_hup + && !program_state.done_hup #endif ) { qApp->enter_loop(); } #ifdef SAFERHANGUP - if (svp.program_state.done_hup && keybuffer.Empty()) return '\033'; + if (program_state.done_hup && keybuffer.Empty()) return '\033'; #endif if (!keybuffer.Empty()) { return keybuffer.GetAscii(); @@ -5179,7 +5179,7 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) bool result=QApplication::notify(receiver,event); #ifdef SAFERHANGUP - if (svp.program_state.done_hup) { + if (program_state.done_hup) { keybuffer.Put('\033'); qApp->exit_loop(); return TRUE; diff --git a/outdated/win/gnome/gnbind.c b/outdated/win/gnome/gnbind.c index 0eeb57f98..6fb043e21 100644 --- a/outdated/win/gnome/gnbind.c +++ b/outdated/win/gnome/gnbind.c @@ -907,7 +907,7 @@ gnome_nhgetch() g_askingQuestion = 1; /* Process events until a key press event arrives. */ while (g_numKeys == 0) { - if (svp.program_state.done_hup) + if (program_state.done_hup) return '\033'; gtk_main_iteration(); } @@ -945,7 +945,7 @@ gnome_nh_poskey(int *x, int *y, int *mod) g_askingQuestion = 0; /* Process events until a key or map-click arrives. */ while (g_numKeys == 0 && g_numClicks == 0) { - if (svp.program_state.done_hup) + if (program_state.done_hup) return '\033'; gtk_main_iteration(); } diff --git a/src/allmain.c b/src/allmain.c index fd22e17a2..957763b8d 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -71,7 +71,7 @@ moveloop_preamble(boolean resuming) } if (!resuming) { /* new game */ - svp.program_state.beyond_savefile_load = 1; /* for TTY_PERM_INVENT */ + program_state.beyond_savefile_load = 1; /* for TTY_PERM_INVENT */ svc.context.rndencode = rnd(9000); set_wear((struct obj *) 0); /* for side-effects of starting gear */ reset_justpicked(gi.invent); @@ -100,7 +100,7 @@ moveloop_preamble(boolean resuming) u.uz0.dlevel = u.uz.dlevel; svc.context.move = 0; - svp.program_state.in_moveloop = 1; + program_state.in_moveloop = 1; /* for perm_invent preset at startup, display persistent inventory after invent is fully populated and the in_moveloop flag has been set */ if (iflags.perm_invent) @@ -166,7 +166,7 @@ moveloop_core(void) boolean monscanmove = FALSE; #ifdef SAFERHANGUP - if (svp.program_state.done_hup) + if (program_state.done_hup) end_of_input(); #endif get_nh_event(); @@ -781,7 +781,7 @@ newgame(void) #ifdef INSURANCE save_currentstate(); #endif - svp.program_state.something_worth_saving++; /* useful data now exists */ + program_state.something_worth_saving++; /* useful data now exists */ /* Success! */ welcome(TRUE); diff --git a/src/artifact.c b/src/artifact.c index 80599729d..c02a6cfb7 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -705,7 +705,7 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask) * when restoring a game */ (void) make_hallucinated((long) !on, - svp.program_state.restoring ? FALSE : TRUE, + program_state.restoring ? FALSE : TRUE, wp_mask); } if (spfx & SPFX_ESP) { diff --git a/src/attrib.c b/src/attrib.c index c7ad35dca..e8d2bd3d1 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -191,7 +191,7 @@ adjattrib( disp.botl = TRUE; if (msgflg <= 0) You_feel("%s%s!", (incr > 1 || incr < -1) ? "very " : "", attrstr); - if (svp.program_state.in_moveloop && (ndx == A_STR || ndx == A_CON)) + if (program_state.in_moveloop && (ndx == A_STR || ndx == A_CON)) (void) encumber_msg(); return TRUE; } diff --git a/src/cmd.c b/src/cmd.c index ea3caa5de..cd2b4b135 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3294,7 +3294,7 @@ rhack(int key) svc.context.nopick = 0; got_prefix_input: #ifdef SAFERHANGUP - if (svp.program_state.done_hup) + if (program_state.done_hup) end_of_input(); #endif if ((cmdq = cmdq_pop()) != 0) { @@ -3634,7 +3634,7 @@ getdir(const char *s) } retry: - svp.program_state.input_state = getdirInp; + program_state.input_state = getdirInp; if (gi.in_doagain || *readchar_queue) dirsym = readchar(); else @@ -4648,7 +4648,7 @@ get_count( unsigned gc_flags) /* control flags: GC_SAVEHIST, GC_ECHOFIRST */ { char qbuf[QBUFSZ]; - int key, save_input_state = svp.program_state.input_state; + int key, save_input_state = program_state.input_state; long cnt = 0L, first = inkey ? (long) (inkey - '0') : 0L; boolean backspaced = FALSE, showzero = TRUE, /* should "Count: 123" go into message history? */ @@ -4670,7 +4670,7 @@ get_count( } else { /* if readchar() has already been called in this loop, it will have reset input_state; put that back to its previous value */ - svp.program_state.input_state = save_input_state; + program_state.input_state = save_input_state; key = readchar(); } @@ -4737,7 +4737,7 @@ parse(void) /* affects readchar() behavior for ESC iff 'altmeta' option is On; is always reset to otherInp by readchar() */ - svp.program_state.input_state = commandInp; + program_state.input_state = commandInp; if (!gc.Cmd.num_pad || (foo = readchar()) == gc.Cmd.spkeys[NHKF_COUNT]) { /* if 'num_pad' is On then readchar() has just reset input_state; @@ -4745,7 +4745,7 @@ parse(void) otherwise "nESC" becomes "nESC" (with not read from keyboard yet) rather than intended count and meta keystroke "nM-" */ - svp.program_state.input_state = commandInp; + program_state.input_state = commandInp; foo = get_count((char *) 0, '\0', LARGEST_INT, &gc.command_count, GC_NOFLAGS); @@ -4791,8 +4791,8 @@ hangup( int sig_unused UNUSED) /* called as signal() handler, so sent * at least one arg */ { - if (svp.program_state.exiting) - svp.program_state.in_moveloop = 0; + if (program_state.exiting) + program_state.in_moveloop = 0; nhwindows_hangup(); #ifdef SAFERHANGUP /* When using SAFERHANGUP, the done_hup flag is tested in rhack @@ -4801,10 +4801,10 @@ hangup( protects against losing objects in the process of being thrown, but also potentially riskier because the disconnected program must continue running longer before attempting a hangup save. */ - svp.program_state.done_hup++; + program_state.done_hup++; /* defer hangup iff game appears to be in progress */ - if (svp.program_state.in_moveloop - && svp.program_state.something_worth_saving) + if (program_state.in_moveloop + && program_state.something_worth_saving) return; #endif /* SAFERHANGUP */ end_of_input(); @@ -4815,16 +4815,16 @@ end_of_input(void) { #ifdef NOSAVEONHANGUP #ifdef INSURANCE - if (flags.ins_chkpt && svp.program_state.something_worth_saving) + if (flags.ins_chkpt && program_state.something_worth_saving) program_state.preserve_locks = 1; /* keep files for recovery */ #endif - svp.program_state.something_worth_saving = 0; /* don't save */ + program_state.something_worth_saving = 0; /* don't save */ #endif #ifndef SAFERHANGUP - if (!svp.program_state.done_hup++) + if (!program_state.done_hup++) #endif - if (svp.program_state.something_worth_saving) + if (program_state.something_worth_saving) (void) dosave0(); if (soundprocs.sound_exit_nhsound) (*soundprocs.sound_exit_nhsound)("end_of_input"); @@ -4875,7 +4875,7 @@ readchar_core(coordxy *x, coordxy *y, int *mod) sym = '\033'; #ifdef ALTMETA } else if (sym == '\033' && iflags.altmeta - && svp.program_state.input_state != otherInp) { + && program_state.input_state != otherInp) { /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' but only when we're called by parse() [possibly via get_count()] or getpos() [to support Alt+digit] or getdir() [for arrow keys @@ -4895,7 +4895,7 @@ readchar_core(coordxy *x, coordxy *y, int *mod) readchar_done: /* next readchar() will be for an ordinary char unless parse() sets this back to non-zero */ - svp.program_state.input_state = otherInp; + program_state.input_state = otherInp; return (char) sym; } @@ -4917,7 +4917,7 @@ readchar_poskey(coordxy *x, coordxy *y, int *mod) { char ch; - svp.program_state.input_state = getposInp; + program_state.input_state = getposInp; ch = readchar_core(x, y, mod); return ch; } @@ -5171,7 +5171,7 @@ yn_function( res = altres; } /* in case we're called via getdir() which sets input_state */ - svp.program_state.input_state = otherInp; + program_state.input_state = otherInp; return res; } diff --git a/src/decl.c b/src/decl.c index 2fd8f2ea4..d11887dd9 100644 --- a/src/decl.c +++ b/src/decl.c @@ -986,7 +986,6 @@ static const struct instance_globals_saved_p init_svp = { DUMMY, /* plname */ DUMMY, /* pl_character */ DUMMY, /* pl_fruit */ - UNDEFINED_VALUES, /* program_state */ }; static const struct instance_globals_saved_q init_svq = { @@ -1029,6 +1028,8 @@ static const struct instance_globals_saved_y init_svy = { UNDEFINED_VALUE /* ymax */ }; +static const struct sinfo init_program_state = { 0 }; + #if 0 struct instance_globals g; #endif /* 0 */ @@ -1078,6 +1079,7 @@ struct instance_globals_saved_t svt; struct instance_globals_saved_u svu; struct instance_globals_saved_x svx; struct instance_globals_saved_y svy; +struct sinfo program_state; const struct const_globals cg = { DUMMY, /* zeroobj */ @@ -1154,6 +1156,7 @@ decl_globals_init(void) svu = init_svu; svx = init_svx; svy = init_svy; + program_state = init_program_state; gv.valuables[0].list = gg.gems; gv.valuables[0].size = SIZE(gg.gems); diff --git a/src/display.c b/src/display.c index 8a47e5058..6a3d5fcda 100644 --- a/src/display.c +++ b/src/display.c @@ -676,10 +676,10 @@ next_to_gas( boolean suppress_map_output(void) { - if (gi.in_mklev || svp.program_state.saving || svp.program_state.restoring) + if (gi.in_mklev || program_state.saving || program_state.restoring) return TRUE; #ifdef HANGUPHANDLING - if (svp.program_state.done_hup) + if (program_state.done_hup) return TRUE; #endif return FALSE; @@ -1658,10 +1658,10 @@ docrt_flags(int refresh_flags) redrawonly = (refresh_flags & docrtRefresh) != 0, nocls = (refresh_flags & docrtNocls) != 0; - if (!u.ux || svp.program_state.in_docrt) + if (!u.ux || program_state.in_docrt) return; /* display isn't ready yet */ - svp.program_state.in_docrt = TRUE; + program_state.in_docrt = TRUE; if (redrawonly) { redraw_map(FALSE); @@ -1713,7 +1713,7 @@ docrt_flags(int refresh_flags) disp.botlx = TRUE; /* force a redraw of the bottom lines */ /* note: caller needs to call bot() to actually redraw status */ } - svp.program_state.in_docrt = FALSE; + program_state.in_docrt = FALSE; } /* for panning beyond a clipped region; resend the current map data to @@ -1949,8 +1949,8 @@ show_glyph(coordxy x, coordxy y, int glyph) oldglyph = gg.gbuf[y][x].glyphinfo.glyph; if (a11y.glyph_updates && !a11y.mon_notices_blocked - && !svp.program_state.in_docrt - && !svp.program_state.in_getlev + && !program_state.in_docrt + && !program_state.in_getlev && (oldglyph != glyph || gg.gbuf[y][x].gnew)) { int c = glyph_to_cmap(glyph); if ((glyph_is_nothing(oldglyph) || glyph_is_unexplored(oldglyph) @@ -2165,7 +2165,7 @@ flush_screen(int cursor_on_u) return; /* if already flushing then return */ flushing = 1; #ifdef HANGUPHANDLING - if (svp.program_state.done_hup) + if (program_state.done_hup) return; #endif diff --git a/src/do.c b/src/do.c index 8f7aa4293..41aaadc6d 100644 --- a/src/do.c +++ b/src/do.c @@ -900,7 +900,7 @@ obj_no_longer_held(struct obj *obj) */ if (!obj->oerodeproof || !rn2(10)) { /* if monsters aren't moving, assume player is responsible */ - if (!svc.context.mon_moving && !svp.program_state.gameover) + if (!svc.context.mon_moving && !program_state.gameover) costly_alteration(obj, COST_DEGRD); obj->otyp = WORM_TOOTH; obj->oerodeproof = 0; @@ -1348,7 +1348,7 @@ save_currentstate(void) { NHFILE *nhfp; - svp.program_state.in_checkpoint++; + program_state.in_checkpoint++; if (flags.ins_chkpt) { /* write out just-attained level, with pets and everything */ nhfp = currentlevel_rewrite(); @@ -1363,7 +1363,7 @@ save_currentstate(void) /* write out non-level state */ savestateinlock(); - svp.program_state.in_checkpoint--; + program_state.in_checkpoint--; } #endif diff --git a/src/do_name.c b/src/do_name.c index f52ea3425..071539677 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -839,7 +839,7 @@ x_monnam( if (mtmp == &gy.youmonst) return strcpy(buf, "you"); /* ignore article, "invisible", &c */ - if (svp.program_state.gameover) + if (program_state.gameover) suppress |= SUPPRESS_HALLUCINATION; if (article == ARTICLE_YOUR && !mtmp->mtame) article = ARTICLE_THE; @@ -857,7 +857,7 @@ x_monnam( do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION); do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE); do_it = !canspotmon(mtmp) && article != ARTICLE_YOUR - && !svp.program_state.gameover && mtmp != u.usteed + && !program_state.gameover && mtmp != u.usteed && !engulfing_u(mtmp) && !(suppress & SUPPRESS_IT); do_saddle = !(suppress & SUPPRESS_SADDLE); do_mappear = mappear_as_mon && !(suppress & SUPPRESS_MAPPEARANCE); @@ -1481,7 +1481,7 @@ const char * hliquid( const char *liquidpref) /* use as-is when not hallucintg (unless empty) */ { - boolean hallucinate = Hallucination && !svp.program_state.gameover; + boolean hallucinate = Hallucination && !program_state.gameover; if (hallucinate || !liquidpref || !*liquidpref) { int indx, count = SIZE(hliquids); diff --git a/src/do_wear.c b/src/do_wear.c index 21f32504e..51b9059a6 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -810,7 +810,7 @@ dragon_armor_handling( case GOLD_DRAGON_SCALES: case GOLD_DRAGON_SCALE_MAIL: (void) make_hallucinated((long) !puton, - svp.program_state.restoring ? FALSE : TRUE, + program_state.restoring ? FALSE : TRUE, W_ARM); break; case ORANGE_DRAGON_SCALES: diff --git a/src/end.c b/src/end.c index c894e7021..3078a0ad3 100644 --- a/src/end.c +++ b/src/end.c @@ -43,7 +43,7 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN; #define nethack_exit exit #endif -#define done_stopprint svp.program_state.stopprint +#define done_stopprint program_state.stopprint /* * The order of these needs to match the macros in hack.h. @@ -175,7 +175,7 @@ staticfn void done_hangup(int sig) { #ifdef HANGUPHANDLING - svp.program_state.done_hup++; + program_state.done_hup++; #endif sethanguphandler((void (*)(int)) SIG_IGN); done_intr(sig); @@ -391,7 +391,7 @@ panic VA_DECL(const char *, str) VA_START(str); VA_INIT(str, char *); - if (svp.program_state.panicking++) + if (program_state.panicking++) NH_abort(NULL); /* avoid loops - this should never happen*/ gb.bot_disabled = TRUE; @@ -404,9 +404,9 @@ panic VA_DECL(const char *, str) iflags.window_inited = FALSE; /* they're gone; force raw_print()ing */ } - raw_print(svp.program_state.gameover + raw_print(program_state.gameover ? "Postgame wrapup disrupted." - : !svp.program_state.something_worth_saving + : !program_state.something_worth_saving ? "Program initialization has failed." : "Suddenly, the dungeon collapses."); #ifndef MICRO @@ -414,11 +414,11 @@ panic VA_DECL(const char *, str) if (!wizard) raw_printf("Report the following error to \"%s\" or at \"%s\".", DEVTEAM_EMAIL, DEVTEAM_URL); - else if (svp.program_state.something_worth_saving) + else if (program_state.something_worth_saving) raw_print("\nError save file being written.\n"); #else /* !NOTIFY_NETHACK_BUGS */ if (!wizard) { - const char *maybe_rebuild = !svp.program_state.something_worth_saving + const char *maybe_rebuild = !program_state.something_worth_saving ? "." : "\nand it may be possible to rebuild."; @@ -437,7 +437,7 @@ panic VA_DECL(const char *, str) /* XXX can we move this above the prints? Then we'd be able to * suppress "it may be possible to rebuild" based on dosave0() * or say it's NOT possible to rebuild. */ - if (svp.program_state.something_worth_saving && !iflags.debug_fuzzer) { + if (program_state.something_worth_saving && !iflags.debug_fuzzer) { set_error_savefile(); if (dosave0()) { /* os/win port specific recover instructions */ @@ -937,7 +937,7 @@ fuzzer_savelife(int how) * Some debugging code pulled out of done() to unclutter it. * 'done_seq' is maintained in done(). */ - if (!svp.program_state.panicking + if (!program_state.panicking && how != PANICKED && how != TRICKED) { savelife(how); @@ -1019,9 +1019,9 @@ done(int how) return; } } - if (svp.program_state.panicking + if (program_state.panicking #ifdef HANGUPHANDLING - || svp.program_state.done_hup + || program_state.done_hup #endif || (how == QUIT && done_stopprint)) { /* skip status update if panicking or disconnected @@ -1094,7 +1094,7 @@ done(int how) /* if hangup has occurred, the only possible answer to a paranoid query is 'no'; we want 'no' as the default for "Die?" but can't accept it more than once if there's no user supplying it */ - && !(svp.program_state.done_hup && gd.done_seq++ == gh.hero_seq) + && !(program_state.done_hup && gd.done_seq++ == gh.hero_seq) #endif && !paranoid_query(ParanoidDie, "Die?")) { pline("OK, so you don't %s.", (how == CHOKING) ? "choke" : "die"); @@ -1128,11 +1128,11 @@ really_done(int how) /* * The game is now over... */ - svp.program_state.gameover = 1; + program_state.gameover = 1; /* in case of a subsequent panic(), there's no point trying to save */ - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; #ifdef HANGUPHANDLING - if (svp.program_state.done_hup) + if (program_state.done_hup) done_stopprint++; #endif /* render vision subsystem inoperative */ @@ -1140,7 +1140,7 @@ really_done(int how) /* maybe use up active invent item(s), place thrown/kicked missile, deal with ball and chain possibly being temporarily off the map */ - if (!svp.program_state.panicking) + if (!program_state.panicking) done_object_cleanup(); /* in case we're panicking; normally cleared by done_object_cleanup() */ iflags.perm_invent = FALSE; @@ -1657,7 +1657,7 @@ container_contents( ATTRNORETURN void nh_terminate(int status) { - svp.program_state.in_moveloop = 0; /* won't be returning to normal play */ + program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); #ifdef MAC @@ -1665,7 +1665,7 @@ nh_terminate(int status) #endif /* don't bother to try to release memory if we're in panic mode, to avoid trouble in case that happens to be due to memory problems */ - if (!svp.program_state.panicking) { + if (!program_state.panicking) { freedynamicdata(); dlb_cleanup(); l_nhcore_done(); @@ -1679,10 +1679,10 @@ nh_terminate(int status) */ /* don't call exit() if already executing within an exit handler; that would cancel any other pending user-mode handlers */ - if (svp.program_state.exiting) + if (program_state.exiting) return; #endif - svp.program_state.exiting = 1; + program_state.exiting = 1; nethack_exit(status); } diff --git a/src/files.c b/src/files.c index 5ff98d560..31f3fa9a0 100644 --- a/src/files.c +++ b/src/files.c @@ -703,7 +703,7 @@ clearlocks(void) int x; #ifdef HANGUPHANDLING - if (svp.program_state.preserve_locks) + if (program_state.preserve_locks) return; #endif #ifndef NO_SIGNAL @@ -1101,7 +1101,7 @@ create_savefile(void) nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_SAVEFILE; nhfp->mode = WRITING; - if (svp.program_state.in_self_recover || do_historical) { + if (program_state.in_self_recover || do_historical) { do_historical = TRUE; /* force it */ nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; @@ -1155,7 +1155,7 @@ open_savefile(void) nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_SAVEFILE; nhfp->mode = READING; - if (svp.program_state.in_self_recover || do_historical) { + if (program_state.in_self_recover || do_historical) { do_historical = TRUE; /* force it */ nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; @@ -1875,7 +1875,7 @@ static struct flock sflock; /* for unlocking, same as above */ #endif #if defined(HANGUPHANDLING) -#define HUP if (!svp.program_state.done_hup) +#define HUP if (!program_state.done_hup) #else #define HUP #endif @@ -3447,7 +3447,7 @@ config_error_init(boolean from_file, const char *sourcename, boolean secure) tmp->next = config_error_data; config_error_data = tmp; - svp.program_state.config_error_ready = TRUE; + program_state.config_error_ready = TRUE; } staticfn boolean @@ -3513,7 +3513,7 @@ config_erradd(const char *buf) punct = c_eos((char *) buf) - 1; /* eos(buf)-1 is valid */ punct = strchr(".!?", *punct) ? "" : "."; - if (!svp.program_state.config_error_ready) { + if (!program_state.config_error_ready) { /* either very early, where pline() will use raw_print(), or player gave bad value when prompted by interactive 'O' command */ pline("%s%s%s", !iflags.window_inited ? "config_error_add: " : "", @@ -3575,7 +3575,7 @@ config_error_done(void) } config_error_data = tmp->next; free(tmp); - svp.program_state.config_error_ready = (config_error_data != 0); + program_state.config_error_ready = (config_error_data != 0); return n; } @@ -3978,14 +3978,14 @@ read_wizkit(void) if (!wizard || !(fp = fopen_wizkit_file())) return; - svp.program_state.wizkit_wishing = 1; + program_state.wizkit_wishing = 1; config_error_init(TRUE, "WIZKIT", FALSE); parse_conf_file(fp, proc_wizkit_line); (void) fclose(fp); config_error_done(); - svp.program_state.wizkit_wishing = 0; + program_state.wizkit_wishing = 0; return; } @@ -4195,8 +4195,8 @@ paniclog( #ifdef PANICLOG FILE *lfile; - if (!svp.program_state.in_paniclog) { - svp.program_state.in_paniclog = 1; + if (!program_state.in_paniclog) { + program_state.in_paniclog = 1; lfile = fopen_datafile(PANICLOG, "a", TROUBLEPREFIX); if (lfile) { #ifdef PANICLOG_FMT2 @@ -4216,7 +4216,7 @@ paniclog( #endif /* !PANICLOG_FMT2 */ (void) fclose(lfile); } - svp.program_state.in_paniclog = 0; + program_state.in_paniclog = 0; } #endif /* PANICLOG */ return; @@ -4323,9 +4323,9 @@ recover_savefile(void) /* * Set a flag for the savefile routines to know the * circumstances and act accordingly: - * svp.program_state.in_self_recover + * program_state.in_self_recover */ - svp.program_state.in_self_recover = TRUE; + program_state.in_self_recover = TRUE; set_savefile_name(TRUE); snhfp = create_savefile(); if (!snhfp) { @@ -4433,11 +4433,11 @@ recover_savefile(void) close_nhfile(gnhfp); close_nhfile(snhfp); close_nhfile(lnhfp); - svp.program_state.in_self_recover = FALSE; + program_state.in_self_recover = FALSE; delete_savefile(); return FALSE; } - /* we don't clear svp.program_state.in_self_recover here, we + /* we don't clear program_state.in_self_recover here, we leave it as a flag to reload the structlevel savefile in the caller. The caller should then clear it. */ return TRUE; diff --git a/src/insight.c b/src/insight.c index 163855db4..fbc9fcacb 100644 --- a/src/insight.c +++ b/src/insight.c @@ -2395,7 +2395,7 @@ record_achievement(schar achidx) /* avoid livelog for achievements recorded during final disclosure: nudist and blind-from-birth; also ascension which is suppressed by this gets logged separately in really_done() */ - if (svp.program_state.gameover) + if (program_state.gameover) return; if (absidx >= ACH_RNK1 && absidx <= ACH_RNK8) { @@ -2717,7 +2717,7 @@ dovanquished(void) #define UniqCritterIndx(mndx) \ ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC) -#define done_stopprint svp.program_state.stopprint +#define done_stopprint program_state.stopprint void list_vanquished(char defquery, boolean ask) @@ -2852,7 +2852,7 @@ list_vanquished(char defquery, boolean ask) * still in progress, so use present tense via pline(), or for dumplog * which needs putstr() and past tense. */ - } else if (!svp.program_state.gameover) { + } else if (!program_state.gameover) { /* #vanquished rather than final disclosure, so pline() is ok */ pline("No creatures have been vanquished."); #ifdef DUMPLOG @@ -2927,7 +2927,7 @@ list_genocided(char defquery, boolean ask) char buf[BUFSZ]; boolean genoing, /* prompting for genocide or class genocide */ dumping; /* for DUMPLOG; doesn't need to be conditional */ - boolean both = (svp.program_state.gameover || wizard || discover); + boolean both = (program_state.gameover || wizard || discover); dumping = (defquery == 'd'); genoing = (defquery == 'g'); @@ -3031,7 +3031,7 @@ list_genocided(char defquery, boolean ask) } /* See the comment for similar code near the end of list_vanquished(). */ - } else if (!svp.program_state.gameover) { + } else if (!program_state.gameover) { /* #genocided rather than final disclosure, so pline() is ok and extinction has been ignored */ pline("No creatures have been genocided%s.", genoing ? " yet" : ""); diff --git a/src/invent.c b/src/invent.c index bfac244f6..76df37740 100644 --- a/src/invent.c +++ b/src/invent.c @@ -355,7 +355,7 @@ loot_xname(struct obj *obj) if (wizard) { /* flags.debug */ /* paranoia: before toggling off wizard mode, guard against a panic in xname() producing a normal mode panic save file */ - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; flags.debug = FALSE; } @@ -363,7 +363,7 @@ loot_xname(struct obj *obj) if (save_debug) { flags.debug = TRUE; - svp.program_state.something_worth_saving = 1; + program_state.something_worth_saving = 1; } /* restore the object */ if (obj->oclass == POTION_CLASS) { @@ -2650,7 +2650,7 @@ update_inventory(void) { int save_suppress_price; - if (!svp.program_state.in_moveloop) /* not covered by suppress_map_output */ + if (!program_state.in_moveloop) /* not covered by suppress_map_output */ return; if (suppress_map_output()) /* despite name, used for perm_invent too */ return; @@ -6120,7 +6120,7 @@ sync_perminvent(void) WIN_INVEN = create_nhwindow(NHW_MENU); } - if (WIN_INVEN != WIN_ERR && svp.program_state.beyond_savefile_load) { + if (WIN_INVEN != WIN_ERR && program_state.beyond_savefile_load) { gi.in_sync_perminvent = 1; (void) display_inventory((char *) 0, FALSE); gi.in_sync_perminvent = 0; diff --git a/src/mkmaze.c b/src/mkmaze.c index adc2cd649..0b96a0c6c 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1755,7 +1755,7 @@ restore_waterlevel(NHFILE *nhfp) b->next = (struct bubble *) 0; } else { /* avoid "saving and reloading may fix this" */ - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; /* during restore, information about what level this is might not be available so we're wishy-washy about what we describe */ impossible("No %s to restore?", @@ -1764,7 +1764,7 @@ restore_waterlevel(NHFILE *nhfp) : (Is_airlevel(&u.uz) || Is_airlevel(&gu.uz_save)) ? "clouds" : "air bubbles or clouds"); - svp.program_state.something_worth_saving = 1; + program_state.something_worth_saving = 1; } } diff --git a/src/mon.c b/src/mon.c index 23c7ccde2..1fb32fd86 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1176,7 +1176,7 @@ movemon_singlemon(struct monst *mtmp) if (u.utotype #ifdef SAFERHANGUP /* or if the program has lost contact with the user */ - || svp.program_state.done_hup + || program_state.done_hup #endif ) { gs.somebody_can_move = FALSE; diff --git a/src/o_init.c b/src/o_init.c index 23c62cfd6..e066daf87 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -460,7 +460,7 @@ discover_object( exercise(A_WIS, TRUE); } /* !in_moveloop => initial inventory, gameover => final disclosure */ - if (svp.program_state.in_moveloop && !svp.program_state.gameover) { + if (program_state.in_moveloop && !program_state.gameover) { if (objects[oindx].oc_class == GEM_CLASS) gem_learned(oindx); /* could affect price of unpaid gems */ update_inventory(); diff --git a/src/objnam.c b/src/objnam.c index c9e4efd9b..6cc8a2aeb 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -325,7 +325,7 @@ obj_is_pname(struct obj *obj) { if (!obj->oartifact || !has_oname(obj)) return FALSE; - if (!svp.program_state.gameover && !iflags.override_ID) { + if (!program_state.gameover && !iflags.override_ID) { if (not_fully_identified(obj)) return FALSE; } @@ -371,7 +371,7 @@ distant_name( against a potential extra chance to browse the map with getpos() during final disclosure (not currently implemented, nor planned) */ save_oid = obj->o_id; - if (svp.program_state.gameover) + if (program_state.gameover) obj->o_id = 0; /* this maybe-nearby part used to be replicated in multiple callers */ @@ -955,7 +955,7 @@ xname_flags( "You were acid resistant because of your alchemy smock \ with text \"Kiss the cook\"." when disclosing attributes anyway */ - if (svp.program_state.gameover && obj->o_id && bufspaceleft > 0) { + if (program_state.gameover && obj->o_id && bufspaceleft > 0) { const char *lbl; char tmpbuf[BUFSZ]; @@ -1625,7 +1625,7 @@ doname_base( bill might not be available yet while restore is in progress (objects won't normally be formatted during that time, but if 'perm_invent' is enabled then they might be [not any more...]) */ - if (iflags.suppress_price || svp.program_state.restoring) { + if (iflags.suppress_price || program_state.restoring) { ; /* don't attempt to obtain any shop pricing, even if 'with_price' */ } else if (is_unpaid(obj)) { /* in inventory or in container in invent */ char pricebuf[40]; @@ -4894,7 +4894,7 @@ readobjnam(char *bp, struct obj *no_wish) * Disallow such topology tweaks for WIZKIT startup wishes. */ wiztrap: - if (wizard && !svp.program_state.wizkit_wishing && !d.oclass) { + if (wizard && !program_state.wizkit_wishing && !d.oclass) { /* [inline code moved to separate routine to unclutter readobjnam] */ if ((d.otmp = wizterrainwish(&d)) != 0) return d.otmp; @@ -4982,7 +4982,7 @@ readobjnam(char *bp, struct obj *no_wish) if (rn1cnt > 6 - d.gsize) rn1cnt = 6 - d.gsize; if (d.cnt > rn1cnt - && (!wizard || svp.program_state.wizkit_wishing + && (!wizard || program_state.wizkit_wishing || y_n("Override glob weight limit?") != 'y')) d.cnt = rn1cnt; d.otmp->owt *= (unsigned) d.cnt; diff --git a/src/options.c b/src/options.c index 73c87703d..e454aa31f 100644 --- a/src/options.c +++ b/src/options.c @@ -578,7 +578,7 @@ parseoptions( } /* allow optfn's to test whether they were called from parseoptions() */ - svp.program_state.in_parseoptions++; + program_state.in_parseoptions++; if (got_match && matchidx >= 0) { duplicate = duplicate_opt_detection(matchidx); @@ -604,8 +604,8 @@ parseoptions( } } - if (svp.program_state.in_parseoptions > 0) - svp.program_state.in_parseoptions--; + if (program_state.in_parseoptions > 0) + program_state.in_parseoptions--; #if 0 /* This specialization shouldn't be needed any longer because each of diff --git a/src/pager.c b/src/pager.c index 96dab253b..5c2b8de8d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -507,7 +507,7 @@ waterbody_name(coordxy x, coordxy y) { static char pooltype[40]; schar ltyp; - boolean hallucinate = Hallucination && !svp.program_state.gameover; + boolean hallucinate = Hallucination && !program_state.gameover; if (!isok(x, y)) return "drink"; /* should never happen */ @@ -1203,7 +1203,7 @@ do_screen_description( skipped_venom = 0, found = 0; /* count of matching syms found */ boolean hit_trap, need_to_look = FALSE, submerged = (Underwater && !Is_waterlevel(&u.uz)), - hallucinate = (Hallucination && !svp.program_state.gameover); + hallucinate = (Hallucination && !program_state.gameover); const char *x_str; nhsym tmpsym; glyph_info glyphinfo = nul_glyphinfo; diff --git a/src/pline.c b/src/pline.c index e837780dc..010dea488 100644 --- a/src/pline.c +++ b/src/pline.c @@ -157,10 +157,10 @@ vpline(const char *line, va_list the_args) if (!line || !*line) return; #ifdef HANGUPHANDLING - if (svp.program_state.done_hup) + if (program_state.done_hup) return; #endif - if (svp.program_state.wizkit_wishing) + if (program_state.wizkit_wishing) return; if (a11y.accessiblemsg && isok(a11y.msg_loc.x,a11y.msg_loc.y)) { @@ -542,7 +542,7 @@ raw_printf(const char *line, ...) va_start(the_args, line); vraw_printf(line, the_args); va_end(the_args); - if (!svp.program_state.beyond_savefile_load) + if (!program_state.beyond_savefile_load) ge.early_raw_messages++; } @@ -567,7 +567,7 @@ vraw_printf(const char *line, va_list the_args) #if defined(MSGHANDLER) execplinehandler(line); #endif - if (!svp.program_state.beyond_savefile_load) + if (!program_state.beyond_savefile_load) ge.early_raw_messages++; } @@ -579,10 +579,10 @@ impossible(const char *s, ...) char pbuf2[BUFSZ]; va_start(the_args, s); - if (svp.program_state.in_impossible) + if (program_state.in_impossible) panic("impossible called impossible"); - svp.program_state.in_impossible = 1; + program_state.in_impossible = 1; (void) vsnprintf(pbuf, sizeof pbuf, s, the_args); va_end(the_args); pbuf[BUFSZ - 1] = '\0'; /* sanity */ @@ -594,14 +594,14 @@ impossible(const char *s, ...) pline("%s", pbuf); gp.pline_flags = 0; - if (svp.program_state.in_sanity_check) { + if (program_state.in_sanity_check) { /* skip rest of multi-line feedback */ - svp.program_state.in_impossible = 0; + program_state.in_impossible = 0; return; } Strcpy(pbuf2, "Program in disorder!"); - if (svp.program_state.something_worth_saving) + if (program_state.something_worth_saving) Strcat(pbuf2, " (Saving and reloading may fix this problem.)"); pline("%s", pbuf2); pline("Please report these messages to %s.", DEVTEAM_EMAIL); @@ -621,7 +621,7 @@ impossible(const char *s, ...) } #endif - svp.program_state.in_impossible = 0; + program_state.in_impossible = 0; } RESTORE_WARNING_FORMAT_NONLITERAL diff --git a/src/polyself.c b/src/polyself.c index 2cc1807f0..a40570f83 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -109,7 +109,7 @@ set_uasmon(void) which won't be known during the restore process: but BFlying and BStealth should be set correctly already in that case, so there's nothing to do */ - if (!svp.program_state.restoring) + if (!program_state.restoring) float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */ polysense(); diff --git a/src/priest.c b/src/priest.c index d1ab0cdb1..57de18440 100644 --- a/src/priest.c +++ b/src/priest.c @@ -365,7 +365,7 @@ priestname( /* same as distant_monnam(), more or less... */ if (do_hallu || !high_priest || reveal_high_priest || !Is_astralevel(&u.uz) - || m_next2u(mon) || svp.program_state.gameover) { + || m_next2u(mon) || program_state.gameover) { Strcat(pname, " of "); Strcat(pname, halu_gname(mon_aligntyp(mon))); } diff --git a/src/questpgr.c b/src/questpgr.c index d7a2ec448..29ef494c8 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -456,7 +456,7 @@ staticfn boolean skip_pager(boolean common UNUSED) { /* WIZKIT: suppress plot feedback if starting with quest artifact */ - if (svp.program_state.wizkit_wishing) + if (program_state.wizkit_wishing) return TRUE; return FALSE; } diff --git a/src/restore.c b/src/restore.c index 31b57d2e3..fe02aff0c 100644 --- a/src/restore.c +++ b/src/restore.c @@ -721,7 +721,7 @@ restlevelfile(xint8 ltmp) nhfp = create_levelfile(ltmp, whynot); if (!nhfp) { /* failed to create a new file; don't attempt to make a panic save */ - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; panic("restlevelfile: %s", whynot); } bufon(nhfp->fd); @@ -738,7 +738,7 @@ dorecover(NHFILE *nhfp) int rtmp; /* suppress map display if some part of the code tries to update that */ - svp.program_state.restoring = REST_GSTATE; + program_state.restoring = REST_GSTATE; get_plname_from_file(nhfp, svp.plname); getlev(nhfp, 0, (xint8) 0); @@ -755,7 +755,7 @@ dorecover(NHFILE *nhfp) close_nhfile(nhfp); (void) delete_savefile(); u.usteed_mid = u.ustuck_mid = 0; - svp.program_state.restoring = 0; + program_state.restoring = 0; return 0; } /* after restgamestate() -> restnames() so that 'bases[]' is populated */ @@ -769,7 +769,7 @@ dorecover(NHFILE *nhfp) if (rtmp < 2) return rtmp; /* dorecover called recursively */ - svp.program_state.restoring = REST_LEVELS; + program_state.restoring = REST_LEVELS; /* these pointers won't be valid while we're processing the * other levels, but they'll be reset again by restlevelstate() @@ -831,12 +831,12 @@ dorecover(NHFILE *nhfp) get_plname_from_file(nhfp, svp.plname); /* not 0 nor REST_GSTATE nor REST_LEVELS */ - svp.program_state.restoring = REST_CURRENT_LEVEL; + program_state.restoring = REST_CURRENT_LEVEL; getlev(nhfp, 0, (xint8) 0); close_nhfile(nhfp); restlevelstate(); - svp.program_state.something_worth_saving = 1; /* useful data now exists */ + program_state.something_worth_saving = 1; /* useful data now exists */ if (!wizard && !discover) (void) delete_savefile(); @@ -866,9 +866,9 @@ dorecover(NHFILE *nhfp) gv.vision_full_recalc = 1; /* recompute vision (not saved) */ run_timers(); /* expire all timers that have gone off while away */ - svp.program_state.restoring = 0; /* affects bot() so clear before docrt() */ + program_state.restoring = 0; /* affects bot() so clear before docrt() */ - if (ge.early_raw_messages && !svp.program_state.beyond_savefile_load) { + if (ge.early_raw_messages && !program_state.beyond_savefile_load) { /* * We're about to obliterate some potentially important * startup messages, so give the player a chance to see them. @@ -877,7 +877,7 @@ dorecover(NHFILE *nhfp) wait_synch(); } u.usteed_mid = u.ustuck_mid = 0; - svp.program_state.beyond_savefile_load = 1; + program_state.beyond_savefile_load = 1; docrt(); clear_nhwindow(WIN_MESSAGE); @@ -907,7 +907,7 @@ rest_stairs(NHFILE *nhfp) if (nhfp->structlevel) { Mread(nhfp->fd, &stway, sizeof stway); } - if (svp.program_state.restoring != REST_GSTATE + if (program_state.restoring != REST_GSTATE && stway.tolev.dnum == u.uz.dnum) { /* stairway dlevel is relative, make it absolute */ stway.tolev.dlevel += u.uz.dlevel; @@ -1012,7 +1012,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) short tlev; #endif - svp.program_state.in_getlev = TRUE; + program_state.in_getlev = TRUE; if (ghostly) clear_id_mapping(); @@ -1096,7 +1096,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (nhfp->structlevel) Mread(nhfp->fd, trap, sizeof *trap); if (trap->tx != 0) { - if (svp.program_state.restoring != REST_GSTATE + if (program_state.restoring != REST_GSTATE && trap->dst.dnum == u.uz.dnum) { /* convert relative destination to absolute */ trap->dst.dlevel += u.uz.dlevel; @@ -1140,7 +1140,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) } /* regenerate monsters while on another level */ - if (!u.uz.dlevel || svp.program_state.restoring == REST_LEVELS) + if (!u.uz.dlevel || program_state.restoring == REST_LEVELS) continue; if (ghostly) { /* reset peaceful/malign relative to new character; @@ -1242,7 +1242,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly) clear_id_mapping(); - svp.program_state.in_getlev = FALSE; + program_state.in_getlev = FALSE; } void diff --git a/src/role.c b/src/role.c index 7707e34c7..cc490642f 100644 --- a/src/role.c +++ b/src/role.c @@ -2204,7 +2204,7 @@ genl_player_setup(int screenheight) char pick4u = 'n'; int result = 0; /* assume failure (player chooses to 'quit') */ - svp.program_state.in_role_selection++; /* affects tty menu cleanup */ + program_state.in_role_selection++; /* affects tty menu cleanup */ /* Used to avoid "Is this ok?" if player has already specified all * four facets of role. * Note that rigid_role_checks might force any unspecified facets to @@ -2704,7 +2704,7 @@ genl_player_setup(int screenheight) result = 1; setup_done: - svp.program_state.in_role_selection--; + program_state.in_role_selection--; return result; } diff --git a/src/rumors.c b/src/rumors.c index 540e6f214..11545fb6d 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -763,16 +763,16 @@ doconsult(struct monst *oracl) staticfn void couldnt_open_file(const char *filename) { - int save_something = svp.program_state.something_worth_saving; + int save_something = program_state.something_worth_saving; /* most likely the file is missing, so suppress impossible()'s "saving and restoring might fix this" (unless the fuzzer, which escalates impossible to panic, is running) */ if (!iflags.debug_fuzzer) - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; impossible("Can't open '%s' file.", filename); - svp.program_state.something_worth_saving = save_something; + program_state.something_worth_saving = save_something; } /* is 'word' a capitalized monster name that should be preceded by "the"? diff --git a/src/save.c b/src/save.c index 864f17ead..d46d18633 100644 --- a/src/save.c +++ b/src/save.c @@ -41,7 +41,7 @@ staticfn void zerocomp_bputc(int); #endif #if defined(HANGUPHANDLING) -#define HUP if (!svp.program_state.done_hup) +#define HUP if (!program_state.done_hup) #else #define HUP #endif @@ -59,7 +59,7 @@ dosave(void) clear_nhwindow(WIN_MESSAGE); pline("Saving..."); #if defined(HANGUPHANDLING) - svp.program_state.done_hup = 0; + program_state.done_hup = 0; #endif if (dosave0()) { u.uhp = -1; /* universal game's over indicator */ @@ -86,7 +86,7 @@ dosave0(void) NHFILE *nhfp, *onhfp; int res = 0; - svp.program_state.saving++; /* inhibit status and perm_invent updates */ + program_state.saving++; /* inhibit status and perm_invent updates */ /* we may get here via hangup signal, in which case we want to fix up a few of things before saving so that they won't be restored in an improper state; these will be no-ops for normal save sequence */ @@ -103,7 +103,7 @@ dosave0(void) when punished, make sure ball and chain are placed too */ done_object_cleanup(); /* maybe force some items onto map */ - if (!svp.program_state.something_worth_saving || !gs.SAVEF[0]) + if (!program_state.something_worth_saving || !gs.SAVEF[0]) goto done; fq_save = fqname(gs.SAVEF, SAVEPREFIX, 1); /* level files take 0 */ @@ -230,11 +230,11 @@ dosave0(void) delete_levelfile(0); nh_compress(fq_save); /* this should probably come sooner... */ - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; res = 1; done: - svp.program_state.saving--; + program_state.saving--; return res; } @@ -276,7 +276,7 @@ savegamestate(NHFILE *nhfp) { unsigned long uid; - svp.program_state.saving++; /* caller should/did already set this... */ + program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &uid, sizeof uid); @@ -338,7 +338,7 @@ savegamestate(NHFILE *nhfp) save_luadata(nhfp); if (nhfp->structlevel) bflush(nhfp->fd); - svp.program_state.saving--; + program_state.saving--; return; } @@ -364,7 +364,7 @@ savestateinlock(void) char whynot[BUFSZ]; NHFILE *nhfp; - svp.program_state.saving++; /* inhibit status and perm_invent updates */ + program_state.saving++; /* inhibit status and perm_invent updates */ /* When checkpointing is on, the full state needs to be written * on each checkpoint. When checkpointing is off, only the pid * needs to be in the level.0 file, so it does not need to be @@ -385,7 +385,7 @@ savestateinlock(void) */ nhfp = open_levelfile(0, whynot); if (tricked_fileremoved(nhfp, whynot)) { - svp.program_state.saving--; + program_state.saving--; return; } @@ -408,7 +408,7 @@ savestateinlock(void) than after so that screen updating behaves normally; game data shouldn't be inconsistent yet, unlike it would become midway through saving */ - svp.program_state.saving--; + program_state.saving--; done(TRICKED); return; } @@ -433,7 +433,7 @@ savestateinlock(void) } close_nhfile(nhfp); } - svp.program_state.saving--; + program_state.saving--; gh.havestate = flags.ins_chkpt; return; } @@ -450,7 +450,7 @@ savelev(NHFILE *nhfp, xint8 lev) but we'll be called during run-down */ if (set_uz_save && perform_bwrite(nhfp)) { if (u.uz.dnum == 0 && u.uz.dlevel == 0) { - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; panic("savelev: where are we?"); } gu.uz_save = u.uz; @@ -469,7 +469,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) short tlev; #endif - svp.program_state.saving++; /* even if current mode is FREEING */ + program_state.saving++; /* even if current mode is FREEING */ if (!nhfp) panic("Save on bad file!"); /* impossible */ @@ -564,7 +564,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) if (nhfp->structlevel) bflush(nhfp->fd); } - svp.program_state.saving--; + program_state.saving--; if (release_data(nhfp)) { clear_level_structures(); gf.ftrap = 0; @@ -717,7 +717,7 @@ save_stairs(NHFILE *nhfp) while (stway) { if (perform_bwrite(nhfp)) { - boolean use_relative = (svp.program_state.restoring != REST_GSTATE + boolean use_relative = (program_state.restoring != REST_GSTATE && stway->tolev.dnum == u.uz.dnum); if (use_relative) { /* make dlevel relative to current level */ @@ -988,7 +988,7 @@ savetrapchn(NHFILE *nhfp, struct trap *trap) struct trap *trap2; while (trap) { - boolean use_relative = (svp.program_state.restoring != REST_GSTATE + boolean use_relative = (program_state.restoring != REST_GSTATE && trap->dst.dnum == u.uz.dnum); trap2 = trap->ntrap; if (use_relative) diff --git a/src/sfstruct.c b/src/sfstruct.c index 4c19b6403..ae0b2c5fd 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -194,7 +194,7 @@ bwrite(int fd, const genericptr_t loc, unsigned num) } if (failed) { #if defined(HANGUPHANDLING) - if (svp.program_state.done_hup) + if (program_state.done_hup) nh_terminate(EXIT_FAILURE); else #endif @@ -230,7 +230,7 @@ mread(int fd, genericptr_t buf, unsigned len) } else { pline("Read %d instead of %u bytes.", (int) rlen, len); display_nhwindow(WIN_MESSAGE, TRUE); /* flush before error() */ - if (svp.program_state.restoring) { + if (program_state.restoring) { (void) nhclose(fd); (void) delete_savefile(); error("Error restoring old game."); diff --git a/src/shk.c b/src/shk.c index aa2abdb8a..b91a3bc8b 100644 --- a/src/shk.c +++ b/src/shk.c @@ -4908,7 +4908,7 @@ after_shk_move(struct monst *shkp) /* reset bill_p, need to re-calc player's occupancy too */ eshkp->bill_p = &eshkp->bill[0]; /* only re-check occupancy if game hasn't just ended */ - if (!svp.program_state.gameover) + if (!program_state.gameover) check_special_room(FALSE); } } diff --git a/src/shknam.c b/src/shknam.c index 994e6238d..7bd9f4e21 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -865,7 +865,7 @@ shkname(struct monst *mtmp) } else { const char *shknm = ESHK(mtmp)->shknam; - if (Hallucination && !svp.program_state.gameover) { + if (Hallucination && !program_state.gameover) { const char *const *nlp; int num; diff --git a/src/topten.c b/src/topten.c index 7bd993ca0..4742b9b02 100644 --- a/src/topten.c +++ b/src/topten.c @@ -24,7 +24,7 @@ static long final_fpos; /* [note: do not move this to the 'g' struct] */ #endif -#define done_stopprint svp.program_state.stopprint +#define done_stopprint program_state.stopprint #define newttentry() (struct toptenentry *) alloc(sizeof (struct toptenentry)) #define dealloc_ttentry(ttent) free((genericptr_t) (ttent)) @@ -642,7 +642,7 @@ topten(int how, time_t when) * topten uses alloc() several times, which will lead to * problems if the panic was the result of an alloc() failure. */ - if (svp.program_state.panicking) + if (program_state.panicking) return; if (iflags.toptenwin) { @@ -650,7 +650,7 @@ topten(int how, time_t when) } #if defined(HANGUPHANDLING) -#define HUP if (!svp.program_state.done_hup) +#define HUP if (!program_state.done_hup) #else #define HUP #endif diff --git a/src/vault.c b/src/vault.c index a30a3406d..eca749697 100644 --- a/src/vault.c +++ b/src/vault.c @@ -49,7 +49,7 @@ clear_fcorr(struct monst *grd, boolean forceshow) coordxy fcx, fcy, fcbeg; struct monst *mtmp; boolean sawcorridor = FALSE, - silently = svp.program_state.stopprint ? TRUE : FALSE; + silently = program_state.stopprint ? TRUE : FALSE; struct egd *egrd = EGD(grd); struct trap *trap; struct rm *lev; diff --git a/src/vision.c b/src/vision.c index ff80a29bf..34759bcad 100644 --- a/src/vision.c +++ b/src/vision.c @@ -521,7 +521,7 @@ vision_recalc(int control) int oldseenv; /* previous seenv value */ gv.vision_full_recalc = 0; /* reset flag */ - if (gi.in_mklev || svp.program_state.in_getlev || !iflags.vision_inited) + if (gi.in_mklev || program_state.in_getlev || !iflags.vision_inited) return; /* @@ -825,9 +825,9 @@ vision_recalc(int control) /* This newsym() caused a crash delivering msg about failure to open * dungeon file init_dungeons() -> panic() -> done(11) -> * vision_recalc(2) -> newsym() -> crash! u.ux and u.uy are 0 and - * svp.program_state.panicking == 1 under those circumstances + * program_state.panicking == 1 under those circumstances */ - if (!svp.program_state.panicking) + if (!program_state.panicking) newsym(u.ux, u.uy); /* Make sure the hero shows up! */ /* Set the new min and max pointers. */ diff --git a/src/windows.c b/src/windows.c index 8d4c7e6ff..967b8db8d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1814,7 +1814,7 @@ add_menu_heading(winid tmpwin, const char *buf) color = iflags.menu_headings.color; /* suppress highlighting during end-of-game disclosure */ - if (svp.program_state.gameover) + if (program_state.gameover) attr = ATR_NONE, color = NO_COLOR; add_menu(tmpwin, &nul_glyphinfo, &any, '\0', '\0', attr, color, @@ -1862,10 +1862,10 @@ getlin(const char *query, char *bufp) { boolean old_bot_disabled = gb.bot_disabled; - svp.program_state.in_getlin = 1; + program_state.in_getlin = 1; gb.bot_disabled = TRUE; (*windowprocs.win_getlin)(query, bufp); gb.bot_disabled = old_bot_disabled; - svp.program_state.in_getlin = 0; + program_state.in_getlin = 0; } /*windows.c*/ diff --git a/src/wizcmds.c b/src/wizcmds.c index abab4313a..197a08bee 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1435,7 +1435,7 @@ sanity_check(void) iflags.sanity_no_check = FALSE; return; } - svp.program_state.in_sanity_check++; + program_state.in_sanity_check++; you_sanity_check(); obj_sanity_check(); timer_sanity_check(); @@ -1444,7 +1444,7 @@ sanity_check(void) bc_sanity_check(); trap_sanity_check(); engraving_sanity_check(); - svp.program_state.in_sanity_check--; + program_state.in_sanity_check--; } /* qsort() comparison routine for use in list_migrating_mons() */ diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 48a6c17f6..06f8c93d0 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -193,7 +193,7 @@ nhmain(int argc, char *argv[]) * It seems you really want to play. */ u.uhp = 1; /* prevent RIP on early quits */ - svp.program_state.preserve_locks = 1; + program_state.preserve_locks = 1; #ifndef NO_SIGNAL sethanguphandler((SIG_RET_TYPE) hangup); #endif @@ -272,7 +272,7 @@ nhmain(int argc, char *argv[]) */ if (*svp.plname) { getlock(); - svp.program_state.preserve_locks = 0; /* after getlock() */ + program_state.preserve_locks = 0; /* after getlock() */ } if (*svp.plname && (nhfp = restore_saved_game()) != 0) { diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index db7f05bf3..08d92b7a3 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -794,7 +794,7 @@ vesa_cliparound(int x, int y) clipymax = ROWNO - 1; } if (clipx != oldx || clipy != oldy) { - if (on_level(&u.uz0, &u.uz) && !svp.program_state.restoring) + if (on_level(&u.uz0, &u.uz) && !program_state.restoring) /* (void) doredraw(); */ vesa_redrawmap(); } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 035343cad..f2473cfc5 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -472,7 +472,7 @@ vga_cliparound(int x, int y UNUSED) clipx = clipxmax - (viewport_size - 1); } if (clipx != oldx) { - if (on_level(&u.uz0, &u.uz) && !svp.program_state.restoring) + if (on_level(&u.uz0, &u.uz) && !program_state.restoring) /* (void) doredraw(); */ vga_redrawmap(1); } diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index d81748e80..679f5e627 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -164,7 +164,7 @@ main(int argc, char *argv[]) */ u.uhp = 1; /* prevent RIP on early quits */ #if defined(HANGUPHANDLING) - svp.program_state.preserve_locks = 1; + program_state.preserve_locks = 1; #ifndef NO_SIGNAL sethanguphandler((SIG_RET_TYPE) hangup); #endif @@ -239,7 +239,7 @@ main(int argc, char *argv[]) if (*svp.plname) { getlock(); #if defined(HANGUPHANDLING) - svp.program_state.preserve_locks = 0; /* after getlock() */ + program_state.preserve_locks = 0; /* after getlock() */ #endif } @@ -276,8 +276,8 @@ main(int argc, char *argv[]) } } } - if (svp.program_state.in_self_recover) { - svp.program_state.in_self_recover = FALSE; + if (program_state.in_self_recover) { + program_state.in_self_recover = FALSE; } } diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 725c790c3..8450da5f8 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -82,7 +82,7 @@ eraseoldlocks(void) int i; #if defined(HANGUPHANDLING) - svp.program_state.preserve_locks = 0; /* not required but shows intent */ + program_state.preserve_locks = 0; /* not required but shows intent */ /* cannot use maxledgerno() here, because we need to find a lock name * before starting everything (including the dungeon initialization * that sets astral_level, needed for maxledgerno()) up @@ -216,7 +216,7 @@ getlock(void) } #ifdef SELF_RECOVER if (c == 'r' || c == 'R') { - if (recover_savefile() && svp.program_state.in_self_recover) { + if (recover_savefile() && program_state.in_self_recover) { set_levelfile_name(gl.lock, 0); fq_lock = fqname(gl.lock, LEVELPREFIX, 0); goto gotlock; diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index 0c5045ab9..dcb681caa 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -412,7 +412,7 @@ byebye(void) (void) sys$delprc(&mail_pid, (genericptr_t) 0), mail_pid = 0; #endif #ifdef FREE_ALL_MEMORY - if (progname && !svp.program_state.panicking) { + if (progname && !program_state.panicking) { if (gh.hname == progname) gh.hname = (char *) 0; free((genericptr_t) progname), progname = (char *) 0; @@ -421,7 +421,7 @@ byebye(void) /* SIGHUP doesn't seem to do anything on VMS, so we fudge it here... */ hup = (void (*)(int)) signal(SIGHUP, SIG_IGN); - if (!svp.program_state.exiting++ + if (!program_state.exiting++ && hup != (void (*)(int)) SIG_DFL && hup != (void (*)(int)) SIG_IGN) { (*hup)(SIGHUP); @@ -446,7 +446,7 @@ genericptr_t mechargs) /* [0] is argc, [1..argc] are the real args */ if (condition == SS$_ACCVIO /* access violation */ || (condition >= SS$_ASTFLT && condition <= SS$_TBIT) || (condition >= SS$_ARTRES && condition <= SS$_INHCHME)) { - svp.program_state.done_hup = TRUE; /* pretend hangup has been attempted */ + program_state.done_hup = TRUE; /* pretend hangup has been attempted */ #if (NH_DEVEL_STATUS == NH_STATUS_RELEASED) if (wizard) #endif diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 5ff2f8ce4..9bd26a9a5 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -158,7 +158,7 @@ vms_getchar(void) static volatile int recurse = 0; /* SMG is not AST re-entrant! */ #endif - if (svp.program_state.done_hup) { + if (program_state.done_hup) { /* hangup has occurred; do not attempt to get further user input */ return ESC; } diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index c38a4b36a..770c0f19b 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -936,7 +936,7 @@ void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y) while (dst != sentinel) *dst++ = *fill; - if ((iflags.debug.immediateflips || !svp.program_state.in_moveloop) + if ((iflags.debug.immediateflips || !program_state.in_moveloop) && buffer == console.back_buffer) back_buffer_flip(); } @@ -952,7 +952,7 @@ static void buffer_clear_to_end_of_line(cell_t * buffer, int x, int y) while (dst != sentinel) *dst++ = clear_cell; - if (iflags.debug.immediateflips || !svp.program_state.in_moveloop) + if (iflags.debug.immediateflips || !program_state.in_moveloop) back_buffer_flip(); } @@ -964,7 +964,7 @@ void buffer_write(cell_t * buffer, cell_t * cell, COORD pos) cell_t * dst = buffer + (console.width * pos.Y) + pos.X; *dst = *cell; - if ((iflags.debug.immediateflips || !svp.program_state.in_moveloop) + if ((iflags.debug.immediateflips || !program_state.in_moveloop) && buffer == console.back_buffer) back_buffer_flip(); } @@ -1149,7 +1149,7 @@ tgetch(void) numpad |= 0x10; #endif - return (svp.program_state.done_hup) + return (program_state.done_hup) ? '\033' : keyboard_handling.pCheckInput( console.hConIn, &ir, &count, numpad, 0, &mod, &cc); @@ -1177,7 +1177,7 @@ console_poskey(coordxy *x, coordxy *y, int *mod) if (gc.Cmd.swap_yz) numpad |= 0x10; #endif - ch = (svp.program_state.done_hup) + ch = (program_state.done_hup) ? '\033' : keyboard_handling.pCheckInput( console.hConIn, &ir, &count, numpad, 1, mod, &cc); diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 7f3868560..efa09ebb9 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -771,8 +771,8 @@ attempt_restore: } } } - if (svp.program_state.in_self_recover) { - svp.program_state.in_self_recover = FALSE; + if (program_state.in_self_recover) { + program_state.in_self_recover = FALSE; set_savefile_name(TRUE); } } diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 6cfd17e58..d0128cc62 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -498,7 +498,7 @@ void NetHackQtBind::qt_update_inventory(int arg UNUSED) main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet - if (svp.program_state.something_worth_saving && iflags.perm_invent) + if (program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, false); */ } @@ -667,7 +667,7 @@ char NetHackQtBind::qt_more() // ^C comment in that routine] when the core triggers --More-- via // done2() -> really_done() -> display_nhwindow(WIN_MESSAGE, TRUE) // (get rid of this if the exec() loop issue gets properly fixed) - if (::svp.program_state.gameover) + if (::program_state.gameover) return ch; // bypass --More-- and just continue with program exit NetHackQtMessageWindow *mesgwin = main ? main->GetMessageWindow() : NULL; diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index eb22d36d7..73bade00f 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1015,7 +1015,7 @@ bool NetHackQtMainWindow::ok_for_command() * FIXME: it would be much better to gray-out inapplicable entries * when popping up a command menu instead of needing this. */ - if (::svp.program_state.input_state != commandInp) { + if (::program_state.input_state != commandInp) { NetHackQtBind::qt_nhbell(); // possibly call doKeys("\033"); here? return false; @@ -1059,7 +1059,7 @@ void NetHackQtMainWindow::doQuit(bool) // in case someone wants to change that #ifdef MACOS QString info = nh_qsprintf("This will end your NetHack session.%s", - !svp.program_state.something_worth_saving ? "" + !program_state.something_worth_saving ? "" : "\n(Cancel quitting and use the Save command" "\nto save your current game.)"); /* this is similar to closeEvent but the details are different; @@ -1077,7 +1077,7 @@ void NetHackQtMainWindow::doQuit(bool) break; // return to game case 1: // quit -- bypass the prompting preformed by done2() - svp.program_state.stopprint++; + program_state.stopprint++; ::done(QUIT); /*NOTREACHED*/ break; @@ -1406,7 +1406,7 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) { int ok = 0; - if ( svp.program_state.something_worth_saving ) { + if ( program_state.something_worth_saving ) { /* this used to offer "Save" and "Cancel" but cancel (ignoring the close attempt) won't work if user has clicked on the window's Close button */ @@ -1421,7 +1421,7 @@ void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) case 1: // quit -- bypass the prompting preformed by done2() ok = 1; - svp.program_state.stopprint++; + program_state.stopprint++; ::done(QUIT); /*NOTREACHED*/ break; diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index a23d9e616..57e2f212f 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -220,7 +220,7 @@ char NetHackQtYnDialog::Exec() // for "ynaq" (where "all" is a choice) it's "stop" // and for end of game disclosure it really is "quit" if (question.left(10) == QString("Dump core?") - || (::svp.program_state.gameover + || (::program_state.gameover && question.left(11) == QString("Do you want"))) button_name = "Quit"; else if (is_ynaq) diff --git a/win/X11/winX.c b/win/X11/winX.c index b70bee5ea..f808541d5 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1282,7 +1282,7 @@ X11_update_inventory(int arg) if (iflags.perm_invent) { /* skip any calls to update_inventory() before in_moveloop starts */ - if (svp.program_state.in_moveloop || svp.program_state.gameover) { + if (program_state.in_moveloop || program_state.gameover) { updated_inventory = 1; /* hack to avoid mapping&raising window */ if (!arg) { (void) display_inventory((char *) 0, FALSE); @@ -1798,7 +1798,7 @@ X11_hangup(Widget w, XEvent *event, String *params, Cardinal *num_params) static void X11_bail(const char *mesg) { - svp.program_state.something_worth_saving = 0; + program_state.something_worth_saving = 0; clearlocks(); X11_exit_nhwindows(mesg); nh_terminate(EXIT_SUCCESS); @@ -2041,7 +2041,7 @@ X11_getlin( /* we get here after the popup has exited; put prompt and response into the message window (and into core's dumplog history) unless play hasn't started yet */ - if (svp.program_state.in_moveloop || svp.program_state.gameover) { + if (program_state.in_moveloop || program_state.gameover) { /* single space has meaning (to remove a previously applied name) so show it clearly; don't care about legibility of multiple spaces */ const char *visanswer = !input[0] ? "" diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 62e1f44a3..d27f0ac88 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1988,7 +1988,7 @@ x_event(int exit_condition) /* pkey(retval); */ keep_going = FALSE; #if defined(HANGUPHANDLING) - } else if (svp.program_state.done_hup) { + } else if (program_state.done_hup) { retval = '\033'; inptr = (inptr + 1) % INBUF_SIZE; keep_going = FALSE; @@ -2009,7 +2009,7 @@ x_event(int exit_condition) } keep_going = FALSE; #if defined(HANGUPHANDLING) - } else if (svp.program_state.done_hup) { + } else if (program_state.done_hup) { retval = '\033'; inptr = (inptr + 1) % INBUF_SIZE; keep_going = FALSE; diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index a6a421e57..1fcdf471c 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1222,7 +1222,7 @@ X11_player_selection_dialog(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || svp.program_state.done_hup + || program_state.done_hup #endif ) { clearlocks(); @@ -1300,7 +1300,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || svp.program_state.done_hup + || program_state.done_hup #endif ) { clearlocks(); @@ -1373,7 +1373,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || svp.program_state.done_hup + || program_state.done_hup #endif ) { clearlocks(); @@ -1445,7 +1445,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || svp.program_state.done_hup + || program_state.done_hup #endif ) { clearlocks(); @@ -1515,7 +1515,7 @@ X11_player_selection_prompts(void) if (ps_selected == PS_QUIT #if defined(HANGUPHANDLING) - || svp.program_state.done_hup + || program_state.done_hup #endif ) { clearlocks(); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index c1c9c1534..8e6949d7b 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -789,7 +789,7 @@ curses_display_nhmenu( menu_determine_pages(current_menu); /* Display pre and post-game menus centered */ - if ((svm.moves <= 1 && !gi.invent) || svp.program_state.gameover) { + if ((svm.moves <= 1 && !gi.invent) || program_state.gameover) { win = curses_create_window(wid, current_menu->width, current_menu->height, CENTER); } else { /* Display during-game menus on the right out of the way */ @@ -1033,7 +1033,7 @@ menu_win_size(nhmenu *menu) int maxheaderwidth = menu->prompt ? (int) strlen(menu->prompt) : 0; nhmenu_item *menu_item_ptr, *last_item_ptr = NULL; - if (svp.program_state.gameover) { + if (program_state.gameover) { /* for final inventory disclosure, use full width */ maxwidth = term_cols - 2; /* +2: borders assumed */ } else { diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 2fd1947ec..5dee9900b 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -782,7 +782,7 @@ curses_update_inventory(int arg) } /* skip inventory updating during character initialization */ - if (!svp.program_state.in_moveloop && !svp.program_state.gameover) + if (!program_state.in_moveloop && !program_state.gameover) return; if (!arg) { diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 886233e94..73a939f2a 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -776,7 +776,7 @@ Currently this is limited to arrow keys, but this may be expanded. */ int curses_convert_keys(int key) { - boolean reject = (svp.program_state.input_state == otherInp), + boolean reject = (program_state.input_state == otherInp), as_is = FALSE, numpad_esc = FALSE; int ret = key; diff --git a/win/tty/getline.c b/win/tty/getline.c index 8a648c27d..1a8215c06 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -232,7 +232,7 @@ xwaitforspace(const char *s) /* chars allowed besides return */ morc = 0; while ( #ifdef HANGUPHANDLING - !svp.program_state.done_hup && + !program_state.done_hup && #endif (c = tty_nhgetch()) != EOF) { if (c == '\n' || c == '\r') diff --git a/win/tty/topl.c b/win/tty/topl.c index 89de9e6a6..c20dfa288 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -184,7 +184,7 @@ remember_topl(void) cw->datlen[idx] = (short) len; } Strcpy(cw->data[idx], gt.toplines); - if (!svp.program_state.in_checkpoint) { + if (!program_state.in_checkpoint) { *gt.toplines = '\0'; cw->maxcol = cw->maxrow = (idx + 1) % cw->rows; } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 5ca2d5c45..17dcd1cc2 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -84,7 +84,7 @@ extern void msmsg(const char *, ...); */ #define HUPSKIP() \ do { \ - if (svp.program_state.done_hup) { \ + if (program_state.done_hup) { \ morc = '\033'; \ return; \ } \ @@ -92,7 +92,7 @@ extern void msmsg(const char *, ...); /* morc=ESC - in case we bypass xwaitforspace() which sets that */ #define HUPSKIP_RESULT(RES) \ do { \ - if (svp.program_state.done_hup) \ + if (program_state.done_hup) \ return (RES); \ } while (0) #else /* !HANGUPHANDLING */ @@ -376,11 +376,11 @@ winch_handler(int sig_unused UNUSED) } #endif - svp.program_state.resize_pending++; /* resize_tty() will reset it */ + program_state.resize_pending++; /* resize_tty() will reset it */ /* if nethack is waiting for input, which is the most likely scenario, we will go ahead and respond to the resize immediately; otherwise, tty_nhgetch() will do so the next time it's called */ - if (svp.program_state.getting_char) { + if (program_state.getting_char) { resize_tty(); #if 0 /* [this doesn't work as intended and seems to be unnecessary] */ if (resize_mesg) { @@ -402,7 +402,7 @@ resize_tty(void) struct WinDesc *cw; /* reset to 0 rather than just decrement */ - svp.program_state.resize_pending = 0; + program_state.resize_pending = 0; resize_mesg = 0; getwindowsz(); /* update LI and CO */ @@ -1978,7 +1978,7 @@ tty_dismiss_nhwindow(winid window) can't refresh--force the screen to be cleared instead (affects dismissal of 'reset role filtering' menu if screen height forces that to need a second page) */ - if (svp.program_state.in_role_selection) + if (program_state.in_role_selection) clearscreen = TRUE; erase_menu_or_text(window, cw, clearscreen); @@ -3041,7 +3041,7 @@ ttyinv_add_menu( : !show_gold ? 26 : 27); - if (!svp.program_state.in_moveloop) + if (!program_state.in_moveloop) return; slot = selector_to_slot(ch, ttyinvmode, &ignore); if (inuse_only && slot > 2 * rows_per_side) @@ -3216,7 +3216,7 @@ ttyinv_end_menu(int window, struct WinDesc *cw) { if (iflags.perm_invent || gp.perm_invent_toggling_direction == toggling_on) { - if (svp.program_state.in_moveloop) { + if (program_state.in_moveloop) { boolean inuse_only = ((ttyinvmode & InvInUse) != 0); int rows_per_side = inuse_only ? cw->maxrow - 2 : 0; int old_slots_used = ttyinv_slots_used; /* value before render */ @@ -3245,7 +3245,7 @@ ttyinv_render(winid window, struct WinDesc *cw) uint32 current_row_color = NO_COLOR; struct tty_perminvent_cell *cell; char invbuf[BUFSZ]; - boolean force_redraw = svp.program_state.in_docrt ? TRUE : FALSE, + boolean force_redraw = program_state.in_docrt ? TRUE : FALSE, inuse_only = (ttyinvmode & InvInUse) != 0, show_gold = (ttyinvmode & InvShowGold) != 0 && !inuse_only, sparse = (ttyinvmode & InvSparse) != 0 && !inuse_only; @@ -3603,7 +3603,7 @@ tty_wait_synch(void) if (ttyDisplay->inmore) { addtopl("--More--"); (void) fflush(stdout); - } else if (ttyDisplay->inread > svp.program_state.gameover) { + } else if (ttyDisplay->inread > program_state.gameover) { /* this can only happen if we were reading and got interrupted */ ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; /* do this twice; 1st time gets the Quit? message again */ @@ -4036,19 +4036,19 @@ tty_nhgetch(void) i = randomkey(); } else { #ifdef RESIZABLE - if (svp.program_state.resize_pending) + if (program_state.resize_pending) resize_tty(); #endif - svp.program_state.getting_char++; + program_state.getting_char++; #ifdef UNIX - i = (svp.program_state.getting_char == 1) + i = (program_state.getting_char == 1) ? tgetch() : ((read(fileno(stdin), (genericptr_t) &nestbuf, 1) == 1) ? (int) nestbuf : EOF); #else i = tgetch(); #endif - svp.program_state.getting_char--; + program_state.getting_char--; #ifdef RESIZABLE if (resize_mesg) { resize_mesg = 0; diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index c96aa168d..9ad6c32f0 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -39,7 +39,7 @@ mswin_have_input(void) return #ifdef SAFERHANGUP /* we always have input (ESC) if hangup was requested */ - svp.program_state.done_hup || + program_state.done_hup || #endif (nhi_read_pos != nhi_write_pos); } @@ -69,7 +69,7 @@ mswin_input_pop(void) #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (svp.program_state.done_hup) { + if (program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.ei.kbd.ch = '\033'; @@ -98,7 +98,7 @@ mswin_input_peek(void) #ifdef SAFERHANGUP /* always return ESC when hangup was requested */ - if (svp.program_state.done_hup) { + if (program_state.done_hup) { static MSNHEvent hangup_event; hangup_event.type = NHEVENT_CHAR; hangup_event.ei.kbd.ch = '\033'; diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index 1bfa7fdb6..bd1a5be79 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -457,16 +457,16 @@ MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: { /* exit gracefully */ - if (svp.program_state.gameover) { + if (program_state.gameover) { /* assume the user really meant this, as the game is already * over... */ /* to make sure we still save bones, just set stop printing flag */ - svp.program_state.stopprint++; + program_state.stopprint++; NHEVENT_KBD( '\033'); /* and send keyboard input as if user pressed ESC */ /* additional code for this is done in menu and rip windows */ - } else if (!svp.program_state.something_worth_saving) { + } else if (!program_state.something_worth_saving) { /* User exited before the game started, e.g. during splash display */ /* Just get out. */ @@ -842,7 +842,7 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case IDM_SAVE: if (iflags.debug_fuzzer) break; - if (!svp.program_state.gameover && !svp.program_state.done_hup) + if (!program_state.gameover && !program_state.done_hup) dosave(); else MessageBeep(0); diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index a65bf9823..89d90e2ab 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -351,10 +351,10 @@ MenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; case WM_CLOSE: - if (svp.program_state.gameover) { + if (program_state.gameover) { data->result = -1; data->done = 1; - svp.program_state.stopprint++; + program_state.stopprint++; return TRUE; } else return FALSE; diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 0f951ece5..3fb9ac9ba 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -227,7 +227,7 @@ NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) GetNHApp()->hMainWnd = NULL; DestroyWindow(hWnd); SetFocus(GetNHApp()->hMainWnd); - svp.program_state.stopprint++; + program_state.stopprint++; return TRUE; case WM_DESTROY: diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 9cdb7c2ec..40bfeb7ba 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1251,7 +1251,7 @@ void mswin_update_inventory(int arg) { logDebug("mswin_update_inventory(%d)\n", arg); - if (iflags.perm_invent && svp.program_state.something_worth_saving + if (iflags.perm_invent && program_state.something_worth_saving && iflags.window_inited && WIN_INVEN != WIN_ERR) display_inventory(NULL, FALSE); } @@ -2862,7 +2862,7 @@ int NHMessageBox(HWND hWnd, LPCTSTR text, UINT type) { TCHAR title[MAX_LOADSTRING]; - if (svp.program_state.exiting && !strcmp(text, "\n")) + if (program_state.exiting && !strcmp(text, "\n")) text = "Press Enter to exit"; LoadString(GetNHApp()->hApp, IDS_APP_TITLE_SHORT, title, MAX_LOADSTRING); From 82e6eacfbb622fbf3ebc2a66398364bedd5f7ac3 Mon Sep 17 00:00:00 2001 From: SHIRAKATA Kentaro Date: Fri, 8 Dec 2023 01:38:23 +0900 Subject: [PATCH 033/121] split returning from throwit() into separate function --- src/dothrow.c | 60 +++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/dothrow.c b/src/dothrow.c index 5b4b24e92..fb2ab2cdf 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -15,6 +15,7 @@ staticfn struct obj *find_launcher(struct obj *); staticfn int gem_accept(struct monst *, struct obj *); staticfn boolean toss_up(struct obj *, boolean) NONNULLARG1; staticfn void sho_obj_return_to_u(struct obj * obj); +staticfn void throwit_return(boolean); staticfn struct obj *return_throw_to_inv(struct obj *, long, boolean, struct obj *); staticfn void tmiss(struct obj *, struct monst *, boolean); @@ -1450,6 +1451,14 @@ sho_obj_return_to_u(struct obj *obj) } } +staticfn void +throwit_return(boolean clear_thrownobj) +{ + iflags.returning_missile = (genericptr_t) 0; + if (clear_thrownobj) + gt.thrownobj = (struct obj *) 0; +} + /* throw an object, NB: obj may be consumed in the process */ void throwit(struct obj *obj, @@ -1460,7 +1469,7 @@ throwit(struct obj *obj, { struct monst *mon; int range, urange; - boolean crossbowing, clear_thrownobj = FALSE, + boolean crossbowing, impaired = (Confusion || Stunned || Blind || Hallucination || Fumbling), tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0); @@ -1538,8 +1547,8 @@ throwit(struct obj *obj, } else { hitfloor(obj, TRUE); } - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } else if (obj->otyp == BOOMERANG && !Underwater) { if (Is_airlevel(&u.uz) || Levitation) @@ -1549,8 +1558,8 @@ throwit(struct obj *obj, if (mon == &gy.youmonst) { /* the thing was caught */ exercise(A_DEX, TRUE); obj = return_throw_to_inv(obj, wep_mask, twoweap, oldslot); - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } } else { /* crossbow range is independent of strength */ @@ -1625,7 +1634,8 @@ throwit(struct obj *obj, we're about to return */ if (tethered_weapon) tmp_at(DISP_END, 0); - goto throwit_return; + throwit_return(FALSE); + return; } } @@ -1633,8 +1643,8 @@ throwit(struct obj *obj, boolean obj_gone; if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) { - clear_thrownobj = TRUE; - goto throwit_return; /* alert shk caught it */ + throwit_return(TRUE); /* alert shk caught it */ + return; } (void) snuff_candle(obj); gn.notonhead = (gb.bhitpos.x != mon->mx || gb.bhitpos.y != mon->my); @@ -1658,11 +1668,12 @@ throwit(struct obj *obj, tmp_at(DISP_END, 0); } else if (u.uswallow && !iflags.returning_missile) { swallowit: - if (obj != uball) + if (obj != uball) { (void) mpickobj(u.ustuck, obj); /* clears 'gt.thrownobj' */ - else - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(FALSE); + } else + throwit_return(TRUE); + return; } else { /* Mjollnir must be wielded to be thrown--caller verifies this; aklys must be wielded as primary to return when thrown */ @@ -1712,8 +1723,8 @@ throwit(struct obj *obj, if (!ship_object(obj, u.ux, u.uy, FALSE)) dropy(obj); } - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } else { if (tethered_weapon) tmp_at(DISP_END, 0); @@ -1742,8 +1753,8 @@ throwit(struct obj *obj, tmp_at(DISP_END, 0); breakmsg(obj, cansee(gb.bhitpos.x, gb.bhitpos.y)); if (breakobj(obj, gb.bhitpos.x, gb.bhitpos.y, TRUE, TRUE)) { - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } } if (!Deaf && !Underwater) { @@ -1755,8 +1766,8 @@ throwit(struct obj *obj, } } if (flooreffects(obj, gb.bhitpos.x, gb.bhitpos.y, "fall")) { - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } obj_no_longer_held(obj); if (mon && mon->isshk && is_pick(obj)) { @@ -1765,13 +1776,13 @@ throwit(struct obj *obj, if (*u.ushops || obj->unpaid) check_shop_obj(obj, gb.bhitpos.x, gb.bhitpos.y, FALSE); (void) mpickobj(mon, obj); /* may merge and free obj */ - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } (void) snuff_candle(obj); if (!mon && ship_object(obj, gb.bhitpos.x, gb.bhitpos.y, FALSE)) { - clear_thrownobj = TRUE; - goto throwit_return; + throwit_return(TRUE); + return; } gt.thrownobj = (struct obj *) 0; place_object(obj, gb.bhitpos.x, gb.bhitpos.y); @@ -1797,10 +1808,7 @@ throwit(struct obj *obj, gv.vision_full_recalc = 1; } - throwit_return: - iflags.returning_missile = (genericptr_t) 0; - if (clear_thrownobj) - gt.thrownobj = (struct obj *) 0; + throwit_return(FALSE); return; } From 1dc9f7324a28ee83c5196549ed4737673f7f31a0 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 14 Jul 2024 11:24:49 -0700 Subject: [PATCH 034/121] fix #K4201 - bhitpos is clobbered by lookat() The look-at-screen code was setting bhitpos before calling look_at_monster() but that hasn't been needed for around 25 years. Fix is trivial. However, having such a low level routine as show_glyph() call do_screen_description() seems like a recipe for trouble. --- src/pager.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pager.c b/src/pager.c index 5c2b8de8d..1c93d494e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -651,8 +651,6 @@ lookat(coordxy x, coordxy y, char *buf, char *monbuf) Sprintf(buf, "interior of %s", mon_nam(u.ustuck)); pm = u.ustuck->data; } else if (glyph_is_monster(glyph)) { - gb.bhitpos.x = x; - gb.bhitpos.y = y; if ((mtmp = m_at(x, y)) != 0) { look_at_monster(buf, monbuf, mtmp, x, y); pm = mtmp->data; @@ -1901,8 +1899,6 @@ look_all( if (glyph_is_monster(glyph)) { struct monst *mtmp; - gb.bhitpos.x = x; /* [is this actually necessary?] */ - gb.bhitpos.y = y; if (u_at(x, y) && canspotself()) { (void) self_lookat(lookbuf); ++count; From 61affaed37d1f1a805139ebeb2783adf50a1f3bf Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 15 Jul 2024 13:13:01 -0700 Subject: [PATCH 035/121] fix #K4202 - O/mO for prompted values treated \ player's input as a comma-separated list of option:value settings Several compound values that aren't amenable to menus prompt for a line of input and pass it to parseoptions() as if it came from the run-time configuration file. That shouldn't be treating commas as option separators. The fix is trival, at least for handling the text properly without introducing new warnings to complain about rejections. Some options notice an unwanted comma and complain, others don't notice and the extra text gets ignored. --- doc/fixes3-7-0.txt | 4 ++++ src/options.c | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f34db3b58..4c682601d 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1445,6 +1445,10 @@ some theft messages by nymphs force "she", others use default monster naming if a nymph stole worn armor and got killed (perhaps by pet) before hero's next turn, feedback would be "You finish taking off your suit." regardless of the type of armor being taken off +when setting an option interactively [via O or 3.7's mO], if the particular + option uses a prompt to get a line of input (for compounds: 'fruit', + 'scores', most numeric ones), input was treated as a comma-separated + list of option[:value] rather than just the new value of that option Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/options.c b/src/options.c index e454aa31f..7d7e09fae 100644 --- a/src/options.c +++ b/src/options.c @@ -478,8 +478,19 @@ parseoptions( using_alias = FALSE; go.opt_initial = tinitial; go.opt_from_file = tfrom_file; - if ((op = strchr(opts, ',')) != 0) { + /* + * Process elements of comma-separated list in right to left order. + * When some options are set interactively--notably various compound + * options that issue a prompt for a value--they use parseoptions() + * to handle setting the new value. For those, 'tinitial' is False + * and if user tries to supply a comma-separated list, it will be + * treated as part of the current option, probably failing to parse. + */ + if (tinitial && (op = strchr(opts, ',')) != 0) { *op++ = 0; + /* current element remains pending while the rest of the line gets + handled recursively; if the rest of line contains any commas, + then the process will recurse deeper as it is processed */ if (!parseoptions(op, go.opt_initial, go.opt_from_file)) retval = FALSE; } @@ -8573,8 +8584,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ anything any; menu_item *pick_list; int indexoffset, startpass, endpass; - boolean setinitial = FALSE, fromfile = FALSE, - gavehelp = FALSE, skiphelp = !iflags.cmdassist; + boolean gavehelp = FALSE, skiphelp = !iflags.cmdassist; int clr = NO_COLOR; if (iflags.menu_requested) { @@ -8731,7 +8741,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ /* boolean option */ Sprintf(buf, "%s%s", *allopt[opt_indx].addr ? "!" : "", allopt[opt_indx].name); - (void) parseoptions(buf, setinitial, fromfile); + (void) parseoptions(buf, FALSE, FALSE); } else { /* compound option */ int k = opt_indx, reslt; @@ -8755,7 +8765,7 @@ doset(void) /* changing options via menu by Per Liboriussen */ (void) strncat(eos(buf), abuf, (sizeof buf - 1 - strlen(buf))); /* pass the buck */ - (void) parseoptions(buf, setinitial, fromfile); + (void) parseoptions(buf, FALSE, FALSE); } } if (wc_supported(allopt[opt_indx].name) From d09a5beab35612c39259984ccebca3175dc9db67 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 20 Dec 2023 11:55:58 -0500 Subject: [PATCH 036/121] Rename polyfodder() to polyfood() 'Polyfodder' is already a term frequently used by players to describe items which are useful to hang on to specifically to zap polymorph at (for example, extra unicorn horns, which can be turned into magic markers). Using it as the name of a macro which tests whether a food item will polymorph the creature consuming it is somewhat confusing, and I think 'polyfood' is a lot clearer. --- include/obj.h | 2 +- src/do.c | 2 +- src/eat.c | 2 +- src/mon.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/obj.h b/include/obj.h index 7053772d6..f138f4eae 100644 --- a/include/obj.h +++ b/include/obj.h @@ -306,7 +306,7 @@ struct obj { #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN) /* note: sometimes eggs and tins have special corpsenm values that shouldn't be used as an index into mons[] */ -#define polyfodder(obj) \ +#define polyfood(obj) \ (ofood(obj) && (obj)->corpsenm >= LOW_PM \ && (pm_to_cham((obj)->corpsenm) != NON_PM \ || dmgtype(&mons[(obj)->corpsenm], AD_POLY))) diff --git a/src/do.c b/src/do.c index 41aaadc6d..08b00a9c1 100644 --- a/src/do.c +++ b/src/do.c @@ -850,7 +850,7 @@ engulfer_digests_food(struct obj *obj) if (obj->otyp == CORPSE) { could_petrify = touch_petrifies(&mons[obj->corpsenm]); - could_poly = polyfodder(obj); + could_poly = polyfood(obj); could_grow = (obj->corpsenm == PM_WRAITH); could_heal = (obj->corpsenm == PM_NURSE); } else if (obj->otyp == GLOB_OF_GREEN_SLIME) { diff --git a/src/eat.c b/src/eat.c index dd52fd0b0..707449772 100644 --- a/src/eat.c +++ b/src/eat.c @@ -3865,7 +3865,7 @@ Popeye(int threat) && (mndx == PM_LIZARD || acidic(&mons[mndx]))); /* polymorph into a fiery monster */ case SLIMED: - return (boolean) polyfodder(otin); + return (boolean) polyfood(otin); /* no tins can cure these (yet?) */ case SICK: case VOMITING: diff --git a/src/mon.c b/src/mon.c index 1fb32fd86..a59a8a93f 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1374,7 +1374,7 @@ m_consume_obj(struct monst *mtmp, struct obj *otmp) || corpsenm == PM_LARGE_MIMIC || corpsenm == PM_GIANT_MIMIC)); slimer = (otmp->otyp == GLOB_OF_GREEN_SLIME); - poly = polyfodder(otmp); + poly = polyfood(otmp); grow = mlevelgain(otmp); heal = mhealup(otmp); eyes = (otmp->otyp == CARROT); From b363b702d755a3c84e003d2dd66d0be9c9598d91 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 20 Dec 2023 12:00:13 -0500 Subject: [PATCH 037/121] Make pets unwilling to eat all polyfood() corpses The previous is_shapeshifter() test meant that pets were still perfectly willing to eat genetic engineer corpses and be polymorphed. Use polyfood() instead. Fixes #1183. --- src/dog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dog.c b/src/dog.c index cf9adc4f2..1aab95644 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1003,7 +1003,7 @@ dogfood(struct monst *mon, struct obj *obj) return POISON; /* avoid polymorph unless starving or abused (in which case the pet will consider it for a chance to become more powerful) */ - else if (is_shapeshifter(fptr) && mon->mtame > 1 && !starving) + else if (polyfood(obj) && mon->mtame > 1 && !starving) return MANFOOD; else if (vegan(fptr)) return herbi ? CADAVER : MANFOOD; From ce206b813f6c552199c03419083f1cb53c52f8ab Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 16 Jul 2024 00:01:43 -0700 Subject: [PATCH 038/121] a couple more monst food bits Fix misleading indentation that the polyfood() macro inherited from the misformated polyfodder() macro. Fix a case where a non-pet monster would avoid eating a cockatrice corpse but would eat Medusa's corpse. --- include/obj.h | 2 +- src/mon.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/obj.h b/include/obj.h index f138f4eae..abdd3c735 100644 --- a/include/obj.h +++ b/include/obj.h @@ -309,7 +309,7 @@ struct obj { #define polyfood(obj) \ (ofood(obj) && (obj)->corpsenm >= LOW_PM \ && (pm_to_cham((obj)->corpsenm) != NON_PM \ - || dmgtype(&mons[(obj)->corpsenm], AD_POLY))) + || dmgtype(&mons[(obj)->corpsenm], AD_POLY))) #define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH) #define mhealup(obj) (ofood(obj) && (obj)->corpsenm == PM_NURSE) #define Is_pudding(o) \ diff --git a/src/mon.c b/src/mon.c index a59a8a93f..da6efd321 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1632,7 +1632,7 @@ meatcorpse( /* skip some corpses */ if (vegan(corpsepm) /* ignore veggy corpse even if omnivorous */ /* don't eat harmful corpses */ - || (touch_petrifies(corpsepm) && !resists_ston(mtmp))) + || (flesh_petrifies(corpsepm) && !resists_ston(mtmp))) continue; if (is_rider(corpsepm)) { boolean revived_it = revive_corpse(otmp); From 59fbffd170afaaebdb95c8d86d911d7683dedd5d Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 16 Jul 2024 14:49:34 -0700 Subject: [PATCH 039/121] Guidebook update: "Map (rest of screen)" The description of the default map display was out of date: Sinks aren't conditional anymore, and were changed from '#' to '{'. Statues were still listed as '`' but aren't displayed as that. Room and corridor engravings weren't mentioned. Wall of water and wall of lava weren't mentioned. Drawbridge portcullis ('#' when closed) and span ('.' when open) weren't mentioned. This splits introductory "- and |" into two entries. I've forced CR font (similar to TeX's tt font) for the initial character of all the entries. The formatting of letters for monsters left something to be desired so I've tried to redo it. The 'roff edition seems ok (as least when there's no page break in the middle of it) but I'm not sure how the LaTeX version will fare. I didn't try to include the trailing "and" on the first two lines the way the 'roff version does since I wasn't sure how to accomplish that. --- doc/Guidebook.mn | 103 ++++++++++++++++++++++++++-------------------- doc/Guidebook.tex | 71 +++++++++++++------------------- 2 files changed, 88 insertions(+), 86 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 0d0232850..c9d14f6a5 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -46,7 +46,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y) -.ds f2 April 12, 2024 +.ds f2 July 16, 2024 . .\" A note on some special characters: .\" \(lq = left double quote @@ -455,69 +455,84 @@ option. The map (rest of the screen) .pg The rest of the screen is the map of the level as you have explored it -so far. Each symbol on the screen represents something. You can set -various graphics options to change some of the symbols the game uses; -otherwise, the game will use default symbols. Here is a list of what the -default symbols mean: -.lp "\\- and | " -The walls of a room, or an open door. Or a grave (|). -.lp . -The floor of a room, ice, or a doorless doorway. -.lp # -A corridor, or iron bars, or a tree, or possibly a kitchen sink (if -your dungeon has sinks), or a drawbridge. -.lp > +so far. +Each symbol on the screen represents something. +You can set various graphics options to change some of the symbols the +game uses; otherwise, the game will use default symbols. +Here is a list of what the default symbols mean: +.lp \f(CR\\-\fP +The horizontal or corner walls of a room, or an open east/west door. +.lp \f(CR|\fP +The vertical walls of a room, or an open north/south door, or a grave. +.lp \f(CR.\fP +The floor of a room, or ice, or a doorless doorway, or the span of an +open drawbridge. +.lp \f(CR#\fP +A corridor, or iron bars, or a tree, or the portcullis of a closed +drawbridge. +.lp "" +Note: engravings in corridors also appear as \f(CR#\fP but are shown in +a different color from normal corridor locations. +.lp \f(CR>\fP Stairs down: a way to the next level. -.lp < +.lp \f(CR<\fP Stairs up: a way to the previous level. -.lp + +.lp \f(CR+\fP A closed door, or a spellbook containing a spell you may be able to learn. -.lp @ -Your character or a human. -.lp $ +.lp \f(CR@\fP +Your character or a human or an elf. +.lp \f(CR$\fP A pile of gold. -.lp \(ha \" ^ +.lp \f(CR\(ha\fP \" \(ah == 'hat' == circumflex accent == caret ^ A trap (once you have detected it). -.lp ) +.lp \f(CR)\fP A weapon. -.lp [ +.lp \f(CR[\fP A suit or piece of armor. -.lp % +.lp \f(CR%\fP Something edible (not necessarily healthy). -.lp ? +.lp \f(CR?\fP A scroll. -.lp / +.lp \f(CR/\fP A wand. -.lp = +.lp \f(CR=\fP A ring. -.lp ! +.lp \f(CR!\fP A potion. -.lp ( +.lp \f(CR(\fP A useful item (pick-axe, key, lamp...). -.lp \(dq \" \(dq == double quote +.lp \f(CR\(dq\fP \" \(dq == double quote An amulet or a spider web. -.lp * +.lp \f(CR*\fP A gem or rock (possibly valuable, possibly worthless). -.lp \` -A boulder or statue. -.lp 0 +.lp \f(CR\`\fP +A boulder or statue or an engraving on the floor of a room. +.lp "" +Note: statues are displayed as if they were the monsters they depict +so won't appear as a \fIgrave accent\fP (aka \fIback-tick\fP). +.lp \f(CR0\fP An iron ball. -.lp _ +.lp \f(CR_\fP An altar, or an iron chain. -.lp { -A fountain. -.lp } -A pool of water or moat or a pool of lava. -.lp \\\\ +.lp \f(CR{\fP +A fountain or a sink. +.lp \f(CR}\fP +A pool of water or moat or a wall of water +or a pool of lava or a wall of lava. +.lp \f(CR\\\\\fP An opulent throne. -.lp "a-zA-Z and other symbols" +.lp "\f(CRa\fP-\f(CRz\fP\ \ \fIand\fP" +.lp "\f(CRA\fP-\f(CRZ\fP\ \ \fIand\fP" +.lp "\f(CR@&\(aq\fP" \" \(aq == apostrophe / single quote Letters and certain other symbols represent the various inhabitants -of the Mazes of Menace. Watch out, they can be nasty and vicious. +of the Mazes of Menace. +Watch out, they can be nasty and vicious. Sometimes, however, they can be helpful. -.lp I -This marks the last known location of an invisible or otherwise unseen -monster. Note that the monster could have moved. -The \(oqF\(cq and \(oqm\(cq commands may be useful here. +.lp \f(CRI\fP +Rather than a specific type of monster, this marks the last known +location of an invisible or otherwise unseen monster. +Note that the monster could have moved. +The \(oqs\(cq, \(oqF\(cq, and \(oqm\(cq commands may be useful here. .pg You need not memorize all these symbols; you can ask the game what any symbol represents with the \(oq/\(cq command (see the next section for diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 57d69e381..b4fd65941 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -48,7 +48,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)} -\date{April 12, 2024} +\date{July 16, 2024} \maketitle @@ -514,92 +514,79 @@ game will use default symbols. Here is a list of what the default symbols mean: \blist{} -%.lp -\item[\tb{- {\rm and} |}] -The walls of a room, or an open door. Or a grave ({\tt |}). -%.lp +\item[\tb{-}] +The horizontal or corner walls of a room, or an open east/west door. +\item[\tb{|}] +The vertical walls of a room, or an open north/south door, or a grave. \item[\tb{.}] -The floor of a room, ice, or a doorless doorway. -%.lp +The floor of a room, or ice, or a doorless doorway, or the span of an +open drawbridge. \item[\tb{\#}] -A corridor, or iron bars, or a tree, or possibly a kitchen sink (if -your dungeon has sinks), or a drawbridge. -%.lp +A corridor, or iron bars, or a tree, or the portcullis of a closed +drawbridge.\\ +%.lp "" +Note: engravings in corridors also appear as \f(CR#\fP but are shown in +a different color from normal corridor locations. \item[\tb{>}] Stairs down: a way to the next level. -%.lp \item[\tb{<}] Stairs up: a way to the previous level. -%.lp \item[\tb{+}] A closed door, or a spellbook containing a spell you may be able to learn. -%.lp \item[\tb{@}] -Your character or a human. -%.lp +Your character or a human or an elf. \item[\tb{\$}] A pile of gold. -%.lp \item[\tb{\^}] A trap (once you have detected it). -%.lp \item[\tb{)}] A weapon. -%.lp \item[\tb{[}] A suit or piece of armor. -%.lp \item[\tb{\%}] Something edible (not necessarily healthy). -%.lp \item[\tb{?}] A scroll. -%.lp \item[\tb{/}] A wand. -%.lp \item[\tb{=}] A ring. -%.lp \item[\tb{!}] A potion. -%.lp \item[\tb{(}] A useful item (pick-axe, key, lamp \ldots). -%.lp \item[\tb{"}] An amulet or a spider web. -%.lp \item[\tb{*}] A gem or rock (possibly valuable, possibly worthless). -%.lp \item[\tb{\`}] -A boulder or statue. -%.lp +A boulder or statue or an engraving on the floor of a room.\\ +%.lp "" +Note: statues are displayed as if they were the monsters they depict +so won't appear as a {\it grave accent\/} (aka {\it back-tick}. \item[\tb{0}] An iron ball. -%.lp \item[\tb{\verb+_+}] An altar, or an iron chain. -%.lp \item[\tb{\{}] -A fountain. -%.lp +A fountain or a sink. \item[\tb{\}}] -A pool of water or moat or a pool of lava. -%.lp +A pool of water or moat or a wall of water +or a pool of lava or a wall of lava. \item[\tb{$\backslash$}] An opulent throne. -%.lp -\item[\tb{a-zA-Z {\rm \& other symbols}}] +\item[\tb{a-z}] +\item[\tb{A-Z}] +\item[\tb{@\&\-}] Letters and certain other symbols represent the various inhabitants -of the Mazes of Menace. Watch out, they can be nasty and vicious. +of the Mazes of Menace. +Watch out, they can be nasty and vicious. Sometimes, however, they can be helpful. -%.lp \item[\tb{I}] -This marks the last known location of an invisible or otherwise unseen -monster. Note that the monster could have moved. -The `{\tt F}' and `{\tt m}' commands may be useful here. +Rather than a specific type of monster, this marks the last known +location of an invisible or otherwise unseen monster. +Note that the monster could have moved. +The `{\tt s}', `{\tt F}', and `{\tt m}' commands may be useful here. \elist %.pg From 474edb46f86e4d9dabee14181b0629c855729665 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 16 Jul 2024 19:48:10 -0700 Subject: [PATCH 040/121] more Guidebook map characters Previous update left out a couple of classes of monsters that are represented by punctuation. for ghosts is deliberately not included. --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index c9d14f6a5..8e385db10 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -523,7 +523,7 @@ or a pool of lava or a wall of lava. An opulent throne. .lp "\f(CRa\fP-\f(CRz\fP\ \ \fIand\fP" .lp "\f(CRA\fP-\f(CRZ\fP\ \ \fIand\fP" -.lp "\f(CR@&\(aq\fP" \" \(aq == apostrophe / single quote +.lp "\f(CR@&\(aq:;\fP" \" \(aq == apostrophe / single quote Letters and certain other symbols represent the various inhabitants of the Mazes of Menace. Watch out, they can be nasty and vicious. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index b4fd65941..a1eb4abf2 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -577,7 +577,7 @@ or a pool of lava or a wall of lava. An opulent throne. \item[\tb{a-z}] \item[\tb{A-Z}] -\item[\tb{@\&\-}] +\item[\tb{@\&\-:;}] Letters and certain other symbols represent the various inhabitants of the Mazes of Menace. Watch out, they can be nasty and vicious. From afe0d03678f05e93bb2dfd084aa9263870fd5fc1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 17 Jul 2024 08:00:46 -0400 Subject: [PATCH 041/121] fix Guidebook.tex --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index a1eb4abf2..4a3a530ef 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -525,7 +525,7 @@ open drawbridge. A corridor, or iron bars, or a tree, or the portcullis of a closed drawbridge.\\ %.lp "" -Note: engravings in corridors also appear as \f(CR#\fP but are shown in +Note: engravings in corridors also appear as \# but are shown in a different color from normal corridor locations. \item[\tb{>}] Stairs down: a way to the next level. From e44bfe4eb245c1a49008ef15e271c5220bc53a9d Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 17 Jul 2024 08:13:11 -0400 Subject: [PATCH 042/121] fix sentence structure in Guidebook.tex Commit 59fbffd1 neglected to include the closing ')' --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 4a3a530ef..cad1d9819 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -563,7 +563,7 @@ A gem or rock (possibly valuable, possibly worthless). A boulder or statue or an engraving on the floor of a room.\\ %.lp "" Note: statues are displayed as if they were the monsters they depict -so won't appear as a {\it grave accent\/} (aka {\it back-tick}. +so won't appear as a {\it grave accent\/} (aka {\it back-tick}). \item[\tb{0}] An iron ball. \item[\tb{\verb+_+}] From a7240f8689c759c53fb6104faa11661d7ad2ce0e Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 17 Jul 2024 10:02:25 -0400 Subject: [PATCH 043/121] update tested versions of Visual Studio 2024-07-17 --- sys/windows/Makefile.nmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index ba53f5810..011aa8253 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -8,8 +8,8 @@ # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio 2019 Community Edition v 16.11.37 -# - Microsoft Visual Studio 2022 Community Edition v 17.10.2 +# - Microsoft Visual Studio 2019 Community Edition v 16.11.38 +# - Microsoft Visual Studio 2022 Community Edition v 17.10.4 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -985,7 +985,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2019 = 14.29.30154.0 -TESTEDVS2022 = 14.40.33811.0 +TESTEDVS2022 = 14.40.33812.0 VS2019CUR = $(TESTEDVS2019:.=) VS2022CUR = $(TESTEDVS2022:.=) From 5f36d4711038e090925c60db49a5b9b974e5a43e Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 17 Jul 2024 07:37:19 -0700 Subject: [PATCH 044/121] Guidebook.mn comment "\(ah" transposed the letters; should have been "\(ha", matching the actual usage on the same line. Also, the reference to "circumflex accent" wasn't appropriate since that's the small caret you get with "^" or "\^". --- doc/Guidebook.mn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 8e385db10..37b04a2f2 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -483,7 +483,7 @@ A closed door, or a spellbook containing a spell you may be able to learn. Your character or a human or an elf. .lp \f(CR$\fP A pile of gold. -.lp \f(CR\(ha\fP \" \(ah == 'hat' == circumflex accent == caret ^ +.lp \f(CR\(ha\fP \" \(ha == 'hat' == full sized caret ^ A trap (once you have detected it). .lp \f(CR)\fP A weapon. From 75561da3be8c68c31260f4448ba20f4f6909bfd5 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 17 Jul 2024 13:33:22 -0700 Subject: [PATCH 045/121] zillionth comment typo fix Plus a bit of reformatting where extending "static" to "staticfn" on the first segment of a would-have-wrapped line made the other segment(s) no longer line up. --- src/botl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/botl.c b/src/botl.c index ba671c94a..f3230cab7 100644 --- a/src/botl.c +++ b/src/botl.c @@ -427,7 +427,7 @@ botl_score(void) /* hidden_gold(False): only gold in containers whose contents are known */ umoney = money_cnt(gi.invent) + hidden_gold(FALSE); - /* don't include initial gold; don't impose penalty if its all gone */ + /* don't include initial gold; don't impose penalty if it's all gone */ if ((umoney -= u.umoney0) < 0L) umoney = 0L; depthbonus = 50 * (deepest - 1) @@ -508,8 +508,8 @@ staticfn void split_clridx(int, int *, int *); staticfn boolean is_ltgt_percentnumber(const char *); staticfn boolean has_ltgt_percentnumber(const char *); staticfn int splitsubfields(char *, char ***, int); -staticfn boolean is_fld_arrayvalues(const char *, const char *const *, int, int, - int *); +staticfn boolean is_fld_arrayvalues(const char *, const char *const *, + int, int, int *); staticfn int query_arrayvalue(const char *, const char *const *, int, int); staticfn void status_hilite_add_threshold(int, struct hilite_s *); staticfn boolean parse_status_hl2(char (*)[QBUFSZ], boolean); @@ -520,7 +520,7 @@ staticfn unsigned long str2conditionbitmask(char *); staticfn boolean parse_condition(char (*)[QBUFSZ], int); staticfn char *hlattr2attrname(int, char *, size_t); staticfn void status_hilite_linestr_add(int, struct hilite_s *, unsigned long, - const char *); + const char *); staticfn void status_hilite_linestr_done(void); staticfn int status_hilite_linestr_countfield(int); staticfn void status_hilite_linestr_gather_conditions(void); @@ -529,7 +529,7 @@ staticfn char *status_hilite2str(struct hilite_s *); staticfn int status_hilite_menu_choose_field(void); staticfn int status_hilite_menu_choose_behavior(int); staticfn int status_hilite_menu_choose_updownboth(int, const char *, boolean, - boolean); + boolean); staticfn boolean status_hilite_menu_add(int); staticfn boolean status_hilite_remove(int); staticfn boolean status_hilite_menu_fld(int); From dfa9d9df3cca355b129a4e82be403d3fb7fcc681 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 19 Jul 2024 15:34:38 -0700 Subject: [PATCH 046/121] untested Guidebook.tex fix A recent change accidentally put a dash where a hyphen (default value for S_golem) is intended. I'm not sure whether verbatim is necessary here, but it ought to work. --- doc/Guidebook.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index cad1d9819..0ef3cdc1b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -577,7 +577,7 @@ or a pool of lava or a wall of lava. An opulent throne. \item[\tb{a-z}] \item[\tb{A-Z}] -\item[\tb{@\&\-:;}] +\item[\tb{@\&\verb+'+:;}] Letters and certain other symbols represent the various inhabitants of the Mazes of Menace. Watch out, they can be nasty and vicious. From d5785f287e0b855f14e243f13f67076ebc24d636 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 23 Jul 2024 01:06:24 -0400 Subject: [PATCH 047/121] GitHub issue #1254 > If there's a trap on a no-dig level, the floor beneath it will always be "too hard to dig into", making it impossible to remove the trap. > > As you can still dig pits in these levels (just not holes), the floor under the trap itself resisting to become a pit seems inconsistent. > > Steps to reproduce: > > Go to no-dig level like Mine's End > Make a trap > Dig a pit next to it -> works > Dig on the trap -> does not work Return more information about the dig_check() results to caller (was just a boolean). Move the messaging that was in dig_check() into a separate digcheck_fail_message() function that uses the expanded return information. Resolves #1254 . --- include/extern.h | 4 +- include/hack.h | 22 ++++++++ src/apply.c | 2 +- src/dig.c | 134 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 123 insertions(+), 39 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8476b017b..0be195583 100644 --- a/include/extern.h +++ b/include/extern.h @@ -498,7 +498,9 @@ extern int wiz_mgender(void); extern int dig_typ(struct obj *, coordxy, coordxy); extern boolean is_digging(void); extern int holetime(void); -extern boolean dig_check(struct monst *, boolean, coordxy, coordxy); +extern enum digcheck_result dig_check(struct monst *, coordxy, coordxy); +extern void digcheck_fail_message(enum digcheck_result, struct monst *, + coordxy, coordxy); extern void digactualhole(coordxy, coordxy, struct monst *, int); extern boolean dighole(boolean, boolean, coord *); extern int use_pick_axe(struct obj *) NONNULLARG1; diff --git a/include/hack.h b/include/hack.h index 1a08246fb..fdd7740a4 100644 --- a/include/hack.h +++ b/include/hack.h @@ -327,6 +327,28 @@ struct _create_particular_data { boolean sleeping, saddled, invisible, hidden; }; +/* dig_check() results */ + +enum digcheck_result { + DIGCHECK_PASSED = 1, + DIGCHECK_PASSED_DESTROY_TRAP = 2, + DIGCHECK_PASSED_PITONLY = 3, + DIGCHECK_FAILED = 4, + DIGCHECK_FAIL_ONSTAIRS = DIGCHECK_FAILED, + DIGCHECK_FAIL_ONLADDER, + DIGCHECK_FAIL_THRONE, + DIGCHECK_FAIL_ALTAR, + DIGCHECK_FAIL_AIRLEVEL, + DIGCHECK_FAIL_WATERLEVEL, + DIGCHECK_FAIL_TOOHARD, + DIGCHECK_FAIL_UNDESTROYABLETRAP, + DIGCHECK_FAIL_CANTDIG, + DIGCHECK_FAIL_BOULDER, + DIGCHECK_FAIL_OBJ_POOL_OR_TRAP +}; + + + /* Dismount: causes for why you are no longer riding */ enum dismount_types { DISMOUNT_GENERIC = 0, diff --git a/src/apply.c b/src/apply.c index 32a9b14ad..bf867c3e5 100644 --- a/src/apply.c +++ b/src/apply.c @@ -3945,7 +3945,7 @@ do_break_wand(struct obj *obj) if (obj->otyp == WAN_DIGGING) { schar typ; - if (dig_check(BY_OBJECT, FALSE, x, y)) { + if (dig_check(BY_OBJECT, x, y) < DIGCHECK_FAILED) { if (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)) { /* normally, pits and holes don't anger guards, but they * do if it's a wall or door that's being dug */ diff --git a/src/dig.c b/src/dig.c index 26b327c99..dfa23dc5e 100644 --- a/src/dig.c +++ b/src/dig.c @@ -205,59 +205,97 @@ is_digging(void) #define BY_YOU (&gy.youmonst) #define BY_OBJECT ((struct monst *) 0) -boolean -dig_check(struct monst *madeby, boolean verbose, coordxy x, coordxy y) +enum digcheck_result +dig_check(struct monst *madeby, coordxy x, coordxy y) { struct trap *ttmp = t_at(x, y); - const char *verb = - (madeby == BY_YOU && uwep && is_axe(uwep)) ? "chop" : "dig in"; if (On_stairs(x, y)) { stairway *stway = stairway_at(x, y); if (stway->isladder) { - if (verbose) - pline_The("ladder resists your effort."); - } else if (verbose) - pline_The("stairs are too hard to %s.", verb); - return FALSE; + return DIGCHECK_FAIL_ONLADDER; + } else { + return DIGCHECK_FAIL_ONSTAIRS; + } } else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) { - if (verbose) - pline_The("throne is too hard to break apart."); - return FALSE; + return DIGCHECK_FAIL_THRONE; } else if (IS_ALTAR(levl[x][y].typ) && (madeby != BY_OBJECT || (altarmask_at(x, y) & AM_SANCTUM) != 0)) { - if (verbose) - pline_The("altar is too hard to break apart."); - return FALSE; + return DIGCHECK_FAIL_ALTAR; } else if (Is_airlevel(&u.uz)) { - if (verbose) - You("cannot %s thin air.", verb); - return FALSE; + return DIGCHECK_FAIL_AIRLEVEL; } else if (Is_waterlevel(&u.uz)) { - if (verbose) - pline_The("%s splashes and subsides.", hliquid("water")); - return FALSE; + return DIGCHECK_FAIL_WATERLEVEL; } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR - && (levl[x][y].wall_info & W_NONDIGGABLE) != 0) - || (ttmp - && (undestroyable_trap(ttmp->ttyp) - || (!Can_dig_down(&u.uz) && !levl[x][y].candig)))) { - if (verbose) - pline_The("%s here is too hard to %s.", surface(x, y), verb); - return FALSE; + && (levl[x][y].wall_info & W_NONDIGGABLE) != 0)) { + return DIGCHECK_FAIL_TOOHARD; + } else if (ttmp && undestroyable_trap(ttmp->ttyp)) { + return DIGCHECK_FAIL_UNDESTROYABLETRAP; + } else if (!Can_dig_down(&u.uz) && !levl[x][y].candig) { + if (ttmp) { + if (ttmp->ttyp != HOLE && !is_pit(ttmp->ttyp)) + return DIGCHECK_PASSED_DESTROY_TRAP; + else + return DIGCHECK_FAIL_CANTDIG; + } else { + return DIGCHECK_PASSED_PITONLY; + } } else if (sobj_at(BOULDER, x, y)) { - if (verbose) - There("isn't enough room to %s here.", verb); - return FALSE; + return DIGCHECK_FAIL_BOULDER; } else if (madeby == BY_OBJECT /* the block against existing traps is mainly to prevent broken wands from turning holes into pits */ && (ttmp || is_pool_or_lava(x, y))) { /* digging by player handles pools separately */ - return FALSE; + return DIGCHECK_FAIL_OBJ_POOL_OR_TRAP; + } + return DIGCHECK_PASSED; +} + +void +digcheck_fail_message(enum digcheck_result digresult, struct monst *madeby, + coordxy x, coordxy y) +{ + const char *verb = + (madeby == BY_YOU && uwep && is_axe(uwep)) ? "chop" : "dig in"; + + if (digresult < DIGCHECK_FAILED) + return; + + switch (digresult) { + case DIGCHECK_FAIL_AIRLEVEL: + You("cannot %s thin air.", verb); + break; + case DIGCHECK_FAIL_ALTAR: + pline_The("altar is too hard to break apart."); + break; + case DIGCHECK_FAIL_BOULDER: + There("isn't enough room to %s here.", verb); + break; + case DIGCHECK_FAIL_ONLADDER: + pline_The("ladder resists your effort."); + break; + case DIGCHECK_FAIL_ONSTAIRS: + pline_The("stairs are too hard to %s.", verb); + break; + case DIGCHECK_FAIL_THRONE: + pline_The("throne is too hard to break apart."); + break; + case DIGCHECK_FAIL_CANTDIG: + case DIGCHECK_FAIL_TOOHARD: + pline_The("%s here is too hard to %s.", surface(x, y), verb); + break; + case DIGCHECK_FAIL_UNDESTROYABLETRAP: + case DIGCHECK_FAIL_WATERLEVEL: + pline_The("%s splashes and subsides.", hliquid("water")); + break; + case DIGCHECK_FAIL_OBJ_POOL_OR_TRAP: + case DIGCHECK_PASSED: + case DIGCHECK_PASSED_PITONLY: + case DIGCHECK_PASSED_DESTROY_TRAP: + break; } - return TRUE; } staticfn int @@ -267,6 +305,7 @@ dig(void) coordxy dpx = svc.context.digging.pos.x, dpy = svc.context.digging.pos.y; boolean ispick = uwep && is_pick(uwep); const char *verb = (!uwep || is_pick(uwep)) ? "dig into" : "chop through"; + enum digcheck_result dcresult = DIGCHECK_PASSED; lev = &levl[dpx][dpy]; /* perhaps a nymph stole your pick-axe while you were busy digging */ @@ -278,8 +317,11 @@ dig(void) return 0; if (svc.context.digging.down) { - if (!dig_check(BY_YOU, TRUE, u.ux, u.uy)) + dcresult = dig_check(BY_YOU, u.ux, u.uy); + if (dcresult >= DIGCHECK_FAILED) { + digcheck_fail_message(dcresult, BY_YOU, u.ux, u.uy); return 0; + } } else { /* !svc.context.digging.down */ if (IS_TREE(lev->typ) && !may_dig(dpx, dpy) && dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) { @@ -370,6 +412,17 @@ dig(void) /* we haven't made any progress toward a pit yet */ svc.context.digging.effort = 0; return 0; + } else if (ttmp && dcresult == DIGCHECK_PASSED_DESTROY_TRAP) { + const char *ttmpname = trapname(ttmp->ttyp, FALSE); + + if (ispick) + You("destroy %s with %s.", + ttmp->tseen ? the(ttmpname) : an(ttmpname), + yobjnam(uwep, (const char *) 0)); + deltrap(ttmp); + /* we haven't made any progress toward a pit yet */ + svc.context.digging.effort = 0; + return 0; } if (IS_ALTAR(lev->typ)) { @@ -637,6 +690,7 @@ digactualhole(coordxy x, coordxy y, struct monst *madeby, int ttyp) } shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE); oldobjs = svl.level.objects[x][y]; + ttmp = maketrap(x, y, ttyp); if (!ttmp) return; @@ -836,7 +890,8 @@ dighole(boolean pit_only, boolean by_magic, coord *cc) schar typ, old_typ; coordxy dig_x, dig_y; boolean nohole, retval = FALSE; - + enum digcheck_result dig_check_result; + if (!cc) { dig_x = u.ux; dig_y = u.uy; @@ -849,7 +904,10 @@ dighole(boolean pit_only, boolean by_magic, coord *cc) ttmp = t_at(dig_x, dig_y); lev = &levl[dig_x][dig_y]; - nohole = (!Can_dig_down(&u.uz) && !lev->candig); + dig_check_result = dig_check(BY_YOU, dig_x, dig_y); + /* nohole = (!Can_dig_down(&u.uz) && !lev->candig); */ + nohole = (dig_check_result == DIGCHECK_FAIL_CANTDIG + || dig_check_result == DIGCHECK_FAIL_TOOHARD); old_typ = lev->typ; if ((ttmp && (undestroyable_trap(ttmp->ttyp) || nohole)) @@ -952,7 +1010,9 @@ dighole(boolean pit_only, boolean by_magic, coord *cc) } /* finally we get to make a hole */ - if (nohole || pit_only) + if (nohole || pit_only + || dig_check_result == DIGCHECK_PASSED_DESTROY_TRAP + || dig_check_result == DIGCHECK_PASSED_PITONLY) digactualhole(dig_x, dig_y, BY_YOU, PIT); else digactualhole(dig_x, dig_y, BY_YOU, HOLE); From 906813f0b23d5899c6721f8f4d58328d65120753 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 23 Jul 2024 01:11:04 -0400 Subject: [PATCH 048/121] fixes update Closes #1245 Previous commit had a typo of 1254 in the reference --- doc/fixes3-7-0.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 4c682601d..ed99dbfff 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1449,6 +1449,8 @@ when setting an option interactively [via O or 3.7's mO], if the particular option uses a prompt to get a line of input (for compounds: 'fruit', 'scores', most numeric ones), input was treated as a comma-separated list of option[:value] rather than just the new value of that option +when there was a trap on a no-dig level, the floor beneath it was always + "too hard to dig into", making it impossible to remove the trap Fixes to 3.7.0-x General Problems Exposed Via git Repository From 082671ab0da0a2139847452f566cb5daf0807d3f Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 23 Jul 2024 10:51:42 -0400 Subject: [PATCH 049/121] follow-up for digcheck_fail_message() --- src/dig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dig.c b/src/dig.c index dfa23dc5e..e1ec1439f 100644 --- a/src/dig.c +++ b/src/dig.c @@ -284,9 +284,9 @@ digcheck_fail_message(enum digcheck_result digresult, struct monst *madeby, break; case DIGCHECK_FAIL_CANTDIG: case DIGCHECK_FAIL_TOOHARD: + case DIGCHECK_FAIL_UNDESTROYABLETRAP: pline_The("%s here is too hard to %s.", surface(x, y), verb); break; - case DIGCHECK_FAIL_UNDESTROYABLETRAP: case DIGCHECK_FAIL_WATERLEVEL: pline_The("%s splashes and subsides.", hliquid("water")); break; From b08fb9fb932ab2913b40d3f98d65c719c09b1d1f Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 23 Jul 2024 10:40:28 -0700 Subject: [PATCH 050/121] github issue #1262 - #terrain vs gas regions Issue reported by elunna: none of the display choices for #terrain offered a way to show the terrain beneath temporary gas/cloud regions (except "full map" in wizard mode or explore mode). That prevented the command from being used to find stairs and portals which had been mapped before becoming covered up. Adding extra menu choices to deal with visible regions would result in #terrain becoming a mess. Instead, treat regions as if they were traps. Picking a choice that includes traps will show region spots which are in view as cloud or poison cloud, picking one that excludes traps will show the underlying terrain. Region spots which aren't within view are handled the same as before: whatever the hero remembers at their location gets displayed. The default menu choice excludes traps so will display stairs that are covered by gas cloud regions, but not portals, same as when no regions are present. When showing traps and one is covered by a gas cloud, the trap will be shown rather than the gas cloud, making it possible to see known portals. At the moment the new "#terrain handles regions like traps" feature hasn't been documented anywhere. That might get rectified someday. I'm not sure whether trap detection ought to also detect regions now. This doesn't attempt to tackle that and I think that I'll pretend that the idea never occurred to me. 'parnoid_confirm:traps' definitely ought to prompt for confirmation when entering a visible harmful region. This doesn't add that. Bonus fix: it's possible for a visible region to cover up a not yet explored location. Searching next to such a spot wasn't changing the spot to be marked as explored (unless hero was blind). Now it will. Fixes #1262 --- doc/fixes3-7-0.txt | 5 ++++- src/detect.c | 54 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index ed99dbfff..12b006505 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1455 $ $NHDT-Date: 1720895738 2024/07/13 18:35:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1457 $ $NHDT-Date: 1721684298 2024/07/22 21:38:18 $ General Fixes and Modified Features ----------------------------------- @@ -1451,6 +1451,9 @@ when setting an option interactively [via O or 3.7's mO], if the particular list of option[:value] rather than just the new value of that option when there was a trap on a no-dig level, the floor beneath it was always "too hard to dig into", making it impossible to remove the trap +the #terrain command didn't know how to cope with visible gas/cloud regions; + treat as traps as far as player choice of whether to show or hide; + if/when a spot contains both region and trap, show the trap Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/detect.c b/src/detect.c index ed85b92d7..2c5e9e281 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 detect.c $NHDT-Date: 1715284441 2024/05/09 19:54:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.178 $ */ +/* NetHack 3.7 detect.c $NHDT-Date: 1721684299 2024/07/22 21:38:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1914,7 +1914,7 @@ dosearch0(int aflag) /* intrinsic autosearch vs explicit searching */ if (u_at(x, y)) continue; - if (Blind && !aflag) + if (!aflag && (Blind || visible_region_at(x, y))) feel_location(x, y); if (levl[x][y].typ == SDOOR) { if (rnl(7 - fund)) @@ -2022,6 +2022,11 @@ premap_detect(void) } } +/* used to see under visible gas/cloud regions; caller must declare cmaptmp */ +#define glyph_is_gascloud(glyph) \ + (glyph_is_cmap(glyph) && ((cmaptmp = glyph_to_cmap(glyph)) == S_cloud \ + || cmaptmp == S_poisoncloud)) + staticfn int reveal_terrain_getglyph( coordxy x, coordxy y, @@ -2029,14 +2034,16 @@ reveal_terrain_getglyph( int default_glyph, unsigned which_subset) { + struct trap *t; + struct monst *mtmp; int glyph, levl_glyph; uchar seenv; boolean keep_traps = (which_subset & TER_TRP) != 0, keep_objs = (which_subset & TER_OBJ) != 0, keep_mons = (which_subset & TER_MON) != 0, full = (which_subset & TER_FULL) != 0; - struct monst *mtmp; - struct trap *t; + int cmaptmp = 0; /* used by glyph_is_gascloud() macro */ + NhRegion *reg = visible_region_at(x, y); /* for 'full', show the actual terrain for the entire level, otherwise what the hero remembers for seen locations with @@ -2059,23 +2066,38 @@ reveal_terrain_getglyph( glyph = !swallowed ? glyph_at(x, y) : levl_glyph; if (keep_mons && u_at(x, y) && swallowed) glyph = mon_to_glyph(u.ustuck, rn2_on_display_rng); - else if (((glyph_is_monster(glyph) - || glyph_is_warning(glyph)) && !keep_mons) + else if ((!keep_mons && (glyph_is_monster(glyph) + || glyph_is_warning(glyph))) || glyph_is_swallow(glyph)) glyph = levl_glyph; - if (((glyph_is_object(glyph) && !keep_objs) + if (((!keep_objs && glyph_is_object(glyph)) || glyph_is_invisible(glyph)) && keep_traps && !covers_traps(x, y)) { if ((t = t_at(x, y)) != 0 && t->tseen) glyph = trap_to_glyph(t); } - if ((glyph_is_object(glyph) && !keep_objs) - || (glyph_is_trap(glyph) && !keep_traps) + if ((!keep_objs && glyph_is_object(glyph)) + /* we either show both traps and visible regions (trap if both + are present at the same spot) or neither traps nor regions */ + || (!keep_traps && (glyph_is_trap(glyph) + || (reg && glyph_is_gascloud(glyph)))) || glyph_is_invisible(glyph)) { if (!seenv) { - glyph = default_glyph; + /* it's possible to have a visible region shown at an + otherwise unexplored location (cast stinking cloud + through unexplored corridor into lit room, then approach + far enough to be adjacent to the cloud without having + seen the corridor underneath it) */ + glyph = !reg ? default_glyph : GLYPH_UNEXPLORED; } else if (svl.lastseentyp[x][y] == levl[x][y].typ) { glyph = back_to_glyph(x, y); + } else if (keep_traps && reg && glyph_is_gascloud(glyph)) { + t = t_at(x, y); + glyph = (t && t->tseen) ? trap_to_glyph(t) + : back_to_glyph(x, y); + /* FIXME? what about objects temporarily hidden by regions? + when objects are being shown, shouldn't showing them take + precedence over showing the region, just like traps? */ } else { /* look for a mimic here posing as furniture; if we don't find one, we'll have to fake it */ @@ -2115,17 +2137,21 @@ reveal_terrain_getglyph( return glyph; } +#undef glyph_is_gascloud + #ifdef DUMPLOG void dump_map(void) { + char buf[COLBUFSZ]; coordxy x, y; int glyph, skippedrows, lastnonblank; - unsigned subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON; - int default_glyph = cmap_to_glyph(svl.level.flags.arboreal ? S_tree - : S_stone); - char buf[COLBUFSZ]; boolean blankrow, toprow; + unsigned subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON; + /* cmap_to_glyph() evaluates its argument multiple times, so pull the + tree vs stone conditional out of it */ + nhsym default_sym = svl.level.flags.arboreal ? S_tree : S_stone; + int default_glyph = cmap_to_glyph(default_sym); /* * Squeeze out excess vertical space when dumping the map. From faca234055372488f1af12073b2edb7c3d58d120 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 23 Jul 2024 16:22:30 -0400 Subject: [PATCH 051/121] follow-up for dig_check changes Use the is_hole() macro to cover off holes and trapdoors. --- src/dig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dig.c b/src/dig.c index e1ec1439f..92d7cd771 100644 --- a/src/dig.c +++ b/src/dig.c @@ -234,7 +234,7 @@ dig_check(struct monst *madeby, coordxy x, coordxy y) return DIGCHECK_FAIL_UNDESTROYABLETRAP; } else if (!Can_dig_down(&u.uz) && !levl[x][y].candig) { if (ttmp) { - if (ttmp->ttyp != HOLE && !is_pit(ttmp->ttyp)) + if (!is_hole(ttmp->ttyp) && !is_pit(ttmp->ttyp)) return DIGCHECK_PASSED_DESTROY_TRAP; else return DIGCHECK_FAIL_CANTDIG; From d963c6dd6f3a5921acf4d4a9a6e46525b29aeeee Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 24 Jul 2024 11:01:23 -0700 Subject: [PATCH 052/121] github issue #1263 - lich attacks Issue reported by loggersviii: monsters killed by liches can produce corpses which auto-revive as zombies, but liches aren't able to harm zombies and get stuck in an endless slap fight when those revive. Liches have a touch attack for cold damage and they have a spell casting attack. They don't use their spell attack in monster vs monster combat, so cold resistant foes don't receive any damage. Prevent them from becoming harmless by changing the cold damage to physical damage if the target resists cold. Fixes #1263 --- include/permonst.h | 18 +++++++++--------- src/mhitu.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/include/permonst.h b/include/permonst.h index 436da22eb..6942ae247 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 permonst.h $NHDT-Date: 1596498555 2020/08/03 23:49:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.7 permonst.h $NHDT-Date: 1721844081 2024/07/24 18:01:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.25 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -11,14 +11,14 @@ enum monnums { #include "monsters.h" #undef MONS_ENUM NUMMONS, - NON_PM = -1, /* "not a monster */ - LOW_PM = NON_PM + 1, /* first monster in mons */ - LEAVESTATUE = NON_PM - 1, /* leave statue instead of corpse; - * there are two lower values assigned - * in end.c so that (x == LEAVESTATUE) - * will test FALSE in bones.c: - * (NON_PM - 2) for no corpse - * (NON_PM - 3) for no corpse, no grave */ + NON_PM = -1, /* "not a monster" */ + LOW_PM = NON_PM + 1, /* first monster in mons */ + LEAVESTATUE = NON_PM - 1, /* leave statue instead of corpse; + * there are two lower values assigned + * in end.c so that (x == LEAVESTATUE) + * will test FALSE in bones.c: + * (NON_PM - 2) for no corpse + * (NON_PM - 3) for no corpse, no grave */ HIGH_PM = NUMMONS - 1, SPECIAL_PM = PM_LONG_WORM_TAIL /* [normal] < ~ < [special] */ /* mons[SPECIAL_PM] through mons[NUMMONS-1], inclusive, are diff --git a/src/mhitu.c b/src/mhitu.c index 56c731425..9a5ebf830 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitu.c $NHDT-Date: 1689448844 2023/07/15 19:20:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ */ +/* NetHack 3.7 mhitu.c $NHDT-Date: 1721844072 2024/07/24 18:01:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.318 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -132,8 +132,10 @@ mswings( boolean bash) /* True: polearm used at too close range */ { if (flags.verbose && !Blind && mon_visible(mtmp)) { - pline_mon(mtmp, "%s %s %s%s %s.", Monnam(mtmp), mswings_verb(otemp, bash), - (otemp->quan > 1L) ? "one of " : "", mhis(mtmp), xname(otemp)); + pline_mon(mtmp, "%s %s %s%s %s.", Monnam(mtmp), + mswings_verb(otemp, bash), + (otemp->quan > 1L) ? "one of " : "", + mhis(mtmp), xname(otemp)); } } @@ -302,12 +304,15 @@ expels( /* select a monster's next attack, possibly substituting for its usual one */ struct attack * -getmattk(struct monst *magr, struct monst *mdef, - int indx, int prev_result[], struct attack *alt_attk_buf) +getmattk( + struct monst *magr, struct monst *mdef, + int indx, int prev_result[], + struct attack *alt_attk_buf) { struct permonst *mptr = magr->data; struct attack *attk = &mptr->mattk[indx]; struct obj *weap = (magr == &gy.youmonst) ? uwep : MON_WEP(magr); + boolean udefend = mdef == &gy.youmonst; /* honor SEDUCE=0 */ if (!SYSOPT_SEDUCE) { @@ -338,7 +343,7 @@ getmattk(struct monst *magr, struct monst *mdef, attk->adtyp = AD_STUN; /* make drain-energy damage be somewhat in proportion to energy */ - } else if (attk->adtyp == AD_DREN && mdef == &gy.youmonst) { + } else if (attk->adtyp == AD_DREN && udefend) { int ulev = max(u.ulevel, 6); *alt_attk_buf = *attk; @@ -400,7 +405,31 @@ getmattk(struct monst *magr, struct monst *mdef, *alt_attk_buf = *attk; attk = alt_attk_buf; attk->adtyp = AD_PHYS; + + /* liches have a touch attack for cold damage and also a spell attack; + they won't use the spell for monster vs monster so become impotent + aganst cold resistant foes; change the touch damage from cold to + physical if target will resist */ + } else if (indx == 0 && attk->aatyp == AT_TUCH && attk->adtyp == AD_COLD + && (udefend ? Cold_resistance : resists_cold(mdef)) + /* don't substitute if target is immune to normal damage */ + && mdef->data != &mons[PM_SHADE]) { + *alt_attk_buf = *attk; + attk = alt_attk_buf; + attk->adtyp = AD_PHYS; + /* lessen new physical damage compared to old cold damage: + * before after + * lich: 1d10 1d6 + * demi: 3d4 2d4 + * master: 3d6 2d6 + * arch-: 5d6 3d6 + */ + attk->damn = (attk->damn + 1) / 2; + if (attk->damd == 10) + attk->damd = 6; + } + return attk; } From 3913cebdb429d7f6445a199ae32be4af3b9219b6 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Fri, 26 Jul 2024 14:47:16 -0400 Subject: [PATCH 053/121] make "make fetch-lua" handle multiple lua versions --- sys/unix/Makefile.top | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 957bfe81e..4c7efb14d 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.top $NHDT-Date: 1693519381 2023/08/31 22:03:01 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.91 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1722019636 2024/07/26 18:47:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -353,8 +353,8 @@ fetch-Lua: export curlstatus=$$?; \ if [ $$curlstatus -eq 0 ]; then \ if [ ! -z "$$shac" ]; then \ - echo Checking integrity with $$shac; \ - $$shac -w -c ../submodules/CHKSUMS < lua-$(LUA_VERSION).tar.gz; \ + echo Checking integrity of lua-$(LUA_VERSION).tar.gz with $$shac; \ + $$shac -w --ignore-missing -c ../submodules/CHKSUMS < lua-$(LUA_VERSION).tar.gz; \ fi; \ tar zxf lua-$(LUA_VERSION).tar.gz && \ rm -f lua-$(LUA_VERSION).tar.gz; \ From c1d18e03eaaa4e8fd5e9b97a613e740552f5910e Mon Sep 17 00:00:00 2001 From: nhkeni Date: Fri, 26 Jul 2024 15:59:16 -0400 Subject: [PATCH 054/121] add checksum for lua 5.4.7 --- submodules/CHKSUMS | 1 + 1 file changed, 1 insertion(+) diff --git a/submodules/CHKSUMS b/submodules/CHKSUMS index 44ae314a0..bea046547 100644 --- a/submodules/CHKSUMS +++ b/submodules/CHKSUMS @@ -5,3 +5,4 @@ # generate: # shasum -a 256 FILETOCHECK >>THISFILE 7d5ea1b9cb6aa0b59ca3dde1c6adcb57ef83a1ba8e5432c0ecd06bf439b3ad88 lua-5.4.6.tar.gz +9fbf5e28ef86c69858f6d3d34eccc32e911c1a28b4120ff3e84aaa70cfbf1e30 lua-5.4.7.tar.gz From 5adabc07a3391e2ec7452d2c47b1d98dd0d9aa02 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 26 Jul 2024 14:53:33 -0700 Subject: [PATCH 055/121] missing comment: YMonnam() variant of x_monnam() YMonnam() was added three weeks ago but the comment preceding x_monnam() didn't get updated to list it. --- src/do_name.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/do_name.c b/src/do_name.c index 071539677..82c486451 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -790,6 +790,7 @@ rndghostname(void) * a_monnam: a newt it an invisible orc Fido * m_monnam: newt xan orc Fido * y_monnam: your newt your xan your invisible orc Fido + * YMonnam: Your newt Your xan Your invisible orc Fido * noname_monnam(mon,article): * article newt art xan art invisible orc art dog */ From 190aeb921b9070b06e69bc2733343e308ea8a325 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Fri, 26 Jul 2024 21:19:41 -0400 Subject: [PATCH 056/121] fetch-lua bits make it clearer how to change the fetch try order avoid odd output if more than one lua .gz file exists make it clearer if we don't have a checksum for a fetched file --- sys/unix/Makefile.top | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 3ed1433e1..f1501658a 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.top $NHDT-Date: 1722019636 2024/07/26 18:47:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1722043180 2024/07/27 01:19:40 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.108 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -323,6 +323,7 @@ dofiles-nodlb: LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty +LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) fetch-lua-mirror: LUA_URL :=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @@ -339,7 +340,7 @@ fetch-Lua: shac="$$shac1 -a 256"; elif [ ! -z $$shac2 ]; then \ shac=$$shac2; else echo "CAUTION: no way to check integrity"; \ fi; \ - set -- DUMMY $(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD); \ + set -- DUMMY $(LUA_URL_list); \ luafile=lua-$(LUA_VERSION).tar.gz; \ export curlstatus=1; \ mkdir -p lib && cd lib && \ @@ -347,13 +348,20 @@ fetch-Lua: shift; \ if [ $$curlstatus -ne 0 ]; then \ luaurl=https://$$1/$$luafile; \ - echo trying $$luaurl; \ + echo Trying $$luaurl; \ curl -R -O $$luaurl; \ curlstatus=$$?; \ if [ $$curlstatus -eq 0 ]; then \ if [ ! -z "$$shac" ]; then \ - echo Checking integrity of $$luafile with $$shac; \ - $$shac -w --ignore-missing -c ../submodules/CHKSUMS < $$luafile; \ + CHKSUMS=../submodules/CHKSUMS; \ + CHKSUMSTMP=../submodules/CHKSUMS.tmp; \ + fgrep $$luafile < $$CHKSUMS > $$CHKSUMSTMP; \ + if [ -z $$CHKSUMSTMP ]; then \ + echo "Cannot check $$luafile - no checksum known"; \ + else \ + echo Checking integrity of $$luafile with $$shac; \ + $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ + fi; \ fi; \ tar zxf $$luafile && \ rm -f $$luafile; \ From 2d68ee8f9f1903398fd8b7bdac19cb89ea7effe1 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 27 Jul 2024 14:49:17 -0700 Subject: [PATCH 057/121] fix #K4210 - vampshifter fog clouds Messaging for vampires changing into fog clouds was inconsistent in 3.6.x but already fixed in to-be-3.7. However, maintaining an extra set of shape change messages (one in newcham(), the other in vamp_shift() which turns out to only be used when a vampshifter turns into a fog cloud in order to pass under a closed door) was a nuisance. Redo vamp_shift() to use newcham() feedback. Update that feedback to be accessibility-aware and also to use "Your " instead of "The " when appropriate. While in there, remove a couple of trailing spaces and eliminate use of one dynamically constructed format string that necessitated warning manipulation. --- include/extern.h | 4 +- src/mon.c | 105 +++++++++++++++++++++++++---------------------- src/monmove.c | 83 +++++++++++++++++-------------------- 3 files changed, 96 insertions(+), 96 deletions(-) diff --git a/include/extern.h b/include/extern.h index 0be195583..27c308019 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1720128155 2024/07/04 21:22:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1430 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1722116044 2024/07/27 21:34:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1433 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1757,7 +1757,7 @@ extern void kill_genocided_monsters(void); extern void golemeffects(struct monst *, int, int); extern boolean angry_guards(boolean); extern void pacify_guards(void); -extern void decide_to_shapeshift(struct monst *, int) NONNULLARG1; +extern void decide_to_shapeshift(struct monst *) NONNULLARG1; extern boolean vamp_stone(struct monst *) NONNULLARG1; extern void check_gear_next_turn(struct monst *) NONNULLARG1; extern void copy_mextra(struct monst *, struct monst *); diff --git a/src/mon.c b/src/mon.c index da6efd321..97a7faed5 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1718303201 2024/06/13 18:26:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.576 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1722116051 2024/07/27 21:34:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.583 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -712,7 +712,7 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags) case PM_FIRE_ANT: case PM_GIANT_BEETLE: case PM_QUEEN_BEE: case PM_QUIVERING_BLOB: case PM_ACID_BLOB: case PM_GELATINOUS_CUBE: - case PM_CHICKATRICE: case PM_COCKATRICE: case PM_PYROLISK: + case PM_CHICKATRICE: case PM_COCKATRICE: case PM_PYROLISK: case PM_JACKAL: case PM_FOX: case PM_COYOTE: case PM_WEREJACKAL: case PM_LITTLE_DOG: case PM_DINGO: case PM_DOG: case PM_LARGE_DOG: @@ -780,7 +780,7 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags) case PM_GNOME: case PM_GNOME_LEADER: case PM_GNOMISH_WIZARD: case PM_GNOME_RULER: - case PM_GIANT: case PM_STONE_GIANT: case PM_HILL_GIANT: + case PM_GIANT: case PM_STONE_GIANT: case PM_HILL_GIANT: case PM_FIRE_GIANT: case PM_FROST_GIANT: case PM_ETTIN: case PM_STORM_GIANT: case PM_TITAN: @@ -1151,9 +1151,7 @@ m_calcdistress(struct monst *mtmp) /* possibly polymorph shapechangers and lycanthropes */ if (ismnum(mtmp->cham)) - decide_to_shapeshift(mtmp, (canspotmon(mtmp) - || engulfing_u(mtmp)) - ? SHIFT_MSG : 0); + decide_to_shapeshift(mtmp); were_change(mtmp); /* gradually time out temporary problems */ @@ -2808,8 +2806,6 @@ lifesaved_monster(struct monst *mtmp) } } -DISABLE_WARNING_FORMAT_NONLITERAL - /* when a shape-shifted vampire is killed, it reverts to base form instead of dying; moved into separate routine to unclutter mondead() */ staticfn boolean @@ -2820,7 +2816,7 @@ vamprises(struct monst *mtmp) if (ismnum(mndx) && mndx != monsndx(mtmp->data) && !(svm.mvitals[mndx].mvflags & G_GENOD)) { coord new_xy; - char buf[BUFSZ]; + char action[BUFSZ]; /* alternate message phrasing for some monster types */ boolean spec_mon = (nonliving(mtmp->data) || noncorporeal(mtmp->data) @@ -2830,13 +2826,12 @@ vamprises(struct monst *mtmp) || amorphous(mtmp->data)); coordxy x = mtmp->mx, y = mtmp->my; - /* construct a format string before transformation; - will be capitalized when used, expects one %s arg */ - Snprintf(buf, sizeof buf, - "%s suddenly %s and rises as %%s!", + /* construct a 'before' argument to pass to pline(); this used + to construct a dynamic format string but that's overkill */ + Snprintf(action, sizeof action, "%s suddenly %s and rises as", x_monnam(mtmp, ARTICLE_THE, spec_mon ? (char *) 0 : "seemingly dead", - (SUPPRESS_INVISIBLE | SUPPRESS_IT), FALSE), + (SUPPRESS_INVISIBLE | AUGMENT_IT), FALSE), spec_death ? "reconstitutes" : "transforms"); mtmp->mcanmove = 1; mtmp->mfrozen = 0; @@ -2857,19 +2852,16 @@ vamprises(struct monst *mtmp) rloc_to(mtmp, new_xy.x, new_xy.y); } (void) newcham(mtmp, &mons[mndx], NO_NC_FLAGS); - if (mtmp->data == &mons[mndx]) - mtmp->cham = NON_PM; - else - mtmp->cham = mndx; + mtmp->cham = (mtmp->data == &mons[mndx]) ? NON_PM : mndx; if (canspotmon(mtmp)) { /* 3.6.0 used a_monnam(mtmp); that was weird if mtmp was named: "Dracula suddenly transforms and rises as Dracula"; 3.6.1 used mtmp->data->mname; that ignored hallucination */ - pline_mon(mtmp, upstart(buf), - x_monnam(mtmp, ARTICLE_A, (char *) 0, + pline_mon(mtmp, "%s %s!", upstart(action), + x_monnam(mtmp, ARTICLE_A, (char *) 0, (SUPPRESS_NAME | SUPPRESS_IT | SUPPRESS_INVISIBLE), - FALSE)); + FALSE)); gv.vamp_rise_msg = TRUE; } newsym(x, y); @@ -2878,8 +2870,6 @@ vamprises(struct monst *mtmp) return FALSE; } -RESTORE_WARNING_FORMAT_NONLITERAL - /* specific combination of x_monnam flags for livelogging; show what was actually killed even when unseen or hallucinated to be something else */ #define livelog_mon_nam(mtmp) \ @@ -4671,16 +4661,12 @@ pick_animal(void) } void -decide_to_shapeshift(struct monst *mon, int shiftflags) +decide_to_shapeshift(struct monst *mon) { struct permonst *ptr = 0; int mndx; unsigned was_female = mon->female; - boolean msg = FALSE, dochng = FALSE; - - if ((shiftflags & SHIFT_MSG) - || ((shiftflags & SHIFT_SEENMSG) && sensemon(mon))) - msg = TRUE; + boolean dochng = FALSE; if (!is_vampshifter(mon)) { /* regular shapeshifter */ @@ -4729,11 +4715,27 @@ decide_to_shapeshift(struct monst *mon, int shiftflags) } } if (dochng) { - if (newcham(mon, ptr, msg ? NC_SHOW_MSG : 0) && is_vampshifter(mon)) { - /* for vampshift, override the 10% chance for sex change */ - ptr = mon->data; - if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr)) - mon->female = was_female; + unsigned ncflags = (is_vampshifter(mon) || canspotmon(mon)) + ? NC_SHOW_MSG : 0U; + + if (!ncflags) { + /* cheat */ + struct permonst *oldptr = mon->data; + + mon->data = ptr; + if (canspotmon(mon)) + ncflags = NC_SHOW_MSG; + mon->data = oldptr; + } + + if (newcham(mon, ptr, ncflags)) { + /* for vampshift, override the 10% chance for sex change + (by forcing original gender in case that occurred) */ + if (is_vampshifter(mon)) { + ptr = mon->data; + if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr)) + mon->female = was_female; + } } } } @@ -5077,10 +5079,11 @@ newcham( { boolean polyspot = ((ncflags & NC_VIA_WAND_OR_SPELL) !=0), /* "The oldmon turns into a newmon!" */ - msg = ((ncflags & NC_SHOW_MSG) != 0); + msg = ((ncflags & NC_SHOW_MSG) != 0), + seenorsensed = canspotmon(mtmp); int hpn, hpd, mndx, tryct; struct permonst *olddata = mtmp->data; - char *p, oldname[BUFSZ], l_oldname[BUFSZ], newname[BUFSZ]; + char *p, oldname[BUFSZ], l_oldname[BUFSZ]; /* Riders are immune to polymorph and green slime (but apparent Rider might actually be a doppelganger) */ @@ -5101,9 +5104,10 @@ newcham( } if (msg) { - /* like Monnam() but never mention saddle */ - Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0, - SUPPRESS_SADDLE, FALSE)); + Strcpy(oldname, + /* like YMonnam() but never mention saddle */ + x_monnam(mtmp, mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE, + (char *) 0, SUPPRESS_SADDLE, FALSE)); oldname[0] = highc(oldname[0]); } /* we need this one whether msg is true or not */ @@ -5251,17 +5255,20 @@ newcham( newsym(mtmp->mx, mtmp->my); if (msg) { - Strcpy(newname, noname_monnam(mtmp, ARTICLE_A)); - /* oldname was capitalized above; newname will be lower case */ - if (!strcmpi(newname, "it")) { /* can't see or sense it now */ - if (!!strcmpi(oldname, "it")) /* could see or sense it before */ - pline("%s disappears!", oldname); + /* oldname is capitalized and might be an assigned name */ + if (!canspotmon(mtmp)) { /* can't see or sense it now */ + if (seenorsensed) /* could see or sense it before */ + pline_mon(mtmp, "%s disappears!", oldname); (void) usmellmon(mdat); - } else { /* can see or sense it now */ - if (!strcmpi(oldname, "it")) /* couldn't see or sense it before */ - pline("%s appears!", upstart(newname)); - else - pline("%s turns into %s!", oldname, newname); + } else if (!seenorsensed) { /* couldn't see/sense before, can now */ + char *mnm = x_monnam(mtmp, mtmp->mtame ? ARTICLE_YOUR : ARTICLE_A, + (char *) 0, 0, FALSE); + + pline_mon(mtmp, "%s appears!", upstart(mnm)); + } else { /* saw/sensed it before, still see/sense it now */ + pline_mon(mtmp, "%s turns into %s!", oldname, + /* "a " even if it has a name assigned */ + noname_monnam(mtmp, ARTICLE_A)); } } diff --git a/src/monmove.c b/src/monmove.c index 0c563c3de..5822d5fc9 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monmove.c $NHDT-Date: 1701435190 2023/12/01 12:53:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.229 $ */ +/* NetHack 3.7 monmove.c $NHDT-Date: 1722116054 2024/07/27 21:34:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.255 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -18,9 +18,9 @@ staticfn boolean holds_up_web(coordxy, coordxy); staticfn int count_webbing_walls(coordxy, coordxy); staticfn boolean soko_allow_web(struct monst *); staticfn boolean m_search_items(struct monst *, coordxy *, coordxy *, int *, - int *); + int *) NONNULLPTRS; staticfn int postmov(struct monst *, struct permonst *, coordxy, coordxy, int, - boolean, boolean, boolean, boolean); + unsigned, boolean, boolean, boolean) NONNULLPTRS; staticfn boolean leppie_avoidance(struct monst *); staticfn void leppie_stash(struct monst *); staticfn boolean m_balks_at_approaching(struct monst *); @@ -598,19 +598,20 @@ mind_blast(struct monst *mtmp) } } -/* called every turn for each living monster on the map, - and the hero */ +/* called every turn for each living monster on the map, and the hero; + caller makes sure that we're not called for DEADMONSTER() */ void m_everyturn_effect(struct monst *mtmp) { boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux : mtmp->mx, - y = is_u ? u.uy : mtmp->my; + y = is_u ? u.uy : mtmp->my; if (mtmp->data == &mons[PM_FOG_CLOUD]) { - NhRegion *reg = visible_region_at(x, y); - - if (!reg) + /* don't leave a vapor cloud if some other gas cloud is already + present, or when flowing under closed doors so that visibility + changes aren't mixed with messages about doing such */ + if (!closed_door(x, y) && !visible_region_at(x, y)) create_gas_cloud(x, y, 1, 0); /* harmless vapor */ } } @@ -626,7 +627,7 @@ m_postmove_effect(struct monst *mtmp) { boolean is_u = (mtmp == &gy.youmonst) ? TRUE : FALSE; coordxy x = is_u ? u.ux0 : mtmp->mx, - y = is_u ? u.uy0 : mtmp->my; + y = is_u ? u.uy0 : mtmp->my; /* Hezrous create clouds of stench. This does not cost a move. */ if (mtmp->data == &mons[PM_HEZROU]) /* stench */ @@ -1371,7 +1372,7 @@ m_search_items( } } -finish_search: + finish_search: if (minr < SQSRCHRADIUS && *appr == -1) { if (distmin(omx, omy, mtmp->mux, mtmp->muy) <= 3) { *ggx = mtmp->mux; @@ -1390,7 +1391,7 @@ postmov( struct permonst *ptr, coordxy omx, coordxy omy, int mmoved, - boolean sawmon, + unsigned seenflgs, boolean can_tunnel, boolean can_unlock, boolean can_open) @@ -1419,15 +1420,18 @@ postmov( && IS_DOOR(levl[nix][niy].typ) && ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0) && can_fog(mtmp)) { - if (sawmon) { + /* note: remove_monster()+place_monster is not right for + long worms but they won't reach here */ + if (seenflgs) { remove_monster(nix, niy); place_monster(mtmp, omx, omy); newsym(nix, niy), newsym(omx, omy); } - if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) { + if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], + ((seenflgs & 1) != 0) ? TRUE : FALSE)) { ptr = mtmp->data; /* update cached value */ } - if (sawmon) { + if (seenflgs) { remove_monster(omx, omy); place_monster(mtmp, nix, niy); newsym(omx, omy), newsym(nix, niy); @@ -1475,7 +1479,7 @@ postmov( if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0 && amorphous(ptr)) { if (flags.verbose && canseemon(mtmp)) - pline_mon(mtmp, "%s %s under the door.", Monnam(mtmp), + pline_mon(mtmp, "%s %s under the door.", YMonnam(mtmp), (ptr == &mons[PM_FOG_CLOUD] || ptr->mlet == S_LIGHT) ? "flows" : "oozes"); } else if (here->doormask & D_LOCKED && can_unlock) { @@ -1647,7 +1651,7 @@ m_move(struct monst *mtmp, int after) boolean getitems = FALSE; boolean avoid = FALSE; boolean better_with_displacing = FALSE; - boolean sawmon = canspotmon(mtmp); /* before it moved */ + unsigned seenflgs; struct permonst *ptr; int chi, mmoved = MMOVE_NOTHING; /* not strictly nec.: chi >= 0 will do */ long info[9]; @@ -1673,9 +1677,13 @@ m_move(struct monst *mtmp, int after) return MMOVE_DONE; /* still eating */ } if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) - && can_hide_under_obj(svl.level.objects[mtmp->mx][mtmp->my]) && rn2(10)) + && can_hide_under_obj(svl.level.objects[mtmp->mx][mtmp->my]) + && rn2(10)) return MMOVE_NOTHING; /* do not leave hiding place */ + /* set up pre-move visibility flags */ + seenflgs = (canseemon(mtmp) ? 1 : 0) | (canspotmon(mtmp) ? 2 : 0); + /* Where does 'mtmp' think you are? Not necessary if m_move() called from this file, but needed for other calls of m_move(). */ set_apparxy(mtmp); /* set mtmp->mux, mtmp->muy */ @@ -1691,7 +1699,7 @@ m_move(struct monst *mtmp, int after) /* my dog gets special treatment */ if (mtmp->mtame) { return postmov(mtmp, ptr, omx, omy, dog_move(mtmp, after), - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); } /* and the acquisitive monsters get special treatment */ @@ -1720,7 +1728,7 @@ m_move(struct monst *mtmp, int after) mmoved = MMOVE_NOTHING; } return postmov(mtmp, ptr, omx, omy, mmoved, - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); } /* likewise for shopkeeper, guard, or priest */ @@ -1742,7 +1750,7 @@ m_move(struct monst *mtmp, int after) case 1: return postmov(mtmp, ptr, omx, omy, (xm != 1) ? MMOVE_NOTHING : MMOVE_MOVED, - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); } } @@ -1765,7 +1773,7 @@ m_move(struct monst *mtmp, int after) else mnexto(mtmp, RLOC_MSG); return postmov(mtmp, ptr, omx, omy, MMOVE_MOVED, - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); } not_special: if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp) @@ -1825,7 +1833,7 @@ m_move(struct monst *mtmp, int after) if (getitems && m_search_items(mtmp, &ggx, &ggy, &mmoved, &appr)) return postmov(mtmp, ptr, omx, omy, mmoved, - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); /* don't tunnel if hostile and close enough to prefer a weapon */ if (can_tunnel && needspick(ptr) @@ -1988,7 +1996,7 @@ m_move(struct monst *mtmp, int after) worm_nomove(mtmp); } return postmov(mtmp, ptr, omx, omy, mmoved, - sawmon, can_tunnel, can_unlock, can_open); + seenflgs, can_tunnel, can_unlock, can_open); } /* The part of m_move that deals with a monster attacking another monster (and @@ -2287,6 +2295,9 @@ can_fog(struct monst *mtmp) return FALSE; } +/* this is called when a vampire turns into a fog cloud in order to move + under a closed door; if it was sensed via telepathy or seen via + infravision, its new fog cloud shape will disappear */ staticfn int vamp_shift( struct monst *mon, @@ -2294,34 +2305,16 @@ vamp_shift( boolean domsg) { int reslt = 0; - char oldmtype[BUFSZ]; - boolean sawmon = canseemon(mon); /* before shape change */ - - /* remember current monster type before shapechange */ - Strcpy(oldmtype, domsg ? noname_monnam(mon, ARTICLE_THE) : ""); if (mon->data == ptr) { /* already right shape */ reslt = 1; - domsg = FALSE; } else if (is_vampshifter(mon)) { - reslt = newcham(mon, ptr, NO_NC_FLAGS); - } - - if (reslt && domsg) { - /* might have seen vampire/bat/wolf with infravision then be - unable to see the same creature when it turns into a fog cloud */ - if (canspotmon(mon)) - You("%s %s where %s was.", - !canseemon(mon) ? "now detect" : "observe", - noname_monnam(mon, ARTICLE_A), oldmtype); - else - You("can no longer %s %s.", sawmon ? "see" : "sense", oldmtype); - /* this message is given when it turns into a fog cloud - in order to move under a closed door */ + reslt = newcham(mon, ptr, domsg ? NC_SHOW_MSG : NO_NC_FLAGS); + /* shape-change message is given when vampshifter turns into a + fog cloud in order to move under a closed door */ display_nhwindow(WIN_MESSAGE, FALSE); } - return reslt; } From 93ece2c9b4c7c52e8d3e22bc5b73d972778c0e84 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sat, 27 Jul 2024 18:24:41 -0400 Subject: [PATCH 058/121] update fetch-lua-TARGET targets --- sys/unix/Makefile.top | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index f1501658a..adaf5cbe8 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.top $NHDT-Date: 1722043180 2024/07/27 01:19:40 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.108 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1722119081 2024/07/27 22:24:41 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.109 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -325,10 +325,14 @@ LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) -fetch-lua-mirror: LUA_URL :=$(LUA_URL_MIRROR) +fetch-lua-mirror: LUA_URL_list:=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @true +fetch-lua-nhd: LUA_URL_list:=$(LUA_URL_NHD) +fetch-lua-nhd: fetch-Lua + @true + fetch-lua: fetch-Lua @true From 4353ee49d82abc848fb2d6f46165dac144b1325e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 28 Jul 2024 12:24:36 -0400 Subject: [PATCH 059/121] sed substitution went too far (wasm cross-compile) Also, link with hacklib --- sys/libnh/libnhmain.c | 6 +++--- sys/unix/hints/include/cross-post.370 | 4 ++-- sys/unix/hints/include/cross-pre2.370 | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 06f8c93d0..d43cdc362 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -227,7 +227,7 @@ nhmain(int argc, char *argv[]) /* wizard mode access is deferred until here */ set_playmode(); /* sets plname to "wizard" for wizard mode */ /* hide any hyphens from plnamesuffix() */ - svp.plnamelen = exact_username ? (int) strlen(svp.plname) : 0; + gp.plnamelen = exact_username ? (int) strlen(svp.plname) : 0; /* strip role,race,&c suffix; calls askname() if plname[] is empty or holds a generic user name like "player" or "games" */ plnamesuffix(); @@ -382,12 +382,12 @@ process_options(int argc, char *argv[]) case 'u': if (argv[0][2]) { (void) strncpy(svp.plname, argv[0] + 2, sizeof svp.plname - 1); - svp.plnamelen = 0; /* plname[] might have -role-race attached */ + gp.plnamelen = 0; /* plname[] might have -role-race attached */ } else if (argc > 1) { argc--; argv++; (void) strncpy(svp.plname, argv[0], sizeof svp.plname - 1); - svp.plnamelen = 0; + gp.plnamelen = 0; } else { raw_print("Player name expected after -u"); } diff --git a/sys/unix/hints/include/cross-post.370 b/sys/unix/hints/include/cross-post.370 index f8106995a..557b3504a 100644 --- a/sys/unix/hints/include/cross-post.370 +++ b/sys/unix/hints/include/cross-post.370 @@ -82,10 +82,10 @@ dodata: endif # CROSS_TO_MSDOS ifdef CROSS_TO_WASM -$(WASM_TARGET): pregame $(TARGETPFX)date.o $(HOSTOBJ) $(HOBJ) $(LUACROSSLIB) $(WASM_DATA_DIR) +$(WASM_TARGET): pregame $(TARGET_HACKLIB) $(TARGETPFX)date.o $(HOSTOBJ) $(HOBJ) $(LUACROSSLIB) $(WASM_DATA_DIR) -rm $@ $(TARGET_CC) $(TARGET_LFLAGS) $(TARGET_CFLAGS) -o $@ \ - $(HOBJ) $(TARGETPFX)date.o $(TARGET_LIBS) + $(HOBJ) $(TARGETPFX)date.o $(TARGET_HACKLIB) $(TARGET_LIBS) $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/perm diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.370 index 55294e286..fa5f0911c 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.370 @@ -275,7 +275,8 @@ WASM_CFLAGS += -Wshadow # Nethack C flags WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.370 WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -WASM_CFLAGS += -g -I../include -DNOTPARMDECL +#WASM_CFLAGS += -g -I../include -DNOTPARMDECL +WASM_CFLAGS += -I../include -DNOTPARMDECL # NetHack sources control WASM_CFLAGS += -DDLB WASM_CFLAGS += -DHACKDIR=\"$(HACKDIR)\" From e911c71320834252ed8cccca479420fd2dac19f0 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 29 Jul 2024 23:58:55 -0700 Subject: [PATCH 060/121] Guidebook: more map symbols --- doc/Guidebook.mn | 7 ++++++- doc/Guidebook.tex | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 37b04a2f2..e4aec2f8d 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -46,7 +46,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y) -.ds f2 July 16, 2024 +.ds f2 July 29, 2024 . .\" A note on some special characters: .\" \(lq = left double quote @@ -533,6 +533,11 @@ Rather than a specific type of monster, this marks the last known location of an invisible or otherwise unseen monster. Note that the monster could have moved. The \(oqs\(cq, \(oqF\(cq, and \(oqm\(cq commands may be useful here. +.lp \f(CR1\fP-\f(CR5\fP +The digits 1 through 5 may be displayed, marking unseen monsters sensed +via the \fIWarning\fP attribute. +Less dangerous monsters are indicated by lower values, more dangerous by +higher values. .pg You need not memorize all these symbols; you can ask the game what any symbol represents with the \(oq/\(cq command (see the next section for diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 0ef3cdc1b..5d66c9c1c 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -48,7 +48,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)} -\date{July 16, 2024} +\date{July 29, 2024} \maketitle @@ -587,6 +587,11 @@ Rather than a specific type of monster, this marks the last known location of an invisible or otherwise unseen monster. Note that the monster could have moved. The `{\tt s}', `{\tt F}', and `{\tt m}' commands may be useful here. +\item[\tb{1-5}] +The digits 1 through 5 may be displayed, marking unseen monsters sensed +via the {\it Warning\/} attribute. +Less dangerous monsters are indicated by lower values, more dangerous by +higher values. \elist %.pg From e5504367550ecb906f6f06f8479c2b78b1ad6190 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 30 Jul 2024 11:52:34 -0700 Subject: [PATCH 061/121] shapechanger crash fix A recent change was setting mon->data prior to canspotmon(mon) but that triggered a crash if the temporary mon->data was Null. All the testing was done with vampshifers and this affects non-vampshifers. Push even more shapechange messaging into newcham() by not trying to determine whether requesting a message from it will oblige. --- src/mon.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/mon.c b/src/mon.c index 97a7faed5..b11b6cdf3 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1722116051 2024/07/27 21:34:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.583 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1722365546 2024/07/30 18:52:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.584 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4669,7 +4669,7 @@ decide_to_shapeshift(struct monst *mon) boolean dochng = FALSE; if (!is_vampshifter(mon)) { - /* regular shapeshifter */ + /* regular shapeshifter; 'ptr' is Null */ if (!rn2(6)) dochng = TRUE; } else if (!(mon->mstrategy & STRAT_WAITFORU)) { @@ -4715,20 +4715,7 @@ decide_to_shapeshift(struct monst *mon) } } if (dochng) { - unsigned ncflags = (is_vampshifter(mon) || canspotmon(mon)) - ? NC_SHOW_MSG : 0U; - - if (!ncflags) { - /* cheat */ - struct permonst *oldptr = mon->data; - - mon->data = ptr; - if (canspotmon(mon)) - ncflags = NC_SHOW_MSG; - mon->data = oldptr; - } - - if (newcham(mon, ptr, ncflags)) { + if (newcham(mon, ptr, NC_SHOW_MSG)) { /* for vampshift, override the 10% chance for sex change (by forcing original gender in case that occurred) */ if (is_vampshifter(mon)) { From 35dfcb6810bb8944bc27214a7310193ae9a621b4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 1 Aug 2024 09:57:18 -0400 Subject: [PATCH 062/121] NetHack Daily Cron Output (1 commits) --- doc/Guidebook.txt | 2936 +++++++++++++++++++++++---------------------- 1 file changed, 1501 insertions(+), 1435 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 0e08d3e33..26ff90445 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for NetHack 3.7.0 by Mike Stephenson and others) - February 29, 2024 + July 29, 2024 @@ -126,7 +126,7 @@ - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -258,7 +258,7 @@ - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -324,7 +324,7 @@ - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -390,7 +390,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -450,13 +450,13 @@ game uses; otherwise, the game will use default symbols. Here is a list of what the default symbols mean: - - and | - The walls of a room, or an open door. Or a grave (|). + - The horizontal or corner walls of a room, or an open east/west + door. - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -466,10 +466,17 @@ - . The floor of a room, ice, or a doorless doorway. + | The vertical walls of a room, or an open north/south door, or a + grave. - # A corridor, or iron bars, or a tree, or possibly a kitchen sink - (if your dungeon has sinks), or a drawbridge. + . The floor of a room, or ice, or a doorless doorway, or the span + of an open drawbridge. + + # A corridor, or iron bars, or a tree, or the portcullis of a + closed drawbridge. + + Note: engravings in corridors also appear as # but are shown in a + different color from normal corridor locations. > Stairs down: a way to the next level. @@ -478,7 +485,7 @@ + A closed door, or a spellbook containing a spell you may be able to learn. - @ Your character or a human. + @ Your character or a human or an elf. $ A pile of gold. @@ -504,25 +511,18 @@ * A gem or rock (possibly valuable, possibly worthless). - ` A boulder or statue. + ` A boulder or statue or an engraving on the floor of a room. + + Note: statues are displayed as if they were the monsters they de- + pict so won't appear as a grave accent (aka back-tick). 0 An iron ball. _ An altar, or an iron chain. - { A fountain. - - } A pool of water or moat or a pool of lava. - - \ An opulent throne. - - a-zA-Z and other symbols - Letters and certain other symbols represent the various inhabi- - tants of the Mazes of Menace. Watch out, they can be nasty and - vicious. Sometimes, however, they can be helpful. - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -532,63 +532,63 @@ - I This marks the last known location of an invisible or otherwise - unseen monster. Note that the monster could have moved. The `F' - and `m' commands may be useful here. + { A fountain or a sink. - You need not memorize all these symbols; you can ask the game - what any symbol represents with the `/' command (see the next section + } A pool of water or moat or a wall of water or a pool of lava or a + wall of lava. + + \ An opulent throne. + + a-z and + + A-Z and + + @&':; + Letters and certain other symbols represent the various inhabi- + tants of the Mazes of Menace. Watch out, they can be nasty and + vicious. Sometimes, however, they can be helpful. + + I Rather than a specific type of monster, this marks the last known + location of an invisible or otherwise unseen monster. Note that + the monster could have moved. The `s', `F', and `m' commands may + be useful here. + + 1-5 The digits 1 through 5 may be displayed, marking unseen monsters + sensed via the Warning attribute. Less dangerous monsters are + indicated by lower values, more dangerous by higher values. + + You need not memorize all these symbols; you can ask the game + what any symbol represents with the `/' command (see the next section for more info). 4. Commands - Commands can be initiated by typing one or two characters to - which the command is bound to, or typing the command name in the ex- - tended commands entry. Some commands, like "search", do not require - that any more information be collected by NetHack. Other commands - might require additional information, for example a direction, or an - object to be used. For those commands that require additional infor- + Commands can be initiated by typing one or two characters to + which the command is bound to, or typing the command name in the ex- + tended commands entry. Some commands, like "search", do not require + that any more information be collected by NetHack. Other commands + might require additional information, for example a direction, or an + object to be used. For those commands that require additional infor- mation, NetHack will present you with either a menu of choices or with a command line prompt requesting information. Which you are presented with will depend chiefly on how you have set the menustyle option. - For example, a common question, in the form "What do you want to - use? [a-zA-Z ?*]", asks you to choose an object you are carrying. - Here, "a-zA-Z" are the inventory letters of your possible choices. - Typing `?' gives you an inventory list of these items, so you can see - what each letter refers to. In this example, there is also a `*' in- - dicating that you may choose an object not on the list, if you wanted - to use something unexpected. Typing a `*' lists your entire inven- + For example, a common question, in the form "What do you want to + use? [a-zA-Z ?*]", asks you to choose an object you are carrying. + Here, "a-zA-Z" are the inventory letters of your possible choices. + Typing `?' gives you an inventory list of these items, so you can see + what each letter refers to. In this example, there is also a `*' in- + dicating that you may choose an object not on the list, if you wanted + to use something unexpected. Typing a `*' lists your entire inven- tory, so you can see the inventory letters of every object you're car- - rying. Finally, if you change your mind and decide you don't want to + rying. Finally, if you change your mind and decide you don't want to do this command after all, you can press the ESC key to abort the com- mand. - You can put a number before some commands to repeat them that - many times; for example, "10s" will search ten times. If you have the - number_pad option set, you must type `n' to prefix a count, so the ex- - ample above would be typed "n10s" instead. Commands for which counts - make no sense ignore them. In addition, movement commands can be pre- - fixed for greater control (see below). To cancel a count or a prefix, - press the ESC key. - - The list of commands is rather long, but it can be read at any - time during the game through the `?' command, which accesses a menu of - helpful texts. Here are the default key bindings for your reference: - - ? Help menu: display one of several help texts available. - - / The "whatis" command, to tell what a symbol represents. You may - choose to specify a location or type a symbol (or even a whole - word) to explain. Specifying a location is done by moving the - cursor to a particular spot on the map and then pressing one of - `.', `,', `;', or `:'. `.' will explain the symbol at the chosen - location, conditionally check for "More info?" depending upon - whether the help option is on, and then you will be asked to pick - another location; `,' will explain the symbol but skip any - NetHack 3.7.0 February 29, 2024 + + NetHack 3.7.0 July 29, 2024 @@ -598,38 +598,72 @@ - additional information, then let you pick another location; `;' - will skip additional info and also not bother asking you to - choose another location to examine; `:' will show additional - info, if any, without asking for confirmation. When picking a - location, pressing the ESC key will terminate this command, or - pressing `?' will give a brief reminder about how it works. + You can put a number before some commands to repeat them that + many times; for example, "10s" will search ten times. If you have the + number_pad option set, you must type `n' to prefix a count, so the ex- + ample above would be typed "n10s" instead. Commands for which counts + make no sense ignore them. In addition, movement commands can be pre- + fixed for greater control (see below). To cancel a count or a prefix, + press the ESC key. + + The list of commands is rather long, but it can be read at any + time during the game through the `?' command, which accesses a menu of + helpful texts. Here are the default key bindings for your reference: + + ? Help menu: display one of several help texts available. + + / The "whatis" command, to tell what a symbol represents. You may + choose to specify a location or type a symbol (or even a whole + word) to explain. Specifying a location is done by moving the + cursor to a particular spot on the map and then pressing one of + `.', `,', `;', or `:'. `.' will explain the symbol at the chosen + location, conditionally check for "More info?" depending upon + whether the help option is on, and then you will be asked to pick + another location; `,' will explain the symbol but skip any addi- + tional information, then let you pick another location; `;' will + skip additional info and also not bother asking you to choose an- + other location to examine; `:' will show additional info, if any, + without asking for confirmation. When picking a location, press- + ing the ESC key will terminate this command, or pressing `?' will + give a brief reminder about how it works. If the autodescribe option is on, a short description of what you see at each location is shown as you move the cursor. Typing `#' - while picking a location will toggle that option on or off. The - whatis_coord option controls whether the short description in- + while picking a location will toggle that option on or off. The + whatis_coord option controls whether the short description in- cludes map coordinates. - Specifying a name rather than a location always gives any addi- + Specifying a name rather than a location always gives any addi- tional information available about that name. - You may also request a description of nearby monsters, all mon- - sters currently displayed, nearby objects, or all objects. The - whatis_coord option controls which format of map coordinate is + You may also request a description of nearby monsters, all mon- + sters currently displayed, nearby objects, or all objects. The + whatis_coord option controls which format of map coordinate is included with their descriptions. & Tell what a command does. - < Go up to the previous level (if you are on a staircase or lad- + < Go up to the previous level (if you are on a staircase or lad- der). > Go down to the next level (if you are on a staircase or ladder). [yuhjklbn] - Go one step in the direction indicated (see Figure 3). If you + Go one step in the direction indicated (see Figure 3). If you sense or remember a monster there, you will fight the monster in- - stead. Only these one-step movement commands cause you to fight + stead. Only these one-step movement commands cause you to fight + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 11 + + + monsters; the others (below) are "safe." +----------------------------------------------------------------+ | y k u 7 8 9 | @@ -648,39 +682,27 @@ remember a monster there). A few non-movement commands use the `m' prefix to request operat- - ing via menu (to temporarily override the menustyle:traditional - option). Primarily useful for `,' (pickup) when there is only - one class of objects present (where there won't be any "what - kinds of objects?" prompt, so no opportunity to answer `m' at - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 11 - - - + ing via menu (to temporarily override the menustyle:traditional + option). Primarily useful for `,' (pickup) when there is only + one class of objects present (where there won't be any "what + kinds of objects?" prompt, so no opportunity to answer `m' at that prompt). The prefix will make "#travel" command show a menu of interesting - targets in sight. It can also be used with the `\' (known, show + targets in sight. It can also be used with the `\' (known, show a list of all discovered objects) and the ``' (knownclass, show a list of discovered objects in a particular class) commands to of- - fer a menu of several sorting alternatives (which sets a new + fer a menu of several sorting alternatives (which sets a new value for the sortdiscoveries option); also for "#vanquished" and "#genocided" commands to offer a sorting menu. - A few other commands (eat food, offer sacrifice, apply tinning- - kit, drink/quaff, dip, tip container) use the `m' prefix to skip - checking for applicable objects on the floor and go straight to - checking inventory, or (for "#loot" to remove a saddle), skip + A few other commands (eat food, offer sacrifice, apply tinning- + kit, drink/quaff, dip, tip container) use the `m' prefix to skip + checking for applicable objects on the floor and go straight to + checking inventory, or (for "#loot" to remove a saddle), skip containers and go straight to adjacent monsters. - In debug mode (aka "wizard mode"), the `m' prefix may also be + In debug mode (aka "wizard mode"), the `m' prefix may also be used with the "#teleport" and "#wizlevelport" commands. F[yuhjklbn] @@ -690,37 +712,15 @@ Prefix: move until something interesting is found. G[yuhjklbn] or +[yuhjklbn] - Prefix: similar to `g', but forking of corridors is not consid- + Prefix: similar to `g', but forking of corridors is not consid- ered interesting. - Note: + means holding the or key - down like while typing and releasing , then releas- - ing . ^ is used as shorthand elsewhere in the - Guidebook to mean the same thing. Control characters are case- - insensitive so ^x and ^X are the same. - - M[yuhjklbn] - Old versions supported `M' as a movement prefix which combined - the effect of `m' with +. That is no longer - supported as a prefix but similar effect can be achieved by using - `m' and G in combination. m can also be used in com- - bination with g, +, or - +. - - _ Travel to a map location via a shortest-path algorithm. - - The shortest path is computed over map locations the hero knows - about (e.g. seen or previously traversed). If there is no known - path, a guess is made instead. Stops on most of the same condi- - tions as the `G' prefix, but without picking up objects, so im- - plicitly forces the `m' prefix. For ports with mouse support, - the command is also invoked when a mouse-click takes place on a - location other than the current position. + Note: + means holding the or key + down like while typing and releasing , then releas- + ing . ^ is used as shorthand elsewhere in the - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -730,18 +730,39 @@ + Guidebook to mean the same thing. Control characters are case- + insensitive so ^x and ^X are the same. + + M[yuhjklbn] + Old versions supported `M' as a movement prefix which combined + the effect of `m' with +. That is no longer + supported as a prefix but similar effect can be achieved by using + `m' and G in combination. m can also be used in com- + bination with g, +, or + +. + + _ Travel to a map location via a shortest-path algorithm. + + The shortest path is computed over map locations the hero knows + about (e.g. seen or previously traversed). If there is no known + path, a guess is made instead. Stops on most of the same condi- + tions as the `G' prefix, but without picking up objects, so im- + plicitly forces the `m' prefix. For ports with mouse support, + the command is also invoked when a mouse-click takes place on a + location other than the current position. + . Wait or rest, do nothing for one turn. Precede with the `m' pre- - fix to wait for a turn even next to a hostile monster, if + fix to wait for a turn even next to a hostile monster, if safe_wait is on. a Apply (use) a tool (pick-axe, key, lamp...). - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. A Remove one or more worn items, such as armor. - Use `T' (take off) to take off only one piece of armor or `R' + Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. ^A Repeat the previous command. @@ -762,10 +783,23 @@ In answer to the question + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 13 + + + "What kinds of things do you want to drop? [!%= BUCXPaium]" - you should type zero or more object symbols possibly followed by - `a' and/or `i' and/or `u' and/or `m'. In addition, one or more + you should type zero or more object symbols possibly followed by + `a' and/or `i' and/or `u' and/or `m'. In addition, one or more of the blessed/uncursed/cursed groups may be typed. DB - drop all objects known to be blessed. @@ -779,34 +813,22 @@ Dm - use a menu to pick which object(s) to drop. D%u - drop only unpaid food. - The last example shows a combination. There are four categories + The last example shows a combination. There are four categories of object filtering: class (`!' for potions, `?' for scrolls, and so on), shop status (`u' for unpaid, in other words, owned by the shop), bless/curse state (`B', `U', `C', and `X' as shown above), and novelty (`P', recently picked up items; controlled by picking - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 13 - - - up or dropping things rather than by any time factor). - If you specify more than one value in a category (such as "!?" + If you specify more than one value in a category (such as "!?" for potions and scrolls or "BU" for blessed and uncursed), an in- - ventory object will meet the criteria if it matches any of the + ventory object will meet the criteria if it matches any of the specified values (so "!?" means `!' or `?'). If you specify more than one category, an inventory object must meet each of the cat- egory criteria (so "%u" means class `%' and unpaid `u'). Lastly, - you may specify multiple values within multiple categories: - "!?BU" will select all potions and scrolls which are known to be - blessed or uncursed. (In versions prior to 3.6, filter combina- + you may specify multiple values within multiple categories: + "!?BU" will select all potions and scrolls which are known to be + blessed or uncursed. (In versions prior to 3.6, filter combina- tions behaved differently.) ^D Kick something (usually a door). @@ -815,44 +837,22 @@ Normally checks for edible item(s) on the floor, then if none are found or none are chosen, checks for edible item(s) in inventory. - Precede `e' with the `m' prefix to bypass attempting to eat any- + Precede `e' with the `m' prefix to bypass attempting to eat any- thing off the floor. - If you attempt to eat while already satiated, you might choke to - death. If you risk it, you will be asked whether to "continue - eating?" if you survive the first bite. You can set the para- - noid_confirmation:eating option to require a response of yes in- + If you attempt to eat while already satiated, you might choke to + death. If you risk it, you will be asked whether to "continue + eating?" if you survive the first bite. You can set the para- + noid_confirmation:eating option to require a response of yes in- stead of just y. E Engrave a message on the floor. E- - write in the dust with your fingers. - Engraving the word "Elbereth" will cause most monsters to not at- - tack you hand-to-hand (but if you attack, you will rub it out); - this is often useful to give yourself a breather. - - f Fire (shoot or throw) one of the objects placed in your quiver - (or quiver sack, or that you have at the ready). You may select - ammunition with a previous `Q' command, or let the computer pick - something appropriate if autoquiver is true. If your wielded - weapon has the throw-and-return property, your quiver is empty, - and autoquiver is false, you will throw that wielded weapon in- - stead of filling the quiver. This will also automatically use a - polearm if wielded. If fireassist is true, firing will automati- - cally try to wield a launcher (for example, a bow or a sling) - matching the ammo in the quiver; this might take multiple turns, - and get interrupted by a monster. Remember to swap back to your - main melee weapon afterwards. - - See also `t' (throw) for more general throwing and shooting. - - i List your inventory (everything you're carrying). - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -862,8 +862,29 @@ - I List selected parts of your inventory, usually be specifying the - character for a particular set of objects, like `[' for armor or + Engraving the word "Elbereth" will cause most monsters to not at- + tack you hand-to-hand (but if you attack, you will rub it out); + this is often useful to give yourself a breather. + + f Fire (shoot or throw) one of the objects placed in your quiver + (or quiver sack, or that you have at the ready). You may select + ammunition with a previous `Q' command, or let the computer pick + something appropriate if autoquiver is true. If your wielded + weapon has the throw-and-return property, your quiver is empty, + and autoquiver is false, you will throw that wielded weapon in- + stead of filling the quiver. This will also automatically use a + polearm if wielded. If fireassist is true, firing will automati- + cally try to wield a launcher (for example, a bow or a sling) + matching the ammo in the quiver; this might take multiple turns, + and get interrupted by a monster. Remember to swap back to your + main melee weapon afterwards. + + See also `t' (throw) for more general throwing and shooting. + + i List your inventory (everything you're carrying). + + I List selected parts of your inventory, usually be specifying the + character for a particular set of objects, like `[' for armor or `!' for potions. I* - list all gems in inventory; @@ -880,45 +901,24 @@ O Set options. - A menu showing the current option values will be displayed. You + A menu showing the current option values will be displayed. You can change most values simply by selecting the menu entry for the - given option (ie, by typing its letter or clicking upon it, de- - pending on your user interface). For the non-boolean choices, a - further menu or prompt will appear once you've closed this menu. - The available options are listed later in this Guidebook. Op- - tions are usually set before the game rather than with the `O' - command; see the section on options below. Precede `O' with the + given option (ie, by typing its letter or clicking upon it, de- + pending on your user interface). For the non-boolean choices, a + further menu or prompt will appear once you've closed this menu. + The available options are listed later in this Guidebook. Op- + tions are usually set before the game rather than with the `O' + command; see the section on options below. Precede `O' with the `m' prefix to show advanced options. ^O Show overview. - Shortcut for "#overview": list interesting dungeon levels vis- + Shortcut for "#overview": list interesting dungeon levels vis- ited. - (Prior to 3.6.0, `^O' was a debug mode command which listed the - placement of all special levels. Use "#wizwhere" to run that - command.) - - p Pay your shopping bill. - - P Put on an accessory (ring, amulet, or blindfold). - - This command may also be used to wear armor. The prompt for - which inventory item to use will only list accessories, but - choosing an unlisted item of armor will attempt to wear it. (See - the `W' command below. It lists armor as the inventory choices - but will accept an accessory and attempt to put that on.) - - ^P Repeat previous message. - - Subsequent `^P's repeat earlier messages. For some interfaces, - the behavior can be varied via the msg_window option. - - q Quaff (drink) something (potion, water, etc). - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -928,12 +928,33 @@ - When there is a fountain or sink present, it asks whether to + (Prior to 3.6.0, `^O' was a debug mode command which listed the + placement of all special levels. Use "#wizwhere" to run that + command.) + + p Pay your shopping bill. + + P Put on an accessory (ring, amulet, or blindfold). + + This command may also be used to wear armor. The prompt for + which inventory item to use will only list accessories, but + choosing an unlisted item of armor will attempt to wear it. (See + the `W' command below. It lists armor as the inventory choices + but will accept an accessory and attempt to put that on.) + + ^P Repeat previous message. + + Subsequent `^P's repeat earlier messages. For some interfaces, + the behavior can be varied via the msg_window option. + + q Quaff (drink) something (potion, water, etc). + + When there is a fountain or sink present, it asks whether to drink from that. If that is declined, then it offers a chance to - choose a potion from inventory. Precede `q' with the `m' prefix + choose a potion from inventory. Precede `q' with the `m' prefix to skip asking about drinking from a fountain or sink. - Q Select an object for your quiver, quiver sack, or just generally + Q Select an object for your quiver, quiver sack, or just generally at the ready (only one of these is available at a time). You can then throw this (or one of these) using the `f' command. @@ -946,45 +967,24 @@ be removed without asking, but you can set the paranoid_confirma- tion:Remove option to require a prompt. - This command may also be used to take off armor. The prompt for - which inventory item to remove only lists worn accessories, but + This command may also be used to take off armor. The prompt for + which inventory item to remove only lists worn accessories, but an item of worn armor can be chosen. (See the `T' command below. It lists armor as the inventory choices but will accept an acces- sory and attempt to remove it.) ^R Redraw the screen. - s Search for secret doors and traps around you. It usually takes - several tries to find something. Precede with the `m' prefix to + s Search for secret doors and traps around you. It usually takes + several tries to find something. Precede with the `m' prefix to search for a turn even next to a hostile monster, if safe_wait is on. - Can also be used to figure out whether there is still a monster + Can also be used to figure out whether there is still a monster at an adjacent "remembered, unseen monster" marker. - S Save the game (which suspends play and exits the program). The - saved game will be restored automatically the next time you play - using the same character name. - In normal play, once a saved game is restored the file used to - hold the saved data is deleted. In explore mode, once restora- - tion is accomplished you are asked whether to keep or delete the - file. Keeping the file makes it feasible to play for a while - then quit without saving and later restore again. - - There is no "save current game state and keep playing" command, - not even in explore mode where saved game files can be kept and - re-used. - - t Throw an object or shoot a projectile. - - There's no separate "shoot" command. If you throw an arrow while - wielding a bow, you are shooting that arrow and any weapon skill - bonus or penalty for bow applies. If you throw an arrow while - not wielding a bow, you are throwing it by hand and it will - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -994,24 +994,44 @@ - generally be less effective than when shot. + S Save the game (which suspends play and exits the program). The + saved game will be restored automatically the next time you play + using the same character name. + + In normal play, once a saved game is restored the file used to + hold the saved data is deleted. In explore mode, once restora- + tion is accomplished you are asked whether to keep or delete the + file. Keeping the file makes it feasible to play for a while + then quit without saving and later restore again. + + There is no "save current game state and keep playing" command, + not even in explore mode where saved game files can be kept and + re-used. + + t Throw an object or shoot a projectile. + + There's no separate "shoot" command. If you throw an arrow while + wielding a bow, you are shooting that arrow and any weapon skill + bonus or penalty for bow applies. If you throw an arrow while + not wielding a bow, you are throwing it by hand and it will gen- + erally be less effective than when shot. See also `f' (fire) for throwing or shooting an item pre-selected via the `Q' (quiver) command, with some extra assistance. T Take off armor. - If you're wearing more than one piece, you'll be prompted for + If you're wearing more than one piece, you'll be prompted for which one to take off. (Note that this treats a cloak covering a suit and/or a shirt, or a suit covering a shirt, as if the under- - lying items weren't there.) When you're only wearing one, then - by default it will be taken off without asking, but you can set + lying items weren't there.) When you're only wearing one, then + by default it will be taken off without asking, but you can set the paranoid_confirmation:Remove option to require a prompt. - This command may also be used to remove accessories. The prompt + This command may also be used to remove accessories. The prompt for which inventory item to take off only lists worn armor, but a - worn accessory can be chosen. (See the `R' command above. It - lists accessories as the inventory choices but will accept an + worn accessory can be chosen. (See the `R' command above. It + lists accessories as the inventory choices but will accept an item of armor and attempt to take it off.) ^T Teleport, if you have the ability. @@ -1024,33 +1044,13 @@ w- - wield nothing, use your bare (or gloved) hands. - Some characters can wield two weapons at once; use the `X' com- + Some characters can wield two weapons at once; use the `X' com- mand (or the "#twoweapon" extended command) to do so. - W Wear armor. - - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to - use will only list armor, but choosing an unlisted accessory will - attempt to put it on. (See the `P' command above. It lists ac- - cessories as the inventory choices but will accept an item of ar- - mor and attempt to wear it.) - - x Exchange your wielded weapon with the item in your alternate - weapon slot. - - The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the ex- - change still takes place. - - X Toggle two-weapon combat, if your character can do it. Also - available via the "#twoweapon" extended command. - - (In versions prior to 3.6 this keystroke ran the command to - switch from normal play to "explore mode", also known as - NetHack 3.7.0 February 29, 2024 + + NetHack 3.7.0 July 29, 2024 @@ -1060,8 +1060,28 @@ - "discovery mode", which has now been moved to "#exploremode" and - M-X.) + W Wear armor. + + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to + use will only list armor, but choosing an unlisted accessory will + attempt to put it on. (See the `P' command above. It lists ac- + cessories as the inventory choices but will accept an item of ar- + mor and attempt to wear it.) + + x Exchange your wielded weapon with the item in your alternate + weapon slot. + + The latter is used as your secondary weapon when engaging in two- + weapon combat. Note that if one of these slots is empty, the ex- + change still takes place. + + X Toggle two-weapon combat, if your character can do it. Also + available via the "#twoweapon" extended command. + + (In versions prior to 3.6 this keystroke ran the command to + switch from normal play to "explore mode", also known as "discov- + ery mode", which has now been moved to "#exploremode" and M-X.) ^X Display basic information about your character. @@ -1090,6 +1110,22 @@ : Look at what is here. + + + __________ + (R)UNIX is a registered trademark of The Open Group. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 18 + + + ; Show what type of thing a visible symbol corresponds to. , Pick up some things from the floor beneath you. @@ -1110,22 +1146,6 @@ ( Tell what tools you are using. - - - __________ - (R)UNIX is a registered trademark of The Open Group. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 18 - - - * Tell what equipment you are using. Combines the preceding five type-specific commands into one. @@ -1160,6 +1180,18 @@ Allows scrolling with the menu_first_page, menu_previous_page, menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 19 + + + default). Some interfaces also support menu_shift_left and menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. @@ -1179,19 +1211,6 @@ command. If that happens, you can use the extended command "#terrain" instead. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 19 - - - # Perform an extended command. @@ -1227,6 +1246,18 @@ ent slot. In that situation, moving (no count given) a compati- ble stack will merge if either stack has a name when the other doesn't and give that name to the result, while splitting (count + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 20 + + + given) will ignore the source stack's name when deciding whether to merge with the destination stack. @@ -1246,18 +1277,6 @@ If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 20 - - - #attributes Show your attributes. Default key is `^X'. @@ -1293,6 +1312,18 @@ See the section below entitled "Conduct" for details. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 21 + + + #debugfuzzer Start the fuzz tester. Debug mode only. @@ -1312,18 +1343,6 @@ #droptype Drop specific item types. Default key is `D'. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 21 - - - #eat Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. @@ -1360,6 +1379,17 @@ mode and debug mode it also shows types which have become ex- tinct. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 22 + + + The display order is the same as is used by #vanquished. The `m' prefix brings up a menu of available sorting orders, and doing that for either #genocided or #vanquished changes the order for @@ -1377,20 +1407,8 @@ is `;'. #help - Show the help menu. Default key is `?', and also `h' if - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 22 - - - - number_pad is on. + Show the help menu. Default key is `?', and also `h' if num- + ber_pad is on. #herecmdmenu Show a menu of possible actions directed at your current loca- @@ -1425,6 +1443,19 @@ #known Show what object types have been discovered. Default key is `\'. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 23 + + + The `m' prefix allows assigning a new value to the sortdiscover- ies option to control the order in which the discoveries are dis- played. @@ -1444,18 +1475,6 @@ #look Look at what is here, under you. Default key is `:'. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 23 - - - #lookaround Describe what you can see, or remember, of your surroundings. @@ -1491,6 +1510,18 @@ Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 24 + + + #optionsfull Show advanced game option settings. No default key. Precede with the `m' prefix to execute the simpler options command. @@ -1511,17 +1542,6 @@ This will also force all visited levels to be displayed rather than just the "interesting" subset. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 24 - - - Autocompletes. Default keys are `^O', and `M-O'. #panic @@ -1556,6 +1576,18 @@ (Hint: entering the dungeon alive is treated as having received help. You probably shouldn't start off a new game by praying right away.) Since using this command by accident can cause + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 25 + + + trouble, there is an option to make you confirm your intent be- fore praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. @@ -1575,19 +1607,6 @@ #quit Quit the program without saving your game. Autocompletes. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 25 - - - Since using this command by accident would throw away the current game, you are asked to confirm your intent before quitting. De- fault response is n (no); continue playing. To really quit, re- @@ -1624,6 +1643,17 @@ Ride (or stop riding) a saddled creature. Autocompletes. De- fault key is `M-R'. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 26 + + + #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. @@ -1641,21 +1671,9 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 26 - - - - overwrite the file, removing all comments, so if you have manu- - ally edited the config file, don't use this. + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually + edited the config file, don't use this. #search Search for traps and secret doors around you. Default key is @@ -1690,6 +1708,18 @@ Will display the result in a message if there is one tool in use (worn blindfold or towel or lenses, lit lamp(s) and/or candle(s), + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 27 + + + leashes attached to pets). Will display a menu if there are more than one or if the command is preceded by the `m' prefix. @@ -1709,17 +1739,6 @@ ration file. Use the shell command `exit' to return to the game. Default key is `!'. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 27 - - - #showgold Report the gold in your inventory, including gold you know about in containers you're carrying. If you are inside a shop, report @@ -1754,6 +1773,19 @@ #takeoff Take off one piece of armor. Default key is `T'. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 28 + + + #takeoffall Remove all armor. Default key is `A'. @@ -1773,19 +1805,6 @@ Autocompletes. Default key is `' or `' (see Del above). - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 28 - - - #therecmdmenu Show a menu of possible actions directed at a location next to you. The menu is limited to a subset of the likeliest actions, @@ -1822,6 +1841,17 @@ #turn Turn undead away. Autocompletes. Default key is `M-t'. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 29 + + + #twoweapon Toggle two-weapon combat on or off. Autocompletes. Default key is `X', and also `M-2' if number_pad is off. @@ -1839,19 +1869,6 @@ #up Go up a staircase. Default key is `<'. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 29 - - - #vanquished List vanquished monsters by type and count. @@ -1889,6 +1906,18 @@ the running copy was built from sources (not the version's re- lease date). Default key is `v'. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 30 + + + #vision Show vision array. Autocompletes. Debug mode only. @@ -1906,18 +1935,6 @@ Show what type of thing a symbol corresponds to. Default key is `/'. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 30 - - - #wield Wield a weapon. Default key is `w'. @@ -1955,6 +1972,18 @@ #wizkill Remove monsters from play by just pointing at them. By default the hero gets credit or blame for killing the targets. Precede + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 31 + + + this command with the `m' prefix to override that. Autocom- pletes. Debug mode only. @@ -1973,17 +2002,6 @@ Also displays first, second, and last random engravings, epi- taphs, and hallucinatory monsters. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 31 - - - Autocompletes. Debug mode only. #wizseenv @@ -2020,6 +2038,18 @@ On Windows and MS-DOS, the "Alt" key can be used in this fashion. On other systems, if typing "Alt" plus another key transmits a two character sequence consisting of an Escape followed by the other key, + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 32 + + + you may set the altmeta option to have NetHack combine them into meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- @@ -2037,19 +2067,6 @@ M-2 #twoweapon (unless the number_pad option is enabled) - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 32 - - - M-a #adjust M-A #annotate @@ -2086,6 +2103,19 @@ M-R #ride + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 33 + + + M-s #sit M-t #turn @@ -2104,18 +2134,6 @@ - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 33 - - - If the number_pad option is on, some additional letter commands are available: @@ -2152,6 +2170,18 @@ doors; you can walk right through. Others have doors in them, which may be open, closed, or locked. To open a closed door, use the `o' (open) command; to close it again, use the `c' (close) command. By + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 34 + + + default the autoopen option is enabled, so simply attempting to walk onto a closed door's location will attempt to open it without needing `o'. Opening via autoopen will not work if you are confused or @@ -2170,18 +2200,6 @@ tool, you'll be asked whether to use it on the door's lock. Alterna- tively, you can break a closed door (whether locked or not) down by kicking it via the `^D' (kick) command. Kicking down a door destroys - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 34 - - - it and makes a lot of noise which might wake sleeping monsters. Some closed doors are booby-trapped and will explode if an at- @@ -2218,6 +2236,18 @@ the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 35 + + + Monsters can fall prey to traps, too, which can potentially be used as a defensive strategy. Unfortunately traps can be harmful to your pet(s) as well. Monsters, including pets, usually will avoid @@ -2236,18 +2266,6 @@ to another level, but one which is always below the current level. Usually that will be the next level down but it can be farther. Un- like (level) teleporters, the destination level of a particular trap - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 35 - - - door or hole is persistent, so falling into one will bring you to the same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- @@ -2283,6 +2301,19 @@ tion for information about getting feedback for your actions in Sokoban. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 36 + + + 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going @@ -2302,18 +2333,6 @@ created (from scratch for most random levels, from a template for some "special" levels, or loaded from the remains of an earlier game for a "bones" level as briefly described below). Monsters are only active - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 36 - - - on the current level; those on other levels are essentially placed into stasis. @@ -2349,6 +2368,18 @@ usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 37 + + + Shopkeepers sometime run out of money. When that happens, you'll be offered credit instead of gold when you try to sell something. Credit can be used to pay for purchases, but it is only good in the @@ -2367,19 +2398,6 @@ Several aspects of shop behavior might be unexpected. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 37 - - - * The price of a given item can vary due to a variety of factors. * A shopkeeper treats the spot immediately inside the door as if it @@ -2417,6 +2435,17 @@ movement direction to step on objects without attempting auto-pickup and without giving feedback about them. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 38 + + + The mention_walls option controls whether you get feedback if you try to walk into a wall or solid stone or off the edge of the map. Normally nothing happens (unless the hero is blind and no wall is @@ -2434,18 +2463,6 @@ doors are. Assuming that you're able to do so, moving onto water or lava or ice will give feedback if not yet on that type of terrain but not repeat it (unless there has been some intervening message) when - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 38 - - - moving from water to another water spot, or lava to lava, or ice to ice. Moving off of any of those back onto "normal" terrain will give one message too, unless there is feedback about one or more objects, @@ -2482,6 +2499,19 @@ The slight strangeness of this level is a feature, not a bug.... + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 39 + + + 6. Monsters Monsters you cannot see are not displayed on the screen. Beware! @@ -2501,17 +2531,6 @@ get to choose what you'll say), but chatting with some monsters such as a shopkeeper or the Oracle of Delphi can produce useful results. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 39 - - - 6.1. Fighting If you see a monster and you wish to fight it, just attempt to @@ -2547,6 +2566,18 @@ Your pet also gains experience from killing monsters, and can grow over time, gaining hit points and doing more damage. Initially, + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 40 + + + your pet may even be better at killing things than you, which makes pets useful for low-level characters. @@ -2566,18 +2597,6 @@ has had to resort to magic and wizardry in order to forge the al- liance. Once you do have the beast under your control however, you can easily climb in and out of the saddle with the "#ride" command. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 40 - - - Lead the beast around the dungeon when riding, in the same manner as you would move yourself. It is the beast that you will see displayed on the map. @@ -2613,6 +2632,18 @@ However, if you encounter a monster which you can't see or sense--perhaps it is invisible and has just tapped you on the noggin-- + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 41 + + + a special "remembered, unseen monster" marker will be displayed at the location where you think it is. That will persist until you have proven that there is no monster there, even if the unseen monster @@ -2632,18 +2663,6 @@ As you add items to your inventory, you also add the weight of that object to your load. The amount that you can carry depends on - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 41 - - - your strength and your constitution. The stronger and sturdier you are, the less the additional load will affect you. There comes a point, though, when the weight of all of that stuff you are carrying @@ -2679,6 +2698,18 @@ an object which has already been named, specifying a space as the value will remove the prior name instead of assigning a new one. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 42 + + + 7.1. Curses and Blessings Any object that you find may be cursed, even if the object is @@ -2698,18 +2729,6 @@ uncursed. They could just as easily have been described as unblessed, but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 42 - - - you will. There are magical means of bestowing or removing curses upon ob- @@ -2745,6 +2764,18 @@ There are wielded weapons, like maces and swords, and thrown weapons, like arrows and spears. To hit monsters with a weapon, you + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 43 + + + must wield it and attack them, or throw it at them. You can simply elect to throw a spear. To shoot an arrow, you should first wield a bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings @@ -2764,18 +2795,6 @@ ficiency (see below). The monster's armor class--a general defense rating, not necessarily due to wearing of armor--is a factor too; also, some monsters are particularly vulnerable to certain types of - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 43 - - - weapons. Many weapons can be wielded in one hand; some require both hands. @@ -2811,6 +2830,18 @@ You can throw just about anything via the `t' command. It will prompt for the item to throw; picking `?' will list things in your in- ventory which are considered likely to be thrown, or picking `*' will + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 44 + + + list your entire inventory. After you've chosen what to throw, you will be prompted for a direction rather than for a specific target. The distance something can be thrown depends mainly on the type of ob- @@ -2830,18 +2861,6 @@ You can simplify the throwing operation by using the `Q' command to select your preferred "missile", then using the `f' command to throw it. You'll be prompted for a direction as above, but you don't - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 44 - - - have to specify which item to throw each time you use `f'. There is also an option, autoquiver, which has NetHack choose another item to automatically fill your quiver (or quiver sack, or have at the ready) @@ -2878,6 +2897,17 @@ you progress through a game, depending on your role, your experience level, and use of the weapons. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 45 + + + For the purposes of proficiency, weapons have been divided up into various groups such as daggers, broadswords, and polearms. Each role has a limit on what level of proficiency a character can achieve @@ -2896,18 +2926,6 @@ barehanded combat or martial arts skill beyond expert to "master" or "grand master". - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 45 - - - Use of a weapon in which you're restricted or unskilled will in- cur a modest penalty in the chance to hit a monster and also in the amount of damage done when you do hit; at basic level, there is no @@ -2944,6 +2962,18 @@ the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 46 + + + The whole process can be simplified via use of the pushweapon op- tion. When it is enabled, then using `w' to wield something causes the currently wielded weapon to become your alternate weapon. So the @@ -2962,18 +2992,6 @@ yourself from their blows. Some types of armor offer better protec- tion than others. Your armor class is a measure of this protection. Armor class (AC) is measured as in AD&D, with 10 being the equivalent - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 46 - - - of no armor, and lower numbers meaning better armor. Each suit of ar- mor which exists in AD&D gives the same protection in NetHack. @@ -3010,6 +3028,18 @@ pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 47 + + + Many types of armor are subject to some kind of damage like rust. Such damage can be repaired. Some types of armor may inhibit spell casting. @@ -3028,18 +3058,6 @@ Food is necessary to survive. If you go too long without eating you will faint, and eventually die of starvation. Some types of food - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 47 - - - will spoil, and become unhealthy to eat, if not protected. Food stored in ice boxes or tins ("cans") will usually stay fresh, but ice boxes are heavy, and tins take a while to open. @@ -3076,6 +3094,18 @@ appearing in your system mailbox, you must let NetHack know where to look for new mail by setting the "MAIL" environment variable to the file name of your mailbox. You may also want to set the "MAILREADER" + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 48 + + + environment variable to the file name of your favorite reader, so NetHack can shell to it when you read the scroll. On versions of NetHack where mail is randomly generated internal to the game, these @@ -3095,17 +3125,6 @@ at them. It is also sometimes very useful to dip ("#dip") an object into a potion. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 48 - - - The command to drink a potion is `q' (quaff). 7.7. Wands (`/') @@ -3139,6 +3158,20 @@ The command to use a wand is `z' (zap). To break one, use the `a' (apply) command. + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 49 + + + 7.8. Rings (`=') Rings are very useful items, since they are relatively permanent @@ -3160,18 +3193,6 @@ The commands to use rings are `P' (put on) and `R' (remove). `A', `W', and `T' can also be used; see Amulets. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 49 - - - 7.9. Spellbooks (`+') Spellbooks are tomes of mighty magic. When studied with the `r' @@ -3204,11 +3225,23 @@ become proficient (to varying degrees), spells are similarly grouped. Successfully casting a spell exercises its skill group; using the "#enhance" command to advance a sufficiently exercised skill will af- - fect all spells within the group. Advanced skill may increase the po- - tency of spells, reduce their risk of failure during casting attempts, - and improve the accuracy of the estimate for how much longer they will - be retained in your memory. Skill slots are shared with weapons - skills. (See also the section on "Weapon proficiency".) + fect all spells within the group. Advanced skill may increase the + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 50 + + + + potency of spells, reduce their risk of failure during casting at- + tempts, and improve the accuracy of the estimate for how much longer + they will be retained in your memory. Skill slots are shared with + weapons skills. (See also the section on "Weapon proficiency".) Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. @@ -3226,18 +3259,6 @@ ple, lamps burn out after a while. Other tools are containers, which objects can be placed into or taken out of. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 50 - - - Some tools (such as a blindfold) can be worn and can be put on and removed like other accessories (rings, amulets); see Amulets. Other tools (such as pick-axe) can be wielded as weapons in addition @@ -3271,6 +3292,18 @@ example, the 3 refers to number of stacks of compatible items, not to the total number of individual items. So a sack holding 2 sky blue potions, 7 arrows, and 350 gold pieces would be described as having 3 + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 51 + + + items rather than 10 or 359. And you would need to have 3 unused in- ventory slots available in order to take everything out (for the case where the items you remove don't combine into bigger stacks with @@ -3289,21 +3322,6 @@ tents into another container. (As of this writing, the other con- tainer must be carried rather than on the floor.) - - - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 51 - - - 7.11. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like @@ -3340,6 +3358,18 @@ Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or you can smash it into a pile of small rocks with breaking magic or a + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 52 + + + pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing it any further be blocked. Using the move-without-picking-up prefix @@ -3358,18 +3388,6 @@ shown as ``' but by the letter representing the monster they depict instead. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 52 - - - 7.14. Gold (`$') Gold adds to your score, and you can buy things in shops with it. @@ -3404,6 +3422,20 @@ enabled in order to show an item differently when it is the top one of a pile. + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 53 + + + 8. Conduct As if winning NetHack were not difficult enough, certain players @@ -3425,17 +3457,6 @@ your god for help with starvation does not violate any food challenges either. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 53 - - - A strict vegan diet is one which avoids any food derived from an- imals. The primary source of nutrition is fruits and vegetables. The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') are @@ -3469,6 +3490,18 @@ corpse. Please note that the term "vegan" is used here only in the context of diet. You are still free to choose not to use or wear items derived from animals (e.g. leather, dragon hide, bone, horns, + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 54 + + + coral), but the game will not keep track of this for you. Also note that "milky" potions may be a translucent white, but they do not con- tain milk, so they are compatible with a vegan diet. Slime molds or @@ -3491,17 +3524,6 @@ and kick weapons; use a wand, spell, or other type of item; or fight with your hands and feet. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 54 - - - In NetHack, a pacifist refuses to cause the death of any other monster (i.e. if you would get experience for the death). This is a particularly difficult challenge, although it is still possible to @@ -3533,8 +3555,20 @@ you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be displayed if you have entered the Sokoban branch of the dungeon during - the current game. Once that has happened, it becomes part of dis- - closed conduct even if you haven't done anything interesting there. + the current game. Once that has happened, it becomes part of + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 55 + + + + disclosed conduct even if you haven't done anything interesting there. Ending the game with "never broke the Sokoban rules" conduct is most meaningful if you also manage to perform the "obtained the Sokoban prize" achievement (see Achievements below).) @@ -3555,19 +3589,6 @@ to make a wish for an item, you may choose "nothing" if you want to decline. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 55 - - - 8.1. Achievements End of game disclosure will also display various achievements @@ -3601,6 +3622,18 @@ Invocation - Gained access to the bottommost level of Gehennom. Amulet - Acquired the fabled Amulet of Yendor. Endgame - Reached the Elemental Planes. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 56 + + + Astral - Reached the Astral Plane level. Blind - Blind from birth. Deaf - Deaf from birth. @@ -3622,18 +3655,6 @@ There's no guaranteed Novel so the achievement to read one might not always be attainable (except perhaps by wishing). Similarly, the Big Room level is not always present. Unlike with the Novel, there's - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 56 - - - no way to wish for this opportunity. The "special items" hidden in Mines' End and Sokoban are not @@ -3667,6 +3688,18 @@ Options may be set in a number of ways. Within the game, the `O' command allows you to view all options and change most of them. You can also set options automatically by placing them in a configuration + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 57 + + + file, or in the NETHACKOPTIONS environment variable. Some versions of NetHack also have front-end programs that allow you to set options be- fore starting the game or a global configuration for system adminis- @@ -3689,17 +3722,6 @@ "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 57 - - - On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. Any line in the configuration file starting with `#' is treated @@ -3732,6 +3754,18 @@ tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 58 + + + Example: OPTIONS=dogname:Fido @@ -3754,18 +3788,6 @@ The location that bones files are kept. Defaults to HACKDIR, must be writable. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 58 - - - LOCKDIR The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. @@ -3799,6 +3821,17 @@ BIND=^X:getpos.autodescribe + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 59 + + + CHOOSE Chooses at random one of the comma-separated parameters as an active section name. Lines in other sections are ignored. @@ -3820,18 +3853,6 @@ MENUCOLOR Highlight menu lines with different colors. See the "Configuring - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 59 - - - Menu Colors" section. MSGTYPE @@ -3864,31 +3885,10 @@ line, up to a maximum of 128 lines. Each line is processed by the function that handles wishing. - Example: - - WIZKIT=~/wizkit.txt - Here is an example of configuration file contents: - - - - - - - - - - - - - - - - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -3898,6 +3898,14 @@ + Example: + + WIZKIT=~/wizkit.txt + + + + Here is an example of configuration file contents: + # Set your character's role, race, gender, and alignment. OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful # @@ -3944,17 +3952,9 @@ The NETHACKOPTIONS value is effectively the same as a single OP- TIONS directive in a configuration file. The "OPTIONS=" prefix is im- plied and comma separated options are processed from right to left. - Other types of configuration directives such as BIND or MSGTYPE are - not allowed. - - Instead of a comma-separated list of options, NETHACKOPTIONS can - be set to the full name of a configuration file you want to use. If - that full name doesn't start with a slash, precede it with `@' (at- - sign) to let NetHack know that the rest is intended as a file name. - If it does start with `/', the at-sign is optional. - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -3964,6 +3964,15 @@ + Other types of configuration directives such as BIND or MSGTYPE are + not allowed. + + Instead of a comma-separated list of options, NETHACKOPTIONS can + be set to the full name of a configuration file you want to use. If + that full name doesn't start with a slash, precede it with `@' (at- + sign) to let NetHack know that the rest is intended as a file name. + If it does start with `/', the at-sign is optional. + 9.4. Customization options Here are explanations of what the various options do. Character @@ -4010,17 +4019,8 @@ See pickup_types and also autopickup_exception for ways to refine the behavior. - Note: prior to version 3.7.0, the default for autopickup was on. - autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make - ready some suitable weapon. Note that it will not take into account - the blessed/cursed status, enchantment, damage, or quality of the - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -4030,6 +4030,14 @@ + Note: prior to version 3.7.0, the default for autopickup was on. + + autoquiver + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make + ready some suitable weapon. Note that it will not take into account + the blessed/cursed status, enchantment, damage, or quality of the weapon; you are free to manually fill your quiver or quiver sack or make ready with the `Q' command instead. If no weapon is found or the option is false, the `t' (throw) command is executed instead. @@ -4076,17 +4084,9 @@ boulder Set the character used to display boulders (default is the "large - rock" class symbol, ``'). - - catname - Name your starting cat (for example "catname:Morris"). Cannot be - set with the `O' command. - - character - Synonym for "role" to pick the type of your character (for example - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -4096,6 +4096,14 @@ + rock" class symbol, ``'). + + catname + Name your starting cat (for example "catname:Morris"). Cannot be + set with the `O' command. + + character + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4143,16 +4151,8 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listings of vanquished monsters and of genocided types can be - sorted, so there are two additional choices for `v' and `g': - ? - prompt you and default to ask on the prompt; - # - disclose it without prompting, ask for sort order. - - Asking refers to picking one of the orderings from a menu. The `+' - - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -4162,9 +4162,16 @@ - disclose without prompting choice, or being prompted and answering - `y' rather than `a', will default to showing monsters in the order - specified by the sortvanquished option. + The listings of vanquished monsters and of genocided types can + be sorted, so there are two additional choices for `v' and `g': + + ? - prompt you and default to ask on the prompt; + # - disclose it without prompting, ask for sort order. + + Asking refers to picking one of the orderings from a menu. The + `+' disclose without prompting choice, or being prompted and + answering `y' rather than `a', will default to showing monsters + in the order specified by the sortvanquished option. Omitted categories are implicitly added with `n' prefix. Specified categories with omitted prefix implicitly use `+' prefix. Order of @@ -4209,16 +4216,9 @@ fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining - inventory letters. Persistent. - - force_invmenu - Commands asking for an inventory item show a menu instead of a text - query with possible menu letters. Default is off. - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -4228,6 +4228,13 @@ + on). If this is off, dropping an object shifts all the remaining + inventory letters. Persistent. + + force_invmenu + Commands asking for an inventory item show a menu instead of a text + query with possible menu letters. Default is off. + fruit Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy @@ -4275,16 +4282,9 @@ highlight pets and setting it will turn the hilite_pet option on or off as warranted. - hilite_pile - Visually distinguish piles of objects from individual objects (de- - fault off). The behavior of this option depends on the type of win- - dowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- - symbol beside the object on the top of the pile. - - NetHack 3.7.0 February 29, 2024 + NetHack 3.7.0 July 29, 2024 @@ -4294,9 +4294,34 @@ + hilite_pile + Visually distinguish piles of objects from individual objects (de- + fault off). The behavior of this option depends on the type of win- + dowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- + symbol beside the object on the top of the pile. + hitpointbar - Show a hit point bar graph behind your name and title. Only avail- - able for TTY and Windows GUI, and only when statushilites is on. + Show a hit point bar graph behind your name and title in the status + display (default off). + + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will + be used for the bar. However if it specifies video attributes, they + will be ignored in favor of inverse. For tty and curses, blink will + also be used if the current hitpoint value is at or below the criti- + cal HP threshold. + + The "Qt" interface also supports hitpointbar, by drawing a solid bar + above the name and title with a hard-coded color scheme. (As of + this writing, having the bar enabled unintentionally inhibits resiz- + ing the status panel. To resize that, use the #optionsfull command + to toggle the hitpointbar option off, perform the resize while it's + off, then use the same command to toggle it back on.) horsename Name your starting horse (for example "horsename:Trigger"). Cannot @@ -4323,6 +4348,18 @@ lootabc When using a menu to interact with a container, use the old `a', `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 67 + + + and `b' (default off). Persistent. mail @@ -4349,17 +4386,6 @@ Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 67 - - - menustyle Controls the method used when you need to choose various objects (in response to the Drop (aka droptype) command, for instance). The @@ -4388,6 +4414,18 @@ menu_first_page Key to jump to the first page in a menu. Default `^'. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 68 + + + menu_headings Controls how the headings in a menu are highlighted. Takes a text attribute, or text color and attribute separated by ampersand. For @@ -4414,18 +4452,6 @@ Do not clear the screen before drawing menus, and align menus to the right edge of the screen. Only for the tty port. (default on) - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 68 - - - menu_previous_page Key to go to the previous menu page. Default `<'. @@ -4453,6 +4479,19 @@ Show a message when hero notices a monster movement (default is off). + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 69 + + + monpolycontrol Prompt for new form whenever any monster changes shape (default off). Debug mode only. @@ -4480,18 +4519,6 @@ rently it is only supported for tty (all four choices) and for curses (`f' and `r' choices, default `r'). The possible values are: - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 69 - - - s - single message (default; only choice prior to 3.4.0); c - combination, two messages as "single", then as "full"; f - full window, oldest message first; @@ -4520,6 +4547,17 @@ null Send padding nulls to the terminal (default on). Persistent. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 70 + + + number_pad Use digit keys instead of letters to move (default 0 or off). Valid settings are: @@ -4547,21 +4585,10 @@ taining the symbols for the various object types. Any omitted types are filled in at the end from the previous order. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 70 - - - paranoid_confirmation A space separated list of specific situations where alternate prompting is desired. The default is "paranoid_confirmation:pray - swim". + swim trap". Confirm - for any prompts which are set to require "yes" rather than `y', also require "no" to reject instead of ac- @@ -4585,6 +4612,18 @@ immediately praying; on by default; (to require "yes" rather than just `y', set Confirm too); trap - require `y' to confirm an attempt to move into or onto + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 71 + + + a known trap, unless doing so is considered to be harmless; (to require "yes" rather than just `y', set Confirm too); confirmation can be skipped by using the @@ -4612,18 +4651,6 @@ and remove some old ones, you can use multiple paranoid_confirmation option settings, or you can use the `+' form and list entries to be added by their name and entries to be removed by `!' and name. The - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 71 - - - positive (no `!') and negative (with `!') entries can be intermixed. perm_invent @@ -4650,6 +4677,19 @@ Note: if gold has been equipped in quiver/ammo-pouch then it will be included for all despite that mode normally omitting gold. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 72 + + + petattr Specifies one or more text highlighting attributes to use when show- ing pets on the map. Effectively a superset of the hilite_pet bool- @@ -4678,18 +4718,6 @@ pickup_types or match an autopickup exception. Default is on. Per- sistent. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 72 - - - pickup_thrown If this option is on and autopickup is also on, try to pick up things that you threw, even if they aren't in pickup_types or match @@ -4716,6 +4744,18 @@ which the message "there are few/several/many objects here" is given instead of showing a popup list of those objects. A value of 0 means "no limit" (always list the objects); a value of 1 effectively + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 73 + + + means "never show the objects" since the pile size will always be at least that big; default value is 5. Persistent. @@ -4735,6 +4775,9 @@ wise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. + query_menu + Use a menu when asked specific yes/no queries, instead of a prompt. + quick_farsight When set, usually prevents the "you sense your surroundings" message where play pauses to allow you to browse the map whenever clairvoy- @@ -4743,19 +4786,6 @@ ance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Persistent. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 73 - - - race Selects your race (for example, race:human). Choices are human, dwarf, elf, gnome, and orc but most roles restrict which of the non- @@ -4780,6 +4810,18 @@ option or its value(s) with `!' or "no". Examples: + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 74 + + + OPTIONS=role:!arc !bar !kni OPTIONS=!role:arc bar kni @@ -4810,18 +4852,6 @@ crawl - like walk, but pause briefly after each step. This option only affects the game's screen display, not the actual - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 74 - - - results of moving. The default is "run"; versions prior to 3.4.1 used "teleport" only. Whether or not the effect is noticeable will depend upon the window port used or on the type of terminal. Per- @@ -4845,6 +4875,19 @@ the first letter of each category (`t', `a', or `o') is necessary. Persistent. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 75 + + + showdamage Whenever your character takes damage, show a message of the damage taken, and the amount of hit points left. @@ -4876,18 +4919,6 @@ silent Suppress terminal beeps (default on). Persistent. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 75 - - - sortdiscoveries Controls the sorting behavior for the output of the `\' and ``' com- mands. Persistent. @@ -4911,6 +4942,18 @@ Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 76 + + + The possible values are: full - always sort the lists; @@ -4943,17 +4986,6 @@ prefix before either the #vanquished command or the #genocided com- mand. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 76 - - - sounds Allow sounds to be emitted from an integrated sound library (default on). @@ -4977,6 +5009,17 @@ Allow updates to the status lines at the bottom of the screen (de- fault true). + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 77 + + + suppress_alert This option may be set to a NetHack version level to suppress alert notification messages about feature changes for that and prior ver- @@ -5008,18 +5051,6 @@ Put the ending display in a NetHack window instead of on stdout (de- fault off). Setting this option makes the score list visible when a windowing version of NetHack is started without a parent window, but - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 77 - - - it no longer leaves the score list around after game end on a termi- nal or emulating window. @@ -5043,6 +5074,18 @@ The possible settings are: + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 78 + + + c - compass ("east" or "3s" or "2n,4w"); f - full compass ("east" or "3south" or "2north,4west"); m - map (map column x=0 is not used); @@ -5074,18 +5117,6 @@ next and previous targets, use a menu instead to pick a target. (default off) - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 78 - - - whatis_moveskip When getting a location on the map, and using shifted movement keys or meta-digit keys to fast-move, instead of moving 8 units at a @@ -5108,6 +5139,19 @@ Augment object descriptions with their objects' weight (default off). Debug mode only. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 79 + + + zerocomp When writing out a save file, perform zero-comp compression of the contents. Not all ports support zero-comp compression. It has no ef- @@ -5140,18 +5184,6 @@ (letters and punctuation) rather than tiles graphics. In some cases, characters can be augmented with line-drawing symbols; use the symset option to select a symbol set such as DECgraphics or - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 79 - - - IBMgraphics if your display supports them. Setting ascii_map to True forces tiled_map to be False. @@ -5173,8 +5205,20 @@ windows. font_message - If NetHack can, it should use a font by the chosen name for the mes- - sage window. + If NetHack can, it should use a font by the chosen name for the + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 80 + + + + message window. font_status If NetHack can, it should use a font by the chosen name for the sta- @@ -5206,18 +5250,6 @@ guicolor Use color text and/or highlighting attributes when displaying some non-map data (such as menu selector letters). Curses interface - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 80 - - - only; default is on. large_font @@ -5240,6 +5272,18 @@ mance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 81 + + + scroll_amount If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. @@ -5273,17 +5317,6 @@ The curses interface does likewise if the align_status option is set to top or bottom but ignores statuslines when set to left or right. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 81 - - - The Qt interface already displays more than 3 lines for status so uses the statuslines value differently. A value of 3 renders status in the Qt interface's original format, with the status window spread @@ -5306,6 +5339,17 @@ Specify the name of an alternative tile file to override the de- fault. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 82 + + + Note: the X11 interface uses X resources rather than NetHack's op- tions to select an alternate tile file. See NetHack.ad, the sample X "application defaults" file. @@ -5338,18 +5382,6 @@ persistent inventory window if enabled. Curses interface only. Ac- ceptable values are - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 82 - - - 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) [default] @@ -5369,21 +5401,34 @@ umns. windowcolors - If NetHack can, it should display windows with the specified fore- - ground/background colors. Windows GUI only. The format is + If NetHack can, it should display all windows of a particular style + with the specified foreground and background colors. Windows GUI + and curses windowport only. The format is - OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or "text", - and foreground and background are colors, either a hexadecimal - \'#rrggbb', one of the named colors (black, red, green, brown, blue, - magenta, cyan, orange, brightgreen, yellow, brightblue, brightmagenta, - brightcyan, white, trueblack, gray, purple, silver, maroon, fuchsia, - lime, olive, navy, teal, aqua), or one of Windows UI colors (active- - border, activecaption, appworkspace, background, btnface, btnshadow, - btntext, captiontext, graytext, greytext, highlight, highlighttext, - inactiveborder, inactivecaption, menu, menutext, scrollbar, window, - windowframe, windowtext). + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 83 + + + + OPTION=windowcolors:style foreground/background + + where style is one of "menu", "message", "status", or "text", and + foreground and background are colors, either numeric (hash sign fol- + lowed by three pairs of hexadecimal digits, #rrggbb), one of the + named colors (black, red, green, brown, blue, magenta, cyan, orange, + bright-green, yellow, bright-blue, bright-magenta, bright-cyan, + white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, + teal, aqua), or (for Windows only) one of Windows UI colors (true- + black, activeborder, activecaption, appworkspace, background, btn- + face, btnshadow, btntext, captiontext, graytext, greytext, high- + light, highlighttext, inactiveborder, inactivecaption, menu, menu- + text, scrollbar, window, windowframe, windowtext). wraptext If NetHack can, it should wrap long lines of text if they don't fit @@ -5405,17 +5450,6 @@ and is only needed if your browser cannot handle arbitrarily long URLs. - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 83 - - - 9.7. Platform-specific Customization options Here are explanations of options that are used by specific plat- @@ -5436,6 +5470,18 @@ prior to a command--preceded by n if the number_pad option is set-- is also subject to this conversion, so attempting to abort the count by typing ESC will leave NetHack waiting for another character to + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 84 + + + complete the two character sequence. Type a second ESC to finish cancelling such a count. At other prompts a single ESC suffices. @@ -5469,19 +5515,6 @@ tempts "vesa", then "vga", and finally sets "default" if neither of those modes works. Cannot be set with the `O' command. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 84 - - - video_height Set the VGA mode resolution height (MS-DOS only, with video:vesa) @@ -5501,6 +5534,20 @@ cult to read, try adjusting these scales; if this does not correct the problem, try !color. Cannot be set with the `O' command. + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 85 + + + 9.8. Regular Expressions Regular expressions are normally POSIX extended regular expres- @@ -5536,18 +5583,6 @@ they appear in your configuration file, thus allowing a later rule to override an earlier rule. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 85 - - - Exceptions can be set with the `O' command, but because they are not included in your configuration file, they won't be in effect if you save and then restore your game. autopickup_exception rules and not @@ -5564,6 +5599,21 @@ autopickup. The last example results in the exclusion of items known to be cursed from autopickup. + + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 86 + + + 9.10. Changing Key Bindings It is possible to change the default key bindings of some special @@ -5602,18 +5652,6 @@ count Prefix key to start a count, to repeat a command this many times. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 86 - - - With number_pad only. Default is `n'. getdir.help @@ -5630,6 +5668,18 @@ getdir.self When asked for a direction, the key to target yourself. Default is + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 87 + + + `.'. getdir.self2 @@ -5667,19 +5717,6 @@ When asked for a location, the key to go to previous closest mon- ster. Default is `M'. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 87 - - - getpos.obj.next When asked for a location, the key to go to next closest object. Default is `o'. @@ -5698,6 +5735,17 @@ meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `*'. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 88 + + + getpos.filter When asked for a location, change the filtering mode when using one of the next or previous keys to cycle through targets. Toggles be- @@ -5733,19 +5781,6 @@ When asked for a location, the key to go to next closest unexplored location. Default is `x'. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 88 - - - getpos.unexplored.prev When asked for a location, the key to go to previous closest unex- plored location. Default is `X'. @@ -5762,6 +5797,21 @@ When asked for a location, the key to go to previous closest valid location. Default is `Z'. + + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 89 + + + 9.11. Configuring Message Types You can change the way the messages are shown in the message @@ -5800,18 +5850,6 @@ Some platforms allow you to define colors used in menu lines when the line matches a user-defined pattern. At this time the tty, - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 89 - - - curses, win32tty and win32gui interfaces support this. In general, the configuration file entries to describe the menu @@ -5828,6 +5866,18 @@ The pattern should be a regular expression. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 90 + + + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- cyan, and white. And no-color, the default foreground color, which @@ -5866,18 +5916,6 @@ The following configuration file entries are relevant to mapping user sounds to messages: - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 90 - - - SOUNDDIR The directory that houses the sound files to be played. @@ -5894,6 +5932,18 @@ volume - the volume to be set while playing the sound file; sound index - optional; the index corresponding to a sound file. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 91 + + + The pattern should be a regular expression. For example: @@ -5932,18 +5982,6 @@ Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 91 - - - cyan, and white. And "no-color", the default foreground color on the display, which is not necessarily the same as black or white or any of the other colors. @@ -5959,12 +5997,24 @@ Note that the display may substitute or ignore particular at- tributes depending upon its capabilities, and in general may interpret the attributes any way it wants. For example, on some display systems - a request for bold might yield blink or vice versa. On others, issu- - ing an attribute request while another is already set up will replace - the earlier attribute rather than combine with it. Since NetHack is- - sues attribute requests sequentially (at least with the tty interface) - rather than all at once, the only way a situation like that can be - controlled is to specify just one attribute. + a request for bold might yield blink or vice versa. On others, + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 92 + + + + issuing an attribute request while another is already set up will re- + place the earlier attribute rather than combine with it. Since + NetHack issues attribute requests sequentially (at least with the tty + interface) rather than all at once, the only way a situation like that + can be controlled is to specify just one attribute. You can adjust the appearance of the following status fields: title dungeon-level experience-level @@ -5998,18 +6048,6 @@ * "always" will set the default attributes for that field. - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 92 - - - * "up", "down" set the field attributes for when the field value changes upwards or downwards. This attribute times out after statushilites turns. @@ -6026,6 +6064,18 @@ prefixed with `<=' or `>=', it also matches when value is below or above the percentage. Use prefix `<' or `>' to match when strictly below or above. (The numeric limit is relaxed + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 93 + + + slightly for those: >-1% and <101% are allowed.) Only four fields support percentage rules. Percentages for "hitpoints" and "power" are straightforward; they're based on the corre- @@ -6063,19 +6113,6 @@ The in-game options menu can help you determine the correct syn- tax for a configuration file. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 93 - - - The whole feature can be disabled by setting option statushilites to 0. @@ -6094,6 +6131,17 @@ + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 94 + + + 9.15. Modifying NetHack Symbols NetHack can load entire symbol sets from the symbol file. @@ -6129,19 +6177,6 @@ [ S_armor (suit or piece of armor) [ S_armour (suit or piece of armor) ^ S_arrow_trap (arrow trap) - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 94 - - - 0 S_ball (iron ball) # S_bars (iron bars) B S_bat (bat or bird) @@ -6160,6 +6195,19 @@ C S_centaur (centaur) _ S_chain (iron chain) # S_cloud (cloud) + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 95 + + + c S_cockatrice (cockatrice) $ S_coin (pile of coins) # S_corr (corridor) @@ -6195,19 +6243,6 @@ S_ghost (ghost) H S_giant (giant humanoid) G S_gnome (gnome) - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 95 - - - ' S_golem (golem) | S_grave (grave) g S_gremlin (gremlin) @@ -6226,6 +6261,19 @@ J S_jabberwock (jabberwock) j S_jelly (jelly) k S_kobold (kobold) + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 96 + + + K S_kop (Keystone Kop) ^ S_land_mine (land mine) } S_lava (molten lava) @@ -6261,19 +6309,6 @@ r S_rodent (rodent) ^ S_rolling_boulder_trap (rolling boulder trap) . S_room (floor of a room) - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 96 - - - / S_rslant (diagonal beam [zap animation]) ^ S_rust_trap (rust trap) R S_rustmonst (rust monster or disenchanter) @@ -6292,6 +6327,19 @@ S_stone (solid rock) ] S_strange_obj (strange object) - S_sw_bc (swallow bottom center) + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 97 + + + \ S_sw_bl (swallow bottom left) / S_sw_br (swallow bottom right) | S_sw_ml (swallow middle left) @@ -6327,19 +6375,6 @@ - S_vodoor (open door in vertical wall) v S_vortex (vortex) | S_vwall (vertical wall) - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 97 - - - / S_wand (wand) } S_water (water) ) S_weapon (weapon) @@ -6359,6 +6394,18 @@ * Several symbols in this table appear to be blank. They are the space character, except for S_pet_override and S_hero_override which + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 98 + + + don't have any default value and can only be used if enabled in the "sysconf" file. @@ -6393,20 +6440,8 @@ The list of acceptable glyphid's can be produced by nethack --dumpg- lyphids. Individual NetHack glyphs can be specified using the G_ pre- fix, or you can use an S_ symbol for a glyphid and store the custom - representation for all NetHack glyphs that would map to that - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 98 - - - - particular symbol. + representation for all NetHack glyphs that would map to that particu- + lar symbol. You will need to select a symset with a UTF8 handler to enable the display of the customizations, such as the Enhanced symset. @@ -6425,6 +6460,18 @@ an idea what the screen layout is like. You'll also need to be able to locate the PC cursor. It is always where your character is located. Merely searching for an @-sign will not always find your character + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 99 + + + since there are other humanoids represented by the same sign. Your screen-reader should also have a function which gives you the row and column of your review cursor and the PC cursor. These co-ordinates @@ -6459,19 +6506,6 @@ paranoid_confirmation:swim Prevent walking into water or lava. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 99 - - - accessiblemsg Adds direction or location information to messages. @@ -6493,6 +6527,17 @@ Give feedback messages when walking towards a wall or when travel command was interrupted. + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 100 + + + whatis_coord:compass When targeting with cursor, describe the cursor position with coor- dinates relative to your character. @@ -6526,18 +6571,6 @@ WIZARDS = A space-separated list of user names who are allowed to play in debug mode (commonly referred to as wizard mode). A value of a single asterisk (*) allows anyone to start a game in debug - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 100 - - - mode. SHELLERS = A list of users who are allowed to use the shell escape @@ -6559,6 +6592,18 @@ BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as read. + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 101 + + + The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for binary writing of entire structs, "lendian" for binary writing of each field in lit- @@ -6591,19 +6636,6 @@ POINTSMIN = Minimum number of points to get an entry in the score file. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 101 - - - PERS_IS_UID = 0 or 1 to use user names or numeric userids, respec- tively, to identify unique people for the score file. @@ -6626,6 +6658,18 @@ available if your game is compiled with DUMPLOG. Allows the follow- ing placeholders: + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 102 + + + %% - literal `%' %v - version (eg. "3.7.0-0") %u - game UID @@ -6657,23 +6701,11 @@ 10. Scoring NetHack maintains a list of the top scores or scorers on your ma- - chine, depending on how it is set up. In the latter case, each - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 102 - - - - account on the machine can post only one non-winning score on this - list. If you score higher than someone else on this list, or better - your previous score, you will be inserted in the proper place under - your current name. How many scores are kept can also be set up when + chine, depending on how it is set up. In the latter case, each ac- + count on the machine can post only one non-winning score on this list. + If you score higher than someone else on this list, or better your + previous score, you will be inserted in the proper place under your + current name. How many scores are kept can also be set up when NetHack is compiled. Your score is chiefly based upon how much experience you gained, @@ -6689,6 +6721,21 @@ If you just want to see what the current top players/games list is, you can type nethack -s all on most versions. + + + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 103 + + + 11. Explore mode NetHack is an intricate and difficult game. Novices might falter @@ -6723,19 +6770,6 @@ start a game in debug mode when not allowed or not available will re- sult in falling back to explore mode instead. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 103 - - - 12. Credits The original hack game was modeled on the Berkeley UNIX rogue @@ -6756,6 +6790,18 @@ on UNIX systems by posting that to Usenet newsgroup net.sources (later renamed comp.sources) releasing version 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and finally 1.0.3 in July of 1985. Usenet + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 104 + + + newsgroup net.games.hack (later renamed rec.games.hack, eventually re- placed by rec.games.roguelike.nethack) was created for discussing it. @@ -6790,18 +6836,6 @@ Meluch, Stephen Spackman and Pierre Martineau designed overlay code for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. Along with various other Dungeoneers, they continued to enhance the - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 104 - - - PC, Macintosh, and Amiga ports through the later revisions of 3.0. Version 3.0 went through ten relatively rapidly released "patch- @@ -6821,6 +6855,19 @@ quests, a new endgame and many other new features, and produced NetHack 3.1. Version 3.1.0 was released in January of 1993. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 105 + + + Ken Lorber, Gregg Wonderly and Greg Olson, with help from Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. @@ -6856,18 +6903,6 @@ Team which rechristened them "tiles", original usage which has subse- quently been picked up by various other games. NetHack's tiles sup- port was then implemented on other platforms (initially MS-DOS but - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 105 - - - eventually Windows, Qt, and X11 too). The 3.2 NetHack Development Team, comprised of Michael Allison, @@ -6887,6 +6922,18 @@ Version 3.2 proved to be more stable than previous versions. Many bugs were fixed, abuses eliminated, and game features tuned for + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 106 + + + better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusiasts @@ -6922,18 +6969,6 @@ trieval of old character names to use for random ghost and statue names in the current game.) - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 106 - - - The 3.3 NetHack Development Team, consisting of Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean Luick, Pat @@ -6952,6 +6987,19 @@ growing bug list, 3.3 proved stable enough to last for more than a year and a half. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 107 + + + The 3.4 NetHack Development Team initially consisted of Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul @@ -6987,19 +7035,6 @@ Christian "Marvin" Bressler maintained 3.4 for the Atari after he resurrected it for 3.3.1. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 107 - - - The release of NetHack 3.4.3 in December 2003 marked the begin- ning of a long release hiatus. 3.4.3 proved to be a remarkably stable version that provided continued enjoyment by the community for more @@ -7019,6 +7054,18 @@ on that code snapshot would be retired and never used in an official NetHack release. An announcement was posted on the NetHack Develop- ment Team's official nethack.org website to that effect, stating that + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 108 + + + there would never be a 3.4.4, 3.5, or 3.5.0 official release version. In January 2015, preparation began for the release of NetHack @@ -7053,19 +7100,6 @@ Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of NetHack 3.6 for Microsoft Windows. - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 108 - - - Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has updated and tested it for the most recent version of OpenVMS (V8.4 as of this @@ -7085,6 +7119,19 @@ In early May 2019, another 320 bug fixes along with some enhance- ments and the adopted curses window port, were released as 3.6.2. + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 109 + + + Bart House, who had contributed to the game as a porting team participant for decades, joined the NetHack Development Team in late May 2019. @@ -7119,19 +7166,6 @@ vnull.net (gone for now, but not forgotten). - - - - NetHack 3.7.0 February 29, 2024 - - - - - - NetHack Guidebook 109 - - - 12.2. Dungeoneers From time to time, some depraved individual out there in netland @@ -7151,6 +7185,19 @@ Benson I. Margulies Johnny Lee Ralf Brown Bill Dyer Jon W{tte Ray Chason Boudewijn Waijers Jonathan Handler Richard Addison + + + + NetHack 3.7.0 July 29, 2024 + + + + + + NetHack Guidebook 110 + + + Bruce Cox Joshua Delahunty Richard Beigel Bruce Holloway Karl Garrison Richard P. Hughey Bruce Mewborne Keizo Yamamoto Rob Menke @@ -7188,7 +7235,26 @@ of their respective holders. - NetHack 3.7.0 February 29, 2024 + + + + + + + + + + + + + + + + + + + + NetHack 3.7.0 July 29, 2024 From 2ed95119f12c5f04f84f2a9fffd554a540cdb905 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 2 Aug 2024 13:24:20 -0400 Subject: [PATCH 063/121] update tested versions of Visual Studio 2024-08-02 --- sys/windows/Makefile.nmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 011aa8253..39f601412 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -9,7 +9,7 @@ # # Visual Studio Compilers Tested: # - Microsoft Visual Studio 2019 Community Edition v 16.11.38 -# - Microsoft Visual Studio 2022 Community Edition v 17.10.4 +# - Microsoft Visual Studio 2022 Community Edition v 17.10.5 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -985,7 +985,7 @@ rc=Rc.exe # # Recently tested versions: TESTEDVS2019 = 14.29.30154.0 -TESTEDVS2022 = 14.40.33812.0 +TESTEDVS2022 = 14.40.33813.0 VS2019CUR = $(TESTEDVS2019:.=) VS2022CUR = $(TESTEDVS2022:.=) From 9e4237f6f7fc5888ce9f8bc40422ffc036c7b82e Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 10 Aug 2024 12:38:56 -0700 Subject: [PATCH 064/121] couple of weapon.c bits Some trivial stuff I've had sitting around for a while. --- src/weapon.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/weapon.c b/src/weapon.c index e4442420d..00b77c18c 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 weapon.c $NHDT-Date: 1690488665 2023/07/27 20:11:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 3.7 weapon.c $NHDT-Date: 1723318730 2024/08/10 19:38:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -11,7 +11,7 @@ #include "hack.h" staticfn void give_may_advance_msg(int); -staticfn void finish_towel_change(struct obj *obj, int); +staticfn void finish_towel_change(struct obj *obj, int) NONNULLARG1; staticfn boolean could_advance(int); staticfn boolean peaked_skill(int); staticfn int slots_required(int); @@ -66,8 +66,10 @@ static NEARDATA const char *const barehands_or_martial[] = { ? barehands_or_martial[martial_bonus()] \ : odd_skill_names[-skill_names_indices[type]]) -static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK, - S_NAGA, S_GIANT, '\0' }; +/* targets that provide attacker with small to-hit bonus when using a spear */ +static NEARDATA const char kebabable[] = { + S_XORN, S_DRAGON, S_JABBERWOCK, S_NAGA, S_GIANT, '\0' +}; staticfn void give_may_advance_msg(int skill) @@ -184,7 +186,7 @@ hitval(struct obj *otmp, struct monst *mon) } /* Historical note: The original versions of Hack used a range of damage - * which was similar to, but not identical to the damage used in Advanced + * which was similar to, but not identical to, the damage used in Advanced * Dungeons and Dragons. I figured that since it was so close, I may as well * make it exactly the same as AD&D, adding some more weapons in the process. * This has the advantage that it is at least possible that the player would @@ -976,10 +978,10 @@ finish_towel_change(struct obj *obj, int newspe) /* increase a towel's wetness */ void -wet_a_towel(struct obj *obj, - int amt, /* positive: new value; negative: increment by -amt; - zero: no-op */ - boolean verbose) +wet_a_towel( + struct obj *obj, + int amt, /* positive: new val; negative: increment by -amt; zero: no-op */ + boolean verbose) { int newspe = (amt <= 0) ? obj->spe - amt : amt; From 3f2d46823a69fc9d33a0bd3befd7507455c1e042 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sat, 10 Aug 2024 16:25:35 -0400 Subject: [PATCH 065/121] add nhlua target (for internal use) --- sys/unix/Makefile.top | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index adaf5cbe8..c7bb4b524 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -161,6 +161,16 @@ luabin: ( cd $(LUATOP) \ && make $(LUAMAKEFILES) all && cd $(LUA2NHTOP) ) +# This is only needed for some internal tools. +nhlua: + base=`ls -td lib/lua-*|head -1` ; \ + [ -z $$base ] && $(MAKE) fetch-lua ; \ + base=`ls -td lib/lua-*|head -1` ; \ + cp -R $$base/ lib/nhlsrc ; \ + rm -f util/nhlua ; \ + ( cd lib/nhlsrc && $(MAKE) clean posix ) ; \ + cp lib/nhlsrc/src/lua util/nhlua + # hints file could set LUATESTTARGET to this if GITSUBMODULES is defined submodules/lua/lua.h: git submodule init submodules/lua From 3ed2110757ce308aa9804fef39f8ce95ca7c9507 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 10 Aug 2024 16:24:51 -0700 Subject: [PATCH 066/121] monsters in regions vs #terrain While trying to track down a display problem with regions [when a monster is shown over a region because the hero is adjacent, it doesn't revert to the region's cloud glyph when hero moves farther away; that's not resolved yet], I discovered a different display problem for the same thing. If you pick a #terrain choice that keeps traps it is supposed to show region spots too, but that didn't work when there was a monster at the same spot. It removed the monster but showed background there. --- doc/fixes3-7-0.txt | 3 +++ src/detect.c | 28 ++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 12b006505..372527e9c 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2005,6 +2005,9 @@ if peaceful monsters react when seeing hero attack a peaceful monster, don't farlook of water/lava location listed wall of lava before molten lava; because of that, lava was omitted ("molten" suppressed to reduce vebosity, resulting in "lava" which got skipped as substring of "wall of lava") +having #terrain display gas cloud regions as if they were traps didn't work + for monsters in such regions that are shown when adjacent to hero or + sensed via ESP Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/detect.c b/src/detect.c index 2c5e9e281..99da4604d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -2042,8 +2042,6 @@ reveal_terrain_getglyph( keep_objs = (which_subset & TER_OBJ) != 0, keep_mons = (which_subset & TER_MON) != 0, full = (which_subset & TER_FULL) != 0; - int cmaptmp = 0; /* used by glyph_is_gascloud() macro */ - NhRegion *reg = visible_region_at(x, y); /* for 'full', show the actual terrain for the entire level, otherwise what the hero remembers for seen locations with @@ -2055,6 +2053,10 @@ reveal_terrain_getglyph( glyph = back_to_glyph(x, y); levl[x][y].seenv = seenv; } else { + int cmaptmp = 0; /* used by glyph_is_gascloud() macro */ + NhRegion *reg = visible_region_at(x, y); + boolean was_mon = FALSE; + levl_glyph = svl.level.flags.hero_memory ? levl[x][y].glyph : seenv ? back_to_glyph(x, y) : default_glyph; @@ -2064,12 +2066,14 @@ reveal_terrain_getglyph( the invisible monster glyph, which is handled like an object, replacing any object or trap at its spot) */ glyph = !swallowed ? glyph_at(x, y) : levl_glyph; - if (keep_mons && u_at(x, y) && swallowed) + if (keep_mons && u_at(x, y) && swallowed) { glyph = mon_to_glyph(u.ustuck, rn2_on_display_rng); - else if ((!keep_mons && (glyph_is_monster(glyph) + } else if ((!keep_mons && (glyph_is_monster(glyph) || glyph_is_warning(glyph))) - || glyph_is_swallow(glyph)) + || glyph_is_swallow(glyph)) { glyph = levl_glyph; + was_mon = TRUE; + } if (((!keep_objs && glyph_is_object(glyph)) || glyph_is_invisible(glyph)) && keep_traps && !covers_traps(x, y)) { @@ -2081,6 +2085,7 @@ reveal_terrain_getglyph( are present at the same spot) or neither traps nor regions */ || (!keep_traps && (glyph_is_trap(glyph) || (reg && glyph_is_gascloud(glyph)))) + || (reg && was_mon) || glyph_is_invisible(glyph)) { if (!seenv) { /* it's possible to have a visible region shown at an @@ -2089,15 +2094,18 @@ reveal_terrain_getglyph( far enough to be adjacent to the cloud without having seen the corridor underneath it) */ glyph = !reg ? default_glyph : GLYPH_UNEXPLORED; - } else if (svl.lastseentyp[x][y] == levl[x][y].typ) { - glyph = back_to_glyph(x, y); - } else if (keep_traps && reg && glyph_is_gascloud(glyph)) { + } else if (keep_traps && reg + && (glyph_is_gascloud(glyph) || was_mon)) { t = t_at(x, y); - glyph = (t && t->tseen) ? trap_to_glyph(t) - : back_to_glyph(x, y); + /* we need reg->glyph here when there's a monster shown + at a region spot; the region glyph isn't the remembered + background glyph or the current glyph */ + glyph = (t && t->tseen) ? trap_to_glyph(t) : reg->glyph; /* FIXME? what about objects temporarily hidden by regions? when objects are being shown, shouldn't showing them take precedence over showing the region, just like traps? */ + } else if (svl.lastseentyp[x][y] == levl[x][y].typ) { + glyph = back_to_glyph(x, y); } else { /* look for a mimic here posing as furniture; if we don't find one, we'll have to fake it */ From 37ad527512ced2454a2fc1b500f3125821b18237 Mon Sep 17 00:00:00 2001 From: nhkeni Date: Sat, 10 Aug 2024 21:18:34 -0400 Subject: [PATCH 067/121] make git ignore checksums temp file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0030d75a8..f7849967c 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,4 @@ bundle/* *.user util/*.lib util/*.exp +submodules/CHKSUMS.tmp From 0eb8896301f20435205b57077159b523faaf3a43 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 11 Aug 2024 14:59:57 -0700 Subject: [PATCH 068/121] paranoid_confirm:Trap vs vapor+gas cloud regions Extend paranoid_confirm:trap to also ask for confirmation when attempting to enter a gas cloud region (scroll of stinking cloud, breath from green dragons or iron golems, steam clouds from boiling water, vapor left by fog cloud movement, no doubt several others). Like with traps, can be overridden for a given move by using the 'm' prefix. Unlike traps, doesn't try to guess whether moving into a region will be harmless. Doesn't affect movement into cloud terrain (Plane of Air). Update the Guidebook to describe the revised behavior of paranoid_confirm:trap and to mention how #terrain deals with regions. 'any_visible_region()' got mixed in with this but isn't used yet. Affects extern.h and region.c. --- doc/Guidebook.mn | 12 +++++++++--- doc/Guidebook.tex | 9 +++++++-- doc/fixes3-7-0.txt | 4 +++- include/extern.h | 4 +++- src/hack.c | 40 ++++++++++++++++++++++++++++++++++++---- src/region.c | 33 ++++++++++++++++++++++++++++----- 6 files changed, 86 insertions(+), 16 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index e4aec2f8d..9472d54b1 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -46,7 +46,7 @@ .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 DATE(%B %-d, %Y) -.ds f2 July 29, 2024 +.ds f2 August 11, 2024 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1696,6 +1696,9 @@ In normal play you can view the explored portion of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. .lp "" +If there are visible clouds of gas in view, they are treated like traps +when deciding whether to show them or the floor underneath them. +.lp "" In explore mode, you can choose to view the full map rather than just its explored portion. In debug mode there are additional choices. @@ -4323,7 +4326,8 @@ symbols for the various object types. Any omitted types are filled in at the end from the previous order. .lp paranoid_confirmation A space separated list of specific situations where alternate -prompting is desired. The default is \(lqparanoid_confirmation:pray swim trap\(rq. +prompting is desired. +The default is \(lqparanoid_confirmation:pray swim trap\(rq. .PS Were-change .PL Confirm for any prompts which are set to require \(lqyes\(rq rather than \(oqy\(cq, @@ -4357,6 +4361,8 @@ than immediately praying; on by default; .PL trap require \(oqy\(cq to confirm an attempt to move into or onto a known trap, unless doing so is considered to be harmless; +when enabled, this confirmation is also used for moving into visible +gas cloud regions; (to require \(lqyes\(rq rather than just \(oqy\(cq, set Confirm too); confirmation can be skipped by using the \(oq\f(CRm\fP\(cq movement prefix; .PL swim @@ -4373,7 +4379,7 @@ commands even when wearing just one applicable item; .PL all turn on all of the above. .PE -By default, the pray and swim choices are enabled, the others disabled. +By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, use \f(CRparanoid_confirmation:none\fP. To keep them enabled while setting any of the others, you can diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5d66c9c1c..6524dd281 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -48,7 +48,7 @@ \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{DATE(%B %-d, %Y)} -\date{July 29, 2024} +\date{August 11, 2024} \maketitle @@ -1804,6 +1804,9 @@ In normal play you can view the explored portion of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps.\\ %.lp "" +If there are visible clouds of gas in view, they are treated like traps +when deciding whether to show them or the floor underneath them.\\ +%.lp "" In explore mode, you can choose to view the full map rather than just its explored portion. In debug mode there are additional choices.\\ @@ -4752,6 +4755,8 @@ than immediately praying; on by default; \item[{\tt trap~~~}] require `{\tt y}' to confirm an attempt to move into or onto a known trap, unless doing so is considered to be harmless; +when enabled, this confirmation is also used for moving into visible +gas cloud regions; (to require ``yes'' rather than just `y', set Confirm too); confirmation can be skipped by using the `{\tt m}' movement prefix; \item[{\tt swim~~~}] @@ -4770,7 +4775,7 @@ turn on all of the above. \elist %.ei %.ed -By default, the pray and swim choices are enabled, the others disabled. +By default, the pray, swim, and trap choices are enabled, the others disabled. To disable them without setting any of the other choices, use ``{\it paranoid\verb+_+confirmation:none}''. To keep them enabled while setting any of the others, you can diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 372527e9c..88a089184 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1457 $ $NHDT-Date: 1721684298 2024/07/22 21:38:18 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1460 $ $NHDT-Date: 1723410638 2024/08/11 21:10:38 $ General Fixes and Modified Features ----------------------------------- @@ -2546,6 +2546,8 @@ paranoid_confirm:swim to prevent accidental dunking into dangerous liquids; paranoid_confirm:trap to confirm entering a known trap unless it is harmless; like revised paranoid_confirm:pray, requires y/n response; add paranoid_confirm:Confirm to require yes/no instead +extend 'paranoid_confirm:trap' to request confirmation when entering visible + gas cloud regions paranoid_confirm:Autoall to confirm picking 'A' in menustyle:Full filter menu looking at a monster will indicate whether it is asleep, and waking up a monster yields a message diff --git a/include/extern.h b/include/extern.h index 27c308019..62e286f4a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1722116044 2024/07/27 21:34:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1433 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1723410638 2024/08/11 21:10:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1434 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2574,6 +2574,8 @@ extern boolean in_out_region(coordxy, coordxy); extern boolean m_in_out_region(struct monst *, coordxy, coordxy) NONNULLARG1; extern void update_player_regions(void); extern void update_monster_region(struct monst *) NONNULLARG1; +extern int reg_damg(NhRegion *) NONNULLARG1; +extern boolean any_visible_region(void); extern NhRegion *visible_region_at(coordxy, coordxy); extern void show_region(NhRegion *, coordxy, coordxy) NONNULLARG1; extern void save_regions(NHFILE *) NONNULLARG1; diff --git a/src/hack.c b/src/hack.c index 8a47f5b69..f59e26eb7 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1720128165 2024/07/04 21:22:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.449 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1723410639 2024/08/11 21:10:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.452 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2517,11 +2517,12 @@ domove_core(void) { struct monst *mtmp; struct rm *tmpr; + NhRegion *newreg, *oldreg; coordxy x, y; struct trap *trap = NULL; int glyph; coordxy chainx = 0, chainy = 0, - ballx = 0, bally = 0; /* ball&chain new positions */ + ballx = 0, bally = 0; /* ball&chain new positions */ int bc_control = 0; /* control for ball&chain */ boolean cause_delay = FALSE, /* dragging ball will skip a move */ displaceu = FALSE; /* involuntary swap */ @@ -2624,10 +2625,14 @@ domove_core(void) return; /* maybe ask player for confirmation before walking into known traps */ - if (ParanoidTrap && (trap = t_at(x, y)) != 0 && trap->tseen + if (ParanoidTrap && !Stunned && !Confusion + /* skip if player used 'm' prefix or is moving recklessly */ && (!svc.context.nopick || svc.context.run) - && !Stunned && !Confusion + /* check for discovered trap */ + && (trap = t_at(x, y)) != 0 && trap->tseen + /* check whether attempted move will be viable */ && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) + /* override confirmation if the trap is harmless to the hero */ && (immune_to_trap(&gy.youmonst, trap->ttyp) != TRAP_CLEARLY_IMMUNE /* Hallucination: all traps still show as ^, but the hero can't tell what they are, so treat as dangerous */ @@ -2662,6 +2667,33 @@ domove_core(void) return; } } + /* treat entering a visible region like entering a trap */ + if (ParanoidTrap && !Blind && !Stunned && !Confusion && !Hallucination + /* skip if player used 'm' prefix or is moving recklessly */ + && (!svc.context.nopick || svc.context.run) + /* check for region(s) */ + && (newreg = visible_region_at(x, y)) != 0 + && ((oldreg = visible_region_at(u.ux, u.uy)) == 0 + /* if moving from one region into another, only ask for + confirmation if the one potentially being entered inflicts + damage (poison gas) and the one being exited doesn't (vapor) */ + || (reg_damg(newreg) > 0 && reg_damg(oldreg) == 0)) + /* check whether attempted move will be viable */ + && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) + /* we don't override confirmation for poison resistance since the + region also hinders hero's vision even if/when no damage is done */ + ) { + char qbuf[QBUFSZ]; + + Snprintf(qbuf, sizeof qbuf, "%s into that %s cloud?", + locomotion(gy.youmonst.data, "step"), + (reg_damg(newreg) > 0) ? "poison gas" : "vapor"); + if (!paranoid_query(ParanoidConfirm, upstart(qbuf))) { + nomul(0); + svc.context.move = 0; + return; + } + } if (u.utrap) { boolean moved = trapmove(x, y, trap); diff --git a/src/region.c b/src/region.c index 43383ea2f..cbabf4885 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.c $NHDT-Date: 1707462965 2024/02/09 07:16:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.7 region.c $NHDT-Date: 1723410640 2024/08/11 21:10:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -628,6 +628,29 @@ remove_mon_from_regions(struct monst *mon) #endif /*0*/ +/* per-turn damaeg inflicted by visible region; hides details from caller */ +int +reg_damg(NhRegion *reg) +{ + int damg = (!reg->visible || reg->ttl == -2L) ? 0 : reg->arg.a_int; + + return damg; +} + +/* check whether current level has any visible regions */ +boolean +any_visible_region(void) +{ + int i; + + for (i = 0; i < svn.n_regions; i++) { + if (!gr.regions[i]->visible || gr.regions[i]->ttl == -2L) + continue; + return TRUE; + } + return FALSE; +} + /* * Check if a spot is under a visible region (eg: gas cloud). * Returns NULL if not, otherwise returns region. @@ -666,8 +689,8 @@ save_regions(NHFILE *nhfp) goto skip_lots; if (nhfp->structlevel) { /* timestamp */ - bwrite(nhfp->fd, (genericptr_t) &svm.moves, sizeof (svm.moves)); - bwrite(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof (svn.n_regions)); + bwrite(nhfp->fd, (genericptr_t) &svm.moves, sizeof svm.moves); + bwrite(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof svn.n_regions); } for (i = 0; i < svn.n_regions; i++) { r = gr.regions[i]; @@ -747,11 +770,11 @@ rest_regions(NHFILE *nhfp) tmstamp = (svm.moves - tmstamp); if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof (svn.n_regions)); + mread(nhfp->fd, (genericptr_t) &svn.n_regions, sizeof svn.n_regions); gm.max_regions = svn.n_regions; if (svn.n_regions > 0) - gr.regions = (NhRegion **) alloc(sizeof (NhRegion *) * svn.n_regions); + gr.regions = (NhRegion **) alloc(svn.n_regions * sizeof (NhRegion *)); for (i = 0; i < svn.n_regions; i++) { r = gr.regions[i] = (NhRegion *) alloc(sizeof (NhRegion)); if (nhfp->structlevel) { From fd57c9ca83f51cffdfcfbb47e93924e15692f7d1 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 13 Aug 2024 13:28:24 -0700 Subject: [PATCH 069/121] wizard mode #timeout command vs gas regions Show visible regions among the other timed events. Turn number is relative rather than absolute. Location is the internal bounding box which tends to cover more area than just the gas cloud spots. When multiple regions are present (common on Plane of Fire), they're listed in arbitrary order. It would be better to order them by timeout or by location or both, but the extra effort to do that seems unjustified. --- include/extern.h | 3 +- src/region.c | 116 ++++++++++++++++++++++++++++++++--------------- src/timeout.c | 5 +- src/wizcmds.c | 4 +- 4 files changed, 88 insertions(+), 40 deletions(-) diff --git a/include/extern.h b/include/extern.h index 62e286f4a..d9a91b52f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1723410638 2024/08/11 21:10:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1434 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1723580890 2024/08/13 20:28:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1435 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2576,6 +2576,7 @@ extern void update_player_regions(void); extern void update_monster_region(struct monst *) NONNULLARG1; extern int reg_damg(NhRegion *) NONNULLARG1; extern boolean any_visible_region(void); +extern void visible_region_summary(winid); extern NhRegion *visible_region_at(coordxy, coordxy); extern void show_region(NhRegion *, coordxy, coordxy) NONNULLARG1; extern void save_regions(NHFILE *) NONNULLARG1; diff --git a/src/region.c b/src/region.c index cbabf4885..4dfef5530 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.c $NHDT-Date: 1723410640 2024/08/11 21:10:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ +/* NetHack 3.7 region.c $NHDT-Date: 1723580898 2024/08/13 20:28:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -39,6 +39,7 @@ NhRegion *create_force_field(coordxy,coordxy,int,long); staticfn void reset_region_mids(NhRegion *); staticfn boolean is_hero_inside_gas_cloud(void); +staticfn void make_gas_cloud(NhRegion *, int, boolean) NONNULLARG1; static const callback_proc callbacks[] = { #define INSIDE_GAS_CLOUD 0 @@ -651,6 +652,46 @@ any_visible_region(void) return FALSE; } +/* for the wizard mode #timeout command */ +void +visible_region_summary(winid win) +{ + NhRegion *reg; + char buf[BUFSZ], typbuf[QBUFSZ]; + int i, damg, hdr_done = 0; + + for (i = 0; i < svn.n_regions; i++) { + reg = gr.regions[i]; + if (!reg->visible || reg->ttl == -2L) + continue; + + if (!hdr_done++) { + putstr(win, 0, ""); + putstr(win, 0, "Visible regions"); + } + /* + * TODO? sort the regions by time-to-live or by bounding box. + */ + + /* we display relative time (turns left) rather than absolute + (the turn when region will go away); + since time-to-live has already been decremented, regions + which are due to timeout on the next turn have ttl==0; + adding 1 is intended to make the display be less confusing */ + Sprintf(buf, "%5ld", reg->ttl + 1L); + damg = reg->arg.a_int; + if (damg) + Sprintf(typbuf, "poison gas (%d)", damg); + else + Strcpy(typbuf, "vapor"); + Sprintf(eos(buf), " %-16s", typbuf); + Sprintf(eos(buf), " @[%d,%d..%d,%d]", + reg->bounding_box.lx, reg->bounding_box.ly, + reg->bounding_box.hx, reg->bounding_box.hy); + putstr(win, 0, buf); + } +} + /* * Check if a spot is under a visible region (eg: gas cloud). * Returns NULL if not, otherwise returns region. @@ -1148,13 +1189,41 @@ is_hero_inside_gas_cloud(void) return FALSE; } +/* details of gas cloud creation which are common to create_gas_cloud() + and create_gas_cloud_selection() */ +staticfn void +make_gas_cloud( + NhRegion *cloud, + int damage, + boolean inside_cloud) +{ + if (!gi.in_mklev && !svc.context.mon_moving) + set_heros_fault(cloud); /* assume player has created it */ + cloud->inside_f = INSIDE_GAS_CLOUD; + cloud->expire_f = EXPIRE_GAS_CLOUD; + cloud->arg = cg.zeroany; + cloud->arg.a_int = damage; + cloud->visible = TRUE; + cloud->glyph = cmap_to_glyph(damage ? S_poisoncloud : S_cloud); + add_region(cloud); + + if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud()) { + You("are enveloped in a cloud of %s!", + damage ? "noxious gas" : "steam"); + iflags.last_msg = PLNMSG_ENVELOPED_IN_GAS; + } +} + /* Create a gas cloud which starts at (x,y) and grows outward from it via * breadth-first search. * cloudsize is the number of squares the cloud will attempt to fill. * damage is how much it deals to afflicted creatures. */ #define MAX_CLOUD_SIZE 150 NhRegion * -create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage) +create_gas_cloud( + coordxy x, coordxy y, + int cloudsize, + int damage) { NhRegion *cloud; int i, j; @@ -1195,13 +1264,13 @@ create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage) for (i = 4; i > 0; --i) { coordxy swapidx = rn2(i); coord tmp = dirs[swapidx]; - dirs[swapidx] = dirs[i-1]; - dirs[i-1] = tmp; + + dirs[swapidx] = dirs[i - 1]; + dirs[i - 1] = tmp; } int nvalid = 0; /* # of valid adjacent spots */ for (i = 0; i < 4; ++i) { - /* try all 4 directions */ - + /* try all 4 cardinal directions */ int dx = dirs[i].x, dy = dirs[i].y; boolean isunpicked = TRUE; @@ -1245,28 +1314,15 @@ create_gas_cloud(coordxy x, coordxy y, int cloudsize, int damage) /* If cloud was constrained in small space, give it more time to live. */ cloud->ttl = (cloud->ttl * cloudsize) / newidx; - if (!gi.in_mklev && !svc.context.mon_moving) - set_heros_fault(cloud); /* assume player has created it */ - cloud->inside_f = INSIDE_GAS_CLOUD; - cloud->expire_f = EXPIRE_GAS_CLOUD; - cloud->arg = cg.zeroany; - cloud->arg.a_int = damage; - cloud->visible = TRUE; - cloud->glyph = cmap_to_glyph(damage ? S_poisoncloud : S_cloud); - add_region(cloud); - - if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud()) { - You("are enveloped in a cloud of %s!", - damage ? "noxious gas" : "steam"); - iflags.last_msg = PLNMSG_ENVELOPED_IN_GAS; - } - + make_gas_cloud(cloud, damage, inside_cloud); return cloud; } /* create a single gas cloud from selection */ NhRegion * -create_gas_cloud_selection(struct selectionvar *sel, int damage) +create_gas_cloud_selection( + struct selectionvar *sel, + int damage) { NhRegion *cloud; NhRect tmprect; @@ -1285,19 +1341,7 @@ create_gas_cloud_selection(struct selectionvar *sel, int damage) add_rect_to_reg(cloud, &tmprect); } - if (!gi.in_mklev && !svc.context.mon_moving) - set_heros_fault(cloud); /* assume player has created it */ - cloud->inside_f = INSIDE_GAS_CLOUD; - cloud->expire_f = EXPIRE_GAS_CLOUD; - cloud->arg = cg.zeroany; - cloud->arg.a_int = damage; - cloud->visible = TRUE; - cloud->glyph = cmap_to_glyph(damage ? S_poisoncloud : S_cloud); - add_region(cloud); - - if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud()) - You("are enveloped in a cloud of %s!", - damage ? "noxious gas" : "steam"); + make_gas_cloud(cloud, damage, inside_cloud); return cloud; } diff --git a/src/timeout.c b/src/timeout.c index cee1e927e..2cd53f7be 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.c $NHDT-Date: 1710029105 2024/03/10 00:05:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ +/* NetHack 3.7 timeout.c $NHDT-Date: 1723580900 2024/08/13 20:28:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2056,6 +2056,9 @@ wiz_timeout_queue(void) Sprintf(buf, "Vault counter is %d.", u.uinvault); putstr(win, 0, buf); } + if (any_visible_region()) { + visible_region_summary(win); + } display_nhwindow(win, FALSE); destroy_nhwindow(win); diff --git a/src/wizcmds.c b/src/wizcmds.c index 197a08bee..454b4deb9 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizcmds.c $NHDT-Date: 1716592982 2024/05/24 23:23:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 3.7 wizcmds.c $NHDT-Date: 1723580901 2024/08/13 20:28:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /*-Copyright (c) Robert Patrick Rankin, 2024. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1049,7 +1049,7 @@ wiz_intrinsic(void) if (!Warn_of_mon) { svc.context.warntype.speciesidx = PM_GRID_BUG; svc.context.warntype.species - = &mons[svc.context.warntype.speciesidx]; + = &mons[svc.context.warntype.speciesidx]; } goto def_feedback; case GLIB: From c63b4939046fd744f8ba6a1314d12a1ece6edea5 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 13 Aug 2024 13:53:41 -0700 Subject: [PATCH 070/121] tweak paranoid_confirm:trap vs regions It is possible to have a known trap be at the same location as a gas cloud region. When paranoid_confirm:trap is set, ask for confirmation about entering the region before confirmation about entering the trap since the map will be showing the region rather than the trap. Dual confirmations will be annoying but not new. Before this change, it would ask about entering the trap, and if the answer was yes, it would ask about entering the region. The situation seems to be too rare to warrant implementing a single combined confirmation, and the code to accomplish that would likely be messy. --- src/hack.c | 59 +++++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/hack.c b/src/hack.c index f59e26eb7..028b49645 100644 --- a/src/hack.c +++ b/src/hack.c @@ -2624,6 +2624,38 @@ domove_core(void) if (u_rooted()) return; + /* treat entering a visible gas cloud region like entering a trap; + there could be a known trap as well as a region at the target spot; + if so, ask about entring the region first; even though this could + lead to two consecutive confirmation prompts, the situation seems to + be too uncommon to warrant a separate case with combined trap+region + confirmation */ + if (ParanoidTrap && !Blind && !Stunned && !Confusion && !Hallucination + /* skip if player used 'm' prefix or is moving recklessly */ + && (!svc.context.nopick || svc.context.run) + /* check for region(s) */ + && (newreg = visible_region_at(x, y)) != 0 + && ((oldreg = visible_region_at(u.ux, u.uy)) == 0 + /* if moving from one region into another, only ask for + confirmation if the one potentially being entered inflicts + damage (poison gas) and the one being exited doesn't (vapor) */ + || (reg_damg(newreg) > 0 && reg_damg(oldreg) == 0)) + /* check whether attempted move will be viable */ + && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) + /* we don't override confirmation for poison resistance since the + region also hinders hero's vision even if/when no damage is done */ + ) { + char qbuf[QBUFSZ]; + + Snprintf(qbuf, sizeof qbuf, "%s into that %s cloud?", + locomotion(gy.youmonst.data, "step"), + (reg_damg(newreg) > 0) ? "poison gas" : "vapor"); + if (!paranoid_query(ParanoidConfirm, upstart(qbuf))) { + nomul(0); + svc.context.move = 0; + return; + } + } /* maybe ask player for confirmation before walking into known traps */ if (ParanoidTrap && !Stunned && !Confusion /* skip if player used 'm' prefix or is moving recklessly */ @@ -2667,33 +2699,6 @@ domove_core(void) return; } } - /* treat entering a visible region like entering a trap */ - if (ParanoidTrap && !Blind && !Stunned && !Confusion && !Hallucination - /* skip if player used 'm' prefix or is moving recklessly */ - && (!svc.context.nopick || svc.context.run) - /* check for region(s) */ - && (newreg = visible_region_at(x, y)) != 0 - && ((oldreg = visible_region_at(u.ux, u.uy)) == 0 - /* if moving from one region into another, only ask for - confirmation if the one potentially being entered inflicts - damage (poison gas) and the one being exited doesn't (vapor) */ - || (reg_damg(newreg) > 0 && reg_damg(oldreg) == 0)) - /* check whether attempted move will be viable */ - && test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE) - /* we don't override confirmation for poison resistance since the - region also hinders hero's vision even if/when no damage is done */ - ) { - char qbuf[QBUFSZ]; - - Snprintf(qbuf, sizeof qbuf, "%s into that %s cloud?", - locomotion(gy.youmonst.data, "step"), - (reg_damg(newreg) > 0) ? "poison gas" : "vapor"); - if (!paranoid_query(ParanoidConfirm, upstart(qbuf))) { - nomul(0); - svc.context.move = 0; - return; - } - } if (u.utrap) { boolean moved = trapmove(x, y, trap); From 061f56492893c7ed6b954865c426b6a41e7b36c7 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 16 Aug 2024 11:40:12 -0700 Subject: [PATCH 071/121] monster display vs gas cloud regions This fixes the bug where a monster displayed instead of a gas cloud because the hero was next to it didn't revert to gas cloud when hero moved and was no longer next to the monster. --- doc/fixes3-7-0.txt | 4 +++- src/allmain.c | 13 ++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 88a089184..8e801bdd9 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1460 $ $NHDT-Date: 1723410638 2024/08/11 21:10:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1461 $ $NHDT-Date: 1723833609 2024/08/16 18:40:09 $ General Fixes and Modified Features ----------------------------------- @@ -2008,6 +2008,8 @@ farlook of water/lava location listed wall of lava before molten lava; because having #terrain display gas cloud regions as if they were traps didn't work for monsters in such regions that are shown when adjacent to hero or sensed via ESP +when a monster within a gas cloud was displayed on the map because the hero + was next to it, it remained displayed if hero moved away Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/allmain.c b/src/allmain.c index 957763b8d..024867dc8 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 allmain.c $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.238 $ */ +/* NetHack 3.7 allmain.c $NHDT-Date: 1723833610 2024/08/16 18:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -425,11 +425,14 @@ moveloop_core(void) see_traps(); if (u.uswallow) swallowed(0); - } else if (Unblind_telepat) { + } else if (Unblind_telepat || Warning || Warn_of_mon + /* this is needed for the case where you saw a monster + due to being next to it while it's in a gas cloud + and then you moved away; it should no longer be seen + when that happens, even if it hasn't moved */ + || any_visible_region()) { /* TODO: optimize this */ see_monsters(); - } else if (Warning || Warn_of_mon) - see_monsters(); - + } if (gv.vision_full_recalc) vision_recalc(0); /* vision! */ } From 4fb7dd2cd0fa8f1fd53c245b2a7916a83248be2d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 16 Aug 2024 11:59:38 -0700 Subject: [PATCH 072/121] more monster display vs gas clouds Various bits tried while flailing about with map display of monsters in visible regions. The newsym()/mon_overrides_region() part is definitely an improvement because the logic about whether to show a monster in a region or just the region wasn't easy to comprehend and was even harder to extend. I'm not sure whether the _map_location() part is necessary. --- src/display.c | 87 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/src/display.c b/src/display.c index 6a3d5fcda..349fb6056 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1707462961 2024/02/09 07:16:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.231 $ */ +/* NetHack 3.7 display.c $NHDT-Date: 1723834773 2024/08/16 18:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -125,13 +125,13 @@ staticfn void show_mon_or_warn(coordxy, coordxy, int); staticfn void display_monster(coordxy, coordxy, - struct monst *, int, boolean) NONNULLPTRS; + struct monst *, int, boolean) NONNULLPTRS; staticfn int swallow_to_glyph(int, int); staticfn void display_warning(struct monst *) NONNULLARG1; -staticfn boolean next_to_gas(struct monst *, coordxy, coordxy) NONNULLARG1; - +staticfn boolean mon_overrides_region(struct monst *, coordxy, coordxy); staticfn int check_pos(coordxy, coordxy, int); -staticfn void get_bkglyph_and_framecolor(coordxy x, coordxy y, int *, uint32 *); +staticfn void get_bkglyph_and_framecolor(coordxy x, coordxy y, int *, + uint32 *); staticfn int tether_glyph(coordxy, coordxy); staticfn void mimic_light_blocking(struct monst *) NONNULLARG1; @@ -141,10 +141,10 @@ staticfn boolean more_than_one(coordxy, coordxy, coordxy, coordxy, coordxy); #endif staticfn int set_twall(coordxy, coordxy, coordxy, coordxy, - coordxy, coordxy, coordxy, coordxy); + coordxy, coordxy, coordxy, coordxy); staticfn int set_wall(coordxy, coordxy, int); staticfn int set_corn(coordxy, coordxy, coordxy, coordxy, - coordxy, coordxy, coordxy, coordxy); + coordxy, coordxy, coordxy, coordxy); staticfn int set_crosswall(coordxy, coordxy); staticfn void set_seenv(struct rm *, coordxy, coordxy, coordxy, coordxy); staticfn void t_warn(struct rm *); @@ -442,10 +442,11 @@ unmap_object(coordxy x, coordxy y) * Internal to display.c, this is a #define for speed. */ #define _map_location(x, y, show) \ - { \ - struct obj *obj; \ - struct trap *trap; \ + do { \ + struct obj *obj; \ + struct trap *trap; \ struct engr *ep; \ + NhRegion *_ml_reg; \ \ if ((obj = vobj_at(x, y)) && !covers_objects(x, y)) \ map_object(obj, show); \ @@ -459,7 +460,9 @@ unmap_object(coordxy x, coordxy y) map_background(x, y, show); \ \ update_lastseentyp(x, y); \ - } + if (show && !Blind && (_ml_reg = visible_region_at(x, y)) != 0) \ + show_region(_ml_reg, x, y); \ + } while (0) void map_location(coordxy x, coordxy y, int show) @@ -651,23 +654,41 @@ warning_of(struct monst *mon) return wl; } -/* returns True if mon is adjacent and would be seen if vision wasn't - blocked by being in a gas cloud (implicit; caller has already checked) */ +/* used by newsym() to decide whether to show a monster or a visible gas + cloud region when both are at the same spot; caller deals with region */ staticfn boolean -next_to_gas( - struct monst *mon, +mon_overrides_region( + struct monst *mon, /* might be Null */ coordxy mx, coordxy my) /* won't match mon->mx,my if long worm's tail */ { - int r = (u.xray_range > 1) ? u.xray_range : 1; + int r; - if (distu(mx, my) > r * (r + 1)) + /* this is redundant because newsym() doesn't call us when swallowed */ + if (u.uswallow && (!mon || mon != u.ustuck)) return FALSE; - /* decide whether monster at could be seen without couldsee() - because the gas cloud inhibits that (don't need to check infravision - when monster is adjacent) */ - if (Blind || !_mon_visible(mon)) - return FALSE; - return TRUE; + + if (mon) { + /* when not a worm tail, show mon if sensed rather than seen */ + if (mx == mon->mx && my == mon->my + && (sensemon(mon) || mon_warning(mon))) + return TRUE; + + /* even if worm tail; + check whether the spot is adjacent and 'mon' would be visible + there if the gas cloud wasn't interfering with normal vision; + _mon_visible() handles mon->mundetected; don't need to check + infravision when monster is adjacent */ + r = (u.xray_range > 1) ? u.xray_range : 1; + if (!Blind && _mon_visible(mon) + && M_AP_TYPE(mon) != M_AP_FURNITURE + && M_AP_TYPE(mon) != M_AP_OBJECT + && distu(mx, my) <= r * (r + 1)) + return TRUE; + } + + /* if not overriding region for current mon, propagate "remembered, + unseen monster" */ + return glyph_is_invisible(levl[mx][my].glyph) ? TRUE : FALSE; } /* map or status window might not be ready for output during level creation @@ -865,7 +886,7 @@ feel_location(coordxy x, coordxy y) show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr)); } /* draw monster on top if we can sense it */ - if ((x != u.ux || y != u.uy) && (mon = m_at(x, y)) != 0 && sensemon(mon)) + if (!u_at(x, y) && (mon = m_at(x, y)) != 0 && sensemon(mon)) display_monster(x, y, mon, (tp_sensemon(mon) || MATCH_WARN_OF_MON(mon)) ? PHYSICALLY_SEEN @@ -933,18 +954,18 @@ newsym(coordxy x, coordxy y) * seen when there's no gas region. * * FIXME: - * The adjacency checking here works when the hero is outside - * the region and the monster is inside, and when they're both - * inside, but not when the hero is inside and monster outside - * (because 'reg' will be Null for mon's ). Checking - * whether hero is inside a region for every newsym() seems - * excessive. The hero is usually blind when in a gas cloud - * so the problem is less noticeable then it might otherwise be. + * The adjacency checking [in mon_overrides_region()] works + * when the hero is outside the region and the monster is + * inside, and when they're both inside, but not when the + * hero is inside and monster outside (because 'reg' will be + * Null for mon's ). Checking whether hero is inside + * a region for every newsym() seems excessive. The hero is + * usually blind when in a gas cloud so the problem is less + * noticeable then it might otherwise be. */ if (reg && (ACCESSIBLE(lev->typ) || (reg->visible && is_pool_or_lava(x, y)))) { - if (!(mon && (((sensemon(mon) || mon_warning(mon)) && !worm_tail) - || next_to_gas(mon, x, y)))) { /* even if tail */ + if (!mon_overrides_region(mon, x, y)) { show_region(reg, x, y); return; } From 5617f32eb4f8e78980148342c03cf173acc8d530 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 16 Aug 2024 12:26:17 -0700 Subject: [PATCH 073/121] region bit When hero was swallowed and a temporary region at swallower's spot expired, hero was told "the gas cloud around you dissipates". This just suppresses the message rather than changing it into "the gas cloud around dissipates". --- doc/fixes3-7-0.txt | 2 ++ src/region.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 8e801bdd9..6ec26dce7 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1454,6 +1454,8 @@ when there was a trap on a no-dig level, the floor beneath it was always the #terrain command didn't know how to cope with visible gas/cloud regions; treat as traps as far as player choice of whether to show or hide; if/when a spot contains both region and trap, show the trap +region expiration reported "the gas cloud around you dissipates" even when the + hero was swallowed Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/region.c b/src/region.c index 4dfef5530..c01bfa031 100644 --- a/src/region.c +++ b/src/region.c @@ -1085,7 +1085,7 @@ expire_gas_cloud(genericptr_t p1, genericptr_t p2 UNUSED) if (pass == 1) { if (!does_block(x, y, &levl[x][y])) unblock_point(x, y); - if (u_at(x, y)) + if (u_at(x, y) && !u.uswallow) gg.gas_cloud_diss_within = TRUE; } else { /* pass==2 */ if (cansee(x, y)) @@ -1209,6 +1209,9 @@ make_gas_cloud( if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud()) { You("are enveloped in a cloud of %s!", + /* FIXME: "steam" is wrong if this cloud is just the trail of + a fog cloud's movmement; changing to "vapor" would handle + that but seems a step backward when it really is steam */ damage ? "noxious gas" : "steam"); iflags.last_msg = PLNMSG_ENVELOPED_IN_GAS; } From d441d6159bf325054a214714b195103cb61de6fe Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 16 Aug 2024 22:18:46 -0700 Subject: [PATCH 074/121] zillionth+1 and +2 comment typo fixes --- src/region.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/region.c b/src/region.c index c01bfa031..3a65e583e 100644 --- a/src/region.c +++ b/src/region.c @@ -629,7 +629,7 @@ remove_mon_from_regions(struct monst *mon) #endif /*0*/ -/* per-turn damaeg inflicted by visible region; hides details from caller */ +/* per-turn damage inflicted by visible region; hides details from caller */ int reg_damg(NhRegion *reg) { @@ -1210,7 +1210,7 @@ make_gas_cloud( if (!gi.in_mklev && !inside_cloud && is_hero_inside_gas_cloud()) { You("are enveloped in a cloud of %s!", /* FIXME: "steam" is wrong if this cloud is just the trail of - a fog cloud's movmement; changing to "vapor" would handle + a fog cloud's movement; changing to "vapor" would handle that but seems a step backward when it really is steam */ damage ? "noxious gas" : "steam"); iflags.last_msg = PLNMSG_ENVELOPED_IN_GAS; From 45690624e53071ec7c9a19dd796836ae477abc34 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Aug 2024 11:02:28 -0700 Subject: [PATCH 075/121] fix pyrolisk egg panic when eating from floor From a change made about two and half months ago: eating a pyrolisk egg tried to use it up from inventory even when it was on the floor. That would trigger an object lost panic. --- doc/fixes3-7-0.txt | 1 + src/eat.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 6ec26dce7..38330a56e 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2012,6 +2012,7 @@ having #terrain display gas cloud regions as if they were traps didn't work sensed via ESP when a monster within a gas cloud was displayed on the map because the hero was next to it, it remained displayed if hero moved away +eating a pyrolisk egg on the floor triggered an "object lost" panic Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/eat.c b/src/eat.c index 707449772..8e20d5579 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2028,7 +2028,10 @@ fprefx(struct obj *otmp) switch (otmp->otyp) { case EGG: if (otmp->corpsenm == PM_PYROLISK) { - useup(otmp); + if (carried(otmp)) + useup(otmp); + else + useupf(otmp, 1L); explode(u.ux, u.uy, -11, d(3, 6), 0, EXPL_FIERY); return FALSE; } else if (stale_egg(otmp)) { @@ -2842,8 +2845,8 @@ doeat(void) if (otmp == svc.context.victual.piece) { - boolean one_bite_left - = (svc.context.victual.usedtime + 1 >= svc.context.victual.reqtime); + boolean one_bite_left = (svc.context.victual.usedtime + 1 + >= svc.context.victual.reqtime); /* If they weren't able to choke, they don't suddenly become able to * choke just because they were interrupted. On the other hand, if From 23532b012b1cddae8ac06ff98b61fd000529e91f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Aug 2024 11:19:45 -0700 Subject: [PATCH 076/121] farlook of "`" Allow farlook/quicklook to step through all engravings--corridor ones as well as room ones--with repeated '`' when picking location with getpos(), similar to how repeated '^' goes through all traps no matter what display character they use. It isn't possible to look at corridor engravings by using their default symbol '#'. It is possible by using 'a' for "anything of interest" but that matches lots of other stuff. This tries to add an NHDT tags line to sym.h. That was followed by 'git nhadd' which did stage it for commit, but date/branch/revision tag expansion isn't working. I did something similar to defsym.h about 5 weeks ago; that one worked and I don't recall having needed to do anything special. --- include/sym.h | 3 ++- src/getpos.c | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/sym.h b/include/sym.h index 44efaffe7..d965ec2ff 100644 --- a/include/sym.h +++ b/include/sym.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sym.h */ +/* NetHack 3.7 sym.h $NHDT-Date: $ $NHDT-Branch: $ $NHDT-Revision: $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -105,6 +105,7 @@ struct symsetentry { #define is_cmap_water(i) ((i) == S_pool || (i) == S_water) #define is_cmap_lava(i) ((i) == S_lava || (i) == S_lavawall) #define is_cmap_stairs(i) ((i) >= S_upstair && (i) <= S_brdnladder) +#define is_cmap_engraving(i) ((i) == S_engroom || (i) == S_engrcorr) /* misc symbol definitions */ enum misc_symbols { diff --git a/src/getpos.c b/src/getpos.c index 3457d70e7..1e0c813d2 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 getpos.c $NHDT-Date: 1708126536 2024/02/16 23:35:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ +/* NetHack 3.7 getpos.c $NHDT-Date: 1723875487 2024/08/17 06:18:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ /*-Copyright (c) Pasi Kallinen, 2023. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1033,7 +1033,11 @@ getpos(coord *ccp, boolean force, const char *goal) || c == (int) gs.showsyms[sidx] /* have '^' match webs and vibrating square or any other trap that uses something other than '^' */ - || (c == '^' && is_cmap_trap(sidx))) + || (c == '^' && is_cmap_trap(sidx)) + /* have room engraving character (default '`') + match corridor engravings (default '#') too */ + || (c == gs.showsyms[S_engroom] + && is_cmap_engraving(sidx))) matching[sidx] = (char) ++k; } if (k) { From 94eef3c3db8b818fc83e297312ec8d9ff86b4c8c Mon Sep 17 00:00:00 2001 From: SHIRAKATA Kentaro Date: Sun, 14 Jul 2024 23:34:50 +0900 Subject: [PATCH 077/121] split "poof" in potion_dip() into a separate function --- src/potion.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/potion.c b/src/potion.c index a51be8127..25e5e4f0c 100644 --- a/src/potion.c +++ b/src/potion.c @@ -41,6 +41,7 @@ staticfn int dip_ok(struct obj *); staticfn int dip_hands_ok(struct obj *); staticfn void hold_potion(struct obj *, const char *, const char *, const char *); +staticfn void poof(struct obj *); staticfn int potion_dip(struct obj *obj, struct obj *potion); /* used to indicate whether quaff or dip has skipped an opportunity to @@ -2379,6 +2380,14 @@ dip_into(void) return potion_dip(obj, potion); } +staticfn void +poof(struct obj *potion) +{ + if (potion->dknown) + trycall(potion); + useup(potion); +} + /* called by dodip() or dip_into() after obj and potion have been chosen */ staticfn int potion_dip(struct obj *obj, struct obj *potion) @@ -2403,8 +2412,10 @@ potion_dip(struct obj *obj, struct obj *potion) boolean useeit = !Blind || (obj == ublindf && Blindfolded_only); const char *obj_glows = Yobjnam2(obj, "glow"); - if (H2Opotion_dip(potion, obj, useeit, obj_glows)) - goto poof; + if (H2Opotion_dip(potion, obj, useeit, obj_glows)) { + poof(potion); + return ECMD_TIME; + } } else if (obj->otyp == POT_POLYMORPH || potion->otyp == POT_POLYMORPH) { /* some objects can't be polymorphed */ if (obj_unpolyable(obj->otyp == POT_POLYMORPH ? potion : obj)) { @@ -2434,7 +2445,8 @@ potion_dip(struct obj *obj, struct obj *potion) return ECMD_TIME; } else { pline1(nothing_seems_to_happen); - goto poof; + poof(potion); + return ECMD_TIME; } } potion->in_use = FALSE; /* didn't go poof */ @@ -2561,7 +2573,8 @@ potion_dip(struct obj *obj, struct obj *potion) if (potion->otyp == POT_WATER && obj->otyp == TOWEL) { pline_The("towel soaks it up!"); /* wetting towel already done via water_damage() in H2Opotion_dip */ - goto poof; + poof(potion); + return ECMD_TIME; } if (is_poisonable(obj)) { @@ -2574,19 +2587,23 @@ potion_dip(struct obj *obj, struct obj *potion) Strcpy(buf, The(xname(potion))); pline("%s forms a coating on %s.", buf, the(xname(obj))); obj->opoisoned = TRUE; - goto poof; + poof(potion); + return ECMD_TIME; } else if (obj->opoisoned && (potion->otyp == POT_HEALING || potion->otyp == POT_EXTRA_HEALING || potion->otyp == POT_FULL_HEALING)) { pline("A coating wears off %s.", the(xname(obj))); obj->opoisoned = 0; - goto poof; + poof(potion); + return ECMD_TIME; } } if (potion->otyp == POT_ACID) { - if (erode_obj(obj, 0, ERODE_CORRODE, EF_GREASE) != ER_NOTHING) - goto poof; + if (erode_obj(obj, 0, ERODE_CORRODE, EF_GREASE) != ER_NOTHING) { + poof(potion); + return ECMD_TIME; + } } if (potion->otyp == POT_OIL) { @@ -2736,12 +2753,6 @@ potion_dip(struct obj *obj, struct obj *potion) pline("Interesting..."); return ECMD_TIME; - - poof: - if (potion->dknown) - trycall(potion); - useup(potion); - return ECMD_TIME; } /* *monp grants a wish and then leaves the game */ From 39665ba017e96c99e1055940e315933571540629 Mon Sep 17 00:00:00 2001 From: SHIRAKATA Kentaro Date: Wed, 24 Jul 2024 22:38:00 +0900 Subject: [PATCH 078/121] split "getcad" into a separate function --- src/shk.c | 77 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/src/shk.c b/src/shk.c index b91a3bc8b..0ec28f217 100644 --- a/src/shk.c +++ b/src/shk.c @@ -42,6 +42,8 @@ struct sortbill_item { typedef struct sortbill_item Bill; staticfn void makekops(coord *); +staticfn void getcad(struct monst *, const char *, coordxy, coordxy, boolean, + boolean, boolean); staticfn void call_kops(struct monst *, boolean); staticfn void kops_gone(boolean); @@ -5040,6 +5042,42 @@ makekops(coord *mm) } } +staticfn void +getcad( + struct monst *shkp, const char *dmgstr, coordxy x, coordxy y, + boolean uinshp, boolean animal, boolean pursue) +{ + boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */ + || !strcmp(dmgstr, "damage")); /* pick-axe */ + + if (muteshk(shkp)) { + if (animal && !helpless(shkp)) + yelp(shkp); + } else if (pursue || uinshp || !um_dist(x, y, 1)) { + if (!Deaf) { + SetVoice(shkp, 0, 80, 0); + verbalize("How dare you %s my %s?", dmgstr, + dugwall ? "shop" : "door"); + } else { + pline("%s is %s that you decided to %s %s %s!", + Shknam(shkp), ROLL_FROM(angrytexts), + dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); + } + } else { + if (!Deaf) { + pline("%s shouts:", Shknam(shkp)); + SetVoice(shkp, 0, 80, 0); + verbalize("Who dared %s my %s?", dmgstr, + dugwall ? "shop" : "door"); + } else { + pline("%s is %s that someone decided to %s %s %s!", + Shknam(shkp), ROLL_FROM(angrytexts), + dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); + } + } + hot_pursuit(shkp); +} + void pay_for_damage(const char *dmgstr, boolean cant_mollify) { @@ -5048,8 +5086,6 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) boolean uinshp = (*u.ushops != '\0'); char qbuf[80]; coordxy x, y; - boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */ - || !strcmp(dmgstr, "damage")); /* pick-axe */ boolean animal, pursue; struct damage *tmp_dam, *appear_here = 0; long cost_of_damage = 0L; @@ -5120,7 +5156,8 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) if (!cansee(shkp->mx, shkp->my)) return; pursue = TRUE; - goto getcad; + getcad(shkp, dmgstr, x, y, uinshp, animal, pursue); + return; } if (uinshp) { @@ -5130,8 +5167,10 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) mnexto(shkp, RLOC_NOMSG); } pursue = um_dist(shkp->mx, shkp->my, 1); - if (pursue) - goto getcad; + if (pursue) { + getcad(shkp, dmgstr, x, y, uinshp, animal, pursue); + return; + } } else { /* * Make shkp show up at the door. Effect: If there is a monster @@ -5164,33 +5203,7 @@ pay_for_damage(const char *dmgstr, boolean cant_mollify) if ((um_dist(x, y, 1) && !uinshp) || cant_mollify || (money_cnt(gi.invent) + ESHK(shkp)->credit) < cost_of_damage || !rn2(50)) { - getcad: - if (muteshk(shkp)) { - if (animal && !helpless(shkp)) - yelp(shkp); - } else if (pursue || uinshp || !um_dist(x, y, 1)) { - if (!Deaf) { - SetVoice(shkp, 0, 80, 0); - verbalize("How dare you %s my %s?", dmgstr, - dugwall ? "shop" : "door"); - } else { - pline("%s is %s that you decided to %s %s %s!", - Shknam(shkp), ROLL_FROM(angrytexts), - dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); - } - } else { - if (!Deaf) { - pline("%s shouts:", Shknam(shkp)); - SetVoice(shkp, 0, 80, 0); - verbalize("Who dared %s my %s?", dmgstr, - dugwall ? "shop" : "door"); - } else { - pline("%s is %s that someone decided to %s %s %s!", - Shknam(shkp), ROLL_FROM(angrytexts), - dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); - } - } - hot_pursuit(shkp); + getcad(shkp, dmgstr, x, y, uinshp, animal, pursue); return; } From 01910d29989d8ded9f5ec4835a0dd021fb67acad Mon Sep 17 00:00:00 2001 From: SHIRAKATA Kentaro Date: Mon, 12 Aug 2024 14:59:32 +0900 Subject: [PATCH 079/121] split "moverock_done" into a separate function --- src/hack.c | 54 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/hack.c b/src/hack.c index 028b49645..53da33e80 100644 --- a/src/hack.c +++ b/src/hack.c @@ -9,6 +9,7 @@ /* #define DEBUG */ /* uncomment for debugging */ staticfn boolean could_move_onto_boulder(coordxy, coordxy); +staticfn void moverock_done(coordxy, coordxy); staticfn int moverock(void); staticfn void dosinkfall(void); staticfn boolean findtravelpath(int); @@ -152,6 +153,15 @@ could_move_onto_boulder(coordxy sx, coordxy sy) return squeezeablylightinvent(); } +staticfn void +moverock_done(coordxy sx, coordxy sy) +{ + struct obj *otmp; + for (otmp = svl.level.objects[sx][sy]; otmp; otmp = otmp->nexthere) + if (otmp->otyp == BOULDER) + otmp->next_boulder = 0; /* resume normal xname() for this obj */ +} + staticfn int moverock(void) { @@ -161,7 +171,6 @@ moverock(void) struct monst *mtmp, *shkp; const char *what; boolean costly, firstboulder = TRUE; - int res = 0; sx = u.ux + u.dx, sy = u.uy + u.dy; /* boulder starting position */ while ((otmp = sobj_at(BOULDER, sx, sy)) != 0) { @@ -170,8 +179,8 @@ moverock(void) pline("That feels like a boulder."); map_object(otmp, TRUE); nomul(0); - res = -1; - goto moverock_done; + moverock_done(sx, sy); + return -1; } /* when otmp->next_boulder is 1, xname() will format it as @@ -197,6 +206,7 @@ moverock(void) reveals an unseen boulder or lack of remembered, unseen monster */ if (svc.context.nopick) { int oldglyph = glyph_at(sx, sy); /* before feel_location() */ + int res; feel_location(sx, sy); /* same for all 3 if/else-if/else cases */ if (throws_rocks(gy.youmonst.data)) { @@ -221,7 +231,8 @@ moverock(void) svc.context.door_opened = svc.context.move = TRUE; res = -1; /* don't move to , so no soko guilt */ } - goto moverock_done; /* stop further push attempts */ + moverock_done(sx, sy); /* stop further push attempts */ + return res; } if (Levitation || Is_airlevel(&u.uz)) { /* FIXME? behavior in an air bubble on the water level should @@ -232,8 +243,8 @@ moverock(void) feel_location(sx, sy); You("don't have enough leverage to push %s.", the(xname(otmp))); /* Give them a chance to climb over it? */ - res = -1; - goto moverock_done; + moverock_done(sx, sy); + return -1; } if (verysmall(gy.youmonst.data) && !u.usteed) { if (Blind) @@ -261,8 +272,8 @@ moverock(void) if (revive_nasty(rx, ry, "You sense movement on the other side.")) { - res = -1; - goto moverock_done; + moverock_done(sx, sy); + return -1; } if (mtmp && !noncorporeal(mtmp->data) @@ -307,6 +318,7 @@ moverock(void) if (ttmp) { int newlev = 0; /* lint suppression */ d_level dest; + int res; /* if a trap operates on the boulder, don't attempt to move any others at this location; return -1 @@ -336,7 +348,8 @@ moverock(void) if (cansee(rx, ry)) newsym(rx, ry); res = sobj_at(BOULDER, sx, sy) ? -1 : 0; - goto moverock_done; + moverock_done(sx, sy); + return res; } break; case SPIKED_PIT: @@ -353,7 +366,8 @@ moverock(void) if (mtmp && !Blind) newsym(rx, ry); res = sobj_at(BOULDER, sx, sy) ? -1 : 0; - goto moverock_done; + moverock_done(sx, sy); + return res; case HOLE: case TRAPDOOR: Soundeffect(se_kerplunk_boulder_gone, 40); @@ -377,7 +391,8 @@ moverock(void) if (cansee(rx, ry)) newsym(rx, ry); res = sobj_at(BOULDER, sx, sy) ? -1 : 0; - goto moverock_done; + moverock_done(sx, sy); + return res; case LEVEL_TELEP: /* 20% chance of picking current level; 100% chance for that if in single-level branch (Knox) or in endgame */ @@ -408,7 +423,8 @@ moverock(void) } seetrap(ttmp); res = sobj_at(BOULDER, sx, sy) ? -1 : 0; - goto moverock_done; + moverock_done(sx, sy); + return res; default: break; /* boulder not affected by this trap */ } @@ -541,19 +557,13 @@ moverock(void) sokoban_guilt(); break; } else { - res = -1; - goto moverock_done; + moverock_done(sx, sy); + return -1; } } } - res = 0; - - moverock_done: - for (otmp = svl.level.objects[sx][sy]; otmp; otmp = otmp->nexthere) - if (otmp->otyp == BOULDER) - otmp->next_boulder = 0; /* resume normal xname() for this obj */ - - return res; + moverock_done(sx, sy); + return 0; } /* From 214e508890ede2cfa970af83954197b31da9310b Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Aug 2024 19:02:20 -0700 Subject: [PATCH 080/121] address issue #1267 - hasted shopkeepers Issue reported by ars3niy: a hasted shopkeeper always gets 2 moves per turn and had a tendency to move away from the door and then move right back, keeping it blocked. I didn't view the ttyrec and didn't reproduce the situation, but I have noticed something of the sort in the past. This reduces shk speed so that there will usually be 2 moves per turn but not always, increasing the likelihood of leaving the door unblocked when nearby hero does not owe anything. This change results in a slowed shopkeeper having speed dropped to 11 rather than 12. I suspect that the original 18 speed might have been picked to guarantee slowed speed of at least 12, but if so, that was in the days when speed 11 would have provided 11 consecutive moves and then a turn guaranteed to not allow a move rather than the current 11 out of 12 chance to move each turn. Fixes #1267 --- doc/fixes3-7-0.txt | 4 +++- include/monsters.h | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 38330a56e..cb4dd31b1 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1461 $ $NHDT-Date: 1723833609 2024/08/16 18:40:09 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1464 $ $NHDT-Date: 1723945837 2024/08/18 01:50:37 $ General Fixes and Modified Features ----------------------------------- @@ -1456,6 +1456,8 @@ the #terrain command didn't know how to cope with visible gas/cloud regions; if/when a spot contains both region and trap, show the trap region expiration reported "the gas cloud around you dissipates" even when the hero was swallowed +reduce shopkeeper's innate speed from 18 to 16 so that a hasted shopkeeper + doesn't always get 2 moves per turn Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/include/monsters.h b/include/monsters.h index 3c7a8a0fd..e1987f8db 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monsters.h $NHDT-Date: 1705092146 2024/01/12 20:42:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 3.7 monsters.h $NHDT-Date: 1723945838 2024/08/18 01:50:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2693,8 +2693,17 @@ | M2_SHAPESHIFTER, M3_INFRAVISIBLE, 11, HI_DOMESTIC, DOPPELGANGER), + /* 3.7: shopkeepers used to have speed 18, but if/when they were + hasted they always got 2 moves per turn and had a tendency to move + away from blocking the door and then move right back; since they + might start with a potion of speed and drink that as soon as the + hero gets close, once inside the shop the hero could have trouble + getting out again; also, being slowed still guaranteed one move + per turn; reduce their innate speed from 18 to 16 for a hasted + speed of 22 rather than 24 and slowed speed of 11 rather than 12; + they will still block the shop door, but not as tenaciously */ MON(NAM("shopkeeper"), S_HUMAN, - LVL(12, 18, 0, 50, 0), G_NOGEN, + LVL(12, 16, 0, 50, 0), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_PHYS, 4, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 400, MS_SELL, MZ_HUMAN), 0, 0, From 9bc6e1bee1abc5d97cda0118f9341728ddcc7ab5 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Aug 2024 19:07:44 -0700 Subject: [PATCH 081/121] speed monster vs peacefuls Testing the shopkeeper speed change, I noticed that zapping the shk with speed monster made her angry. Since being hasted is beneficial for the target, don't become angry. --- src/zap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zap.c b/src/zap.c index 0bdc7baf2..e4ead85a6 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1715284462 2024/05/09 19:54:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.539 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1723946858 2024/08/18 02:07:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.542 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -218,8 +218,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) mon_adjust_speed(mtmp, 1, otmp); check_gear_next_turn(mtmp); /* might want speed boots */ } - if (mtmp->mtame) - helpful_gesture = TRUE; + /* wake but don't anger a peaceful target */ + helpful_gesture = TRUE; break; case WAN_UNDEAD_TURNING: case SPE_TURN_UNDEAD: From 158e3b12dcb444936cad6e2070bb216738a93e00 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 18 Aug 2024 11:29:04 -0700 Subject: [PATCH 082/121] comment thinko Some_Monnam() returns "Someone" or "Something", not "Someone" or "It". Removing the redundant '&& uchain != NULL' test shouldn't produce any change in behavior. --- src/steal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/steal.c b/src/steal.c index b26e5484b..45bf6adef 100644 --- a/src/steal.c +++ b/src/steal.c @@ -371,7 +371,7 @@ steal(struct monst *mtmp, char *objnambuf) no longer being visible; it could also be a case of a blinded hero being able to see via wearing the Eyes of the Overworld and having those stolen; remember the name as it is now; if unseen, - monkeys will be "It" and nymphs will be "Someone" */ + nymphs will be "Someone" and monkeys will be "Something" */ Strcpy(Monnambuf, Some_Monnam(mtmp)); /* food being eaten might already be used up but will not have @@ -574,13 +574,13 @@ steal(struct monst *mtmp, char *objnambuf) otmp->oclass); } /* hero's blindfold might have just been stolen; if so, replace - cached "It" or "Someone" with Monnam */ + cached "Someone" or "Something" with Monnam */ if (!seen && canspotmon(mtmp)) Strcpy(Monnambuf, Monnam(mtmp)); } else if (otmp->owornmask) { /* weapon or ball&chain */ struct obj *item = otmp; - if (otmp == uball && uchain != NULL) + if (otmp == uball) /* non-Null uball implies non-Null uchain */ item = uchain; /* yields a more accurate 'takes off' message */ worn_item_removal(mtmp, item); /* if we switched from uball to uchain for the preface message, From f8c399bf50c21f4c8a4864ff14965550eb0aac17 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 19 Aug 2024 10:06:29 -0700 Subject: [PATCH 083/121] \#timeout for regions Support tab separation for the region portion of #timeout output. This works ok under Qt. However, the output from #timeout uses a fixed-width font so tab separation isn't necessary. No idea how well it will work for mswin. --- src/region.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/region.c b/src/region.c index 3a65e583e..7a034f612 100644 --- a/src/region.c +++ b/src/region.c @@ -659,6 +659,7 @@ visible_region_summary(winid win) NhRegion *reg; char buf[BUFSZ], typbuf[QBUFSZ]; int i, damg, hdr_done = 0; + const char *fldsep = iflags.menu_tab_sep ? "\t" : " "; for (i = 0; i < svn.n_regions; i++) { reg = gr.regions[i]; @@ -684,8 +685,8 @@ visible_region_summary(winid win) Sprintf(typbuf, "poison gas (%d)", damg); else Strcpy(typbuf, "vapor"); - Sprintf(eos(buf), " %-16s", typbuf); - Sprintf(eos(buf), " @[%d,%d..%d,%d]", + Sprintf(eos(buf), "%s%-16s", fldsep, typbuf); + Sprintf(eos(buf), "%s@[%d,%d..%d,%d]", fldsep, reg->bounding_box.lx, reg->bounding_box.ly, reg->bounding_box.hx, reg->bounding_box.hy); putstr(win, 0, buf); From 9d1234b87d5d533fb8709feb7ebd628c51d2af62 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 19 Aug 2024 11:59:00 -0700 Subject: [PATCH 084/121] gas cloud dissipation If hero was in a cloud spot when it expired, the feedback would be |The gas cloud around you dissipates. |You see a gas cloud dissipate. --- doc/fixes3-7-0.txt | 2 ++ src/region.c | 28 +++++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index cb4dd31b1..79e89ac8a 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1456,6 +1456,8 @@ the #terrain command didn't know how to cope with visible gas/cloud regions; if/when a spot contains both region and trap, show the trap region expiration reported "the gas cloud around you dissipates" even when the hero was swallowed +region expiration could report "the gas cloud around you dissipates" and also + "you see a gas cloud dissipate" for the same cloud spot reduce shopkeeper's innate speed from 18 to 16 so that a hasted shopkeeper doesn't always get 2 moves per turn diff --git a/src/region.c b/src/region.c index 7a034f612..05866a4e2 100644 --- a/src/region.c +++ b/src/region.c @@ -448,12 +448,20 @@ run_regions(void) } } - if (gg.gas_cloud_diss_within) + if (gg.gas_cloud_diss_within) { pline_The("gas cloud around you dissipates."); - if (gg.gas_cloud_diss_seen) - You_see("%s dissipate.", - gg.gas_cloud_diss_seen == 1 - ? "a gas cloud" : "some gas clouds"); + /* normally won't see additional dissipation when within */ + /* FIXME? this assumes that additional dissipation is close by */ + if (u.xray_range <= 1) + gg.gas_cloud_diss_seen = 0; + gg.gas_cloud_diss_within = FALSE; + } + if (gg.gas_cloud_diss_seen) { + You_see("%s gas cloud%s dissipate.", + (gg.gas_cloud_diss_seen == 1) ? "a" : "some", + plur(gg.gas_cloud_diss_seen)); + gg.gas_cloud_diss_seen = 0; + } } /* @@ -1086,11 +1094,13 @@ expire_gas_cloud(genericptr_t p1, genericptr_t p2 UNUSED) if (pass == 1) { if (!does_block(x, y, &levl[x][y])) unblock_point(x, y); - if (u_at(x, y) && !u.uswallow) - gg.gas_cloud_diss_within = TRUE; } else { /* pass==2 */ - if (cansee(x, y)) - gg.gas_cloud_diss_seen++; + if (!u.uswallow) { + if (u_at(x, y)) + gg.gas_cloud_diss_within = TRUE; + else if (cansee(x, y)) + gg.gas_cloud_diss_seen++; + } } } } From 65b5f2cff17001199d0493c114ffaea0f6f7e2df Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 19 Aug 2024 13:10:28 -0700 Subject: [PATCH 085/121] farlook & probing feedback for monsters in regions When looking at a monster that's inside a gas cloud, include that fact in the output for farlook and for probing. When the monster being examined is sensed rather than seen, you'll sense the presense of the cloud as well as the monster even if the cloud can't be seen. Do likewise for self when using look-here (':'). Bonus fix: zapping wand of probing at self while engulfed reported that you were just held by the engulfer. Also fix an old comment typo/thinko. --- include/hack.h | 3 ++- src/insight.c | 34 ++++++++++++++++++++++++++-------- src/invent.c | 21 ++++++++++++++++++--- src/pager.c | 38 ++++++++++++++++++++++++++++++++------ 4 files changed, 78 insertions(+), 18 deletions(-) diff --git a/include/hack.h b/include/hack.h index fdd7740a4..1d6e457d5 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.h $NHDT-Date: 1717878594 2024/06/08 20:29:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ */ +/* NetHack 3.7 hack.h $NHDT-Date: 1724094288 2024/08/19 19:04:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.261 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1139,6 +1139,7 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define MHID_PREFIX 1 /* include ", mimicking " prefix */ #define MHID_ARTICLE 2 /* include "a " or "an " after prefix */ #define MHID_ALTMON 4 /* if mimicking a monster, include that */ +#define MHID_REGION 8 /* include region when mon is in one */ /* flags for make_corpse() and mkcorpstat(); 0..7 are recorded in obj->spe */ #define CORPSTAT_NONE 0x00 diff --git a/src/insight.c b/src/insight.c index fbc9fcacb..542857501 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1713334807 2024/04/17 06:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.112 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1724094296 2024/08/19 19:04:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.115 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3205,7 +3205,7 @@ mstatusline(struct monst *mtmp) if (mtmp->data == &mons[PM_LONG_WORM]) { int segndx, nsegs = count_wsegs(mtmp); - /* the worm code internals don't consider the head of be one of + /* the worm code internals don't consider the head to be one of the worm's segments, but we count it as such when presenting worm feedback to the player */ if (!nsegs) { @@ -3226,8 +3226,10 @@ mstatusline(struct monst *mtmp) Strcat(info, ", eating"); /* a stethoscope exposes mimic before getting here so this won't be relevant for it, but wand of probing doesn't */ - if (mtmp->mundetected || mtmp->m_ap_type) - mhidden_description(mtmp, MHID_PREFIX | MHID_ARTICLE | MHID_ALTMON, + if (mtmp->mundetected || mtmp->m_ap_type + || visible_region_at(gb.bhitpos.x, gb.bhitpos.y)) + mhidden_description(mtmp, + MHID_PREFIX | MHID_ARTICLE | MHID_ALTMON | MHID_REGION, eos(info)); if (mtmp->mcan) Strcat(info, ", cancelled"); @@ -3311,7 +3313,9 @@ mstatusline(struct monst *mtmp) void ustatusline(void) { + NhRegion *reg; char info[BUFSZ]; + size_t ln; info[0] = '\0'; if (Sick) { @@ -3366,15 +3370,29 @@ ustatusline(void) Strcat(info, Very_fast ? ", very fast" : ", fast"); if (u.uundetected) Strcat(info, ", concealed"); + else if (U_AP_TYPE != M_AP_NOTHING) + Strcat(info, ", disguised"); if (Invis) Strcat(info, ", invisible"); if (u.ustuck) { - if (sticks(gy.youmonst.data)) - Strcat(info, ", holding "); - else + if (u.uswallow) + Strcat(info, digests(u.ustuck->data) ? ", being digested by " + : ", engulfed by "); + else if (!sticks(gy.youmonst.data)) Strcat(info, ", held by "); - Strcat(info, mon_nam(u.ustuck)); + else + Strcat(info, ", holding "); + /* FIXME? a_monnam() uses x_monnam() which has a special case that + forces "the" instead of "a" when formatting u.ustuck while hero + is swallowed; we don't really want that here but it isn't worth + fiddling with just for self-probing while engulfed */ + Strcat(info, a_monnam(u.ustuck)); } + if (!u.uswallow + && (reg = visible_region_at(u.ux, u.uy)) != 0 + && (ln = strlen(info)) < sizeof info) + Snprintf(eos(info), sizeof info - ln, ", in a cloud of %s", + reg_damg(reg) ? "poison gas" : "vapor"); pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", svp.plname, piousness(FALSE, align_str(u.ualign.type)), diff --git a/src/invent.c b/src/invent.c index 76df37740..07ccd98c2 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1702023269 2023/12/08 08:14:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.485 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1724094299 2024/08/19 19:04:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.516 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4658,8 +4658,23 @@ look_here( } return (!!Blind ? ECMD_TIME : ECMD_OK); } - if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen) - There("is %s here.", an(trapname(trap->ttyp, FALSE))); + if (!skip_objects) { + NhRegion *reg; + char regbuf[QBUFSZ]; + + regbuf[0] = '\0'; + if ((reg = visible_region_at(u.ux, u.uy)) != 0) + Sprintf(regbuf, "a %s cloud", + reg_damg(reg) ? "poison gas" : "vapor"); + if ((trap = t_at(u.ux, u.uy)) != 0 && !trap->tseen) + trap = (struct trap *) NULL; + + if (reg || trap) + There("is %s%s%s here.", + reg ? regbuf : "", + (reg && trap) ? " and " : "", + trap ? an(trapname(trap->ttyp, FALSE)) : ""); + } otmp = svl.level.objects[u.ux][u.uy]; dfeature = dfeature_at(u.ux, u.uy, fbuf2); diff --git a/src/pager.c b/src/pager.c index 1c93d494e..eff6bfd6b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1720565361 2024/07/09 22:49:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.275 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1724094301 2024/08/19 19:05:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -118,8 +118,10 @@ self_lookat(char *outbuf) pmname(&mons[u.umonnum], Ugender), svp.plname); if (u.usteed) Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); - if (u.uundetected || (Upolyd && U_AP_TYPE)) - mhidden_description(&gy.youmonst, MHID_PREFIX | MHID_ARTICLE, + if (u.uundetected || (Upolyd && U_AP_TYPE) + || visible_region_at(u.ux, u.uy)) + mhidden_description(&gy.youmonst, + MHID_PREFIX | MHID_ARTICLE | MHID_REGION, eos(outbuf)); if (Punished) Sprintf(eos(outbuf), ", chained to %s", @@ -187,9 +189,12 @@ mhidden_description( { struct obj *otmp; const char *what; + NhRegion *reg; + size_t buflen; boolean incl_prefix = (mhid_flags & MHID_PREFIX) != 0, incl_article = (mhid_flags & MHID_ARTICLE) != 0, - show_altmon = (mhid_flags & MHID_ALTMON) != 0; + show_altmon = (mhid_flags & MHID_ALTMON) != 0, + force_region = (mhid_flags & MHID_REGION) != 0; boolean fakeobj, isyou = (mon == &gy.youmonst); coordxy x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my; int glyph = (svl.level.flags.hero_memory && !isyou) ? levl[x][y].glyph @@ -251,6 +256,26 @@ mhidden_description( Strcat(outbuf, " in murky water"); } } + + /* FIXME: isn't right when looking at long worm tails */ + if ((reg = visible_region_at(x, y)) != 0 + && (buflen = strlen(outbuf)) < BUFSZ - 1) { + int r = (u.xray_range > 1) ? u.xray_range : 1; + + /* at present, hero must be next to the monster; being able to see + from the hero's spot to the monster's spot would be much better, + but a visible region marks all its spots as can't-be-seen, so + this monster's spot is !cansee and !couldsee [maybe we need an + additional vision bit for "hero's side of edge of gas cloud"?] */ + if (distu(x, y) <= r * (r + 1) || force_region) { + int rglyph = reg->glyph; + boolean poison_gas = (glyph_is_cmap(rglyph) + && glyph_to_cmap(rglyph) == S_poisoncloud); + + Snprintf(eos(outbuf), BUFSZ - buflen, ", in a cloud of %s", + poison_gas ? "poison gas" : "vapor"); + } + } } /* extracted from lookat(); also used by namefloorobj() */ @@ -424,8 +449,9 @@ look_at_monster( /* we know the hero sees a monster at this location, but if it's shown due to persistent monster detection he might remember something else */ - if (mtmp->mundetected || M_AP_TYPE(mtmp)) - mhidden_description(mtmp, MHID_PREFIX | MHID_ARTICLE, eos(buf)); + if (mtmp->mundetected || M_AP_TYPE(mtmp) || visible_region_at(x, y)) + mhidden_description(mtmp, MHID_PREFIX | MHID_ARTICLE | MHID_REGION, + eos(buf)); if (monbuf) { unsigned how_seen = howmonseen(mtmp); From 84785db5ecbcc2bb51f358bdcb5314600a67bd85 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 20 Aug 2024 14:02:26 -0700 Subject: [PATCH 086/121] Guidebook's map display of monsters Instead of " a-z and " A-Z and " @&':; for the lists of characters used to show monsters, followed by " I for special "remembered, unseen monster", change the capital letter line " a-z and " A-HJ-Z and " @&':; to emphasize that 'I' is used differently from other letters. Also, add the trailing "and"s to the LaTeX version. I haven't seen what the result looks like. --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 9472d54b1..2446fab6a 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -522,7 +522,7 @@ or a pool of lava or a wall of lava. .lp \f(CR\\\\\fP An opulent throne. .lp "\f(CRa\fP-\f(CRz\fP\ \ \fIand\fP" -.lp "\f(CRA\fP-\f(CRZ\fP\ \ \fIand\fP" +.lp "\f(CRA\fP-\f(CRH\fP\f(CRJ\fP-\f(CRZ\fP\ \ \fIand\fP" .lp "\f(CR@&\(aq:;\fP" \" \(aq == apostrophe / single quote Letters and certain other symbols represent the various inhabitants of the Mazes of Menace. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 6524dd281..dba5ab268 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -575,8 +575,9 @@ A pool of water or moat or a wall of water or a pool of lava or a wall of lava. \item[\tb{$\backslash$}] An opulent throne. -\item[\tb{a-z}] -\item[\tb{A-Z}] +\item[\tb{a-z}] {\normalfont and}] +\item[\tb{A-HJ-Z}] {\normalfont and}] +%should probably change \item[\tb{@\&\verb+'+:;}] to \item[\tb{\verb+@&':;+}] \item[\tb{@\&\verb+'+:;}] Letters and certain other symbols represent the various inhabitants of the Mazes of Menace. From 0afa5bd564db121c7ba46b40b4428889872d036e Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Aug 2024 22:01:08 -0700 Subject: [PATCH 087/121] Riders when sorting vanquished monsters by class Explicitly sort and label Riders before major demons when displaying vanquished monsters with sort-by-class. They're lumped in with '&' but they aren't really demons. --- doc/fixes3-7-0.txt | 2 ++ src/insight.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 79e89ac8a..9b45266b4 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2590,6 +2590,8 @@ for ranger characters, shooting any type of arrow while wielding the Longbow change the #vanquished command from debug-only to general user command add 'sortvanquished' option to be able to set the preferred sort order without using 'm #vanquished' and to have it persist across save/restore +when sorting vanquished monsters by monster class, treat the Riders as a + separate class from major demons add #genocided command have 'I u' mention whether there are any unpaid items on the floor (unusual but not impossible); it doesn't itemize them or show shop price diff --git a/src/insight.c b/src/insight.c index 542857501..aba80ef02 100644 --- a/src/insight.c +++ b/src/insight.c @@ -2632,6 +2632,14 @@ vanqsort_cmp( } res = mcls1 - mcls2; /* class */ if (res == 0) { + /* Riders are in the same class as major demons; group Riders + at the start of that class regardless of secondary ordering; + res -1 => #1 is a Rider, #2 isn't; + 0 => both riders or both major demons; + +1 => #2 is a Rider, #1 isn't */ + res = is_rider(&mons[indx2]) - is_rider(&mons[indx1]); + if (res) + break; mlev1 = mons[indx1].mlevel; mlev2 = mons[indx2].mlevel; res = mlev1 - mlev2; /* mlevel low to high */ @@ -2710,6 +2718,7 @@ int dovanquished(void) { list_vanquished(iflags.menu_requested ? 'a' : 'y', FALSE); + iflags.menu_requested = FALSE; return ECMD_OK; } @@ -2746,12 +2755,19 @@ list_vanquished(char defquery, boolean ask) total_killed += (long) nkilled; } + /* + * FIXME: + * Setting sort order should take place for explicit 'm #vanquished' + * even when there are less than 2 types vanquished so far. + */ + /* vanquished creatures list; * includes all dead monsters, not just those killed by the player */ if (ntypes != 0) { char mlet, prev_mlet = 0; /* used as small integer, not character */ - boolean class_header, uniq_header, was_uniq = FALSE; + boolean class_header, uniq_header, Rider, + was_uniq = FALSE, special_hdr = FALSE; c = ask ? yn_function( "Do you want an account of creatures vanquished?", @@ -2780,9 +2796,17 @@ list_vanquished(char defquery, boolean ask) for (ni = 0; ni < ntypes; ni++) { i = mindx[ni]; nkilled = svm.mvitals[i].died; + Rider = is_rider(&mons[i]); mlet = mons[i].mlet; - if (class_header && mlet != prev_mlet) { - Strcpy(buf, def_monsyms[(int) mlet].explain); + if (class_header + && (mlet != prev_mlet || (special_hdr && !Rider))) { + if (!Rider) { + Strcpy(buf, def_monsyms[(int) mlet].explain); + special_hdr = FALSE; + } else { + Strcpy(buf, "Rider"); + special_hdr = TRUE; + } /* 'ask' implies final disclosure, where highlighting of various header lines is suppressed */ putstr(klwin, ask ? ATR_NONE : iflags.menu_headings.attr, From a2980520953a7a990ca7df4d97e9788a519e863e Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 24 Aug 2024 19:04:41 -0700 Subject: [PATCH 088/121] fix a FIXME for 'm #vanquished' If player uses the 'm' prefix before the #vanquished command when the vanquished monsters list has fewer than two types so far, select the preferred sort for #vanquished even though it won't be applicable yet. Also, when prompting about vanquished monsters during end of game disclosure, where an 'a' response is given special meaning, use "[ynq]" instead of "[ynaq]" if there is only one type of monster vanquished. It's skipped altogether when the list has zero types and there's no point in picking sort order when there is just one type. The player can still answer with 'a' when [ynq] doesn't show that (for tty and curses at least, probably X11); 'a' will end up behaving as 'y' in that case. --- src/insight.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/insight.c b/src/insight.c index aba80ef02..91c74994e 100644 --- a/src/insight.c +++ b/src/insight.c @@ -2717,7 +2717,7 @@ set_vanq_order(boolean for_vanq) int dovanquished(void) { - list_vanquished(iflags.menu_requested ? 'a' : 'y', FALSE); + list_vanquished(iflags.menu_requested ? 'A' : 'y', FALSE); iflags.menu_requested = FALSE; return ECMD_OK; } @@ -2728,6 +2728,7 @@ dovanquished(void) #define done_stopprint program_state.stopprint +/* used for #vanquished and end of game disclosure and end of game dumplog */ void list_vanquished(char defquery, boolean ask) { @@ -2738,12 +2739,25 @@ list_vanquished(char defquery, boolean ask) winid klwin; short mindx[NUMMONS]; char c, buf[BUFSZ], buftoo[BUFSZ]; - boolean dumping; /* for DUMPLOG; doesn't need to be conditional */ + /* 'A' is only supplied by 'm #vanquished'; 'd' is only supplied by + dump_everything() when writing dumplog, so won't happen if built + without '#define DUMPLOG' but there's no need for conditionals here */ + boolean force_sort = (defquery == 'A'), + dumping = (defquery == 'd'); - dumping = (defquery == 'd'); - if (dumping) { + /* normally we don't ask about sort order for the vanquished list unless + it contains at least two entries; however, if player has used explicit + 'm #vanquished', choose order no matter what it contains so far */ + if (force_sort) { /* iflags.menu_requested via dovanquished() */ + /* choose value for vanq_sortmode via menu; ESC cancels choosing + sort order but continues with vanquishd monsters display */ + (void) set_vanq_order(TRUE); + } + if (dumping || force_sort) { + /* switch from 'A' or 'd' to 'y'; 'ask' is already False for the + cases that might supply 'A' or 'd' */ defquery = 'y'; - ask = FALSE; /* redundant; caller passes False with defquery=='d' */ + ask = FALSE; /* redundant */ } /* get totals first */ @@ -2755,12 +2769,6 @@ list_vanquished(char defquery, boolean ask) total_killed += (long) nkilled; } - /* - * FIXME: - * Setting sort order should take place for explicit 'm #vanquished' - * even when there are less than 2 types vanquished so far. - */ - /* vanquished creatures list; * includes all dead monsters, not just those killed by the player */ @@ -2769,10 +2777,23 @@ list_vanquished(char defquery, boolean ask) boolean class_header, uniq_header, Rider, was_uniq = FALSE, special_hdr = FALSE; - c = ask ? yn_function( - "Do you want an account of creatures vanquished?", - ynaqchars, defquery, TRUE) - : defquery; + if (ask) { + char allow_yn[10]; + + if (ntypes > 1) { + Strcpy(allow_yn, ynaqchars); + } else { + Strcpy(allow_yn, ynqchars); /* don't include 'a', but */ + Strcat(allow_yn, "\033a"); /* allow user to answer 'a' */ + if (defquery == 'a') /* potential default from 'disclose' */ + defquery = 'y'; + } + c = yn_function("Do you want an account of creatures vanquished?", + allow_yn, defquery, TRUE); + } else { + c = defquery; + } + if (c == 'q') done_stopprint++; if (c == 'y' || c == 'a') { From 9365789b6dc3de8bd66881594b3500aad7bbbe10 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 25 Aug 2024 12:15:17 -0700 Subject: [PATCH 089/121] revise #wizbury feedback Simplify the code added in April. --- src/dig.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/dig.c b/src/dig.c index 92d7cd771..309f06a67 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dig.c $NHDT-Date: 1709928001 2024/03/08 20:00:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.211 $ */ +/* NetHack 3.7 dig.c $NHDT-Date: 1724613307 2024/08/25 19:15:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.219 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2294,26 +2294,24 @@ wiz_debug_cmd_bury(void) ++before; bury_objs(x, y); + + for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) + ++after; } - if (before == 0) { /* there was nothing here */ + diff = before - after; + if (before == 0) + /* there was nothing here */ pline("No objects here or adjacent to bury."); - } else { - for (x = u.ux - 1; x <= u.ux + 1; x++) - for (y = u.uy - 1; y <= u.uy + 1; y++) { - if (!isok(x, y)) - continue; - for (otmp = svl.level.objects[x][y]; otmp; otmp = otmp->nexthere) - ++after; - } - diff = before - after; - /* will be 0 if only unburiable objects (The Amulet, &c) are present; - if uball got buried, uchain went away--count that as being buried */ - if (diff == 0) - pline("No objects buried."); - else - pline("%d object%s buried.", diff, plur(diff)); - } + else if (diff == 0) + /* before and after will be the same if only unburiable objects are + present (The Amulet, invocation items, Rider corpses, uchain when + uball doesn't get buried: carried or floor beyond burial range) */ + pline("No objects buried."); + else + /* usual case; if uball got buried, uchain went away and won't be + counted as buried */ + pline("%d object%s buried.", diff, plur(diff)); return ECMD_OK; } #endif /* DEBUG */ From 83b85d4be95b8e3dad99a8420bc9f321cf0e3e3a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 25 Aug 2024 13:11:05 -0700 Subject: [PATCH 090/121] add a FIXME comment to secret door detection ^E and wand of secret door detection used to just update the map without any other feedback, but were changed post-3.6 to issue a message about what things are being discovered. But the message is misleading if [some of] the things revealed are obscured by objects or by monsters. Presumeably by regions too. --- src/detect.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/detect.c b/src/detect.c index 99da4604d..347829a34 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1701,6 +1701,18 @@ findit(void) char buf[BUFSZ]; struct found_things found; + /* + * FIXME: + * When things are found, this should show the updated map and allow + * browsing. + * + * Currently, "You reveal a trap!" will map the trap but not reveal it + * if that trap is covered by something, which is fairly common for + * early levels where corpses of fake heroes usually hide the traps + * that killed them. That's most likely to occur for wizard mode ^E + * but can happen in normal play by using wand of secret door detection. + */ + if (u.uswallow) return 0; From a5700805c661ae5fe60d447f85773fd04eacb569 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Aug 2024 14:37:46 -0700 Subject: [PATCH 091/121] fix obscure secret corridor bug magic_map_background() would overwrite remembered objects and traps. That meant discovery of secret corridors by secret door detection or ^E would forget embedded objects at their locations. --- doc/fixes3-7-0.txt | 4 ++++ src/display.c | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 9b45266b4..cefca5ecd 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1460,6 +1460,10 @@ region expiration could report "the gas cloud around you dissipates" and also "you see a gas cloud dissipate" for the same cloud spot reduce shopkeeper's innate speed from 18 to 16 so that a hasted shopkeeper doesn't always get 2 moves per turn +when a secret corridor was discovered by wand of secret door detection or by + wizard mode ^E and converted into a regular corridor, if there was a + formerly embbered object at the spot, presence of the object would be + forgotten unless within range of a light source Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/display.c b/src/display.c index 349fb6056..fc4db6f7f 100644 --- a/src/display.c +++ b/src/display.c @@ -248,7 +248,7 @@ magic_map_background(coordxy x, coordxy y, int show) else if (lev->typ == CORR && glyph == cmap_to_glyph(S_litcorr)) glyph = cmap_to_glyph(S_corr); } - if (svl.level.flags.hero_memory) + if (svl.level.flags.hero_memory && glyph_is_cmap(lev->glyph)) lev->glyph = glyph; if (show) show_glyph(x, y, glyph); @@ -1120,6 +1120,8 @@ tether_glyph(coordxy x, coordxy y) * * DISP_BEAM - Display the given glyph at each location, but do not erase * any until the close call. + * DISP_ALL - Same as DISP_BEAM except glyph is shown at the specified + * spot even when that spot can't be seen. * DISP_TETHER - Display a tether glyph at each location, and the tethered * object at the farthest location, but do not erase any * until the return trip or close. @@ -1277,7 +1279,7 @@ flash_glyph_at(coordxy x, coordxy y, int tg, int rpt) rpt *= 2; /* two loop iterations per 'count' */ glyph[0] = tg; glyph[1] = (svl.level.flags.hero_memory) ? levl[x][y].glyph - : back_to_glyph(x, y); + : back_to_glyph(x, y); /* even iteration count (guaranteed) ends with glyph[1] showing; caller might want to override that, but no newsym() calls here in case caller has tinkered with location visibility */ @@ -1974,13 +1976,14 @@ show_glyph(coordxy x, coordxy y, int glyph) && !program_state.in_getlev && (oldglyph != glyph || gg.gbuf[y][x].gnew)) { int c = glyph_to_cmap(glyph); + if ((glyph_is_nothing(oldglyph) || glyph_is_unexplored(oldglyph) || is_cmap_furniture(c)) && !is_cmap_wall(c) && !is_cmap_room(c)) { if ((a11y.mon_notices && glyph_is_monster(glyph)) || (glyph_is_monster(oldglyph)) || u_at(x, y)) { - /* nothing */ + ; /* nothing */ } else { show_glyph_change = TRUE; } From 9b79e0be8df5b692cdd6fddbf825f7ab13608037 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Aug 2024 21:27:54 -0700 Subject: [PATCH 092/121] fix the 'fix obscure secret corridor bug' commit The fix to prevent finding secert corridors via secret door detection from forgetting objects broke magic mapping. --- src/display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index fc4db6f7f..0e82a6cfa 100644 --- a/src/display.c +++ b/src/display.c @@ -248,7 +248,8 @@ magic_map_background(coordxy x, coordxy y, int show) else if (lev->typ == CORR && glyph == cmap_to_glyph(S_litcorr)) glyph = cmap_to_glyph(S_corr); } - if (svl.level.flags.hero_memory && glyph_is_cmap(lev->glyph)) + if (svl.level.flags.hero_memory + && (glyph_is_unexplored(lev->glyph) || glyph_is_cmap(lev->glyph))) lev->glyph = glyph; if (show) show_glyph(x, y, glyph); From 482ba2dc35c767265ffd296440ab2d0a0a62ef9a Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 27 Aug 2024 12:10:21 -0700 Subject: [PATCH 093/121] fixes typo --- doc/fixes3-7-0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index cefca5ecd..a29a52c5d 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1462,7 +1462,7 @@ reduce shopkeeper's innate speed from 18 to 16 so that a hasted shopkeeper doesn't always get 2 moves per turn when a secret corridor was discovered by wand of secret door detection or by wizard mode ^E and converted into a regular corridor, if there was a - formerly embbered object at the spot, presence of the object would be + formerly embedded object at the spot, presence of the object would be forgotten unless within range of a light source From 0ce02a7224194227830da93175d9f5f8040cce24 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 27 Aug 2024 12:54:00 -0700 Subject: [PATCH 094/121] old comment thinko --- src/objnam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objnam.c b/src/objnam.c index 6cc8a2aeb..727f91dbd 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3713,7 +3713,7 @@ wizterrainwish(struct _readobjnam_data *d) lev->wall_info |= (old_wall_info & WM_MASK); /* set up trapped flag; open door states aren't eligible */ if (d->trapped == 2 /* 2: wish includes explicit "untrapped" */ - || secret /* secret doors can't trapped due to their use + || secret /* secret doors can't be trapped due to their use * of both doormask and wall_info; those both * overlay rm->flags and partially conflict */ || (lev->doormask & (D_LOCKED | D_CLOSED)) == 0) From 8085d038980a133fe76d609e486475538be46976 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 27 Aug 2024 13:59:57 -0700 Subject: [PATCH 095/121] some miscellaneous formatting and comments Clear out some miscellaneous changes that have been sitting around for a while. --- src/attrib.c | 2 +- src/end.c | 12 +++++++----- src/mkmaze.c | 27 ++++++++++++++++++--------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/attrib.c b/src/attrib.c index e8d2bd3d1..6361ec374 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -242,7 +242,7 @@ losestr(int num, const char *knam, schar k_format) losehp(dmg, knam, k_format); if (Upolyd) { - /* if still polymorphed, reduce you-as-monst maxHP; never below 1 */ + /* when still poly'd, reduce you-as-monst maxHP; never below 1 */ u.mhmax -= min(dmg, u.mhmax - 1); } else if (!waspolyd) { /* not polymorphed now and didn't rehumanize when taking damage; diff --git a/src/end.c b/src/end.c index 3078a0ad3..994690cf4 100644 --- a/src/end.c +++ b/src/end.c @@ -937,8 +937,7 @@ fuzzer_savelife(int how) * Some debugging code pulled out of done() to unclutter it. * 'done_seq' is maintained in done(). */ - if (!program_state.panicking - && how != PANICKED && how != TRICKED) { + if (!program_state.panicking && how != PANICKED && how != TRICKED) { savelife(how); /* periodically restore characteristics plus lost experience @@ -986,11 +985,14 @@ fuzzer_savelife(int how) svk.killer.name[0] = '\0'; svk.killer.format = 0; - /* Guard against getting stuck in a loop if we die in one of + /* + * Guard against getting stuck in a loop if we die in one of * the few ways where life-saving isn't effective (cited case * was burning in lava when the level was too full to allow - * teleporting to safety). Deal with it by recreating - * the level, if we're in wizmode */ + * teleporting to safety). Deal with it by recreating the level + * if we're in wizmode (always the case for debug_fuzzer unless + * player has used a debugger to fiddle with 'iflags' bits). + */ if (gd.done_seq++ > gh.hero_seq + 100L) { if (!wizard) return FALSE; /* can't deal with it */ diff --git a/src/mkmaze.c b/src/mkmaze.c index 0b96a0c6c..578f822f8 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -308,8 +308,10 @@ is_exclusion_zone(xint16 type, coordxy x, coordxy y) struct exclusion_zone *ez = sve.exclusion_zones; while (ez) { - if (((type == LR_DOWNTELE && (ez->zonetype == LR_DOWNTELE || ez->zonetype == LR_TELE)) - || (type == LR_UPTELE && (ez->zonetype == LR_UPTELE || ez->zonetype == LR_TELE)) + if (((type == LR_DOWNTELE + && (ez->zonetype == LR_DOWNTELE || ez->zonetype == LR_TELE)) + || (type == LR_UPTELE + && (ez->zonetype == LR_UPTELE || ez->zonetype == LR_TELE)) || type == ez->zonetype) && within_bounded_area(x, y, ez->lx, ez->ly, ez->hx, ez->hy)) return TRUE; @@ -406,7 +408,8 @@ put_lregion_here( { struct monst *mtmp; - if (bad_location(x, y, nlx, nly, nhx, nhy) || is_exclusion_zone(rtype, x, y)) { + if (bad_location(x, y, nlx, nly, nhx, nhy) + || is_exclusion_zone(rtype, x, y)) { if (!oneshot) { return FALSE; /* caller should try again */ } else { @@ -420,7 +423,8 @@ put_lregion_here( mtmp->mtrapped = 0; deltrap(t); } - if (bad_location(x, y, nlx, nly, nhx, nhy) || is_exclusion_zone(rtype, x, y)) + if (bad_location(x, y, nlx, nly, nhx, nhy) + || is_exclusion_zone(rtype, x, y)) return FALSE; } } @@ -807,7 +811,7 @@ stolen_booty(void) cnt = rnd(3); for (i = 0; i < cnt; ++i) migr_booty_item(SKELETON_KEY, gang); - otyp = rn2((GAUNTLETS_OF_DEXTERITY - LEATHER_GLOVES) + 1) + LEATHER_GLOVES; + otyp = rn1((GAUNTLETS_OF_DEXTERITY - LEATHER_GLOVES) + 1, LEATHER_GLOVES); migr_booty_item(otyp, gang); cnt = rnd(10); for (i = 0; i < cnt; ++i) { @@ -1456,6 +1460,8 @@ mkportal(coordxy x, coordxy y, xint16 todnum, xint16 todlevel) return; } +/* augment the Plane of Fire; called from goto_level() when arriving and + moveloop_core() when on the level */ void fumaroles(void) { @@ -1509,13 +1515,16 @@ staticfn void set_wportal(void); staticfn void mk_bubble(coordxy, coordxy, int); staticfn void mv_bubble(struct bubble *, coordxy, coordxy, boolean); +/* augment the Plane of Water; called from goto_level() when arriving and + moveloop_core() when on the level */ void movebubbles(void) { - static const struct rm water_pos = { cmap_b_to_glyph(S_water), WATER, 0, - 0, 0, 0, 0, 0, 0, 0 }; - static const struct rm air_pos = { cmap_b_to_glyph(S_cloud), AIR, 0, 0, 0, - 1, 0, 0, 0, 0 }; + static const struct rm water_pos = { + cmap_b_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0, 0 + }, air_pos = { + cmap_b_to_glyph(S_cloud), AIR, 0, 0, 0, 1, 0, 0, 0, 0 + }; static boolean up = FALSE; struct bubble *b; struct container *cons; From 1595b682cfee97dbfa2d3aad7cb9eb2751d44164 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 29 Aug 2024 07:02:40 -0700 Subject: [PATCH 096/121] do_clear_area() vs map column 0 do_clear_area() runs a callback over each point in a square around a center point. When executed near the edge of the map, it clips the square to avoid going over that edge. But on the left side, it was clipping to column 0 rather than 1, so running the callback routine on column 0 even though that isn't part of the level. This bug doesn't seem to have caused any problems though. --- src/vision.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vision.c b/src/vision.c index 34759bcad..d94c56bf4 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.c $NHDT-Date: 1707424350 2024/02/08 20:32:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 3.7 vision.c $NHDT-Date: 1724939600 2024/08/29 13:53:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2093,8 +2093,8 @@ do_clear_area( /* vision doesn't pass through water or clouds, detection should [this probably ought to be an arg supplied by our caller...] */ - override_vision = - (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) && detecting(func); + override_vision = (detecting(func) + && (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))); if (range > MAX_RADIUS || range < 1) panic("do_clear_area: illegal range %d", range); @@ -2107,8 +2107,8 @@ do_clear_area( y = 0; for (; y <= max_y; y++) { offset = limits[v_abs(y - srow)]; - if ((min_x = (scol - offset)) < 0) - min_x = 0; + if ((min_x = (scol - offset)) < 1) + min_x = 1; if ((max_x = (scol + offset)) >= COLNO) max_x = COLNO - 1; for (x = min_x; x <= max_x; x++) From e645c0b4bb38595e95990930e207d68118a96d1f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 29 Aug 2024 20:51:09 +0300 Subject: [PATCH 097/121] Allow starting game as pauper, without any inventory And also without spells, skills, or preidentified items. This also implies nudist. Breaks saves and bones. --- doc/Guidebook.mn | 6 +++++- doc/Guidebook.tex | 7 ++++++- include/optlist.h | 3 +++ include/patchlevel.h | 2 +- include/you.h | 1 + src/insight.c | 2 ++ src/options.c | 4 ++++ src/topten.c | 1 + src/u_init.c | 8 ++++++++ 9 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 2446fab6a..d55d3c6c4 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -3465,6 +3465,8 @@ Blind from birth. Deaf from birth. .PL Nudist Never wore any armor. +.PL Pauper +Started out with no possessions. .PL Ascended Delivered the Amulet to its final destination. .PE @@ -3501,7 +3503,7 @@ instrument played closely enough\(embut not too close!\(emto the Castle level's drawbridge or can be given to you via prayer boon. .pg -\fIBlind\fP, \fIDeaf\fP, and \fINudist\fP are also conducts, and they can only be +\fIBlind\fP, \fIDeaf\fP, \fINudist\fP, and \FIPauper\fP are also conducts, and they can only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In the case of \fIBlind\fP and \fIDeaf\fP, the option also enforces the conduct. @@ -4396,6 +4398,8 @@ use the \(oq\f(CR+\fP\(cq form and list entries to be added by their name and entries to be removed by \(oq\f(CR!\fP\(cq and name. The positive (no \(oq!\(cq) and negative (with \(oq!\(cq) entries can be intermixed. +.lp pauper +Start the character with no possessions (default false). Persistent. .lp perm_invent If true, always display your current inventory in a window (default false). .lp "" diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index dba5ab268..74e6c6884 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3731,6 +3731,8 @@ Blind from birth. Deaf from birth. \item[{\tt Nudist}] Never wore any armor. +\item[{\tt Pauper}] +Started out with no possessions. \item[{\tt Ascended}] Delivered the Amulet to its final destination. \elist @@ -3777,7 +3779,7 @@ enough---but not too close!---to the Castle level's drawbridge or can be given to you via prayer boon. %.pg -{\it Blind\/}, {\it Deaf\/}, and {\it Nudist\/} are also conducts, and they can only be +{\it Blind\/}, {\it Deaf\/}, {\it Nudist\/}, and {\it Pauper\/} are also conducts, and they can only be enabled by setting the correspondingly named option in {\tt NETHACKOPTIONS} or run-time configuration file prior to game start. In the case of {\it Blind\/} and {\it Deaf\/}, the option also enforces the conduct. @@ -4794,6 +4796,9 @@ and entries to be removed by `{\tt !}' and name. The positive (no `!') and negative (with `!') entries can be intermixed. %.lp +\item[\ib{pauper}] +Start the character with no possessions (default false). Persistent. +%.lp \item[\ib{perm\verb+_+invent}] If true, always display your current inventory in a window (default is false). %.lp "" diff --git a/include/optlist.h b/include/optlist.h index 00b954c60..08288fd08 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -548,6 +548,9 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTC(paranoid_confirmation, Advanced, 28, opt_in, set_in_game, Yes, Yes, Yes, Yes, "prayconfirm", "extra prompting in certain situations") + NHOPTB(pauper, Advanced, 0, opt_in, set_in_config, + Off, Yes, No, No, NoAlias, &u.uroleplay.pauper, Term_False, + "start your character without any items") NHOPTB(perm_invent, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.perm_invent, Term_Off, "show persistent inventory window") diff --git a/include/patchlevel.h b/include/patchlevel.h index c8784d7da..ec66ac797 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 106 +#define EDITLEVEL 107 /* * Development status possibilities. diff --git a/include/you.h b/include/you.h index 8efaea587..cd734ca42 100644 --- a/include/you.h +++ b/include/you.h @@ -162,6 +162,7 @@ struct u_roleplay { boolean blind; /* permanently blind */ boolean nudist; /* has not worn any armor, ever */ boolean deaf; /* permanently deaf */ + boolean pauper; /* no starting inventory */ long numbones; /* # of bones files loaded */ }; diff --git a/src/insight.c b/src/insight.c index 91c74994e..577b01475 100644 --- a/src/insight.c +++ b/src/insight.c @@ -2061,6 +2061,8 @@ show_conduct(int final) you_have_been("deaf from birth"); if (u.uroleplay.nudist) you_have_been("faithfully nudist"); + if (u.uroleplay.pauper) + enl_msg(You_, "have gone", "started out", " without possessions", ""); if (!u.uconduct.food) enl_msg(You_, "have gone", "went", " without food", ""); diff --git a/src/options.c b/src/options.c index 7d7e09fae..01339bfd4 100644 --- a/src/options.c +++ b/src/options.c @@ -5172,6 +5172,10 @@ optfn_boolean( /* After the change */ switch (optidx) { + case opt_pauper: + /* pauper implies nudist */ + u.uroleplay.nudist = u.uroleplay.pauper; + break; case opt_ascii_map: iflags.wc_tiled_map = negated; break; diff --git a/src/topten.c b/src/topten.c index 4742b9b02..f38de9244 100644 --- a/src/topten.c +++ b/src/topten.c @@ -596,6 +596,7 @@ encode_extended_conducts(char *buf) add_achieveX(buf, "blind", u.uroleplay.blind); add_achieveX(buf, "deaf", u.uroleplay.deaf); add_achieveX(buf, "nudist", u.uroleplay.nudist); + add_achieveX(buf, "pauper", u.uroleplay.pauper); add_achieveX(buf, "bonesless", !flags.bones); add_achieveX(buf, "petless", !u.uconduct.pets); diff --git a/src/u_init.c b/src/u_init.c index f7356cb56..aa2a2a131 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -559,6 +559,8 @@ static const struct def_skill Skill_W[] = { staticfn void knows_object(int obj) { + if (u.uroleplay.pauper) + return; discover_object(obj, TRUE, FALSE); objects[obj].oc_pre_discovered = 1; /* not a "discovery" */ } @@ -571,6 +573,9 @@ knows_class(char sym) struct obj odummy, *o; int ct; + if (u.uroleplay.pauper) + return; + odummy = cg.zeroobj; odummy.oclass = sym; o = &odummy; /* for use in various obj.h macros */ @@ -1213,6 +1218,9 @@ ini_inv(struct trobj *trop) int otyp; boolean got_sp1 = FALSE; /* got a level 1 spellbook? */ + if (u.uroleplay.pauper) /* pauper gets no items */ + return; + while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { From 0dff31a745aad03fdbb6f480331f18c8af83c9e0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 29 Aug 2024 14:04:40 -0400 Subject: [PATCH 098/121] suppress display.c warning introduced by 4fb7dd2c src/display.c(997): warning C4127: conditional expression is constant --- src/display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 0e82a6cfa..1c22ebbfe 100644 --- a/src/display.c +++ b/src/display.c @@ -982,6 +982,8 @@ newsym(coordxy x, coordxy y) if (see_self) display_self(); } else { + boolean show = FALSE; + see_it = mon && (mon_visible(mon) || (!worm_tail && (tp_sensemon(mon) || MATCH_WARN_OF_MON(mon)))); @@ -994,7 +996,7 @@ newsym(coordxy x, coordxy y) if (tt == BEAR_TRAP || is_pit(tt) || tt == WEB) trap->tseen = 1; } - _map_location(x, y, 0); /* map under the monster */ + _map_location(x, y, show); /* map under the monster */ /* also gets rid of any invisibility glyph */ display_monster(x, y, mon, see_it ? PHYSICALLY_SEEN : DETECTED, From 1fd943e8609f5932f34ef35de3d099e47c2c9854 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 29 Aug 2024 14:08:23 -0700 Subject: [PATCH 099/121] trap/secret door detection enhancement The old secret door detection just redisplayed locations with discoveries (secret doors and traps, mostly). Somewhere along the line it was augmented to find hidden monsters and to deliver one or two messages reporting how many things had been discovered. Now it has been augmented again, to find trapped doors and chests, and to supply a message when the detection attempt fails to find anything. More substantially, it highlights the relevant locations as they're found, before the feedback message(s). Initially I was using tmp_at() to mark all significant locations, but that required --More-- and for player to acknowledge it when detection was done. That would probably be ok for wand of secret door detection and spell of detect unseen, but it would be a hassle for ^E. It's been revised to use flash_glyph_at() [previously only used when ^G creates unseen monsters, I think]. The new behavior seems to be working reasonably well. For curses, the 'timed_delay' option must be set. flash_glyph_at() calls flush_screen() between its output and nap in each cycle of multiple flashes, but that evidently isn't sufficient for curses. Maybe curses init should just force on 'timed_delay'. I've left the tmp_at() stuff in. We might want to modify things to use it instead of flash_glyph_at() when the accessibility flag is set. Its current compile-time selection won't be adequate though. --- doc/fixes3-7-0.txt | 2 + src/detect.c | 205 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 158 insertions(+), 49 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index a29a52c5d..9d9552b29 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2664,6 +2664,8 @@ if hero is punished or tethered to a buried iron ball and has no inventory (or during streaming video 'query_menu' option to use a menu when asked certain yes/no questions pyrolisk eggs explode when broken +wand of secret door detection, spell of detect unseen, and wizard mode ^E now + flash the cursor at each location where detection finds something Platform- and/or Interface-Specific New Features diff --git a/src/detect.c b/src/detect.c index 347829a34..1cadedf69 100644 --- a/src/detect.c +++ b/src/detect.c @@ -11,6 +11,16 @@ #include "hack.h" #include "artifact.h" +#ifndef FOUND_FLASH_COUNT +/* for screen alert shown to player when secret door detection or ^E + finds stuff; to use tmp_at() instead of flash_glyph_at(), define as 0; + extra code for tmp_at() will be included and the flash_glyph_at() + calls will execute but won't do anything */ +#define FOUND_FLASH_COUNT 6 +#endif + +struct found_things; + staticfn boolean unconstrain_map(void); staticfn void reconstrain_map(void); staticfn void map_redisplay(void); @@ -20,13 +30,16 @@ staticfn void do_dknown_of(struct obj *); staticfn boolean check_map_spot(coordxy, coordxy, char, unsigned); staticfn boolean clear_stale_map(char, unsigned); staticfn void sense_trap(struct trap *, coordxy, coordxy, int); -staticfn int detect_obj_traps(struct obj *, boolean, int); +staticfn int detect_obj_traps(struct obj *, boolean, int, + struct found_things *) NO_NNARGS; staticfn void display_trap_map(int); staticfn int furniture_detect(void); +staticfn void foundone(coordxy, coordxy, int); staticfn void findone(coordxy, coordxy, genericptr_t); staticfn void openone(coordxy, coordxy, genericptr_t); staticfn int mfind0(struct monst *, boolean); -staticfn int reveal_terrain_getglyph(coordxy, coordxy, unsigned, int, unsigned); +staticfn int reveal_terrain_getglyph(coordxy, coordxy, unsigned, int, + unsigned); /* dummytrap: used when detecting traps finds a door or chest trap; the couple of fields that matter are always re-initialized during use so @@ -36,6 +49,7 @@ static struct trap dummytrap; /* data for enhanced feedback from findone() */ struct found_things { + coord ft_cc; /* for passing extra info to detect_obj_traps() */ uchar num_sdoors; uchar num_scorrs; uchar num_traps; @@ -892,11 +906,12 @@ staticfn int detect_obj_traps( struct obj *objlist, boolean show_them, - int how) /* 1 for misleading map feedback */ + int how, /* 1 for misleading map feedback */ + struct found_things *ft) /* being called by findone() when non-Null */ { struct obj *otmp; coordxy x, y; - int result = OTRAP_NONE; + int trapglyph, result = OTRAP_NONE; /* * TODO? Display locations of unarmed land mine and beartrap objects. @@ -904,17 +919,32 @@ detect_obj_traps( */ dummytrap.ttyp = TRAPPED_CHEST; + trapglyph = ft ? trap_to_glyph(&dummytrap) : GLYPH_NOTHING; for (otmp = objlist; otmp; otmp = otmp->nobj) { - if (Is_box(otmp) && otmp->otrapped - && get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO)) { + x = y = 0; /* lint suppression */ + if ((Is_box(otmp) && otmp->otrapped) || Has_contents(otmp)) { + /* !get_obj_location and !isok should both be impossible here */ + if (!get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO) + || !isok(x, y) + || (ft && (x != ft->ft_cc.x || y != ft->ft_cc.y))) + continue; + } + if (Is_box(otmp) && otmp->otrapped) { result |= u_at(x, y) ? OTRAP_HERE : OTRAP_THERE; + if (ft) { + flash_glyph_at(x, y, trapglyph, FOUND_FLASH_COUNT); + } if (show_them) { dummytrap.tx = x, dummytrap.ty = y; sense_trap(&dummytrap, x, y, how); } + if (ft) { + foundone(x, y, trapglyph); + ft->num_traps++; + } } if (Has_contents(otmp)) - result |= detect_obj_traps(otmp->cobj, show_them, how); + result |= detect_obj_traps(otmp->cobj, show_them, how, ft); } return result; } @@ -924,7 +954,7 @@ display_trap_map(int cursed_src) { struct monst *mon; struct trap *ttmp; - int door, glyph, ter_typ = TER_DETECT | ( cursed_src ? TER_OBJ : TER_TRP ); + int door, glyph, ter_typ = TER_DETECT | (cursed_src ? TER_OBJ : TER_TRP); coord cc; cls(); @@ -933,14 +963,14 @@ display_trap_map(int cursed_src) /* show chest traps first, first buried chests then floor chests, so that subsequent floor trap display will override if both types are present at the same location */ - (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src); - (void) detect_obj_traps(fobj, TRUE, cursed_src); + (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src, NULL); + (void) detect_obj_traps(fobj, TRUE, cursed_src, NULL); for (mon = fmon; mon; mon = mon->nmon) { if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) continue; - (void) detect_obj_traps(mon->minvent, TRUE, cursed_src); + (void) detect_obj_traps(mon->minvent, TRUE, cursed_src, NULL); } - (void) detect_obj_traps(gi.invent, TRUE, cursed_src); + (void) detect_obj_traps(gi.invent, TRUE, cursed_src, NULL); for (ttmp = gf.ftrap; ttmp; ttmp = ttmp->ntrap) sense_trap(ttmp, 0, 0, cursed_src); @@ -948,7 +978,7 @@ display_trap_map(int cursed_src) dummytrap.ttyp = TRAPPED_DOOR; for (door = 0; door < gd.doorindex; door++) { cc = svd.doors[door]; - if (levl[cc.x][cc.y].typ == SDOOR) /* see above */ + if (levl[cc.x][cc.y].typ == SDOOR) /* can't be trapped; see above */ continue; if (levl[cc.x][cc.y].doormask & D_TRAPPED) { dummytrap.tx = cc.x, dummytrap.ty = cc.y; @@ -997,14 +1027,14 @@ trap_detect( found = TRUE; } /* chest traps (might be buried or carried) */ - if ((tr = detect_obj_traps(fobj, FALSE, 0)) != OTRAP_NONE) { + if ((tr = detect_obj_traps(fobj, FALSE, 0, NULL)) != OTRAP_NONE) { if (tr & OTRAP_THERE) { display_trap_map(cursed_src); return 0; } found = TRUE; } - if ((tr = detect_obj_traps(svl.level.buriedobjlist, FALSE, 0)) + if ((tr = detect_obj_traps(svl.level.buriedobjlist, FALSE, 0, NULL)) != OTRAP_NONE) { if (tr & OTRAP_THERE) { display_trap_map(cursed_src); @@ -1015,7 +1045,8 @@ trap_detect( for (mon = fmon; mon; mon = mon->nmon) { if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) continue; - if ((tr = detect_obj_traps(mon->minvent, FALSE, 0)) != OTRAP_NONE) { + if ((tr = detect_obj_traps(mon->minvent, FALSE, 0, NULL)) + != OTRAP_NONE) { if (tr & OTRAP_THERE) { display_trap_map(cursed_src); return 0; @@ -1023,7 +1054,7 @@ trap_detect( found = TRUE; } } - if (detect_obj_traps(gi.invent, FALSE, 0) != OTRAP_NONE) + if (detect_obj_traps(gi.invent, FALSE, 0, NULL) != OTRAP_NONE) found = TRUE; /* door traps */ for (door = 0; door < gd.doorindex; door++) { @@ -1568,58 +1599,113 @@ cvt_sdoor_to_door(struct rm *lev) lev->doormask = newmask; } -/* find something at one location; it should find all somethings there +/* update the map for something which has just been found by wand of secret + door detection or wizard mode ^E; will be called multiple times during a + single operation if multiple things of interest are discovered */ +staticfn void +foundone(coordxy zx, coordxy zy, int glyph) +{ + if (glyph_is_cmap(glyph) || glyph_is_unexplored(glyph)) + levl[zx][zy].seenv = SVALL; + + if (!Blind) { + seenV save_viz = gv.viz_array[zy][zx]; + + gv.viz_array[zy][zx] = COULD_SEE | IN_SIGHT; + newsym(zx, zy); + gv.viz_array[zy][zx] = save_viz; + } + +#if FOUND_FLASH_COUNT == 0 + /* + * This works [for non-monsters at present] but flash_glyph_at() + * seems preferrable because the tmp_at() variation requires that + * the player respond to --More-- at the end, the flash_glyph + * variation doesn't. + */ + tmp_at(DISP_CHANGE, glyph); + tmp_at(zx, zy); +#endif +} + +/* find something at one location; this should find all somethings there since it is used for magical detection rather than physical searching */ staticfn void findone(coordxy zx, coordxy zy, genericptr_t whatfound) { - struct trap *ttmp; - struct monst *mtmp; + struct rm *lev = &levl[zx][zy]; + struct trap *ttmp = t_at(zx, zy); + struct monst *mtmp = m_at(zx, zy); struct found_things *found_p = (struct found_things *) whatfound; - /* - * This used to use if/else-if/else-if/else/end-if but that only - * found the first hidden thing at the location. Two hidden things - * at the same spot is uncommon, but it's possible for an undetected - * monster to be hiding at the location of an unseen trap. - */ + if (mtmp && (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))) + mtmp = (struct monst *) NULL; + found_p->ft_cc.x = zx; /* needed by detect_obj_traps() */ + found_p->ft_cc.y = zy; - if (levl[zx][zy].typ == SDOOR) { - cvt_sdoor_to_door(&levl[zx][zy]); /* .typ = DOOR */ + if (lev->typ == SDOOR) { + nhsym sym = lev->horizontal ? S_hcdoor : S_vcdoor; + + flash_glyph_at(zx, zy, cmap_to_glyph(sym), FOUND_FLASH_COUNT); + cvt_sdoor_to_door(lev); /* set lev->typ = DOOR */ magic_map_background(zx, zy, 0); - newsym(zx, zy); + foundone(zx, zy, back_to_glyph(zx, zy)); found_p->num_sdoors++; - } else if (levl[zx][zy].typ == SCORR) { - levl[zx][zy].typ = CORR; + } else if (lev->typ == SCORR) { + flash_glyph_at(zx, zy, cmap_to_glyph(S_corr), FOUND_FLASH_COUNT); + lev->typ = CORR; unblock_point(zx, zy); magic_map_background(zx, zy, 0); - newsym(zx, zy); + foundone(zx, zy, cmap_to_glyph(S_corr)); found_p->num_scorrs++; } - if ((ttmp = t_at(zx, zy)) != 0 && !ttmp->tseen + if (ttmp && !ttmp->tseen /* [shouldn't successful 'find' reveal and activate statue traps?] */ && ttmp->ttyp != STATUE_TRAP) { + flash_glyph_at(zx, zy, trap_to_glyph(ttmp), FOUND_FLASH_COUNT); ttmp->tseen = 1; - newsym(zx, zy); + foundone(zx, zy, trap_to_glyph(ttmp)); found_p->num_traps++; } + if (closed_door(zx, zy) && (lev->doormask & D_TRAPPED) != 0) { + dummytrap.ttyp = TRAPPED_DOOR; + dummytrap.tx = zx, dummytrap.ty = zy; + flash_glyph_at(zx, zy, trap_to_glyph(&dummytrap), FOUND_FLASH_COUNT); + dummytrap.tseen = 1; + map_trap(&dummytrap, 1); + sense_trap(&dummytrap, zx, zy, 0); /* handles Hallucination */ + foundone(zx, zy, trap_to_glyph(&dummytrap)); + found_p->num_traps++; + } + /* trapped chests */ + (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, 0, found_p); + (void) detect_obj_traps(fobj, TRUE, 0, found_p); + if (mtmp) + (void) detect_obj_traps(mtmp->minvent, TRUE, 0, found_p); + if (u_at(zx, zy)) + (void) detect_obj_traps(gi.invent, TRUE, 0, found_p); - if ((mtmp = m_at(zx, zy)) != 0 - /* brings hidden monster out of hiding even if already sensed */ - && (!canspotmon(mtmp) || mtmp->mundetected || M_AP_TYPE(mtmp))) { + if (mtmp && (!canspotmon(mtmp) || mtmp->mundetected || M_AP_TYPE(mtmp))) { if (M_AP_TYPE(mtmp)) { + flash_glyph_at(zx, zy, mon_to_glyph(mtmp, rn2_on_display_rng), + FOUND_FLASH_COUNT); seemimic(mtmp); + /*foundone(zx, zy, mon_to_glyph(mtmp, rn2_on_display_rng);*/ found_p->num_mons++; } else if (mtmp->mundetected && (is_hider(mtmp->data) || hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) { + flash_glyph_at(zx, zy, mon_to_glyph(mtmp, rn2_on_display_rng), + FOUND_FLASH_COUNT); mtmp->mundetected = 0; + /*foundone(zx, zy, mon_to_glyph(mtmp, rn2_on_display_rng);*/ newsym(zx, zy); found_p->num_mons++; } - if (!glyph_is_invisible(levl[zx][zy].glyph)) { + if (!glyph_is_invisible(lev->glyph)) { if (!canspotmon(mtmp)) { + flash_glyph_at(zx, zy, GLYPH_INVISIBLE, FOUND_FLASH_COUNT); map_invisible(zx, zy); found_p->num_invis++; } @@ -1627,6 +1713,8 @@ findone(coordxy zx, coordxy zy, genericptr_t whatfound) found_p->num_kept_invis++; } } else if (unmap_invisible(zx, zy)) { + /* flash the invisible monster glyph because it is already gone */ + flash_glyph_at(zx, zy, GLYPH_INVISIBLE, FOUND_FLASH_COUNT); found_p->num_cleared_invis++; } } @@ -1702,20 +1790,21 @@ findit(void) struct found_things found; /* - * FIXME: - * When things are found, this should show the updated map and allow - * browsing. - * - * Currently, "You reveal a trap!" will map the trap but not reveal it - * if that trap is covered by something, which is fairly common for - * early levels where corpses of fake heroes usually hide the traps - * that killed them. That's most likely to occur for wizard mode ^E - * but can happen in normal play by using wand of secret door detection. + * findit() -> do_clear_area(findone) -> findone() -> foundone() + * is used to notify player where various things have been found. + * Changing FOUND_FLASH_COUNT to 0 will switch to tmp_at() to + * highlight all discoveries for the current operation, but requires + * player to respond to --More-- when done. Neither allows browsing + * the map via getpos() autodescribe (until after it has reverted to + * normal display, where found traps might be covered by objects). */ if (u.uswallow) return 0; +#if FOUND_FLASH_COUNT == 0 /* _COUNT > 0 doesn't need to init tmp_at() */ + tmp_at(DISP_ALL, GLYPH_NOTHING); +#endif (void) memset((genericptr_t) &found, 0, sizeof found); do_clear_area(u.ux, u.uy, BOLT_LIM, findone, (genericptr_t) &found); /* count that controls "reveal" punctuation; 0..4 */ @@ -1751,6 +1840,12 @@ findit(void) Strcat(buf, "a trap"); num += found.num_traps; } + +#if FOUND_FLASH_COUNT == 0 + int tmp_num; + tmp_num = num; /* sdoors, scorrs, and traps call tmp_at() */ +#endif + if (found.num_mons) { if (*buf) Strcat(buf, (k > 2) ? ", and " : " and "); @@ -1765,10 +1860,10 @@ findit(void) if (found.num_invis) { if (found.num_invis > 1) - Sprintf(buf, "%d%s invisible monsters", found.num_invis, + Sprintf(buf, "%d%s unseen monsters", found.num_invis, found.num_kept_invis ? " other" : ""); else - Sprintf(buf, "%s invisible monster", + Sprintf(buf, "%s unseen monster", found.num_kept_invis ? "another" : "an"); You("detect %s!", buf); num += found.num_invis; @@ -1783,6 +1878,16 @@ findit(void) } /* note: num_kept_invis is not included in the final result */ + if (!num) + You("don't find anything."); +#if FOUND_FLASH_COUNT == 0 + else if (tmp_num) { + flush_screen(1); + display_nhwindow(WIN_MAP, TRUE); + } + tmp_at(DISP_END, GLYPH_NOTHING); /* note: outside of 'if (tmp_num) { }' */ +#endif + return num; } @@ -2283,4 +2388,6 @@ reveal_terrain( return; } +#undef FOUND_FLASH_COUNT + /*detect.c*/ From 96fc77cc705f576488dec45fe2eb18805900533a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 30 Aug 2024 19:20:31 +0300 Subject: [PATCH 100/121] add pauper to fixes --- doc/fixes3-7-0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 9d9552b29..5b662be8e 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2664,6 +2664,7 @@ if hero is punished or tethered to a buried iron ball and has no inventory (or during streaming video 'query_menu' option to use a menu when asked certain yes/no questions pyrolisk eggs explode when broken +pauper-option to start the character with no possessions wand of secret door detection, spell of detect unseen, and wizard mode ^E now flash the cursor at each location where detection finds something From 8e855617259a50d05464230f94a8d85113de55e0 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 30 Aug 2024 14:19:19 -0700 Subject: [PATCH 101/121] cursesgraphics fix - S_engroom character I normally force DECgraphics for tty and for curses so hadn't noticed this before. I recently let curses default to 'cursesgraphics' and the engraving-in-room character was crossed horizontal and vertical bars, the crosswall character. It certainly stood out in the middle of a room, but the emphasis seems out of proportion for "engraving here". There is no 'epsilon' among the DEC line drawing characters. Curses might be able to render one, but not with DEC-style rendering of 0xEE. Comment out S_engroom so that curses inherits the default backtick. --- dat/symbols | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dat/symbols b/dat/symbols index c979cf48b..af6c04ade 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.7 symbols $NHDT-Date: 1709388512 2024/03/02 14:08:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack 3.7 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -627,10 +627,10 @@ start: curses S_bars: \xfc # meta-|, not-equals sign (was '#') S_tree: \xe7 # meta-g, plus or minus sign S_room: \xfe # meta-z, centered dot - S_engroom: \xee # epsilon - S_corr: \xe1 # meta-a, solid block - S_litcorr: \xe1 # meta-a, solid block - S_engrcorr: \xe1 # meta-a, solid block + # S_engroom: \xee # epsilon [\xee is actually cross wall] + S_corr: \xe1 # meta-a, checkerboard + S_litcorr: \xe1 # meta-a, checkerboard + S_engrcorr: \xe1 # meta-a, checkerboard S_ice: \xfe # meta-z, centered dot S_vodbridge: \xfe # meta-z, centered dot S_hodbridge: \xfe # meta-z, centered dot @@ -702,8 +702,8 @@ start: DECgraphics S_tlwall: \xf5 # meta-u, T left S_trwall: \xf4 # meta-t, T right S_ndoor: \xfe # meta-~, centered dot - S_vodoor: \xe1 # meta-a, solid block - S_hodoor: \xe1 # meta-a, solid block + S_vodoor: \xe1 # meta-a, checkerboard + S_hodoor: \xe1 # meta-a, checkerboard S_bars: \xfc # meta-|, not-equals (used to be pi) S_tree: \xe7 # meta-g, plus-or-minus S_room: \xfe # meta-~, centered dot From 0ce2439e827e26b586bc89152c8eab1a30c39c39 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 31 Aug 2024 14:08:04 -0700 Subject: [PATCH 102/121] github issue #1275: curses init vs pauper Reported by ars3niy, the curses interface could behave strangely on the first turn if the 'pauper' option/conduct was specified. There isn't any definitive flag indicating whether or not the game has started. Since 'moves' has traditionally been initialized to 1 rather than to 0, there were several instances of | if (moves <= 1 && invent != NULL) being used to determine the starting state on the assumption that once hero has inventory, the game has begun. Introduction of the 'pauper' option made the test for non-Null invent become unreliable. For paupers, the program would behave as if the game hadn't started yet until the player finally made a time-consuming move. This changes compile-time initialization of 'moves' from 1 to 0, then sets it to 1 when initial inventory would be bestowed (even when 'pauper' inhibits that). That's probably not the best place for it, but testing for 'moves==0' now should produce an identical effect as 'moves<=1 && invent!=NULL' used to accomplish. It would have been much simpler just to give paupers 1 gold piece, or perhaps one rock, in place of usual starting gear so that their initial inventory wouldn't be empty, but the moves+invent way of checking for start-of-play has always bothered me. Should 'pauper' be preventing 'nethack -X' from giving its starting wand of wishing? Conducts and explore mode don't really overlap so maybe it doesn't matter. Fixes #1275 --- doc/fixes3-7-0.txt | 5 ++++- src/attrib.c | 4 ++-- src/decl.c | 4 ++-- src/mkobj.c | 9 ++++----- src/u_init.c | 8 +++++++- win/curses/cursdial.c | 4 ++-- win/curses/curswins.c | 10 +++++----- 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 5b662be8e..717490f33 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1464 $ $NHDT-Date: 1723945837 2024/08/18 01:50:37 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1471 $ $NHDT-Date: 1725138479 2024/08/31 21:07:59 $ General Fixes and Modified Features ----------------------------------- @@ -2021,6 +2021,9 @@ having #terrain display gas cloud regions as if they were traps didn't work when a monster within a gas cloud was displayed on the map because the hero was next to it, it remained displayed if hero moved away eating a pyrolisk egg on the floor triggered an "object lost" panic +core object creation and the curses interface's window handling both became + confused by the 'pauper' option/conduct because they assumed that invent + being Null meant that the game hadn't started yet Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/attrib.c b/src/attrib.c index 6361ec374..32581990e 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 attrib.c $NHDT-Date: 1651908297 2022/05/07 07:24:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 3.7 attrib.c $NHDT-Date: 1725138479 2024/08/31 21:07:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -1072,7 +1072,7 @@ newhp(void) hp += rnd(gu.urole.hpadv.inrnd); if (gu.urace.hpadv.inrnd > 0) hp += rnd(gu.urace.hpadv.inrnd); - if (svm.moves <= 1L) { /* initial hero; skip for polyself to new man */ + if (svm.moves == 0) { /* initial hero; skip for polyself to new man */ /* Initialize alignment stuff */ u.ualign.type = aligns[flags.initalign].value; u.ualign.record = gu.urole.initrecord; diff --git a/src/decl.c b/src/decl.c index d11887dd9..08b54e4f7 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1720074480 2024/07/04 06:28:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.334 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1725138480 2024/08/31 21:08:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -963,7 +963,7 @@ static const struct instance_globals_saved_m init_svm = { /* dungeon.c */ UNDEFINED_PTR, /* mapseenchn */ /* decl.c */ - 1L, /* moves; misnamed turn counter */ + 0L, /* moves; misnamed turn counter */ { UNDEFINED_VALUES } /* mvitals */ }; diff --git a/src/mkobj.c b/src/mkobj.c index afe335afa..db5a4962c 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1718999849 2024/06/21 19:57:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1725138481 2024/08/31 21:08:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1160,7 +1160,7 @@ mksobj(int otyp, boolean init, boolean artif) otmp = newobj(); *otmp = cg.zeroobj; - otmp->age = svm.moves; + otmp->age = max(svm.moves, 1L); otmp->o_id = next_ident(); otmp->quan = 1L; otmp->oclass = let; @@ -1341,7 +1341,7 @@ start_corpse_timeout(struct obj *body) action = ROT_CORPSE; /* default action: rot away */ rot_adjust = gi.in_mklev ? 25 : 10; /* give some variation */ - age = svm.moves - body->age; + age = max(svm.moves, 1) - body->age; if (age > ROT_AGE) when = rot_adjust; else @@ -2381,8 +2381,7 @@ obj_timer_checks( /* mark the corpse as being on ice */ otmp->on_ice = 1; - debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x, - y); + debugpline3("%s is now on ice at <%d,%d>.", The(xname(otmp)), x, y); /* Adjust the time remaining */ tleft *= ROT_ICE_ADJUSTMENT; restart_timer = TRUE; diff --git a/src/u_init.c b/src/u_init.c index aa2a2a131..ffc7b9151 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 u_init.c $NHDT-Date: 1711165379 2024/03/23 03:42:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 3.7 u_init.c $NHDT-Date: 1725138482 2024/08/31 21:08:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -617,6 +617,12 @@ u_init_role(void) { int i; + /* the program used to check moves<=1 && invent==NULL do decide whether + a new game has started, but due to the 'pauper' option/conduct, can't + rely on invent becoming non-Null anymore; instead, initialize moves + to 0 instead of 1 and then set it to 1 here, where invent init occurs */ + svm.moves = 1L; + switch (Role_switch) { /* rn2(100) > 50 necessary for some choices because some * random number generators are bad enough to seriously diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 8e6949d7b..d02f8a22a 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -227,7 +227,7 @@ curses_character_input_dialog( re-activate them now that input is being requested */ curses_got_input(); - if (gi.invent || (svm.moves > 1)) { + if (svm.moves > 0) { curses_get_window_size(MAP_WIN, &map_height, &map_width); } else { map_height = term_rows; @@ -789,7 +789,7 @@ curses_display_nhmenu( menu_determine_pages(current_menu); /* Display pre and post-game menus centered */ - if ((svm.moves <= 1 && !gi.invent) || program_state.gameover) { + if (svm.moves == 0 || program_state.gameover) { win = curses_create_window(wid, current_menu->width, current_menu->height, CENTER); } else { /* Display during-game menus on the right out of the way */ diff --git a/win/curses/curswins.c b/win/curses/curswins.c index a9a1b7829..0bc7507b6 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -69,7 +69,7 @@ curses_create_window(int wid, int width, int height, orient orientation) if ((orientation == UP) || (orientation == DOWN) || (orientation == LEFT) || (orientation == RIGHT)) { - if (gi.invent || (svm.moves > 1)) { + if (svm.moves > 0) { map_border = curses_window_has_border(MAP_WIN); curses_get_window_xy(MAP_WIN, &mapx, &mapy); curses_get_window_size(MAP_WIN, &maph, &mapw); @@ -104,7 +104,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = (term_rows / 2) - (height / 2); break; case UP: - if (gi.invent || (svm.moves > 1)) { + if (svm.moves > 0) { startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; } else { startx = 0; @@ -113,7 +113,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = mapy + mapb_offset; break; case DOWN: - if (gi.invent || (svm.moves > 1)) { + if (svm.moves > 0) { startx = (mapw / 2) - (width / 2) + mapx + mapb_offset; } else { startx = 0; @@ -129,7 +129,7 @@ curses_create_window(int wid, int width, int height, orient orientation) starty = term_rows - height; break; case RIGHT: - if (gi.invent || (svm.moves > 1)) { + if (svm.moves > 0) { startx = (mapw + mapx + (mapb_offset * 2)) - width; } else { startx = term_cols - width; @@ -222,7 +222,7 @@ curses_refresh_nethack_windows(void) return; } - if ((svm.moves <= 1) && !gi.invent) { + if (svm.moves == 0) { /* Main windows not yet displayed; refresh base window instead */ touchwin(stdscr); refresh(); From dfe2619b4b47764a6bea047300d35c0328bace1f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 31 Aug 2024 15:44:54 -0700 Subject: [PATCH 103/121] github issue #1274 - meta keys on MacOS+tty I can't post comments to github but can commit something that will result in an update of the issue. Hopefully you'll see the commit. Issue reported by RetepV: using the Macbook option key as an alt key and using that as a shift with a regular key does not generate a meta key value for the regular key. This behavior is not new. I see the same thing on OSX 10.11.6. The curses interface calls meta(,TRUE) and