home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i013: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part13/108
- Message-ID: <4296@master.CNA.TEK.COM>
- Date: 28 Jan 93 19:13:10 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2148
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 13
- Archive-name: nethack31/Part13
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 13 (of 108)."
- # Contents: dat/yendor.des src/invent.c
- # Wrapped by billr@saab on Wed Jan 27 16:08:50 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'dat/yendor.des' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dat/yendor.des'\"
- else
- echo shar: Extracting \"'dat/yendor.des'\" \(6672 characters\)
- sed "s/^X//" >'dat/yendor.des' <<'END_OF_FILE'
- X# SCCS Id: @(#)yendor.des 3.1 92/01/10
- X# Copyright (c) 1989 by Jean-Christophe Collet
- X# Copyright (c) 1992 by M. Stephenson and Izchak Miller
- X# NetHack may be freely redistributed. See license for details.
- X#
- X# The top (real) wizard level.
- X# Keeping the Moat for old-time's sake
- XMAZE:"wizard1",random
- XFLAGS:noteleport
- XGEOMETRY:center,center
- XMAP
- X----------------------------.
- X|.......|..|.........|.....|.
- X|.......S..|.}}}}}}}.|.....|.
- X|..--S--|..|.}}---}}.|---S-|.
- X|..|....|..|.}--.--}.|..|..|.
- X|..|....|..|.}|...|}.|..|..|.
- X|..--------|.}--.--}.|..|..|.
- X|..|.......|.}}---}}.|..|..|.
- X|..S.......|.}}}}}}}.|..|..|.
- X|..|.......|.........|..|..|.
- X|..|.......|-----------S-S-|.
- X|..|.......S...............|.
- X----------------------------.
- XENDMAP
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),up
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),down
- XBRANCH:levregion(01,00,79,20),(0,0,28,12)
- XTELEPORT_REGION:levregion(01,00,79,20),(0,0,28,12)
- X# Make it a morgue for rm id in mkmaze.c
- X# for the purpose of random sdoor placement
- XREGION:(12,01,20,09),unlit,"morgue",unfilled
- XMAZEWALK:(28,05),east
- XLADDER:(06,05),down
- X# Non diggable walls
- X# Walls inside the moat stay diggable
- XNON_DIGGABLE:(00,00,11,12)
- XNON_DIGGABLE:(11,00,21,00)
- XNON_DIGGABLE:(11,10,27,12)
- XNON_DIGGABLE:(21,00,27,10)
- X# The wizard and his guards
- XMONSTER:'@',"Wizard of Yendor",(16,05),asleep
- XMONSTER:'d',"hell hound",(15,05)
- XMONSTER:'V',"vampire lord",(17,05)
- X# The local treasure
- XOBJECT:'+',"Book of the Dead",(16,05)
- X# Surrounding terror
- XMONSTER:';',"kraken",(14,02)
- XMONSTER:';',"giant eel",(17,02)
- XMONSTER:';',"kraken",(13,04)
- XMONSTER:';',"giant eel",(13,06)
- XMONSTER:';',"kraken",(19,04)
- XMONSTER:';',"giant eel",(19,06)
- XMONSTER:';',"kraken",(15,08)
- XMONSTER:';',"giant eel",(17,08)
- X# Random monsters
- XMONSTER:'D',random,random
- XMONSTER:'H',random,random
- XMONSTER:'&',random,random
- XMONSTER:'&',random,random
- XMONSTER:'&',random,random
- XMONSTER:'&',random,random
- X# And to make things a little harder.
- XTRAP:"board",(16,04)
- XTRAP:"board",(16,06)
- XTRAP:"board",(15,05)
- XTRAP:"board",(17,05)
- X# Random traps.
- XTRAP:"spiked pit",random
- XTRAP:"sleep gas",random
- XTRAP:"anti magic",random
- XTRAP:"magic",random
- X# Some random loot.
- XOBJECT:'*',"ruby",random
- XOBJECT:'!',random,random
- XOBJECT:'!',random,random
- XOBJECT:'?',random,random
- XOBJECT:'?',random,random
- XOBJECT:'+',random,random
- XOBJECT:'+',random,random
- XOBJECT:'+',random,random
- X
- X
- X# The middle wizard level.
- XMAZE:"wizard2",random
- XFLAGS:noteleport
- XGEOMETRY:center,center
- XMAP
- X----------------------------.
- X|.....|.S....|.............|.
- X|.....|.-------S--------S--|.
- X|.....|.|.........|........|.
- X|..-S--S|.........|........|.
- X|..|....|.........|------S-|.
- X|..|....|.........|.....|..|.
- X|-S-----|.........|.....|..|.
- X|.......|.........|S--S--..|.
- X|.......|.........|.|......|.
- X|-----S----S-------.|......|.
- X|............|....S.|......|.
- X----------------------------.
- XENDMAP
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),up
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),down
- XBRANCH:levregion(01,00,79,20),(0,0,28,12)
- XTELEPORT_REGION:levregion(01,00,79,20),(0,0,28,12)
- XREGION:(09,03,17,09),unlit,"zoo"
- XDOOR:closed,(15,02)
- XDOOR:closed,(11,10)
- XMAZEWALK:(28,05),east
- XLADDER:(12,01),up
- XLADDER:(14,11),down
- X# Non diggable walls everywhere
- XNON_DIGGABLE:(00,00,27,12)
- X# Random traps.
- XTRAP:"spiked pit",random
- XTRAP:"sleep gas",random
- XTRAP:"anti magic",random
- XTRAP:"magic",random
- X# Some random loot.
- XOBJECT:'!',random,random
- XOBJECT:'!',random,random
- XOBJECT:'?',random,random
- XOBJECT:'?',random,random
- XOBJECT:'+',random,random
- X# treasures
- XOBJECT:'"',random,(04,06)
- X
- X
- X# The bottom wizard level.
- X# Memorialize the fakewiz setup.
- XMAZE:"wizard3",random
- XFLAGS:noteleport
- XGEOMETRY:center,center
- XMAP
- X----------------------------.
- X|..|............S..........|.
- X|..|..------------------S--|.
- X|..|..|.........|..........|.
- X|..S..|.}}}}}}}.|..........|.
- X|..|..|.}}---}}.|-S--------|.
- X|..|..|.}--.--}.|..|.......|.
- X|..|..|.}|...|}.|..|.......|.
- X|..---|.}--.--}.|..|.......|.
- X|.....|.}}---}}.|..|.......|.
- X|.....S.}}}}}}}.|..|.......|.
- X|.....|.........|..S.......|.
- X----------------------------.
- XENDMAP
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),up
- XSTAIR:levregion(01,00,79,20),(0,0,28,12),down
- XBRANCH:levregion(01,00,79,20),(0,0,28,12)
- XTELEPORT_REGION:levregion(01,00,79,20),(0,0,28,12)
- XPORTAL:(25,11,25,11),(0,0,0,0),"fakewiz1"
- XMAZEWALK:(28,09),east
- XREGION:(07,03,15,11),unlit,"morgue",unfilled
- XREGION:(17,06,18,11),unlit,"beehive"
- XDOOR:closed,(18,05)
- XDOOR:closed,(19,11)
- XLADDER:(11,07),up
- X# Non diggable walls
- X# Walls inside the moat stay diggable
- XNON_DIGGABLE:(00,00,06,12)
- XNON_DIGGABLE:(06,00,27,02)
- XNON_DIGGABLE:(16,02,27,12)
- XNON_DIGGABLE:(06,12,16,12)
- XMONSTER:'L',random,(10,07)
- XMONSTER:'V',"vampire lord",(12,07)
- X# Some surrounding horrors
- XMONSTER:';',"kraken",(08,05)
- XMONSTER:';',"giant eel",(08,08)
- XMONSTER:';',"kraken",(14,05)
- XMONSTER:';',"giant eel",(14,08)
- X# Other monsters
- XMONSTER:'L',random,random
- XMONSTER:'D',random,random
- XMONSTER:'D',random,(26,09)
- XMONSTER:'&',random,random
- XMONSTER:'&',random,random
- XMONSTER:'&',random,random
- X# And to make things a little harder.
- XTRAP:"board",(10,07)
- XTRAP:"board",(12,07)
- XTRAP:"board",(11,06)
- XTRAP:"board",(11,08)
- X# Some loot
- XOBJECT:')',random,random
- XOBJECT:'!',random,random
- XOBJECT:'?',random,random
- XOBJECT:'?',random,random
- XOBJECT:'(',random,random
- X# treasures
- XOBJECT:'"',random,(11,07)
- X
- X
- X# The former decoy wizard levels.
- X# There are two of these, and we need to
- X# distinguish between them for the portal.
- XMAZE:"fakewiz1",random
- XGEOMETRY:center,center
- XMAP
- X.........
- X.}}}}}}}.
- X.}}---}}.
- X.}--.--}.
- X.}|...|}.
- X.}--.--}.
- X.}}---}}.
- X.}}}}}}}.
- XENDMAP
- XSTAIR:levregion(01,00,79,20),(0,0,8,7),up
- XSTAIR:levregion(01,00,79,20),(0,0,8,7),down
- XBRANCH:levregion(01,00,79,20),(0,0,8,7)
- XTELEPORT_REGION:levregion(01,00,79,20),(0,0,8,7)
- XPORTAL:(4,4,4,4),(0,0,0,0),"wizard3"
- XMAZEWALK:(08,05),east
- XREGION:(04,03,06,06),unlit,"ordinary",unfilled,true
- XMONSTER:'L',random,(04,04)
- XMONSTER:'V',"vampire lord",(03,04)
- XMONSTER:';',"kraken",(06,06)
- X# And to make things a little harder.
- XTRAP:"board",(04,03)
- XTRAP:"board",(04,05)
- XTRAP:"board",(03,04)
- XTRAP:"board",(05,04)
- X
- X
- XMAZE:"fakewiz2",random
- XGEOMETRY:center,center
- XMAP
- X.........
- X.}}}}}}}.
- X.}}---}}.
- X.}--.--}.
- X.}|...|}.
- X.}--.--}.
- X.}}---}}.
- X.}}}}}}}.
- XENDMAP
- XSTAIR:levregion(01,00,79,20),(0,0,8,7),up
- XSTAIR:levregion(01,00,79,20),(0,0,8,7),down
- XBRANCH:levregion(01,00,79,20),(0,0,8,7)
- XTELEPORT_REGION:levregion(01,00,79,20),(0,0,8,7)
- XMAZEWALK:(08,05),east
- XREGION:(04,03,06,06),unlit,"ordinary",unfilled,true
- XMONSTER:'L',random,(04,04)
- XMONSTER:'V',"vampire lord",(03,04)
- XMONSTER:';',"kraken",(06,06)
- X# And to make things a little harder.
- XTRAP:"board",(04,03)
- XTRAP:"board",(04,05)
- XTRAP:"board",(03,04)
- XTRAP:"board",(05,04)
- X# treasures
- XOBJECT:'"',random,(04,04)
- END_OF_FILE
- if test 6672 -ne `wc -c <'dat/yendor.des'`; then
- echo shar: \"'dat/yendor.des'\" unpacked with wrong size!
- fi
- # end of 'dat/yendor.des'
- fi
- if test -f 'src/invent.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/invent.c'\"
- else
- echo shar: Extracting \"'src/invent.c'\" \(47145 characters\)
- sed "s/^X//" >'src/invent.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)invent.c 3.1 92/12/11 */
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X#include "artifact.h"
- X
- X#define NOINVSYM '#'
- X#define CONTAINED_SYM '>' /* designator for inside a container */
- X
- X#ifdef OVL1
- Xstatic void NDECL(reorder_invent);
- Xstatic boolean FDECL(mergable,(struct obj *,struct obj *));
- Xstatic int FDECL(merged,(struct obj *,struct obj *,int));
- X#endif /* OVL1 */
- XSTATIC_DCL void FDECL(assigninvlet,(struct obj *));
- XSTATIC_DCL void FDECL(unlinkinv,(struct obj*));
- XSTATIC_DCL void FDECL(compactify,(char *));
- XSTATIC_PTR int FDECL(ckunpaid,(struct obj *));
- X#ifdef OVLB
- Xstatic struct obj *FDECL(find_unpaid,(struct obj *,struct obj **));
- Xstatic boolean NDECL(wearing_armor);
- Xstatic boolean FDECL(is_worn,(struct obj *));
- X#endif /* OVLB */
- XSTATIC_DCL char FDECL(obj_to_let,(struct obj *));
- X
- X#ifdef OVLB
- X
- Xstatic int lastinvnr = 51; /* 0 ... 51 (never saved&restored) */
- X
- Xchar inv_order[] = { /* manipulated in options.c, used below */
- X AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS, SCROLL_CLASS,
- X SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS, TOOL_CLASS,
- X GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0 };
- X
- X#ifdef WIZARD
- X/* wizards can wish for venom, which will become an invisible inventory
- X * item without this. putting it in inv_order would mean venom would
- X * suddenly become a choice for all the inventory-class commands, which
- X * would probably cause mass confusion. the test for inventory venom
- X * is only WIZARD and not wizard because the wizard can leave venom lying
- X * around on a bones level for normal players to find.
- X */
- Xstatic char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */
- X#endif
- X
- XSTATIC_OVL void
- Xassigninvlet(otmp)
- Xregister struct obj *otmp;
- X{
- X boolean inuse[52];
- X register int i;
- X register struct obj *obj;
- X
- X for(i = 0; i < 52; i++) inuse[i] = FALSE;
- X for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
- X i = obj->invlet;
- X if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
- X if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
- X if(i == otmp->invlet) otmp->invlet = 0;
- X }
- X if((i = otmp->invlet) &&
- X (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
- X return;
- X for(i = lastinvnr+1; i != lastinvnr; i++) {
- X if(i == 52) { i = -1; continue; }
- X if(!inuse[i]) break;
- X }
- X otmp->invlet = (inuse[i] ? NOINVSYM :
- X (i < 26) ? ('a'+i) : ('A'+i-26));
- X lastinvnr = i;
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- X
- X/* note: assumes ASCII; toggling a bit puts lowercase in front of uppercase */
- X#define inv_rank(o) ((o)->invlet ^ 040)
- X
- X/* sort the inventory; used by addinv() and doorganize() */
- Xstatic void
- Xreorder_invent()
- X{
- X struct obj *otmp, *prev, *next;
- X boolean need_more_sorting;
- X
- X do {
- X /*
- X * We expect at most one item to be out of order, so this
- X * isn't nearly as inefficient as it may first appear.
- X */
- X need_more_sorting = FALSE;
- X for (otmp = invent, prev = 0; otmp; ) {
- X next = otmp->nobj;
- X if (next && inv_rank(next) < inv_rank(otmp)) {
- X need_more_sorting = TRUE;
- X if (prev) prev->nobj = next;
- X else invent = next;
- X otmp->nobj = next->nobj;
- X next->nobj = otmp;
- X prev = next;
- X } else {
- X prev = otmp;
- X otmp = next;
- X }
- X }
- X } while (need_more_sorting);
- X}
- X
- X#undef inv_rank
- X
- X/* merge obj with otmp and delete obj if types agree */
- XSTATIC_OVL int
- Xmerged(otmp, obj, lose)
- Xregister struct obj *otmp, *obj;
- Xregister int lose;
- X{
- X if(mergable(otmp, obj)) {
- X /* Approximate age: we do it this way because if we were to
- X * do it "accurately" (merge only when ages are identical)
- X * we'd wind up never merging any corpses.
- X * otmp->age = otmp->age*(1-proportion) + obj->age*proportion;
- X */
- X otmp->age = ((otmp->age*otmp->quan) + (obj->age*obj->quan))
- X / (otmp->quan + obj->quan);
- X otmp->quan += obj->quan;
- X otmp->owt += obj->owt;
- X if(!otmp->onamelth && obj->onamelth)
- X otmp = oname(otmp, ONAME(obj), 1);
- X if(lose) freeobj(obj);
- X obfree(obj,otmp); /* free(obj), bill->otmp */
- X return(1);
- X } else return(0);
- X}
- X
- Xstruct obj *
- Xaddinv(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp, *prev;
- X
- X if (obj->otyp == GOLD_PIECE) {
- X u.ugold += obj->quan;
- X flags.botl = 1;
- X return obj;
- X } else if (obj->otyp == AMULET_OF_YENDOR) {
- X if (u.uhave.amulet) impossible ("already have amulet?");
- X u.uhave.amulet = 1;
- X } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
- X if (u.uhave.menorah) impossible ("already have candelabrum?");
- X u.uhave.menorah = 1;
- X } else if (obj->otyp == BELL_OF_OPENING) {
- X if (u.uhave.bell) impossible ("already have silver bell?");
- X u.uhave.bell = 1;
- X } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- X if (u.uhave.book) impossible ("already have the book?");
- X u.uhave.book = 1;
- X#ifdef MULDGN
- X } else if (is_quest_artifact(obj)) {
- X if (u.uhave.questart) impossible ("already have the artifact?");
- X u.uhave.questart = 1;
- X artitouch();
- X set_artifact_intrinsic(obj, 1, W_ART);
- X#endif
- X } else if(obj->oartifact) {
- X set_artifact_intrinsic(obj, 1, W_ART);
- X }
- X /* merge if possible; find end of chain in the process */
- X for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj)
- X if (merged(otmp, obj, 0)) {
- X obj = otmp;
- X goto added;
- X }
- X /* didn't merge, so insert into chain */
- X if (flags.invlet_constant || !prev) {
- X if (flags.invlet_constant) assigninvlet(obj);
- X obj->nobj = invent; /* insert at beginning */
- X invent = obj;
- X if (flags.invlet_constant) reorder_invent();
- X } else {
- X prev->nobj = obj; /* insert at end */
- X obj->nobj = 0;
- X }
- X
- Xadded:
- X if (obj->otyp == LUCKSTONE
- X || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) {
- X /* new luckstone must be in inventory by this point
- X * for correct calculation */
- X if (stone_luck(TRUE) >= 0) u.moreluck = LUCKADD;
- X else u.moreluck = -LUCKADD;
- X } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP)
- X check_lamps();
- X update_inventory();
- X return(obj);
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- X/* Add an item to the inventory unless we're fumbling, and give a message.
- X * If there aren't any free inventory slots, we'll drop it instead.
- X * If both success and failure messages are NULL, then we're just doing the
- X * fumbling/slot-limit checking for a silent grab.
- X * Note: will drop the whole bunch if the object merges first.
- X */
- Xstruct obj *
- Xhold_another_object(obj, drop_fmt, drop_arg, hold_msg)
- Xstruct obj *obj;
- Xconst char *drop_fmt, *drop_arg, *hold_msg;
- X{
- X long oquan = obj->quan;
- X if (!Blind) obj->dknown = 1; /* maximize mergibility */
- X if (Fumbling) {
- X if (drop_fmt) pline(drop_fmt, drop_arg);
- X dropy(obj);
- X } else {
- X obj = addinv(obj);
- X if (inv_cnt() > 52
- X || ((obj->otyp != LOADSTONE || !obj->cursed)
- X && near_capacity() >= OVERLOADED)) {
- X if (drop_fmt) pline(drop_fmt, drop_arg);
- X dropx(obj);
- X } else {
- X if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan);
- X }
- X }
- X return obj;
- X}
- X
- Xvoid
- Xuseup(obj)
- Xregister struct obj *obj;
- X{
- X /* Note: This works correctly for containers because they */
- X /* (containers) don't merge. */
- X if(obj->quan > 1L){
- X#ifndef NO_SIGNAL
- X obj->in_use = FALSE; /* no longer in use */
- X#endif
- X obj->quan--;
- X obj->owt = weight(obj);
- X } else {
- X setnotworn(obj);
- X freeinv(obj);
- X obfree(obj, (struct obj *) 0); /* deletes contents also */
- X }
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL3
- X
- X/* used by freeinv and doorganize to do list manipulation */
- XSTATIC_OVL
- Xvoid
- Xunlinkinv(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X
- X if(obj == invent)
- X invent = invent->nobj;
- X else {
- X for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
- X if(!otmp->nobj) panic("unlinkinv");
- X otmp->nobj = obj->nobj;
- X }
- X obj->nobj = 0;
- X}
- X
- Xvoid
- Xfreeinv(obj)
- Xregister struct obj *obj;
- X{
- X unlinkinv(obj);
- X
- X if (obj->otyp == GOLD_PIECE) {
- X u.ugold -= obj->quan;
- X flags.botl = 1;
- X return;
- X } else if (obj->otyp == AMULET_OF_YENDOR) {
- X if (!u.uhave.amulet) impossible ("don't have amulet?");
- X u.uhave.amulet = 0;
- X } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
- X if (!u.uhave.menorah) impossible ("don't have candelabrum?");
- X u.uhave.menorah = 0;
- X } else if (obj->otyp == BELL_OF_OPENING) {
- X if (!u.uhave.bell) impossible ("don't have silver bell?");
- X u.uhave.bell = 0;
- X } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- X if (!u.uhave.book) impossible ("don't have the book?");
- X u.uhave.book = 0;
- X#ifdef MULDGN
- X } else if (is_quest_artifact(obj)) {
- X if(!u.uhave.questart) impossible ("don't have the artifact?");
- X u.uhave.questart = 0;
- X set_artifact_intrinsic(obj, 0, W_ART);
- X#endif
- X } else if (obj->oartifact) {
- X set_artifact_intrinsic(obj, 0, W_ART);
- X } else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP
- X || obj->otyp == BRASS_LANTERN) {
- X if (obj->lamplit) {
- X obj->lamplit = 0;
- X if (!Blind) pline("%s goes out!", The(xname(obj)));
- X }
- X check_lamps();
- X } else if (obj->otyp == LOADSTONE) {
- X curse(obj);
- X } else if (obj->otyp == LUCKSTONE
- X || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) {
- X int luckbon = stone_luck(TRUE);
- X if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
- X else if (luckbon >= 0) u.moreluck = LUCKADD;
- X else u.moreluck = -LUCKADD;
- X flags.botl = 1;
- X }
- X update_inventory();
- X}
- X
- Xvoid
- Xdelallobj(x, y)
- Xint x, y;
- X{
- X struct obj *otmp, *otmp2;
- X
- X for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
- X otmp2 = otmp->nexthere;
- X if (otmp == uball)
- X unpunish();
- X if (otmp == uchain)
- X continue;
- X delobj(otmp);
- X }
- X}
- X
- X#endif /* OVL3 */
- X#ifdef OVL2
- X
- X/* destroy object in fobj chain (if unpaid, it remains on the bill) */
- Xvoid
- Xdelobj(obj)
- Xregister struct obj *obj;
- X{
- X#ifdef WALKIES
- X if(obj->otyp == LEASH && obj->leashmon != 0) o_unleash(obj);
- X#endif
- X freeobj(obj);
- X newsym(obj->ox,obj->oy);
- X obfree(obj, (struct obj *) 0); /* frees contents also */
- X}
- X
- X/* unlink obj from chain starting with fobj */
- Xvoid
- Xfreeobj(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X
- X if (obj == fobj)
- X fobj = fobj->nobj;
- X else {
- X for(otmp = fobj; otmp; otmp = otmp->nobj)
- X if (otmp->nobj == obj) {
- X otmp->nobj = obj->nobj;
- X break;
- X }
- X if (!otmp) panic("error in freeobj");
- X }
- X remove_object(obj);
- X}
- X
- X#endif /* OVL2 */
- X#ifdef OVL0
- X
- Xstruct obj *
- Xsobj_at(n,x,y)
- Xregister int n, x, y;
- X{
- X register struct obj *otmp;
- X
- X for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
- X if(otmp->otyp == n)
- X return(otmp);
- X return((struct obj *)0);
- X}
- X
- X#endif /* OVL0 */
- X#ifdef OVLB
- X
- Xint
- Xcarried(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X
- X for(otmp = invent; otmp; otmp = otmp->nobj)
- X if(otmp == obj) return(1);
- X return(0);
- X}
- X
- Xstruct obj *
- Xcarrying(type)
- Xregister int type;
- X{
- X register struct obj *otmp;
- X
- X for(otmp = invent; otmp; otmp = otmp->nobj)
- X if(otmp->otyp == type)
- X return(otmp);
- X return((struct obj *) 0);
- X}
- X
- Xboolean
- Xhave_lizard()
- X{
- X register struct obj *otmp;
- X
- X for(otmp = invent; otmp; otmp = otmp->nobj)
- X if(otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD)
- X return(TRUE);
- X return(FALSE);
- X}
- X
- Xstruct obj *
- Xo_on(id, objchn)
- Xunsigned int id;
- Xregister struct obj *objchn;
- X{
- X struct obj *temp;
- X
- X while(objchn) {
- X if(objchn->o_id == id) return(objchn);
- X if (Is_container(objchn) && (temp = o_on(id,objchn->cobj)))
- X return temp;
- X objchn = objchn->nobj;
- X }
- X return((struct obj *) 0);
- X}
- X
- Xboolean
- Xobj_here(obj, x, y)
- Xregister struct obj *obj;
- Xint x, y;
- X{
- X register struct obj *otmp;
- X
- X for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
- X if(obj == otmp) return(TRUE);
- X return(FALSE);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL2
- X
- Xstruct obj *
- Xg_at(x,y)
- Xregister int x, y;
- X{
- X register struct obj *obj = level.objects[x][y];
- X while(obj) {
- X if (obj->otyp == GOLD_PIECE) return obj;
- X obj = obj->nexthere;
- X }
- X return((struct obj *)0);
- X}
- X
- X#endif /* OVL2 */
- X#ifdef OVLB
- X
- X/* Make a gold object from the hero's gold. */
- Xstruct obj *
- Xmkgoldobj(q)
- Xregister long q;
- X{
- X register struct obj *otmp;
- X
- X otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
- X u.ugold -= q;
- X otmp->quan = q;
- X otmp->owt = weight(otmp);
- X flags.botl = 1;
- X return(otmp);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- X
- XSTATIC_OVL void
- Xcompactify(buf)
- Xregister char *buf;
- X/* compact a string of inventory letters by dashing runs of letters */
- X{
- X register int i1 = 1, i2 = 1;
- X register char ilet, ilet1, ilet2;
- X
- X ilet2 = buf[0];
- X ilet1 = buf[1];
- X buf[++i2] = buf[++i1];
- X ilet = buf[i1];
- X while(ilet) {
- X if(ilet == ilet1+1) {
- X if(ilet1 == ilet2+1)
- X buf[i2 - 1] = ilet1 = '-';
- X else if(ilet2 == '-') {
- X buf[i2 - 1] = ++ilet1;
- X buf[i2] = buf[++i1];
- X ilet = buf[i1];
- X continue;
- X }
- X }
- X ilet2 = ilet1;
- X ilet1 = ilet;
- X buf[++i2] = buf[++i1];
- X ilet = buf[i1];
- X }
- X}
- X
- X/*
- X * getobj returns:
- X * struct obj *xxx: object to do something with.
- X * (struct obj *) 0 error return: no object.
- X * &zeroobj explicitly no object (as in w-).
- X */
- Xstruct obj *
- Xgetobj(let,word)
- Xregister const char *let,*word;
- X{
- X register struct obj *otmp;
- X register char ilet;
- X char buf[BUFSZ], qbuf[QBUFSZ];
- X char lets[BUFSZ];
- X register int foo = 0;
- X register char *bp = buf;
- X xchar allowcnt = 0; /* 0, 1 or 2 */
- X boolean allowgold = FALSE, usegold = FALSE;
- X /* Two possibilities: they can't use gold because it's illegal,
- X * or they can't use gold because they don't have any.
- X */
- X boolean allowall = FALSE;
- X boolean allownone = FALSE;
- X xchar foox = 0;
- X long cnt;
- X boolean prezero = FALSE;
- X
- X if(*let == ALLOW_COUNT) let++, allowcnt = 1;
- X if(*let == GOLD_CLASS) let++,
- X usegold = TRUE, allowgold = (u.ugold ? TRUE : FALSE);
- X#ifdef POLYSELF
- X /* Equivalent of an "ugly check" for gold */
- X if (usegold && !strcmp(word, "eat") && !metallivorous(uasmon))
- X usegold = allowgold = FALSE;
- X#endif
- X if(*let == ALL_CLASSES) let++, allowall = TRUE;
- X if(*let == ALLOW_NONE) let++, allownone = TRUE;
- X /* "ugly check" for reading fortune cookies, part 1 */
- X if(allowall && !strcmp(word, "read")) allowall = FALSE;
- X
- X if(allownone) *bp++ = '-';
- X if(allowgold) *bp++ = def_oc_syms[GOLD_CLASS];
- X if(bp > buf && bp[-1] == '-') *bp++ = ' ';
- X
- X ilet = 'a';
- X for(otmp = invent; otmp; otmp = otmp->nobj){
- X if(!*let || index(let, otmp->oclass)) {
- X bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
- X
- X /* ugly check: remove inappropriate things */
- X if((!strcmp(word, "take off") &&
- X (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))
- X || (otmp==uarm && uarmc)
- X#ifdef TOURIST
- X || (otmp==uarmu && (uarm || uarmc))
- X#endif
- X ))
- X || (!strcmp(word, "wear") &&
- X (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))
- X /* already worn */
- X || (!strcmp(word, "wield") &&
- X (otmp->owornmask & W_WEP))
- X ) {
- X foo--;
- X foox++;
- X }
- X
- X /* Second ugly check; unlike the first it won't trigger an
- X * "else" in "you don't have anything else to ___".
- X */
- X else if ((!strcmp(word, "wear") &&
- X (otmp->oclass == TOOL_CLASS &&
- X otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL))
- X#ifdef POLYSELF
- X || (!strcmp(word, "eat") && !is_edible(otmp))
- X#endif
- X || (!strcmp(word, "can") &&
- X (otmp->otyp != CORPSE))
- X || (!strcmp(word, "write with") &&
- X (otmp->oclass == TOOL_CLASS &&
- X otmp->otyp != MAGIC_MARKER && otmp->otyp != TOWEL))
- X || (!strcmp(word, "rub") &&
- X (otmp->oclass == TOOL_CLASS &&
- X otmp->otyp != OIL_LAMP && otmp->otyp != MAGIC_LAMP &&
- X otmp->otyp != BRASS_LANTERN))
- X || (!strcmp(word, "wield") &&
- X (otmp->oclass == TOOL_CLASS &&
- X otmp->otyp != PICK_AXE && otmp->otyp != UNICORN_HORN))
- X )
- X foo--;
- X } else {
- X
- X /* "ugly check" for reading fortune cookies, part 2 */
- X if ((!strcmp(word, "read") && otmp->otyp == FORTUNE_COOKIE))
- X allowall = TRUE;
- X }
- X
- X if(ilet == 'z') ilet = 'A'; else ilet++;
- X }
- X bp[foo] = 0;
- X if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
- X Strcpy(lets, bp); /* necessary since we destroy buf */
- X if(foo > 5) /* compactify string */
- X compactify(bp);
- X
- X if(!foo && !allowall && !allowgold && !allownone) {
- X You("don't have anything %sto %s.",
- X foox ? "else " : "", word);
- X return((struct obj *)0);
- X }
- X for(;;) {
- X cnt = 0;
- X if (allowcnt == 2) allowcnt = 1; /* abort previous count */
- X if(!buf[0]) {
- X Sprintf(qbuf, "What do you want to %s? [*]", word);
- X } else {
- X Sprintf(qbuf, "What do you want to %s? [%s or ?*]",
- X word, buf);
- X }
- X#ifdef REDO
- X if(!in_doagain)
- X ilet = yn_function(qbuf, NULL, '\0');
- X else
- X#endif
- X ilet = readchar();
- X if(ilet == '0') prezero = TRUE;
- X while(digit(ilet) && allowcnt) {
- X#ifdef REDO
- X if (ilet != '?' && ilet != '*') savech(ilet);
- X#endif
- X cnt = 10*cnt + (ilet - '0');
- X allowcnt = 2; /* signal presence of cnt */
- X ilet = readchar();
- X }
- X if(digit(ilet)) {
- X pline("No count allowed with this command.");
- X continue;
- X }
- X if(index(quitchars,ilet)) {
- X if(flags.verbose)
- X pline("Never mind.");
- X return((struct obj *)0);
- X }
- X if(ilet == '-') {
- X return(allownone ? &zeroobj : (struct obj *) 0);
- X }
- X if(ilet == def_oc_syms[GOLD_CLASS]) {
- X if(!usegold){
- X You("cannot %s gold.", word);
- X return(struct obj *)0;
- X } else if (!allowgold) {
- X You("are not carrying any gold.");
- X return(struct obj *)0;
- X }
- X if(cnt == 0 && prezero) return((struct obj *)0);
- X /* Historic note: early Nethack had a bug which was
- X * first reported for Larn, where trying to drop 2^32-n
- X * gold pieces was allowed, and did interesting things
- X * to your money supply. The LRS is the tax bureau
- X * from Larn.
- X */
- X if(cnt < 0) {
- X pline("The LRS would be very interested to know you have that much.");
- X return(struct obj *)0;
- X }
- X
- X if(!(allowcnt == 2 && cnt < u.ugold))
- X cnt = u.ugold;
- X return(mkgoldobj(cnt));
- X }
- X if(allowcnt == 2 && !strcmp(word,"throw")) {
- X /* permit counts for throwing gold, but don't accept
- X * counts for other things since the throw code will
- X * split off a single item anyway */
- X allowcnt = 1;
- X if(cnt == 0 && prezero) return((struct obj *)0);
- X if(cnt > 1) {
- X You("can only throw one item at a time.");
- X continue;
- X }
- X }
- X if(ilet == '?' || ilet == '*') {
- X ilet = display_inventory(ilet == '?' ? lets : NULL, FALSE);
- X if(!ilet) continue;
- X if(ilet == '\033') {
- X if(flags.verbose)
- X pline("Never mind.");
- X return((struct obj *)0);
- X }
- X /* they typed a letter (not a space) at the prompt */
- X }
- X#ifdef REDO
- X savech(ilet);
- X#endif
- X if(flags.invlet_constant) {
- X for(otmp = invent; otmp; otmp = otmp->nobj)
- X if(otmp->invlet == ilet) break;
- X } else {
- X if(ilet >= 'A' && ilet <= 'Z') ilet += 'z' - 'A' + 1;
- X ilet -= 'a';
- X for(otmp = invent; otmp && ilet;
- X ilet--, otmp = otmp->nobj) ;
- X }
- X if(!otmp) {
- X You("don't have that object.");
- X continue;
- X } else if (cnt < 0 || otmp->quan < cnt) {
- X You("don't have that many! You have only %ld.",
- X otmp->quan);
- X continue;
- X }
- X break;
- X }
- X if(!allowall && let && !index(let,otmp->oclass)) {
- X pline(silly_thing_to, word);
- X return((struct obj *)0);
- X }
- X if(allowcnt == 2) { /* cnt given */
- X if(cnt == 0) return (struct obj *)0;
- X if(cnt != otmp->quan) {
- X register struct obj *obj = splitobj(otmp, cnt);
- X /* Very ugly kludge necessary to prevent someone from trying
- X * to drop one of several loadstones and having the loadstone
- X * now be separate.
- X */
- X if (!strcmp(word, "drop") &&
- X obj->otyp == LOADSTONE && obj->cursed)
- X otmp->corpsenm = obj->invlet;
- X if(otmp == uwep) setuwep(obj);
- X }
- X }
- X return(otmp);
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- XSTATIC_PTR int
- Xckunpaid(otmp)
- Xregister struct obj *otmp;
- X{
- X return((int)(otmp->unpaid));
- X}
- X
- Xstatic boolean
- Xwearing_armor() {
- X return(uarm || uarmc || uarmf || uarmg || uarmh || uarms
- X#ifdef TOURIST
- X || uarmu
- X#endif
- X );
- X}
- X
- Xstatic boolean
- Xis_worn(otmp)
- Xregister struct obj *otmp;
- X{
- X return(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP)));
- X}
- X
- Xstatic const char NEARDATA removeables[] =
- X { ARMOR_CLASS, WEAPON_CLASS, RING_CLASS, AMULET_CLASS, TOOL_CLASS, 0 };
- X
- X/* interactive version of getobj - used for Drop, Identify and */
- X/* Takeoff (A). Return the number of times fn was called successfully */
- Xint
- Xggetobj(word, fn, mx)
- Xregister const char *word;
- Xregister int FDECL((*fn),(OBJ_P)), mx;
- X{
- X char buf[BUFSZ], qbuf[QBUFSZ];
- X register char *ip;
- X register char sym;
- X register int oletct = 0, iletct = 0;
- X register boolean allflag = FALSE;
- X char olets[20], ilets[20];
- X int FDECL((*ckfn),(OBJ_P)) = (int (*)()) 0;
- X xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
- X register boolean takeoff = !strcmp(word, "take off");
- X struct obj *obj;
- X int unpaid, oc_of_sym;
- X
- X if(takeoff && !wearing_armor() && !uwep && !uamul &&
- X !uleft && !uright && !ublindf) {
- X You("are not wearing anything.");
- X return(0);
- X }
- X if(!invent && !allowgold){
- X You("have nothing to %s.", word);
- X return(0);
- X }
- X
- X if (allowgold) ilets[iletct++] = def_oc_syms[GOLD_CLASS];
- X ilets[iletct] = '\0'; /* terminate for index() */
- X unpaid = 0;
- X for (obj = invent; obj; obj = obj->nobj) {
- X sym = (char) def_oc_syms[(int) obj->oclass];
- X if (!index(ilets, sym) && (!takeoff || is_worn(obj))) {
- X ilets[iletct++] = sym;
- X /* necessary because of index() being used above */
- X ilets[iletct] = '\0';
- X }
- X
- X if (obj->unpaid) unpaid = 1;
- X }
- X
- X if (!takeoff && (unpaid || invent)) {
- X ilets[iletct++] = ' ';
- X if (unpaid) ilets[iletct++] = 'u';
- X if (invent) ilets[iletct++] = 'a';
- X }
- X ilets[iletct] = '\0'; /* outside the if to catch iletct==0 case */
- X
- X Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",
- X word, ilets);
- X getlin(qbuf, buf);
- X if(buf[0] == '\033') {
- X clear_nhwindow(WIN_MESSAGE);
- X return(0);
- X }
- X ip = buf;
- X olets[0] = 0;
- X while ((sym = *ip++) != 0) {
- X if(sym == ' ') continue;
- X oc_of_sym = def_char_to_objclass(sym);
- X if(takeoff && !(uwep && oc_of_sym == uwep->oclass)
- X && (oc_of_sym != MAXOCLASSES)) {
- X if(!index(removeables,oc_of_sym)) {
- X pline("Not applicable.");
- X return(0);
- X } else if(oc_of_sym == ARMOR_CLASS && !wearing_armor()) {
- X You("are not wearing any armor.");
- X return(0);
- X } else if(oc_of_sym == WEAPON_CLASS && !uwep) {
- X You("are not wielding anything.");
- X return(0);
- X } else if(oc_of_sym == RING_CLASS && !uright && !uleft) {
- X You("are not wearing rings.");
- X return(0);
- X } else if(oc_of_sym == AMULET_CLASS && !uamul) {
- X You("are not wearing an amulet.");
- X return(0);
- X } else if(oc_of_sym == TOOL_CLASS && !ublindf) {
- X You("are not wearing a blindfold.");
- X return(0);
- X }
- X }
- X if(oc_of_sym == GOLD_CLASS) {
- X if(allowgold == 1)
- X (*fn)(mkgoldobj(u.ugold));
- X else if(!u.ugold)
- X You("have no gold.");
- X allowgold = 2;
- X } else if(sym == 'a' || sym == 'A')
- X allflag = TRUE;
- X else if(sym == 'u' || sym == 'U')
- X ckfn = ckunpaid;
- X else if (oc_of_sym == MAXOCLASSES)
- X You("don't have any %c's.", sym);
- X else if (oc_of_sym != VENOM_CLASS) {/* venom doesn't show up */
- X if (!index(olets, oc_of_sym)) {
- X olets[oletct++] = oc_of_sym;
- X olets[oletct] = 0;
- X }
- X }
- X }
- X if(allowgold == 2 && !oletct)
- X return 1; /* you dropped gold (or at least tried to) */
- X else
- X return askchain((struct obj **)&invent, olets, allflag,
- X fn, ckfn, mx, word);
- X}
- X
- X/*
- X * Walk through the chain starting at objchn and ask for all objects
- X * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
- X * whether the action in question (i.e., fn) has to be performed.
- X * If allflag then no questions are asked. Max gives the max nr of
- X * objects to be treated. Return the number of objects treated.
- X */
- Xint
- Xaskchain(objchn, olets, allflag, fn, ckfn, mx, word)
- Xstruct obj **objchn;
- Xregister int allflag, mx;
- Xregister const char *olets, *word; /* olets is an Obj Class char array */
- Xregister int FDECL((*fn),(OBJ_P)), FDECL((*ckfn),(OBJ_P));
- X{
- X register struct obj *otmp, *otmp2;
- X register char sym, ilet;
- X register int cnt = 0, dud = 0, tmp;
- X boolean takeoff, nodot, ident, ininv;
- X char qbuf[QBUFSZ];
- X
- X takeoff = !strcmp(word, "take off");
- X ident = !strcmp(word, "identify");
- X nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") ||
- X ident || takeoff);
- X ininv = (*objchn == invent);
- X /* Changed so the askchain is interrogated in the order specified.
- X * For example, if a person specifies =/ then first all rings will be
- X * asked about followed by all wands -dgk
- X */
- Xnextclass:
- X ilet = 'a'-1;
- X if ((*objchn)->otyp == GOLD_PIECE) ilet--; /* extra iteration */
- X for (otmp = *objchn; otmp; otmp = otmp2) {
- X if(ilet == 'z') ilet = 'A'; else ilet++;
- X otmp2 = otmp->nobj;
- X if (olets && *olets && otmp->oclass != *olets) continue;
- X if(takeoff && !is_worn(otmp)) continue;
- X if(ckfn && !(*ckfn)(otmp)) continue;
- X if(!allflag) {
- X Strcpy(qbuf, ininv ?
- X xprname(otmp, ilet, !nodot, 0L) : doname(otmp));
- X Strcat(qbuf, "?");
- X sym = (takeoff || ident || otmp->quan < 2L) ?
- X nyaq(qbuf) : nyNaq(qbuf);
- X }
- X else sym = 'y';
- X
- X if (sym == '#') {
- X /* Number was entered; split the object unless it corresponds
- X to 'none' or 'all'. 2 special cases: cursed loadstones and
- X welded weapons (eg, multiple daggers) will remain as merged
- X unit; done to avoid splitting an object that won't be
- X droppable (even if we're picking up rather than dropping).
- X */
- X if (!yn_number)
- X sym = 'n';
- X else {
- X sym = 'y';
- X if (yn_number < otmp->quan && !welded(otmp) &&
- X (!otmp->cursed || otmp->otyp != LOADSTONE)) {
- X struct obj *otmpx = splitobj(otmp, yn_number);
- X if (!otmpx || otmpx->nobj != otmp2)
- X impossible("bad object split in askchain");
- X }
- X }
- X }
- X switch(sym){
- X case 'a':
- X allflag = 1;
- X case 'y':
- X tmp = (*fn)(otmp);
- X if(tmp < 0) goto ret;
- X cnt += tmp;
- X if(--mx == 0) goto ret;
- X case 'n':
- X if(nodot) dud++;
- X default:
- X break;
- X case 'q':
- X goto ret;
- X }
- X }
- X if (olets && *olets && *++olets)
- X goto nextclass;
- X if(!takeoff && (dud || cnt)) pline("That was all.");
- X else if(!dud && !cnt) pline("No applicable objects.");
- Xret:
- X return(cnt);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL2
- X
- XSTATIC_OVL char
- Xobj_to_let(obj) /* should of course only be called for things in invent */
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X register char ilet;
- X
- X if (obj->otyp == GOLD_PIECE)
- X return GOLD_SYM;
- X else if (flags.invlet_constant)
- X return obj->invlet;
- X ilet = 'a';
- X for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
- X if(++ilet > 'z') ilet = 'A';
- X return(otmp ? ilet : NOINVSYM);
- X}
- X
- X/*
- X * Print the indicated quantity of the given object. If quan == 0L then use
- X * the current quantity.
- X */
- Xvoid
- Xprinv(prefix, obj, quan)
- Xconst char *prefix;
- Xregister struct obj *obj;
- Xlong quan;
- X{
- X#ifdef GCC_WARN
- X long savequan = 0;
- X#else
- X long savequan;
- X#endif
- X if ( !prefix ) prefix = "";
- X if (quan) {
- X savequan = obj->quan;
- X obj->quan = quan;
- X }
- X pline("%s%s%s",
- X prefix, *prefix ? " " : "",
- X xprname(obj, obj_to_let(obj), TRUE, 0L));
- X if (quan) obj->quan = savequan;
- X}
- X
- X#endif /* OVL2 */
- X#ifdef OVL1
- X
- Xchar *
- Xxprname(obj,let,dot,cost)
- Xregister struct obj *obj;
- Xregister char let;
- Xregister boolean dot; /* append period; (dot && cost => Iu) */
- Xregister long cost; /* cost (for inventory of unpaid or expended items) */
- X{
- X#ifdef LINT /* handle static char li[BUFSZ]; */
- X char li[BUFSZ];
- X#else
- X static char li[BUFSZ];
- X#endif
- X boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM;
- X /*
- X * If let is:
- X * * Then obj == NULL and we are printing a total amount.
- X * > Then the object is contained and doesn't have an inventory letter.
- X */
- X if (cost != 0 || let == '*') {
- X /* if dot is true, we're doing Iu, otherwise Ix */
- X Sprintf(li, "%c - %-45s %6ld zorkmid%s",
- X (dot && use_invlet ? obj->invlet : let),
- X (let != '*' ? doname(obj) : "Total:"), cost, plur(cost));
- X } else if (obj->otyp == GOLD_PIECE) {
- X Sprintf(li, "%ld gold piece%s%s", obj->quan, plur(obj->quan),
- X (dot ? "." : ""));
- X } else {
- X /* ordinary inventory display or pickup message */
- X Sprintf(li, "%c - %s",
- X (use_invlet ? obj->invlet : let),
- X doname(obj));
- X if(dot) Strcat(li,".");
- X }
- X return li;
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- Xint
- Xddoinv()
- X{
- X (void) display_inventory(NULL, FALSE);
- X return 0;
- X}
- X
- X/*
- X * find_unpaid()
- X *
- X * Scan the given list of objects. If last_found is NULL, return the first
- X * unpaid object found. If last_found is not NULL, then skip over unpaid
- X * objects until last_found is reached, then set last_found to NULL so the
- X * next unpaid object is returned. This routine recursively follows
- X * containers.
- X */
- Xstatic struct obj *
- Xfind_unpaid(list, last_found)
- X struct obj *list, **last_found;
- X{
- X struct obj *obj;
- X
- X while (list) {
- X if (list->unpaid) {
- X if (*last_found) {
- X /* still looking for previous unpaid object */
- X if (list == *last_found)
- X *last_found = (struct obj *) 0;
- X } else
- X return (*last_found = list);
- X }
- X if (Is_container(list) && list->cobj) {
- X if ((obj = find_unpaid(list->cobj, last_found)) != 0)
- X return obj;
- X }
- X list = list->nobj;
- X }
- X return (struct obj *) 0;
- X}
- X
- X/*
- X * If lets == NULL or "", list all objects in the inventory. Otherwise,
- X * list all objects with object classes that match the order in lets.
- X * The last letter could possibly be a '>' which means list unpaid contained
- X * objects.
- X * Returns the letter identifier of a selected item, or 0 (nothing was
- X * selected), or '\033' (the menu was cancelled).
- X */
- Xchar
- Xdisplay_inventory(lets,show_cost)
- Xregister const char *lets;
- Xboolean show_cost;
- X{
- X register struct obj *otmp;
- X struct obj *z_obj;
- X register char ilet;
- X char *invlet = inv_order;
- X int classcount;
- X#if defined(LINT) || defined(GCC_WARN)
- X int save_unpaid = 0;
- X#else
- X int save_unpaid;
- X#endif
- X long cost, totcost;
- X boolean do_containers = FALSE;
- X
- X if(!invent){
- X pline("Not carrying anything.");
- X return 0;
- X }
- X if (lets != NULL) {
- X int ct = strlen(lets); /* count number of inventory slots to show */
- X /* If we've got unpaid items in containers, count all unpaid
- X objects. At least one won't be in any inventory slot. */
- X do_containers = (ct && lets[ct-1] == CONTAINED_SYM);
- X if (do_containers && ct == 1) ct = count_unpaid(invent);
- X /* if only one item of interest, use pline instead of menus */
- X if (ct == 1) {
- X if (do_containers) { /* single non-inventory object */
- X z_obj = (struct obj *) 0;
- X if ((otmp = find_unpaid(invent, &z_obj)) != 0)
- X pline(xprname(otmp, CONTAINED_SYM, TRUE,
- X (show_cost ? unpaid_cost(otmp) : 0L)));
- X else
- X impossible(
- X "display_inventory: no singular unpaid contained objects");
- X } else {
- X for(otmp = invent; otmp; otmp = otmp->nobj) {
- X if (otmp->invlet == lets[0]) {
- X pline(xprname(otmp, lets[0], TRUE,
- X (show_cost ? unpaid_cost(otmp) : 0L)));
- X break;
- X }
- X }
- X }
- X return 0;
- X }
- X }
- X
- X start_menu(WIN_INVEN);
- X cost = totcost = 0;
- Xnextclass:
- X classcount = 0;
- X ilet = 'a';
- X for(otmp = invent; otmp; otmp = otmp->nobj) {
- X if(flags.invlet_constant) ilet = otmp->invlet;
- X if(!lets || !*lets || index(lets, ilet)) {
- X if (!flags.sortpack || otmp->oclass == *invlet) {
- X if (flags.sortpack && !classcount) {
- X add_menu(WIN_INVEN, 0, ATR_INVERSE,
- X let_to_name(*invlet, show_cost));
- X classcount++;
- X }
- X if (show_cost) {
- X totcost += cost = unpaid_cost(otmp);
- X /* suppress "(unpaid)" suffix */
- X save_unpaid = otmp->unpaid;
- X otmp->unpaid = 0;
- X }
- X add_menu(WIN_INVEN, ilet, 0,
- X xprname(otmp, ilet, TRUE, cost));
- X if (show_cost) otmp->unpaid = save_unpaid;
- X }
- X }
- X if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
- X }
- X if (flags.sortpack) {
- X if (*++invlet) goto nextclass;
- X#ifdef WIZARD
- X if (--invlet != venom_inv) {
- X invlet = venom_inv;
- X goto nextclass;
- X }
- X#endif
- X }
- X
- X /* right now, we only do this for unpaid items, so always do cost */
- X if (do_containers) {
- X if (flags.sortpack) add_menu(WIN_INVEN, 0, ATR_INVERSE,
- X let_to_name(CONTAINED_SYM, 1));
- X /*
- X * Search through the container objects in the inventory for
- X * unpaid items. Note that we check each container, not
- X * the invent list. This is because the invent list could
- X * have unpaid items that have been already listed.
- X */
- X for (otmp = invent; otmp; otmp = otmp->nobj) {
- X if (Is_container(otmp) && otmp->cobj) {
- X z_obj = (struct obj *) 0; /* haven't found any */
- X while (find_unpaid(otmp->cobj, (struct obj **)&z_obj)) {
- X totcost += cost = unpaid_cost(z_obj);
- X save_unpaid = z_obj->unpaid;
- X z_obj->unpaid = 0; /* suppress "(unpaid)" suffix */
- X add_menu(WIN_INVEN, 0, 0,
- X xprname(z_obj, CONTAINED_SYM, TRUE, cost));
- X z_obj->unpaid = save_unpaid;
- X }
- X }
- X }
- X }
- X
- X if (show_cost) {
- X /* give 'Totals' line */
- X add_menu(WIN_INVEN, 0, 0, "");
- X add_menu(WIN_INVEN, 0, 0,
- X xprname((struct obj *)0, '*', FALSE, totcost));
- X }
- X end_menu(WIN_INVEN, '\033', "\033 ", NULL);
- X return select_menu(WIN_INVEN);
- X}
- X
- X/*
- X * Returns the number of unpaid items within the given list. This includes
- X * contained objects.
- X */
- Xint
- Xcount_unpaid(list)
- X struct obj *list;
- X{
- X int count = 0;
- X
- X while (list) {
- X if (list->unpaid) count++;
- X if (Is_container(list) && list->cobj)
- X count += count_unpaid(list->cobj);
- X list = list->nobj;
- X }
- X return count;
- X}
- X
- Xint
- Xdotypeinv() /* free after Robert Viduya */
- X/* Changed to one type only, so you don't have to type return */
- X{
- X char c, ilet;
- X char stuff[BUFSZ];
- X register int stct;
- X register struct obj *otmp;
- X boolean billx = *u.ushops && doinvbill(0);
- X boolean do_unpd = FALSE;
- X int unpd, class;
- X
- X if (!invent && !u.ugold && !billx) {
- X You("aren't carrying anything.");
- X return 0;
- X }
- X
- X Strcpy(stuff, "What type of object do you want an inventory of? [");
- X /* collect a list of classes of objects carried, for use as a prompt */
- X stct = collect_obj_classes(eos(stuff), invent, FALSE, (u.ugold != 0));
- X unpd = count_unpaid(invent);
- X if(unpd) Strcat(stuff, "u");
- X if(billx) Strcat(stuff, "x");
- X Strcat(stuff, "]");
- X
- X if(stct > 1) {
- X c = yn_function(stuff, NULL, '\0');
- X#ifdef REDO
- X savech(c);
- X#endif
- X if(c == '\0') {
- X clear_nhwindow(WIN_MESSAGE);
- X return 0;
- X }
- X } else
- X c = stuff[0];
- X
- X if(c == 'x' || c == 'X') {
- X if(billx)
- X (void) doinvbill(1);
- X else
- X pline("No used-up objects on the shopping bill.");
- X return(0);
- X }
- X
- X if (c == 'u' || c == 'U') {
- X if (!unpd) {
- X You("are not carrying any unpaid objects.");
- X return(0);
- X }
- X do_unpd = TRUE;
- X }
- X
- X class = def_char_to_objclass(c); /* change to object class */
- X
- X if(class == GOLD_CLASS)
- X return(doprgold());
- X
- X /* collect all items which match the selected objclass */
- X stct = 0;
- X ilet = 'a';
- X for (otmp = invent; otmp; otmp = otmp->nobj) {
- X if(flags.invlet_constant) ilet = otmp->invlet;
- X if (class == otmp->oclass || (do_unpd && otmp->unpaid)) {
- X stuff[stct++] = ilet;
- X --unpd; /* decrement unpaid count */
- X }
- X if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
- X }
- X /* unpd is now the number of unpaid contained objects */
- X if (do_unpd && unpd)
- X stuff[stct++] = CONTAINED_SYM; /* list contained unpaid items */
- X
- X stuff[stct] = '\0';
- X if(stct == 0)
- X You("have no such objects.");
- X else
- X (void) display_inventory(stuff, do_unpd);
- X
- X return(0);
- X}
- X
- X/* look at what is here */
- Xint
- Xdolook()
- X{
- X register struct obj *otmp, *otmp0;
- X struct trap *trap;
- X const char *verb = Blind ? "feel" : "see";
- X const char *dfeature = (char*) 0;
- X char fbuf[BUFSZ], fbuf2[BUFSZ];
- X int ct;
- X boolean no_article = FALSE;
- X winid tmpwin;
- X
- X if(u.uswallow) {
- X You("%s no objects here.", verb);
- X return(!!Blind);
- X }
- X read_engr_at(u.ux, u.uy); /* Eric Backus */
- X if ((trap = t_at(u.ux,u.uy)) && trap->tseen)
- X pline("There is a%s here.", traps[trap->ttyp]);
- X
- X otmp0 = level.objects[u.ux][u.uy];
- X
- X if(IS_DOOR(levl[u.ux][u.uy].typ)) {
- X switch(levl[u.ux][u.uy].doormask) {
- X case D_NODOOR:
- X dfeature = "doorway"; break;
- X case D_ISOPEN:
- X dfeature = "open door"; break;
- X case D_BROKEN:
- X dfeature = "broken door"; break;
- X default:
- X dfeature = "closed door";
- X }
- X } else if(IS_FOUNTAIN(levl[u.ux][u.uy].typ))
- X /* added by GAN 10/30/86 */
- X dfeature = "fountain";
- X else if(IS_THRONE(levl[u.ux][u.uy].typ))
- X dfeature = "opulent throne";
- X else if(is_lava(u.ux,u.uy))
- X dfeature = "molten lava", no_article = TRUE;
- X else if(is_ice(u.ux,u.uy))
- X dfeature = "ice", no_article = TRUE;
- X else if(is_pool(u.ux,u.uy) && !Underwater)
- X dfeature = "pool of water";
- X#ifdef SINKS
- X else if(IS_SINK(levl[u.ux][u.uy].typ))
- X dfeature = "kitchen sink";
- X#endif
- X else if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
- X Sprintf(fbuf2, "altar to %s (%s)",
- X a_gname(),
- X align_str(Amask2align(levl[u.ux][u.uy].altarmask
- X & ~AM_SHRINE)));
- X dfeature = fbuf2;
- X } else if(u.ux == xupstair && u.uy == yupstair)
- X dfeature = "stairway up";
- X else if(u.ux == xdnstair && u.uy == ydnstair)
- X dfeature = "stairway down";
- X else if(u.ux == sstairs.sx && u.uy == sstairs.sy) {
- X if (sstairs.up)
- X dfeature = "stairway up";
- X else
- X dfeature = "stairway down";
- X } else if(u.ux == xupladder && u.uy == yupladder)
- X dfeature = "ladder up";
- X else if(u.ux == xdnladder && u.uy == ydnladder)
- X dfeature = "ladder down";
- X else if (levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN)
- X dfeature = "lowered drawbridge";
- X
- X if (Blind) {
- X You("try to feel what is %s.",
- X Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
- X "floating here" :
- X "lying here on the floor");
- X if (Levitation &&
- X !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
- X pline("But you can't reach it!");
- X return(0);
- X }
- X }
- X
- X if (dfeature)
- X Sprintf(fbuf, "There is %s%s here.",
- X no_article ? "" :
- X index(vowels,dfeature[0]) ? "an " : "a ",
- X dfeature);
- X
- X if(!otmp0 || (is_pool(u.ux,u.uy) && !Underwater)) {
- X if(dfeature) pline(fbuf);
- X if(Blind || !dfeature)
- X You("%s no objects here.", verb);
- X return(!!Blind);
- X }
- X /* we know there is something here */
- X
- X /* find out if there is more than one object there */
- X for (ct = 0, otmp = otmp0; otmp; otmp = otmp->nexthere)
- X if (++ct > 1) break;
- X
- X if (ct == 1) {
- X if (dfeature) pline(fbuf);
- X You("%s here %s.", verb, doname(otmp0));
- X } else {
- X display_nhwindow(NHW_MESSAGE, FALSE);
- X tmpwin = create_nhwindow(NHW_MENU);
- X if(dfeature) {
- X putstr(tmpwin, 0, fbuf);
- X putstr(tmpwin, 0, "");
- X }
- X putstr(tmpwin, 0, "Things that are here:");
- X for(otmp = otmp0; otmp; otmp = otmp->nexthere) {
- X putstr(tmpwin, 0, doname(otmp));
- X
- X if(Blind && !uarmg &&
- X#ifdef POLYSELF
- X !resists_ston(uasmon) &&
- X#endif
- X (otmp->otyp == CORPSE &&
- X otmp->corpsenm == PM_COCKATRICE)) {
- X#if defined(POLYSELF)
- X if(poly_when_stoned(uasmon)) {
- X You("touched the cockatrice corpse with your bare hands.");
- X (void) polymon(PM_STONE_GOLEM);
- X } else
- X#endif
- X {
- X pline("Touching the cockatrice corpse is a fatal mistake...");
- X You("turn to stone...");
- X killer_format = KILLED_BY_AN;
- X killer = "cockatrice corpse";
- X done(STONING);
- X }
- X }
- X }
- X display_nhwindow(tmpwin, TRUE);
- X destroy_nhwindow(tmpwin);
- X }
- X return(!!Blind);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- X
- Xvoid
- Xstackobj(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X
- X for(otmp = level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere)
- X if(otmp != obj && merged(obj,otmp,1))
- X break;
- X return;
- X}
- X
- Xstatic boolean
- Xmergable(otmp, obj) /* returns TRUE if obj & otmp can be merged */
- X register struct obj *otmp, *obj;
- X{
- X if(obj->otyp != otmp->otyp || obj->unpaid != otmp->unpaid ||
- X obj->spe != otmp->spe || obj->dknown != otmp->dknown ||
- X (obj->bknown != otmp->bknown && pl_character[0] != 'P') ||
- X obj->cursed != otmp->cursed || obj->blessed != otmp->blessed ||
- X obj->no_charge != otmp->no_charge ||
- X obj->obroken != otmp->obroken ||
- X obj->otrapped != otmp->otrapped ||
- X obj->oeroded != otmp->oeroded)
- X return(FALSE);
- X
- X if((obj->oclass==WEAPON_CLASS || obj->oclass==ARMOR_CLASS) &&
- X (obj->oerodeproof!=otmp->oerodeproof || obj->rknown!=otmp->rknown))
- X return FALSE;
- X
- X if(obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten ||
- X obj->orotten != otmp->orotten))
- X return(FALSE);
- X
- X if(obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) {
- X if((obj->corpsenm != otmp->corpsenm) ||
- X (ONAME(obj) && strcmp(ONAME(obj), ONAME(otmp))))
- X return FALSE;
- X }
- X
- X/* if they have names, make sure they're the same */
- X if ( (obj->onamelth != otmp->onamelth &&
- X ((obj->onamelth && otmp->onamelth) || obj->otyp == CORPSE)
- X ) ||
- X (obj->onamelth &&
- X strncmp(ONAME(obj), ONAME(otmp), (int)obj->onamelth)))
- X return FALSE;
- X
- X if(obj->oartifact != otmp->oartifact) return FALSE;
- X
- X if(obj->known == otmp->known ||
- X !objects[otmp->otyp].oc_uses_known) {
- X return(objects[obj->otyp].oc_merge);
- X } else return(FALSE);
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- Xint
- Xdoprgold(){
- X if(!u.ugold)
- X You("do not carry any gold.");
- X else
- X You("are carrying %ld gold piece%s.", u.ugold, plur(u.ugold));
- X return 0;
- X}
- X
- Xint
- Xdoprwep()
- X{
- X if(!uwep) You("are empty %s.", body_part(HANDED));
- X else prinv(NULL, uwep, 0L);
- X return 0;
- X}
- X
- Xint
- Xdoprarm(){
- X if(!wearing_armor())
- X You("are not wearing any armor.");
- X else {
- X#ifdef TOURIST
- X char lets[8];
- X#else
- X char lets[7];
- X#endif
- X register int ct = 0;
- X
- X#ifdef TOURIST
- X if(uarmu) lets[ct++] = obj_to_let(uarmu);
- X#endif
- X if(uarm) lets[ct++] = obj_to_let(uarm);
- X if(uarmc) lets[ct++] = obj_to_let(uarmc);
- X if(uarmh) lets[ct++] = obj_to_let(uarmh);
- X if(uarms) lets[ct++] = obj_to_let(uarms);
- X if(uarmg) lets[ct++] = obj_to_let(uarmg);
- X if(uarmf) lets[ct++] = obj_to_let(uarmf);
- X lets[ct] = 0;
- X (void) display_inventory(lets, FALSE);
- X }
- X return 0;
- X}
- X
- Xint
- Xdoprring(){
- X if(!uleft && !uright)
- X You("are not wearing any rings.");
- X else {
- X char lets[3];
- X register int ct = 0;
- X
- X if(uleft) lets[ct++] = obj_to_let(uleft);
- X if(uright) lets[ct++] = obj_to_let(uright);
- X lets[ct] = 0;
- X (void) display_inventory(lets, FALSE);
- X }
- X return 0;
- X}
- X
- Xint
- Xdopramulet(){
- X if (!uamul)
- X You("are not wearing an amulet.");
- X else
- X prinv(NULL, uamul, 0L);
- X return 0;
- X}
- X
- Xint
- Xdoprtool(){
- X register struct obj *otmp;
- X register int ct=0;
- X char lets[3]; /* Maximum: pick-axe, blindfold */
- X
- X for(otmp = invent; otmp; otmp = otmp->nobj) {
- X if (((otmp->owornmask & W_TOOL) && otmp->oclass==TOOL_CLASS)
- X || (otmp==uwep &&
- X (otmp->otyp==PICK_AXE || otmp->otyp==TIN_OPENER)))
- X lets[ct++] = obj_to_let(otmp);
- X }
- X lets[ct] = 0;
- X if (!ct) You("are not using any tools.");
- X else (void) display_inventory(lets, FALSE);
- X return 0;
- X}
- X
- X/*
- X * uses up an object that's on the floor, charging for it as necessary
- X */
- Xvoid
- Xuseupf(obj)
- Xregister struct obj *obj;
- X{
- X register struct obj *otmp;
- X
- X /* burn_floor_paper() keeps an object pointer that it tries to
- X * useupf() multiple times, so obj must survive if plural */
- X if(obj->quan > 1L)
- X otmp = splitobj(obj, obj->quan - 1L);
- X else
- X otmp = obj;
- X if(costly_spot(otmp->ox, otmp->oy)) {
- X if(index(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0)))
- X addtobill(otmp, FALSE, FALSE, FALSE);
- X else (void)stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE);
- X }
- X delobj(otmp);
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- X
- Xextern const char obj_symbols[]; /* o_init.c */
- X/*
- X * Conversion from a symbol to a string for printing object classes.
- X * This must match the array obj_symbols[].
- X */
- Xstatic const char NEARDATA *names[] = {
- X "Illegal objects", "Amulets", "Coins", "Comestibles", "Weapons",
- X "Tools", "Iron balls", "Chains", "Boulders/Statues", "Armor",
- X "Potions", "Scrolls", "Wands", "Spellbooks", "Rings", "Gems"
- X};
- X
- Xstatic const char NEARDATA oth_symbols[] = {
- X#ifdef WIZARD
- X VENOM_CLASS,
- X#endif
- X CONTAINED_SYM,
- X '\0'
- X};
- X
- Xstatic const char NEARDATA *oth_names[] = {
- X#ifdef WIZARD
- X "Venoms",
- X#endif
- X "Bagged/Boxed items"
- X};
- X
- Xchar *
- Xlet_to_name(let,unpaid)
- Xchar let;
- Xboolean unpaid;
- X{
- X const char *class_name;
- X const char *pos = index(obj_symbols, let);
- X int len;
- X static char NEARDATA *buf = NULL;
- X static unsigned NEARDATA bufsiz = 0;
- X
- X if (pos)
- X class_name = names[pos - obj_symbols];
- X else if ((pos = index(oth_symbols, let)) != 0)
- X class_name = oth_names[pos - oth_symbols];
- X else
- X class_name = names[0];
- X
- X len = strlen(class_name)
- X + (unpaid ? sizeof("unpaid_") : 1); /* count terminating NUL */
- X if (len > bufsiz) {
- X if (buf) free((genericptr_t)buf), buf = NULL;
- X bufsiz = len + 10; /* add slop to avoid incremental reallocations */
- X buf = (char *) alloc(bufsiz);
- X }
- X if (unpaid)
- X Strcat(strcpy(buf, "Unpaid "), class_name);
- X else
- X Strcpy(buf, class_name);
- X return (buf);
- X}
- X
- X#endif /* OVL1 */
- X#ifdef OVLB
- X
- Xvoid
- Xreassign()
- X{
- X register int i;
- X register struct obj *obj;
- X
- X for(obj = invent, i = 0; obj; obj = obj->nobj, i++)
- X obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26);
- X lastinvnr = i;
- X}
- X
- X#endif /* OVLB */
- X#ifdef OVL1
- Xint
- Xdoorganize() /* inventory organizer by Del Lamb */
- X{
- X register struct obj *obj, *otmp;
- X register int ix, cur;
- X register char let;
- X char alphabet[52+1], buf[52+1];
- X char qbuf[QBUFSZ];
- X char allow_all[2];
- X const char *adj_type;
- X
- X /* check to see if the inventory is of the fixed kind */
- X if (!flags.invlet_constant ) {
- X pline("Sorry, only fixed inventories can be adjusted.");
- X return(0);
- X }
- X#if 0
- X /* check to see if the inventory has any gaps left in it */
- X if (inv_cnt() >= 52) {
- X pline("Sorry, no available letters for adjustment.");
- X return(0);
- X }
- X#endif
- X /* get a pointer to the object the user wants to organize */
- X allow_all[0] = ALL_CLASSES; allow_all[1] = '\0';
- X if (!(obj = getobj(allow_all,"adjust"))) return(0);
- X
- X /* initialize the list with all upper and lower case letters */
- X for (let = 'a', ix = 0; let <= 'z';) alphabet[ix++] = let++;
- X for (let = 'A', ix = 26; let <= 'Z';) alphabet[ix++] = let++;
- X alphabet[52] = 0;
- X
- X /* blank out all the letters currently in use in the inventory */
- X /* except those that will be merged with the selected object */
- X for (otmp = invent; otmp; otmp = otmp->nobj)
- X if (otmp != obj && !mergable(otmp,obj))
- X if (otmp->invlet <= 'Z')
- X alphabet[(otmp->invlet) - 'A' + 26] = ' ';
- X else alphabet[(otmp->invlet) - 'a'] = ' ';
- X
- X /* compact the list by removing all the blanks */
- X for (ix = cur = 0; ix <= 52; ix++)
- X if (alphabet[ix] != ' ') buf[cur++] = alphabet[ix];
- X
- X /* and by dashing runs of letters */
- X if(cur > 5) compactify(buf);
- X
- X /* get new letter to use as inventory letter */
- X for (;;) {
- X Sprintf(qbuf, "Adjust letter to what [%s]?",buf);
- X let = yn_function(qbuf, NULL, '\0');
- X if(index(quitchars,let)) {
- X pline("Never mind.");
- X return(0);
- X }
- X if (let == '@' || !letter(let))
- X pline("Select an inventory slot letter.");
- X else
- X break;
- X }
- X
- X /* change the inventory and print the resulting item */
- X adj_type = "Moving:";
- X
- X /*
- X * don't use freeinv/addinv to avoid double-touching artifacts,
- X * dousing lamps, losing luck, cursing loadstone, etc.
- X */
- X unlinkinv(obj);
- X
- X for (otmp = invent; otmp;)
- X if (merged(otmp,obj,0)) {
- X adj_type = "Merging:";
- X obj = otmp;
- X otmp = otmp->nobj;
- X unlinkinv(obj);
- X } else {
- X if (otmp->invlet == let) {
- X adj_type = "Swapping:";
- X otmp->invlet = obj->invlet;
- X }
- X otmp = otmp->nobj;
- X }
- X
- X /* inline addinv (assuming flags.invlet_constant and !merged) */
- X obj->invlet = let;
- X obj->nobj = invent; /* insert at beginning */
- X invent = obj;
- X reorder_invent();
- X
- X prinv(adj_type, obj, 0L);
- X update_inventory();
- X return(0);
- X}
- X
- X#endif /* OVL1 */
- X
- X/*invent.c*/
- END_OF_FILE
- if test 47145 -ne `wc -c <'src/invent.c'`; then
- echo shar: \"'src/invent.c'\" unpacked with wrong size!
- fi
- # end of 'src/invent.c'
- fi
- echo shar: End of archive 13 \(of 108\).
- cp /dev/null ark13isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-